commit 6dd867928d0733c85d727613bfa20072bc7b54a6 Author: MSVSphere Packaging Team Date: Fri Mar 29 16:33:14 2024 +0300 import systemd-239-81.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6b4e19 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch +SOURCES/systemd-239.tar.gz diff --git a/.systemd.metadata b/.systemd.metadata new file mode 100644 index 0000000..bd83be9 --- /dev/null +++ b/.systemd.metadata @@ -0,0 +1,2 @@ +23da9fdb9eeaef49fe1adbf42a18d9e8a99d7911 SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch +8803baa484cbe36680463c8c5e6febeff074b8e7 SOURCES/systemd-239.tar.gz diff --git a/SOURCES/0001-build-sys-Detect-whether-struct-statx-is-defined-in-.patch b/SOURCES/0001-build-sys-Detect-whether-struct-statx-is-defined-in-.patch new file mode 100644 index 0000000..aadd1d6 --- /dev/null +++ b/SOURCES/0001-build-sys-Detect-whether-struct-statx-is-defined-in-.patch @@ -0,0 +1,105 @@ +From 79df4db3fd122f5040bdf2225c3047375de3b0d2 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Sun, 15 Jul 2018 22:43:35 -0700 +Subject: [PATCH] build-sys: Detect whether struct statx is defined in + sys/stat.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Starting with glibc 2.27.9000-36.fc29, include file sys/stat.h will have a +definition for struct statx, in which case include file linux/stat.h should be +avoided, in order to prevent a duplicate definition. + + In file included from ../src/basic/missing.h:18, + from ../src/basic/util.h:28, + from ../src/basic/hashmap.h:10, + from ../src/shared/bus-util.h:12, + from ../src/libsystemd/sd-bus/bus-creds.c:11: + /usr/include/linux/stat.h:99:8: error: redefinition of ‘struct statx’ + struct statx { + ^~~~~ + In file included from /usr/include/sys/stat.h:446, + from ../src/basic/util.h:19, + from ../src/basic/hashmap.h:10, + from ../src/shared/bus-util.h:12, + from ../src/libsystemd/sd-bus/bus-creds.c:11: + /usr/include/bits/statx.h:36:8: note: originally defined here + struct statx + ^~~~~ + +Extend our meson.build to look for struct statx when only sys/stat.h is +included and, in that case, do not include linux/stat.h anymore. + +Tested that systemd builds correctly when using a glibc version that includes a +definition for struct statx. + +glibc Fedora RPM update: +https://src.fedoraproject.org/rpms/glibc/c/28cb5d31fc1e5887912283c889689c47076278ae + +glibc upstream commit: +https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fd70af45528d59a00eb3190ef6706cb299488fcd +--- + meson.build | 5 +++++ + src/basic/missing.h | 5 ++++- + src/basic/xattr-util.c | 1 - + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index 04331dd41a..a0e7240708 100644 +--- a/meson.build ++++ b/meson.build +@@ -425,6 +425,7 @@ decl_headers = ''' + #include + ''' + # FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail ++# FIXME: these should use -D_GNU_SOURCE, since that is defined at build time + + foreach decl : ['char16_t', + 'char32_t', +@@ -439,6 +440,10 @@ foreach decl : ['char16_t', + conf.set10('HAVE_' + decl.underscorify().to_upper(), have) + endforeach + ++conf.set10('HAVE_STRUCT_STATX_IN_SYS_STAT_H', cc.sizeof('struct statx', prefix : ''' ++#include ++''', args : '-D_GNU_SOURCE') > 0) ++ + foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'], + ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'], + ['IFLA_VRF_TABLE', 'linux/if_link.h'], +diff --git a/src/basic/missing.h b/src/basic/missing.h +index 71a07d0574..14ad3d4914 100644 +--- a/src/basic/missing.h ++++ b/src/basic/missing.h +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -25,6 +24,10 @@ + #include + #include + ++#if !HAVE_STRUCT_STATX_IN_SYS_STAT_H ++#include ++#endif ++ + #if HAVE_AUDIT + #include + #endif +diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c +index c5c55ea846..0ee0979837 100644 +--- a/src/basic/xattr-util.c ++++ b/src/basic/xattr-util.c +@@ -2,7 +2,6 @@ + + #include + #include +-#include + #include + #include + #include diff --git a/SOURCES/0002-logind-set-RemoveIPC-to-false-by-default.patch b/SOURCES/0002-logind-set-RemoveIPC-to-false-by-default.patch new file mode 100644 index 0000000..d5244cd --- /dev/null +++ b/SOURCES/0002-logind-set-RemoveIPC-to-false-by-default.patch @@ -0,0 +1,50 @@ +From 0b3833d6c3b751c6dfb40eeb2ef852984c58f546 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 1 Aug 2018 10:58:28 +0200 +Subject: [PATCH] logind: set RemoveIPC to false by default + +Resolves: #1523233 +--- + man/logind.conf.xml | 2 +- + src/login/logind-core.c | 2 +- + src/login/logind.conf.in | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/man/logind.conf.xml b/man/logind.conf.xml +index 9e88764c6f..7d7e869a26 100644 +--- a/man/logind.conf.xml ++++ b/man/logind.conf.xml +@@ -319,7 +319,7 @@ + user fully logs out. Takes a boolean argument. If enabled, the user may not consume IPC resources after the + last of the user's sessions terminated. This covers System V semaphores, shared memory and message queues, as + well as POSIX shared memory and message queues. Note that IPC objects of the root user and other system users +- are excluded from the effect of this setting. Defaults to yes. ++ are excluded from the effect of this setting. Defaults to no. + + + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index dbae4bf5af..511e3acf8f 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -25,7 +25,7 @@ void manager_reset_config(Manager *m) { + + m->n_autovts = 6; + m->reserve_vt = 6; +- m->remove_ipc = true; ++ m->remove_ipc = false; + m->inhibit_delay_max = 5 * USEC_PER_SEC; + m->handle_power_key = HANDLE_POWEROFF; + m->handle_suspend_key = HANDLE_SUSPEND; +diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in +index 1029e29bc7..c7346f9819 100644 +--- a/src/login/logind.conf.in ++++ b/src/login/logind.conf.in +@@ -32,6 +32,6 @@ + #IdleAction=ignore + #IdleActionSec=30min + #RuntimeDirectorySize=10% +-#RemoveIPC=yes ++#RemoveIPC=no + #InhibitorsMax=8192 + #SessionsMax=8192 diff --git a/SOURCES/0003-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch b/SOURCES/0003-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch new file mode 100644 index 0000000..baf095b --- /dev/null +++ b/SOURCES/0003-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch @@ -0,0 +1,53 @@ +From b924c79720cc2bf2edf75fa3ff43bb4954fccf1f Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 1 Aug 2018 13:19:39 +0200 +Subject: [PATCH] pid1: bump DefaultTasksMax to 80% of the kernel pid.max value + +This should be hopefully high enough even for the very big deployments. + +Resolves: #1523236 +--- + man/systemd-system.conf.xml | 2 +- + src/basic/cgroup-util.h | 2 +- + src/core/system.conf.in | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml +index a914ef2523..085086200a 100644 +--- a/man/systemd-system.conf.xml ++++ b/man/systemd-system.conf.xml +@@ -339,7 +339,7 @@ + Configure the default value for the per-unit TasksMax= setting. See + systemd.resource-control5 + for details. This setting applies to all unit types that support resource control settings, with the exception +- of slice units. Defaults to 15%, which equals 4915 with the kernel's defaults on the host, but might be smaller ++ of slice units. Defaults to 80%, which equals 26214 with the kernel's defaults on the host, but might be smaller + in OS containers. + + +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index 1a28a8163a..f10c26ad51 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -100,7 +100,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { + } + + /* Default resource limits */ +-#define DEFAULT_TASKS_MAX_PERCENTAGE 15U /* 15% of PIDs, 4915 on default settings */ ++#define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */ + #define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */ + + typedef enum CGroupUnified { +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index f0a59a79a5..653ec6b8c9 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -45,7 +45,7 @@ + #DefaultBlockIOAccounting=no + #DefaultMemoryAccounting=@MEMORY_ACCOUNTING_DEFAULT@ + #DefaultTasksAccounting=yes +-#DefaultTasksMax=15% ++#DefaultTasksMax=80% + #DefaultLimitCPU= + #DefaultLimitFSIZE= + #DefaultLimitDATA= diff --git a/SOURCES/0004-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch b/SOURCES/0004-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch new file mode 100644 index 0000000..b2de3d8 --- /dev/null +++ b/SOURCES/0004-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch @@ -0,0 +1,51 @@ +From f58c5ced373c2532b5cc44ba2e0c3a28b41472f2 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 15 May 2018 09:24:20 +0200 +Subject: [PATCH] Avoid /tmp being mounted as tmpfs without the user's will + +Ensure PrivateTmp doesn't require tmpfs through tmp.mount, but rather +adds an After relationship. + +rhel-only + +Resolves: #1578772 +--- + src/core/unit.c | 12 ++++++------ + units/basic.target | 3 ++- + 2 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 113205bf25..c9f756c9c7 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -982,13 +982,13 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { + return 0; + + if (c->private_tmp) { +- const char *p; ++ r = unit_add_dependency_by_name(u, UNIT_AFTER, "tmp.mount", NULL, true, UNIT_DEPENDENCY_FILE); ++ if (r < 0) ++ return r; + +- FOREACH_STRING(p, "/tmp", "/var/tmp") { +- r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE); +- if (r < 0) +- return r; +- } ++ r = unit_require_mounts_for(u, "/var/tmp", UNIT_DEPENDENCY_FILE); ++ if (r < 0) ++ return r; + + r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE); + if (r < 0) +diff --git a/units/basic.target b/units/basic.target +index 4f44292249..8fc7c73ef2 100644 +--- a/units/basic.target ++++ b/units/basic.target +@@ -19,4 +19,5 @@ After=sysinit.target sockets.target paths.target slices.target tmp.mount + # require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as + # we support that unit being masked, and this should not be considered an error. + RequiresMountsFor=/var /var/tmp +-Wants=tmp.mount ++# RHEL-only: Disable /tmp on tmpfs. ++#Wants=tmp.mount diff --git a/SOURCES/0005-pid1-bump-maximum-number-of-process-in-user-slice-to.patch b/SOURCES/0005-pid1-bump-maximum-number-of-process-in-user-slice-to.patch new file mode 100644 index 0000000..2beec8c --- /dev/null +++ b/SOURCES/0005-pid1-bump-maximum-number-of-process-in-user-slice-to.patch @@ -0,0 +1,35 @@ +From c7f77dfd2bfa593bfbbdf82eea8b600ca1b46f4c Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 1 Aug 2018 17:17:07 +0200 +Subject: [PATCH] pid1: bump maximum number of process in user slice to 80% of + pid_max + +Related: #1523236 +--- + src/basic/cgroup-util.h | 2 +- + units/user-.slice.d/10-defaults.conf | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index f10c26ad51..26e3ae0404 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -101,7 +101,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { + + /* Default resource limits */ + #define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */ +-#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */ ++#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */ + + typedef enum CGroupUnified { + CGROUP_UNIFIED_UNKNOWN = -1, +diff --git a/units/user-.slice.d/10-defaults.conf b/units/user-.slice.d/10-defaults.conf +index 95ab11b30b..efc9d37c8e 100644 +--- a/units/user-.slice.d/10-defaults.conf ++++ b/units/user-.slice.d/10-defaults.conf +@@ -12,4 +12,4 @@ Description=User Slice of UID %j + After=systemd-user-sessions.service + + [Slice] +-TasksMax=33% ++TasksMax=80% diff --git a/SOURCES/0006-rules-automatically-online-hot-plugged-CPUs.patch b/SOURCES/0006-rules-automatically-online-hot-plugged-CPUs.patch new file mode 100644 index 0000000..78a2656 --- /dev/null +++ b/SOURCES/0006-rules-automatically-online-hot-plugged-CPUs.patch @@ -0,0 +1,33 @@ +From 787420ac2ba9c404e13db08601946bde263523f8 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 22 Sep 2014 07:41:06 +0200 +Subject: [PATCH] rules: automatically online hot-plugged CPUs + +Related: #1523227 +--- + rules/40-redhat.rules | 3 +++ + rules/meson.build | 1 + + 2 files changed, 4 insertions(+) + create mode 100644 rules/40-redhat.rules + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +new file mode 100644 +index 0000000000..2b494e57cf +--- /dev/null ++++ b/rules/40-redhat.rules +@@ -0,0 +1,3 @@ ++# do not edit this file, it will be overwritten on update ++ ++SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" +diff --git a/rules/meson.build b/rules/meson.build +index b6a32ba77e..e7e4362c0c 100644 +--- a/rules/meson.build ++++ b/rules/meson.build +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: LGPL-2.1+ + + rules = files(''' ++ 40-redhat.rules + 60-block.rules + 60-cdrom_id.rules + 60-drm.rules diff --git a/SOURCES/0007-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch b/SOURCES/0007-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch new file mode 100644 index 0000000..8682ffc --- /dev/null +++ b/SOURCES/0007-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch @@ -0,0 +1,37 @@ +From 2991b22f5f40a66ad1cc088e502e7f40ae1806c2 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 22 Sep 2014 07:53:52 +0200 +Subject: [PATCH] rules: add rule for naming Dell iDRAC USB Virtual NIC as + 'idrac' + +Related: #1523227 +--- + rules/73-idrac.rules | 6 ++++++ + rules/meson.build | 1 + + 2 files changed, 7 insertions(+) + create mode 100644 rules/73-idrac.rules + +diff --git a/rules/73-idrac.rules b/rules/73-idrac.rules +new file mode 100644 +index 0000000000..d67fc425b1 +--- /dev/null ++++ b/rules/73-idrac.rules +@@ -0,0 +1,6 @@ ++# do not edit this file, it will be overwritten on update ++ ++# On Dell PowerEdge systems, the iDRAC7 and later support a USB Virtual NIC ++# with terminates in the iDRAC. Help identify this with 'idrac' ++ ++ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="a102", NAME="idrac" +diff --git a/rules/meson.build b/rules/meson.build +index e7e4362c0c..e04a18aca6 100644 +--- a/rules/meson.build ++++ b/rules/meson.build +@@ -17,6 +17,7 @@ rules = files(''' + 70-joystick.rules + 70-mouse.rules + 70-touchpad.rules ++ 73-idrac.rules + 75-net-description.rules + 75-probe_mtd.rules + 78-sound-card.rules diff --git a/SOURCES/0008-rules-enable-memory-hotplug.patch b/SOURCES/0008-rules-enable-memory-hotplug.patch new file mode 100644 index 0000000..c724b28 --- /dev/null +++ b/SOURCES/0008-rules-enable-memory-hotplug.patch @@ -0,0 +1,22 @@ +From d5215083fa1d10f1624ab2f0fb5ba420a2594938 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 13 May 2015 16:56:44 +0200 +Subject: [PATCH] rules: enable memory hotplug + +Related: #1523227 +--- + rules/40-redhat.rules | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 2b494e57cf..8231caae98 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -1,3 +1,7 @@ + # do not edit this file, it will be overwritten on update + ++# CPU hotadd request + SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" ++ ++# Memory hotadd request ++SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online" diff --git a/SOURCES/0009-rules-reload-sysctl-settings-when-the-bridge-module-.patch b/SOURCES/0009-rules-reload-sysctl-settings-when-the-bridge-module-.patch new file mode 100644 index 0000000..24fa821 --- /dev/null +++ b/SOURCES/0009-rules-reload-sysctl-settings-when-the-bridge-module-.patch @@ -0,0 +1,22 @@ +From 4a7602e27a50828ac8a0eb6b83a1c2c722af652d Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 13 May 2015 17:11:48 +0200 +Subject: [PATCH] rules: reload sysctl settings when the bridge module is + loaded + +Related: #1523227 +--- + rules/40-redhat.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 8231caae98..556a3a3a90 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -5,3 +5,6 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online} + + # Memory hotadd request + SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online" ++ ++# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded ++ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge" diff --git a/SOURCES/0010-rules-load-sg-module.patch b/SOURCES/0010-rules-load-sg-module.patch new file mode 100644 index 0000000..92f88b2 --- /dev/null +++ b/SOURCES/0010-rules-load-sg-module.patch @@ -0,0 +1,21 @@ +From a42b57dc8b265f183a8fb6fe9ae32a9d77cbb7c5 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Wed, 20 May 2015 12:34:18 +0200 +Subject: [PATCH] rules: load sg module + +Related: #1523227 +--- + rules/40-redhat.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 556a3a3a90..305e752285 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -8,3 +8,6 @@ SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online" + + # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded + ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge" ++ ++# load SCSI generic (sg) driver ++SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg" diff --git a/SOURCES/0011-rules-prandom-character-device-node-permissions.patch b/SOURCES/0011-rules-prandom-character-device-node-permissions.patch new file mode 100644 index 0000000..1ccc71b --- /dev/null +++ b/SOURCES/0011-rules-prandom-character-device-node-permissions.patch @@ -0,0 +1,21 @@ +From 21c96c3781f473cdbfe7acdb1affba75b50081f1 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 22 Sep 2015 12:28:28 +0200 +Subject: [PATCH] rules: prandom character device node permissions + +Related: #1523227 +--- + rules/40-redhat.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 305e752285..9a48adde19 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -11,3 +11,6 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys + + # load SCSI generic (sg) driver + SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg" ++ ++# Rule for prandom character device node permissions ++KERNEL=="prandom", MODE="0644" diff --git a/SOURCES/0012-rules-load-sg-driver-also-when-scsi_target-appears-4.patch b/SOURCES/0012-rules-load-sg-driver-also-when-scsi_target-appears-4.patch new file mode 100644 index 0000000..67627cc --- /dev/null +++ b/SOURCES/0012-rules-load-sg-driver-also-when-scsi_target-appears-4.patch @@ -0,0 +1,22 @@ +From fab2dff96f59e0851884b4ef32dccab763f5eef1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= +Date: Thu, 18 Aug 2016 14:51:19 +0200 +Subject: [PATCH] rules: load sg driver also when scsi_target appears (#45) + +Related: #1523227 +--- + rules/40-redhat.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 9a48adde19..3335fe5075 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -11,6 +11,7 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys + + # load SCSI generic (sg) driver + SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg" ++SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg" + + # Rule for prandom character device node permissions + KERNEL=="prandom", MODE="0644" diff --git a/SOURCES/0013-rules-don-t-hoplug-memory-on-s390x.patch b/SOURCES/0013-rules-don-t-hoplug-memory-on-s390x.patch new file mode 100644 index 0000000..2c813f1 --- /dev/null +++ b/SOURCES/0013-rules-don-t-hoplug-memory-on-s390x.patch @@ -0,0 +1,23 @@ +From fd091394e52cd652ff5163735b2a91a8c0efe415 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 13 Sep 2016 13:18:38 +0200 +Subject: [PATCH] rules: don't hoplug memory on s390x + +Related: #1523227 +--- + rules/40-redhat.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 3335fe5075..4c56950dab 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -4,7 +4,7 @@ + SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" + + # Memory hotadd request +-SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online" ++SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online" + + # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded + ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge" diff --git a/SOURCES/0014-rules-disable-auto-online-of-hot-plugged-memory-on-I.patch b/SOURCES/0014-rules-disable-auto-online-of-hot-plugged-memory-on-I.patch new file mode 100644 index 0000000..b4d2386 --- /dev/null +++ b/SOURCES/0014-rules-disable-auto-online-of-hot-plugged-memory-on-I.patch @@ -0,0 +1,24 @@ +From a0802638f02b964cb9d2d68bad009561b2bcc910 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 16 Sep 2016 14:45:01 +0200 +Subject: [PATCH] rules: disable auto-online of hot-plugged memory on IBM z + Systems + +Related: #1523227 +--- + rules/40-redhat.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 4c56950dab..c3df320234 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -4,7 +4,7 @@ + SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" + + # Memory hotadd request +-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online" ++SUBSYSTEM=="memory", ACTION=="add", PROGRAM=="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online" + + # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded + ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge" diff --git a/SOURCES/0015-rules-introduce-old-style-by-path-symlinks-for-FCP-b.patch b/SOURCES/0015-rules-introduce-old-style-by-path-symlinks-for-FCP-b.patch new file mode 100644 index 0000000..4305361 --- /dev/null +++ b/SOURCES/0015-rules-introduce-old-style-by-path-symlinks-for-FCP-b.patch @@ -0,0 +1,39 @@ +From 0c5b8096cb23701f8048dba33a38e1b55249cab3 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 28 Mar 2018 17:22:30 +0200 +Subject: [PATCH] rules: introduce old-style by-path symlinks for FCP based + SCSI devices + +Related: #1523227 +--- + rules/40-redhat.rules | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index c3df320234..8ac96933c3 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -15,3 +15,23 @@ SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin + + # Rule for prandom character device node permissions + KERNEL=="prandom", MODE="0644" ++ ++# Rules for creating the ID_PATH for SCSI devices based on the CCW bus ++# using the form: ccw--zfcp-: ++# ++ACTION=="remove", GOTO="zfcp_scsi_device_end" ++ ++# ++# Set environment variable "ID_ZFCP_BUS" to "1" if the devices ++# (both disk and partition) are SCSI devices based on FCP devices ++# ++KERNEL=="sd*", SUBSYSTEMS=="ccw", DRIVERS=="zfcp", ENV{.ID_ZFCP_BUS}="1" ++ ++# For SCSI disks ++KERNEL=="sd*[!0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="disk", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}" ++ ++ ++# For partitions on a SCSI disk ++KERNEL=="sd*[0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="partition", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}-part%n" ++ ++LABEL="zfcp_scsi_device_end" diff --git a/SOURCES/0016-Revert-udev-remove-WAIT_FOR-key.patch b/SOURCES/0016-Revert-udev-remove-WAIT_FOR-key.patch new file mode 100644 index 0000000..b6bb114 --- /dev/null +++ b/SOURCES/0016-Revert-udev-remove-WAIT_FOR-key.patch @@ -0,0 +1,123 @@ +From 1bb734a44952a51285057409ba7b1c3e7a162cea Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 2 Aug 2018 13:16:49 +0200 +Subject: [PATCH] Revert "udev: remove WAIT_FOR key" + +This reverts commit f2b8052fb648b788936dd3e85be6a9aca90fbb2f. + +Resolves: #1523213 +--- + man/udev.xml | 9 +++++++ + src/udev/udev-rules.c | 50 +++++++++++++++++++++++++++++++++++++++ + test/rule-syntax-check.py | 2 +- + 3 files changed, 60 insertions(+), 1 deletion(-) + +diff --git a/man/udev.xml b/man/udev.xml +index 15e6d8eae1..bdf901a8f0 100644 +--- a/man/udev.xml ++++ b/man/udev.xml +@@ -515,6 +515,15 @@ + + + ++ ++ WAIT_FOR ++ ++ Wait for a file to become available or until a timeout of ++ 10 seconds expires. The path is relative to the sysfs device; ++ if no path is specified, this waits for an attribute to appear. ++ ++ ++ + + OPTIONS + +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index f029395884..58af863f3d 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -676,6 +676,41 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi + return 0; + } + ++#define WAIT_LOOP_PER_SECOND 50 ++static int wait_for_file(struct udev_device *dev, const char *file, int timeout) { ++ char filepath[UTIL_PATH_SIZE]; ++ char devicepath[UTIL_PATH_SIZE]; ++ struct stat stats; ++ int loop = timeout * WAIT_LOOP_PER_SECOND; ++ ++ /* a relative path is a device attribute */ ++ devicepath[0] = '\0'; ++ if (file[0] != '/') { ++ strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL); ++ strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL); ++ file = filepath; ++ } ++ ++ while (--loop) { ++ const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND }; ++ ++ /* lookup file */ ++ if (stat(file, &stats) == 0) { ++ log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); ++ return 0; ++ } ++ /* make sure, the device did not disappear in the meantime */ ++ if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) { ++ log_debug("device disappeared while waiting for '%s'", file); ++ return -2; ++ } ++ log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND); ++ nanosleep(&duration, NULL); ++ } ++ log_debug("waiting for '%s' failed", file); ++ return -1; ++} ++ + static void attr_subst_subdir(char *attr, size_t len) { + const char *pos, *tail, *path; + _cleanup_closedir_ DIR *dir = NULL; +@@ -1284,7 +1319,12 @@ static void add_rule(struct udev_rules *rules, char *line, + rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); + } else + LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr); ++ } else if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) { ++ if (op == OP_REMOVE) ++ LOG_AND_RETURN("invalid %s operation", key); + ++ rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL); ++ continue; + } else if (streq(key, "LABEL")) { + if (op == OP_REMOVE) + LOG_AND_RETURN("invalid %s operation", key); +@@ -1838,6 +1878,16 @@ void udev_rules_apply_to_event(struct udev_rules *rules, + if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0) + goto nomatch; + break; ++ case TK_M_WAITFOR: { ++ char filename[UTIL_PATH_SIZE]; ++ int found; ++ ++ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false); ++ found = (wait_for_file(event->dev, filename, 10) == 0); ++ if (!found && (cur->key.op != OP_NOMATCH)) ++ goto nomatch; ++ break; ++ } + case TK_M_ATTR: + if (match_attr(rules, event->dev, event, cur) != 0) + goto nomatch; +diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py +index dfb06d9ed9..706d93632e 100755 +--- a/test/rule-syntax-check.py ++++ b/test/rule-syntax-check.py +@@ -18,7 +18,7 @@ if not rules_files: + quoted_string_re = r'"(?:[^\\"]|\\.)*"' + no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$') + args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$') +-no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$') ++no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$') + args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$') + # Find comma-separated groups, but allow commas that are inside quoted strings. + # Using quoted_string_re + '?' so that strings missing the last double quote diff --git a/SOURCES/0017-net_setup_link-allow-renaming-interfaces-that-were-r.patch b/SOURCES/0017-net_setup_link-allow-renaming-interfaces-that-were-r.patch new file mode 100644 index 0000000..dfa948b --- /dev/null +++ b/SOURCES/0017-net_setup_link-allow-renaming-interfaces-that-were-r.patch @@ -0,0 +1,22 @@ +From ab0228c3d6ceba20cf89ceb1b16b7e314aaaf989 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 7 Aug 2018 10:38:33 +0200 +Subject: [PATCH] net_setup_link: allow renaming interfaces that were renamed + previously + +--- + src/udev/net/link-config.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index cec4f4f779..5113586457 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -306,7 +306,6 @@ static bool should_rename(struct udev_device *device, bool respect_predictable) + + switch (type) { + case NET_NAME_USER: +- case NET_NAME_RENAMED: + /* these were already named by userspace, do not touch again */ + return false; + case NET_NAME_PREDICTABLE: diff --git a/SOURCES/0018-units-drop-DynamicUser-yes-from-systemd-resolved.ser.patch b/SOURCES/0018-units-drop-DynamicUser-yes-from-systemd-resolved.ser.patch new file mode 100644 index 0000000..a42d3c7 --- /dev/null +++ b/SOURCES/0018-units-drop-DynamicUser-yes-from-systemd-resolved.ser.patch @@ -0,0 +1,23 @@ +From b61e8046ebcb28225423fc0073183d68d4c577c4 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 9 Aug 2018 15:28:44 +0200 +Subject: [PATCH] units: drop DynamicUser=yes from systemd-resolved.service + +We don't really need DynamicUser since we add systemd-resolve user +from rpm script +--- + units/systemd-resolved.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index 9982ecebff..aaed406ab2 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -26,7 +26,6 @@ RestartSec=0 + ExecStart=!!@rootlibexecdir@/systemd-resolved + WatchdogSec=3min + User=systemd-resolve +-DynamicUser=yes + CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + PrivateDevices=yes diff --git a/SOURCES/0019-journal-remove-journal-audit-socket.patch b/SOURCES/0019-journal-remove-journal-audit-socket.patch new file mode 100644 index 0000000..bb749c8 --- /dev/null +++ b/SOURCES/0019-journal-remove-journal-audit-socket.patch @@ -0,0 +1,73 @@ +From 8618ef2fb30b4139c9bec4e45fb499cd8192a87f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 9 Aug 2018 23:23:00 +0200 +Subject: [PATCH] journal: remove journal audit socket + +Resolves: #1614554 +--- + units/meson.build | 2 -- + units/systemd-journald-audit.socket | 22 ---------------------- + units/systemd-journald.service.in | 4 ++-- + 3 files changed, 2 insertions(+), 26 deletions(-) + delete mode 100644 units/systemd-journald-audit.socket + +diff --git a/units/meson.build b/units/meson.build +index e4ac6ced64..e54a84ccbf 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -89,8 +89,6 @@ units = [ + 'sockets.target.wants/'], + ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], + ['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], +- ['systemd-journald-audit.socket', '', +- 'sockets.target.wants/'], + ['systemd-journald-dev-log.socket', '', + 'sockets.target.wants/'], + ['systemd-journald.socket', '', +diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket +deleted file mode 100644 +index cb8b774963..0000000000 +--- a/units/systemd-journald-audit.socket ++++ /dev/null +@@ -1,22 +0,0 @@ +-# SPDX-License-Identifier: LGPL-2.1+ +-# +-# This file is part of systemd. +-# +-# systemd is free software; you can redistribute it and/or modify it +-# under the terms of the GNU Lesser General Public License as published by +-# the Free Software Foundation; either version 2.1 of the License, or +-# (at your option) any later version. +- +-[Unit] +-Description=Journal Audit Socket +-Documentation=man:systemd-journald.service(8) man:journald.conf(5) +-DefaultDependencies=no +-Before=sockets.target +-ConditionSecurity=audit +-ConditionCapability=CAP_AUDIT_READ +- +-[Socket] +-Service=systemd-journald.service +-ReceiveBuffer=128M +-ListenNetlink=audit 1 +-PassCredentials=yes +diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in +index 52939e6820..8f5021d0de 100644 +--- a/units/systemd-journald.service.in ++++ b/units/systemd-journald.service.in +@@ -12,12 +12,12 @@ Description=Journal Service + Documentation=man:systemd-journald.service(8) man:journald.conf(5) + DefaultDependencies=no + Requires=systemd-journald.socket +-After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket ++After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket + Before=sysinit.target + + [Service] + Type=notify +-Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket ++Sockets=systemd-journald.socket systemd-journald-dev-log.socket + ExecStart=@rootlibexecdir@/systemd-journald + Restart=always + RestartSec=0 diff --git a/SOURCES/0020-bus-move-BUS_DONT_DESTROY-calls-after-asserts.patch b/SOURCES/0020-bus-move-BUS_DONT_DESTROY-calls-after-asserts.patch new file mode 100644 index 0000000..0141ff4 --- /dev/null +++ b/SOURCES/0020-bus-move-BUS_DONT_DESTROY-calls-after-asserts.patch @@ -0,0 +1,117 @@ +From c6903d1b42d1773fda4df6676618489ad760a2a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 18 Jul 2018 12:16:33 +0200 +Subject: [PATCH] bus: move BUS_DONT_DESTROY calls after asserts + +It's not useful to bump the reference count before checking if the object is +NULL. Thanks to d40f5cc498 we can do this ;). + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1576084, +https://bugzilla.redhat.com/show_bug.cgi?id=1575340, +https://bugzilla.redhat.com/show_bug.cgi?id=1575350. I'm not sure why those two +people hit this code path, while most people don't. At least we won't abort. + +(cherry picked from commit 7ae8edcd03f74da123298330b76c3fc5425042ef) + +Resolves: #1610397 +--- + src/libsystemd/sd-bus/bus-objects.c | 15 ++++++++------- + src/libsystemd/sd-bus/sd-bus.c | 3 ++- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c +index 9609834fa9..a18ff88b07 100644 +--- a/src/libsystemd/sd-bus/bus-objects.c ++++ b/src/libsystemd/sd-bus/bus-objects.c +@@ -2090,7 +2090,6 @@ _public_ int sd_bus_emit_properties_changed_strv( + const char *interface, + char **names) { + +- BUS_DONT_DESTROY(bus); + bool found_interface = false; + char *prefix; + int r; +@@ -2111,6 +2110,8 @@ _public_ int sd_bus_emit_properties_changed_strv( + if (names && names[0] == NULL) + return 0; + ++ BUS_DONT_DESTROY(bus); ++ + do { + bus->nodes_modified = false; + +@@ -2310,8 +2311,6 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p + } + + _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) { +- BUS_DONT_DESTROY(bus); +- + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + struct node *object_manager; + int r; +@@ -2341,6 +2340,8 @@ _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) { + if (r == 0) + return -ESRCH; + ++ BUS_DONT_DESTROY(bus); ++ + do { + bus->nodes_modified = false; + m = sd_bus_message_unref(m); +@@ -2481,8 +2482,6 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char + } + + _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { +- BUS_DONT_DESTROY(bus); +- + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + struct node *object_manager; + int r; +@@ -2512,6 +2511,8 @@ _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { + if (r == 0) + return -ESRCH; + ++ BUS_DONT_DESTROY(bus); ++ + do { + bus->nodes_modified = false; + m = sd_bus_message_unref(m); +@@ -2645,8 +2646,6 @@ static int interfaces_added_append_one( + } + + _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) { +- BUS_DONT_DESTROY(bus); +- + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + struct node *object_manager; + char **i; +@@ -2669,6 +2668,8 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch + if (r == 0) + return -ESRCH; + ++ BUS_DONT_DESTROY(bus); ++ + do { + bus->nodes_modified = false; + m = sd_bus_message_unref(m); +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 089b51a6d9..7f03528b89 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2883,7 +2883,6 @@ finish: + } + + static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { +- BUS_DONT_DESTROY(bus); + int r; + + /* Returns 0 when we didn't do anything. This should cause the +@@ -2899,6 +2898,8 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit + assert_return(!bus->current_message, -EBUSY); + assert(!bus->current_slot); + ++ BUS_DONT_DESTROY(bus); ++ + switch (bus->state) { + + case BUS_UNSET: diff --git a/SOURCES/0021-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch b/SOURCES/0021-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch new file mode 100644 index 0000000..e860755 --- /dev/null +++ b/SOURCES/0021-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch @@ -0,0 +1,23 @@ +From 56f614a5d6305dc1d304c30438db5b394d16e2da Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 12 Oct 2018 13:58:34 +0000 +Subject: [PATCH] random-seed: raise POOL_SIZE_MIN constant to 1024 + +Resolves: #1619268 +--- + src/random-seed/random-seed.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c +index 223b56306c..adc9f298c1 100644 +--- a/src/random-seed/random-seed.c ++++ b/src/random-seed/random-seed.c +@@ -14,7 +14,7 @@ + #include "string-util.h" + #include "util.h" + +-#define POOL_SIZE_MIN 512 ++#define POOL_SIZE_MIN 1024 + + int main(int argc, char *argv[]) { + _cleanup_close_ int seed_fd = -1, random_fd = -1; diff --git a/SOURCES/0022-cryptsetup-add-support-for-sector-size-option-9936.patch b/SOURCES/0022-cryptsetup-add-support-for-sector-size-option-9936.patch new file mode 100644 index 0000000..b66f172 --- /dev/null +++ b/SOURCES/0022-cryptsetup-add-support-for-sector-size-option-9936.patch @@ -0,0 +1,119 @@ +From a046230cfb7e02938e3ad2ac85515636b319651e Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Wed, 29 Aug 2018 15:38:09 +0100 +Subject: [PATCH] cryptsetup: add support for sector-size= option (#9936) + +Bug-Ubuntu: https://launchpad.net/bugs/1776626 + +Closes #8881. + +(cherry picked from commit a9fc640671ef60ac949f1ace6fa687ff242fc233) + +Resolves: #1572563 +--- + man/crypttab.xml | 9 +++++++++ + meson.build | 6 ++++++ + src/cryptsetup/cryptsetup.c | 30 ++++++++++++++++++++++++++++++ + 3 files changed, 45 insertions(+) + +diff --git a/man/crypttab.xml b/man/crypttab.xml +index dcaf03d2ca..3574ce00da 100644 +--- a/man/crypttab.xml ++++ b/man/crypttab.xml +@@ -250,6 +250,15 @@ + option. + + ++ ++ ++ ++ Specifies the sector size in bytes. See ++ cryptsetup8 ++ for possible values and the default value of this ++ option. ++ ++ + + + +diff --git a/meson.build b/meson.build +index a0e7240708..f308db2631 100644 +--- a/meson.build ++++ b/meson.build +@@ -927,11 +927,17 @@ if want_libcryptsetup != 'false' and not fuzzer_build + version : '>= 1.6.0', + required : want_libcryptsetup == 'true') + have = libcryptsetup.found() ++ have_sector = cc.has_member( ++ 'struct crypt_params_plain', ++ 'sector_size', ++ prefix : '#include ') + else + have = false ++ have_sector = false + libcryptsetup = [] + endif + conf.set10('HAVE_LIBCRYPTSETUP', have) ++conf.set10('HAVE_LIBCRYPTSETUP_SECTOR_SIZE', have_sector) + + want_libcurl = get_option('libcurl') + if want_libcurl != 'false' and not fuzzer_build +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 832168184a..87008cb969 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -23,10 +23,14 @@ + + /* internal helper */ + #define ANY_LUKS "LUKS" ++/* as in src/cryptsetup.h */ ++#define CRYPT_SECTOR_SIZE 512 ++#define CRYPT_MAX_SECTOR_SIZE 4096 + + static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */ + static char *arg_cipher = NULL; + static unsigned arg_key_size = 0; ++static unsigned arg_sector_size = CRYPT_SECTOR_SIZE; + static int arg_key_slot = CRYPT_ANY_SLOT; + static unsigned arg_keyfile_size = 0; + static uint64_t arg_keyfile_offset = 0; +@@ -86,6 +90,29 @@ static int parse_one_option(const char *option) { + + arg_key_size /= 8; + ++ } else if ((val = startswith(option, "sector-size="))) { ++ ++#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE ++ r = safe_atou(val, &arg_sector_size); ++ if (r < 0) { ++ log_error_errno(r, "Failed to parse %s, ignoring: %m", option); ++ return 0; ++ } ++ ++ if (arg_sector_size % 2) { ++ log_error("sector-size= not a multiple of 2, ignoring."); ++ return 0; ++ } ++ ++ if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) { ++ log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE); ++ return 0; ++ } ++#else ++ log_error("sector-size= is not supported, compiled with old libcryptsetup."); ++ return 0; ++#endif ++ + } else if ((val = startswith(option, "key-slot="))) { + + arg_type = ANY_LUKS; +@@ -471,6 +498,9 @@ static int attach_luks_or_plain(struct crypt_device *cd, + struct crypt_params_plain params = { + .offset = arg_offset, + .skip = arg_skip, ++#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE ++ .sector_size = arg_sector_size, ++#endif + }; + const char *cipher, *cipher_mode; + _cleanup_free_ char *truncated_cipher = NULL; diff --git a/SOURCES/0023-cryptsetup-do-not-define-arg_sector_size-if-libgcryp.patch b/SOURCES/0023-cryptsetup-do-not-define-arg_sector_size-if-libgcryp.patch new file mode 100644 index 0000000..3413a18 --- /dev/null +++ b/SOURCES/0023-cryptsetup-do-not-define-arg_sector_size-if-libgcryp.patch @@ -0,0 +1,29 @@ +From 96b6171376bfdb7417143a2026beda059fe3e22f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 1 Sep 2018 23:47:46 +0900 +Subject: [PATCH] cryptsetup: do not define arg_sector_size if libgcrypt is + v1.x (#9990) + +Follow-up for #9936. + +(cherry picked from commit 645461f0cf6ec91e5b0b571559fb4cc4898192bc) + +Related: #1572563 +--- + src/cryptsetup/cryptsetup.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 87008cb969..abeba44ee8 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -30,7 +30,9 @@ + static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */ + static char *arg_cipher = NULL; + static unsigned arg_key_size = 0; ++#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE + static unsigned arg_sector_size = CRYPT_SECTOR_SIZE; ++#endif + static int arg_key_slot = CRYPT_ANY_SLOT; + static unsigned arg_keyfile_size = 0; + static uint64_t arg_keyfile_offset = 0; diff --git a/SOURCES/0024-units-don-t-enable-per-service-IP-firewall-by-defaul.patch b/SOURCES/0024-units-don-t-enable-per-service-IP-firewall-by-defaul.patch new file mode 100644 index 0000000..f2bd378 --- /dev/null +++ b/SOURCES/0024-units-don-t-enable-per-service-IP-firewall-by-defaul.patch @@ -0,0 +1,112 @@ +From e143339ac712f745727951973417ce93b5d06d78 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 12 Oct 2018 14:50:09 +0000 +Subject: [PATCH] units: don't enable per-service IP firewall by default + +Resolves: #1630219 +--- + units/systemd-coredump@.service.in | 1 - + units/systemd-hostnamed.service.in | 1 - + units/systemd-journald.service.in | 1 - + units/systemd-localed.service.in | 1 - + units/systemd-logind.service.in | 1 - + units/systemd-machined.service.in | 1 - + units/systemd-portabled.service.in | 1 - + units/systemd-timedated.service.in | 1 - + units/systemd-udevd.service.in | 1 - + 9 files changed, 9 deletions(-) + +diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in +index 215696ecd1..68a68a5055 100644 +--- a/units/systemd-coredump@.service.in ++++ b/units/systemd-coredump@.service.in +@@ -37,5 +37,4 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + StateDirectory=systemd/coredump +diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in +index da74b4fe8b..4e5470dd29 100644 +--- a/units/systemd-hostnamed.service.in ++++ b/units/systemd-hostnamed.service.in +@@ -33,5 +33,4 @@ SystemCallFilter=@system-service sethostname + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + ReadWritePaths=/etc +diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in +index 8f5021d0de..2d5fd0120d 100644 +--- a/units/systemd-journald.service.in ++++ b/units/systemd-journald.service.in +@@ -33,7 +33,6 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + + # 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 a24e61a0cd..ce043db154 100644 +--- a/units/systemd-localed.service.in ++++ b/units/systemd-localed.service.in +@@ -33,5 +33,4 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + ReadWritePaths=/etc +diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in +index 5e090bcf23..6953fac55b 100644 +--- a/units/systemd-logind.service.in ++++ b/units/systemd-logind.service.in +@@ -34,7 +34,6 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + FileDescriptorStoreMax=512 + + # Increase the default a bit in order to allow many simultaneous +diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in +index 1200a90a61..dec2c4b0dc 100644 +--- a/units/systemd-machined.service.in ++++ b/units/systemd-machined.service.in +@@ -27,7 +27,6 @@ SystemCallFilter=@system-service @mount + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + + # 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-portabled.service.in b/units/systemd-portabled.service.in +index a868f61dba..64f14071e8 100644 +--- a/units/systemd-portabled.service.in ++++ b/units/systemd-portabled.service.in +@@ -23,4 +23,3 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 + SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any +diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in +index 906bb4326c..662b39557a 100644 +--- a/units/systemd-timedated.service.in ++++ b/units/systemd-timedated.service.in +@@ -31,5 +31,4 @@ SystemCallFilter=@system-service @clock + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any + ReadWritePaths=/etc +diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in +index 6a3814e5d9..fd9ead3bb8 100644 +--- a/units/systemd-udevd.service.in ++++ b/units/systemd-udevd.service.in +@@ -33,4 +33,3 @@ SystemCallFilter=@system-service @module @raw-io + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes +-IPAddressDeny=any diff --git a/SOURCES/0025-bus-message-do-not-crash-on-message-with-a-string-of.patch b/SOURCES/0025-bus-message-do-not-crash-on-message-with-a-string-of.patch new file mode 100644 index 0000000..6110b2a --- /dev/null +++ b/SOURCES/0025-bus-message-do-not-crash-on-message-with-a-string-of.patch @@ -0,0 +1,45 @@ +From 87922b7adc47f311e89b21e37b26ee300a401e1d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 9 Jul 2018 13:21:44 +0200 +Subject: [PATCH] bus-message: do not crash on message with a string of zero + length + +We'd calculate the "real" length of the string as 'item_size - 1', which does +not work out well when item_size == 0. + +(cherry picked from commit 81b6e63029eefcb0ec03a3a7c248490e38106073) + +Resolves: #1635439 +--- + src/libsystemd/sd-bus/bus-message.c | 6 ++++++ + .../crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e | Bin 0 -> 51 bytes + 2 files changed, 6 insertions(+) + create mode 100644 test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 8d92bc2002..381034f5f8 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -3312,6 +3312,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) { + if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) { + bool ok; + ++ /* D-Bus spec: The marshalling formats for the string-like types all end ++ * with a single zero (NUL) byte, but that byte is not considered to be part ++ * of the text. */ ++ if (c->item_size == 0) ++ return -EBADMSG; ++ + r = message_peek_body(m, &rindex, 1, c->item_size, &q); + if (r < 0) + return r; +diff --git a/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e +new file mode 100644 +index 0000000000000000000000000000000000000000..4488f0a6c685b5d43eddbe41a0c6a3b6be9b02e2 +GIT binary patch +literal 51 +fcmc~1WMC4sJpJnr13KV`0|t%6q+%$@&=ddw)CUPg + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0026-Introduce-free_and_strndup-and-use-it-in-bus-message.patch b/SOURCES/0026-Introduce-free_and_strndup-and-use-it-in-bus-message.patch new file mode 100644 index 0000000..90fedb8 --- /dev/null +++ b/SOURCES/0026-Introduce-free_and_strndup-and-use-it-in-bus-message.patch @@ -0,0 +1,279 @@ +From 26de3af817b0c5746cb61b798ae8e138e01ea17c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 9 Jul 2018 07:03:01 +0200 +Subject: [PATCH] Introduce free_and_strndup and use it in bus-message.c + +v2: fix error in free_and_strndup() + +When the orignal and copied message were the same, but shorter than specified +length l, memory read past the end of the buffer would be performed. A test +case is included: a string that had an embedded NUL ("q\0") is used to replace +"q". + +v3: Fix one more bug in free_and_strndup and add tests. + +v4: Some style fixed based on review, one more use of free_and_replace, and +make the tests more comprehensive. + +(cherry picked from commit 7f546026abbdc56c453a577e52d57159458c3e9c) + +Resolves: #1635428 +--- + src/basic/string-util.c | 28 +++++++- + src/basic/string-util.h | 1 + + src/libsystemd/sd-bus/bus-message.c | 34 ++++------ + src/test/test-string-util.c | 62 ++++++++++++++++++ + ...h-b88ad9ecf4aacf4a0caca5b5543953265367f084 | Bin 0 -> 32 bytes + 5 files changed, 103 insertions(+), 22 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 + +diff --git a/src/basic/string-util.c b/src/basic/string-util.c +index 0a40683493..dfa739996f 100644 +--- a/src/basic/string-util.c ++++ b/src/basic/string-util.c +@@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) { + + assert(p); + +- /* Replaces a string pointer with an strdup()ed new string, ++ /* Replaces a string pointer with a strdup()ed new string, + * possibly freeing the old one. */ + + if (streq_ptr(*p, s)) +@@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) { + return 1; + } + ++int free_and_strndup(char **p, const char *s, size_t l) { ++ char *t; ++ ++ assert(p); ++ assert(s || l == 0); ++ ++ /* Replaces a string pointer with a strndup()ed new string, ++ * freeing the old one. */ ++ ++ if (!*p && !s) ++ return 0; ++ ++ if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0')) ++ return 0; ++ ++ if (s) { ++ t = strndup(s, l); ++ if (!t) ++ return -ENOMEM; ++ } else ++ t = NULL; ++ ++ free_and_replace(*p, t); ++ return 1; ++} ++ + #if !HAVE_EXPLICIT_BZERO + /* + * Pointer to memset is volatile so that compiler must de-reference +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index c0cc4e78d7..96a9260f93 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n); + int split_pair(const char *s, const char *sep, char **l, char **r); + + int free_and_strdup(char **p, const char *s); ++int free_and_strndup(char **p, const char *s, size_t l); + + /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */ + static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 381034f5f8..7c8bad2bdd 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -4175,20 +4175,19 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + + if (contents) { + size_t l; +- char *sig; + + r = signature_element_length(c->signature+c->index+1, &l); + if (r < 0) + return r; + +- assert(l >= 1); ++ /* signature_element_length does verification internally */ + +- sig = strndup(c->signature + c->index + 1, l); +- if (!sig) ++ assert(l >= 1); ++ if (free_and_strndup(&c->peeked_signature, ++ c->signature + c->index + 1, l) < 0) + return -ENOMEM; + +- free(c->peeked_signature); +- *contents = c->peeked_signature = sig; ++ *contents = c->peeked_signature; + } + + if (type) +@@ -4201,19 +4200,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + + if (contents) { + size_t l; +- char *sig; + + r = signature_element_length(c->signature+c->index, &l); + if (r < 0) + return r; + + assert(l >= 2); +- sig = strndup(c->signature + c->index + 1, l - 2); +- if (!sig) ++ if (free_and_strndup(&c->peeked_signature, ++ c->signature + c->index + 1, l - 2) < 0) + return -ENOMEM; + +- free(c->peeked_signature); +- *contents = c->peeked_signature = sig; ++ *contents = c->peeked_signature; + } + + if (type) +@@ -4253,9 +4250,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + if (k > c->item_size) + return -EBADMSG; + +- free(c->peeked_signature); +- c->peeked_signature = strndup((char*) q + 1, k - 1); +- if (!c->peeked_signature) ++ if (free_and_strndup(&c->peeked_signature, ++ (char*) q + 1, k - 1) < 0) + return -ENOMEM; + + if (!signature_is_valid(c->peeked_signature, true)) +@@ -5085,25 +5081,21 @@ int bus_message_parse_fields(sd_bus_message *m) { + + if (*p == 0) { + size_t l; +- char *c; + + /* We found the beginning of the signature + * string, yay! We require the body to be a + * structure, so verify it and then strip the + * opening/closing brackets. */ + +- l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz); ++ l = (char*) m->footer + m->footer_accessible - p - (1 + sz); + if (l < 2 || + p[1] != SD_BUS_TYPE_STRUCT_BEGIN || + p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END) + return -EBADMSG; + +- c = strndup(p + 1 + 1, l - 2); +- if (!c) ++ if (free_and_strndup(&m->root_container.signature, ++ p + 1 + 1, l - 2) < 0) + return -ENOMEM; +- +- free(m->root_container.signature); +- m->root_container.signature = c; + break; + } + +diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c +index 3e72ce2c0a..43a6b14c34 100644 +--- a/src/test/test-string-util.c ++++ b/src/test/test-string-util.c +@@ -5,6 +5,7 @@ + #include "macro.h" + #include "string-util.h" + #include "strv.h" ++#include "tests.h" + #include "utf8.h" + + static void test_string_erase(void) { +@@ -30,6 +31,64 @@ static void test_string_erase(void) { + assert_se(x[9] == '\0'); + } + ++static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) { ++ int r; ++ ++ log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)", ++ __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change)); ++ ++ r = free_and_strndup(t, src, l); ++ assert_se(streq_ptr(*t, expected)); ++ assert_se(r == change); /* check that change occurs only when necessary */ ++} ++ ++static void test_free_and_strndup(void) { ++ static const struct test_case { ++ const char *src; ++ size_t len; ++ const char *expected; ++ } cases[] = { ++ {"abc", 0, ""}, ++ {"abc", 0, ""}, ++ {"abc", 1, "a"}, ++ {"abc", 2, "ab"}, ++ {"abc", 3, "abc"}, ++ {"abc", 4, "abc"}, ++ {"abc", 5, "abc"}, ++ {"abc", 5, "abc"}, ++ {"abc", 4, "abc"}, ++ {"abc", 3, "abc"}, ++ {"abc", 2, "ab"}, ++ {"abc", 1, "a"}, ++ {"abc", 0, ""}, ++ ++ {"", 0, ""}, ++ {"", 1, ""}, ++ {"", 2, ""}, ++ {"", 0, ""}, ++ {"", 1, ""}, ++ {"", 2, ""}, ++ {"", 2, ""}, ++ {"", 1, ""}, ++ {"", 0, ""}, ++ ++ {NULL, 0, NULL}, ++ ++ {"foo", 3, "foo"}, ++ {"foobar", 6, "foobar"}, ++ }; ++ ++ _cleanup_free_ char *t = NULL; ++ const char *prev_expected = t; ++ ++ for (unsigned i = 0; i < ELEMENTSOF(cases); i++) { ++ test_free_and_strndup_one(&t, ++ cases[i].src, cases[i].len, cases[i].expected, ++ !streq_ptr(cases[i].expected, prev_expected)); ++ prev_expected = t; ++ } ++} ++ + static void test_ascii_strcasecmp_n(void) { + + assert_se(ascii_strcasecmp_n("", "", 0) == 0); +@@ -497,7 +556,10 @@ static void test_memory_startswith(void) { + } + + int main(int argc, char *argv[]) { ++ test_setup_logging(LOG_DEBUG); ++ + test_string_erase(); ++ test_free_and_strndup(); + test_ascii_strcasecmp_n(); + test_ascii_strcasecmp_nn(); + test_cellescape(); +diff --git a/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 +new file mode 100644 +index 0000000000000000000000000000000000000000..52469650b5498a45d5d95bd9d933c989cfb47ca7 +GIT binary patch +literal 32 +ccmd1#|DTBg0(2Mzp)7_%AVVXuuuM|`09r!?!~g&Q + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0027-tests-backport-test_setup_logging.patch b/SOURCES/0027-tests-backport-test_setup_logging.patch new file mode 100644 index 0000000..bc669a1 --- /dev/null +++ b/SOURCES/0027-tests-backport-test_setup_logging.patch @@ -0,0 +1,34 @@ +From ab6a1bdf3519d4344dee4e0225c74fc1198c8a60 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 15 Oct 2018 10:54:11 +0000 +Subject: [PATCH] tests: backport test_setup_logging() + +Related: #1635428 +--- + src/shared/tests.c | 6 ++++++ + src/shared/tests.h | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 6b3df0aa07..b10343650f 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -54,3 +54,9 @@ const char* get_testdata_dir(const char *suffix) { + strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1); + return testdir; + } ++ ++void test_setup_logging(int level) { ++ log_set_max_level(level); ++ log_parse_environment(); ++ log_open(); ++} +diff --git a/src/shared/tests.h b/src/shared/tests.h +index b88135ed93..cad21169f8 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -3,3 +3,4 @@ + + char* setup_fake_runtime_dir(void); + const char* get_testdata_dir(const char *suffix); ++void test_setup_logging(int level); diff --git a/SOURCES/0028-journal-change-support-URL-shown-in-the-catalog-entr.patch b/SOURCES/0028-journal-change-support-URL-shown-in-the-catalog-entr.patch new file mode 100644 index 0000000..65b1c32 --- /dev/null +++ b/SOURCES/0028-journal-change-support-URL-shown-in-the-catalog-entr.patch @@ -0,0 +1,23 @@ +From 80d5f0e2057717e9e5588edcabac95b8c238795c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 15 Oct 2018 10:55:50 +0000 +Subject: [PATCH] journal: change support URL shown in the catalog entries + +Resolves: #1550548 +--- + meson_options.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meson_options.txt b/meson_options.txt +index 16c1f2b2fa..ab2a658713 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -205,7 +205,7 @@ option('ntp-servers', type : 'string', + value : 'time1.google.com time2.google.com time3.google.com time4.google.com') + option('support-url', type : 'string', + description : 'the support URL to show in catalog entries included in systemd', +- value : 'https://lists.freedesktop.org/mailman/listinfo/systemd-devel') ++ value : 'https://access.redhat.com/support') + option('www-target', type : 'string', + description : 'the address and dir to upload docs too', + value : 'www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd') diff --git a/SOURCES/0029-resolved-create-etc-resolv.conf-symlink-at-runtime.patch b/SOURCES/0029-resolved-create-etc-resolv.conf-symlink-at-runtime.patch new file mode 100644 index 0000000..e5aeedd --- /dev/null +++ b/SOURCES/0029-resolved-create-etc-resolv.conf-symlink-at-runtime.patch @@ -0,0 +1,48 @@ +From e0f2dd42fb02aa5767d38714c95ac10fb683ad67 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 11 Mar 2016 17:06:17 -0500 +Subject: [PATCH] resolved: create /etc/resolv.conf symlink at runtime + +If the symlink doesn't exists, and we are being started, let's +create it to provie name resolution. + +If it exists, do nothing. In particular, if it is a broken symlink, +we cannot really know if the administator configured it to point to +a location used by some service that hasn't started yet, so we +don't touch it in that case either. + +https://bugzilla.redhat.com/show_bug.cgi?id=1313085 +--- + src/resolve/resolved.c | 4 ++++ + tmpfiles.d/etc.conf.m4 | 3 --- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c +index c01e53e9da..f3d96df458 100644 +--- a/src/resolve/resolved.c ++++ b/src/resolve/resolved.c +@@ -53,6 +53,10 @@ int main(int argc, char *argv[]) { + /* Drop privileges, but only if we have been started as root. If we are not running as root we assume all + * privileges are already dropped. */ + if (getuid() == 0) { ++ r = symlink("../run/systemd/resolve/resolv.conf", "/etc/resolv.conf"); ++ if (r < 0 && errno != EEXIST) ++ log_warning_errno(errno, ++ "Could not create /etc/resolv.conf symlink: %m"); + + /* Drop privileges, but keep three caps. Note that we drop those too, later on (see below) */ + r = drop_privileges(uid, gid, +diff --git a/tmpfiles.d/etc.conf.m4 b/tmpfiles.d/etc.conf.m4 +index df8d42101c..928105ea8d 100644 +--- a/tmpfiles.d/etc.conf.m4 ++++ b/tmpfiles.d/etc.conf.m4 +@@ -13,9 +13,6 @@ L+ /etc/mtab - - - - ../proc/self/mounts + m4_ifdef(`HAVE_SMACK_RUN_LABEL', + t /etc/mtab - - - - security.SMACK64=_ + )m4_dnl +-m4_ifdef(`ENABLE_RESOLVE', +-L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf +-)m4_dnl + C /etc/nsswitch.conf - - - - + m4_ifdef(`HAVE_PAM', + C /etc/pam.d - - - - diff --git a/SOURCES/0030-dissect-image-use-right-comparison-function.patch b/SOURCES/0030-dissect-image-use-right-comparison-function.patch new file mode 100644 index 0000000..f35e9eb --- /dev/null +++ b/SOURCES/0030-dissect-image-use-right-comparison-function.patch @@ -0,0 +1,27 @@ +From e615b80f3fda82ac7fe628800a9ff2103788bd05 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 9 Oct 2018 13:50:55 +0200 +Subject: [PATCH] dissect-image: use right comparison function + +fstype can be NULL here. + +(cherry picked from commit 4db1879acdc0b853e1a7e6e650b6feb917175fac) + +Resolves: #1602706 +--- + src/shared/dissect-image.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c +index fa1cf26ee1..e076c8e7db 100644 +--- a/src/shared/dissect-image.c ++++ b/src/shared/dissect-image.c +@@ -230,7 +230,7 @@ int dissect_image( + .node = TAKE_PTR(n), + }; + +- m->encrypted = streq(fstype, "crypto_LUKS"); ++ m->encrypted = streq_ptr(fstype, "crypto_LUKS"); + + *ret = TAKE_PTR(m); + diff --git a/SOURCES/0031-login-avoid-leak-of-name-returned-by-uid_to_name.patch b/SOURCES/0031-login-avoid-leak-of-name-returned-by-uid_to_name.patch new file mode 100644 index 0000000..e1ea815 --- /dev/null +++ b/SOURCES/0031-login-avoid-leak-of-name-returned-by-uid_to_name.patch @@ -0,0 +1,60 @@ +From 8fdca31b41a6470ceda8e0a84f90a1e5ca28aa5c Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 9 Oct 2018 17:26:19 +0200 +Subject: [PATCH] login: avoid leak of name returned by uid_to_name() + +(cherry picked from commit e99742ef3e9d847da04e71fec0eb426063b25068) + +Resolves: #1602706 +--- + src/login/logind-dbus.c | 4 +++- + src/login/logind-utmp.c | 6 +++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 13298cc855..dca7f4a30f 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -2155,6 +2155,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd + + if (cancelled && m->enable_wall_messages) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; ++ _cleanup_free_ char *username = NULL; + const char *tty = NULL; + uid_t uid = 0; + int r; +@@ -2165,8 +2166,9 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd + (void) sd_bus_creds_get_tty(creds, &tty); + } + ++ username = uid_to_name(uid); + utmp_wall("The system shutdown has been cancelled", +- uid_to_name(uid), tty, logind_wall_tty_filter, m); ++ username, tty, logind_wall_tty_filter, m); + } + + return sd_bus_reply_method_return(message, "b", cancelled); +diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c +index 71ebdfcfb1..8bdd4ab6bf 100644 +--- a/src/login/logind-utmp.c ++++ b/src/login/logind-utmp.c +@@ -61,7 +61,7 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) { + + static int warn_wall(Manager *m, usec_t n) { + char date[FORMAT_TIMESTAMP_MAX] = {}; +- _cleanup_free_ char *l = NULL; ++ _cleanup_free_ char *l = NULL, *username = NULL; + usec_t left; + int r; + +@@ -83,8 +83,8 @@ static int warn_wall(Manager *m, usec_t n) { + return 0; + } + +- utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid), +- m->scheduled_shutdown_tty, logind_wall_tty_filter, m); ++ username = uid_to_name(m->scheduled_shutdown_uid); ++ utmp_wall(l, username, m->scheduled_shutdown_tty, logind_wall_tty_filter, m); + + return 1; + } diff --git a/SOURCES/0032-firewall-util-add-an-assert-that-we-re-not-overwriti.patch b/SOURCES/0032-firewall-util-add-an-assert-that-we-re-not-overwriti.patch new file mode 100644 index 0000000..e092826 --- /dev/null +++ b/SOURCES/0032-firewall-util-add-an-assert-that-we-re-not-overwriti.patch @@ -0,0 +1,36 @@ +From fbe394e9166ddfe847dcac0eab0fcbd3c225dc33 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 10 Oct 2018 09:33:28 +0200 +Subject: [PATCH] firewall-util: add an assert that we're not overwriting a + buffer + +... like commit f28501279d2c28fdbb31d8273b723e9bf71d3b98 does for +out_interface. + +(cherry picked from commit 0b777d20e9a3868b12372ffce8040d1be063cec7) + +Resolves: #1602706 +--- + src/shared/firewall-util.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c +index eb4f5ff616..cba52fb419 100644 +--- a/src/shared/firewall-util.c ++++ b/src/shared/firewall-util.c +@@ -50,8 +50,14 @@ static int entry_fill_basics( + entry->ip.proto = protocol; + + if (in_interface) { ++ size_t l; ++ ++ l = strlen(in_interface); ++ assert(l < sizeof entry->ip.iniface); ++ assert(l < sizeof entry->ip.iniface_mask); ++ + strcpy(entry->ip.iniface, in_interface); +- memset(entry->ip.iniface_mask, 0xFF, strlen(in_interface)+1); ++ memset(entry->ip.iniface_mask, 0xFF, l + 1); + } + if (source) { + entry->ip.src = source->in; diff --git a/SOURCES/0033-journal-file-avoid-calling-ftruncate-with-invalid-fd.patch b/SOURCES/0033-journal-file-avoid-calling-ftruncate-with-invalid-fd.patch new file mode 100644 index 0000000..f37d84e --- /dev/null +++ b/SOURCES/0033-journal-file-avoid-calling-ftruncate-with-invalid-fd.patch @@ -0,0 +1,29 @@ +From ebdb96247433d920b391672e019da9402aabd351 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 10 Oct 2018 13:56:54 +0200 +Subject: [PATCH] journal-file: avoid calling ftruncate with invalid fd + +This can happen if journal_file_close is called from the failure +handling code of journal_file_open before f->fd was established. + +(cherry picked from commit c52368509f48e556be5a4c7a171361b656a25e02) + +Resolves: #1602706 +--- + src/journal/journal-file.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c +index 62e7f68a13..efc3ee052b 100644 +--- a/src/journal/journal-file.c ++++ b/src/journal/journal-file.c +@@ -1846,6 +1846,9 @@ static int journal_file_append_entry_internal( + void journal_file_post_change(JournalFile *f) { + assert(f); + ++ if (f->fd < 0) ++ return; ++ + /* inotify() does not receive IN_MODIFY events from file + * accesses done via mmap(). After each access we hence + * trigger IN_MODIFY by truncating the journal file to its diff --git a/SOURCES/0034-dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-o.patch b/SOURCES/0034-dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-o.patch new file mode 100644 index 0000000..98a69f2 --- /dev/null +++ b/SOURCES/0034-dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-o.patch @@ -0,0 +1,33 @@ +From c232bc1f346a6af9777c216d01f7940898ae1650 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Oct 2018 12:12:33 +0200 +Subject: [PATCH] dhcp6: make sure we have enough space for the DHCP6 option + header + +Fixes a vulnerability originally discovered by Felix Wilhelm from +Google. + +CVE-2018-15688 +LP: #1795921 +https://bugzilla.redhat.com/show_bug.cgi?id=1639067 + +(cherry-picked from commit 4dac5eaba4e419b29c97da38a8b1f82336c2c892) + +Resolves: #1643363 +--- + src/libsystemd-network/dhcp6-option.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c +index 18196b1257..0979497299 100644 +--- a/src/libsystemd-network/dhcp6-option.c ++++ b/src/libsystemd-network/dhcp6-option.c +@@ -103,7 +103,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { + return -EINVAL; + } + +- if (*buflen < len) ++ if (*buflen < offsetof(DHCP6Option, data) + len) + return -ENOBUFS; + + ia_hdr = *buf; diff --git a/SOURCES/0035-core-rename-queued_message-pending_reload_message.patch b/SOURCES/0035-core-rename-queued_message-pending_reload_message.patch new file mode 100644 index 0000000..fa23d06 --- /dev/null +++ b/SOURCES/0035-core-rename-queued_message-pending_reload_message.patch @@ -0,0 +1,133 @@ +From 35a23324975ac6ee0bbd3408394f992007b7a439 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 11:59:06 +0100 +Subject: [PATCH] =?UTF-8?q?core:=20rename=20queued=5Fmessage=20=E2=86=92?= + =?UTF-8?q?=20pending=5Freload=5Fmessage?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This field is only used for pending Reload() replies, hence let's rename +it to be more descriptive and precise. + +No change in behaviour. + +(cherry picked from commit 209de5256b7ba8600c3e73a85a43b86708998d65) + +Resolves: #1647359 +--- + src/core/dbus-manager.c | 4 ++-- + src/core/dbus.c | 12 ++++++------ + src/core/dbus.h | 2 +- + src/core/manager.c | 6 +++--- + src/core/manager.h | 2 +- + 5 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 4ed68af1e0..d39c9b28c4 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -1329,8 +1329,8 @@ static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error * + * is finished. That way the caller knows when the reload + * finished. */ + +- assert(!m->queued_message); +- r = sd_bus_message_new_method_return(message, &m->queued_message); ++ assert(!m->pending_reload_message); ++ r = sd_bus_message_new_method_return(message, &m->pending_reload_message); + if (r < 0) + return r; + +diff --git a/src/core/dbus.c b/src/core/dbus.c +index bf5917696e..256a410215 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -47,23 +47,23 @@ + + static void destroy_bus(Manager *m, sd_bus **bus); + +-int bus_send_queued_message(Manager *m) { ++int bus_send_pending_reload_message(Manager *m) { + int r; + + assert(m); + +- if (!m->queued_message) ++ if (!m->pending_reload_message) + return 0; + + /* If we cannot get rid of this message we won't dispatch any + * D-Bus messages, so that we won't end up wanting to queue + * another message. */ + +- r = sd_bus_send(NULL, m->queued_message, NULL); ++ r = sd_bus_send(NULL, m->pending_reload_message, NULL); + if (r < 0) + log_warning_errno(r, "Failed to send queued message: %m"); + +- m->queued_message = sd_bus_message_unref(m->queued_message); ++ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); + + return 0; + } +@@ -1079,8 +1079,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) { + u->bus_track = sd_bus_track_unref(u->bus_track); + + /* Get rid of queued message on this bus */ +- if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus) +- m->queued_message = sd_bus_message_unref(m->queued_message); ++ if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus) ++ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); + + /* Possibly flush unwritten data, but only if we are + * unprivileged, since we don't want to sync here */ +diff --git a/src/core/dbus.h b/src/core/dbus.h +index 382a96da7d..f1c0fa86c0 100644 +--- a/src/core/dbus.h ++++ b/src/core/dbus.h +@@ -5,7 +5,7 @@ + + #include "manager.h" + +-int bus_send_queued_message(Manager *m); ++int bus_send_pending_reload_message(Manager *m); + + int bus_init_private(Manager *m); + int bus_init_api(Manager *m); +diff --git a/src/core/manager.c b/src/core/manager.c +index 930df4e23a..a24bfcacdf 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2078,7 +2078,7 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) { + return 0; + + /* Anything to do at all? */ +- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->queued_message) ++ if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message) + return 0; + + /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this +@@ -2123,8 +2123,8 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) { + n++, budget--; + } + +- if (budget > 0 && m->queued_message) { +- bus_send_queued_message(m); ++ if (budget > 0 && m->pending_reload_message) { ++ bus_send_pending_reload_message(m); + n++; + } + +diff --git a/src/core/manager.h b/src/core/manager.h +index ea5d425030..c7f4d66ecd 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -215,7 +215,7 @@ struct Manager { + + /* This is used during reloading: before the reload we queue + * the reply message here, and afterwards we send it */ +- sd_bus_message *queued_message; ++ sd_bus_message *pending_reload_message; + + Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */ + diff --git a/SOURCES/0036-core-when-we-can-t-send-the-pending-reload-message-s.patch b/SOURCES/0036-core-when-we-can-t-send-the-pending-reload-message-s.patch new file mode 100644 index 0000000..d75713d --- /dev/null +++ b/SOURCES/0036-core-when-we-can-t-send-the-pending-reload-message-s.patch @@ -0,0 +1,36 @@ +From 52a474cf15bf2b0edb449750eb63eb8cdb9a3780 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 12:00:42 +0100 +Subject: [PATCH] core: when we can't send the pending reload message, say we + ignore it in the warning we log + +No change in behaviour, just better wording. + +(cherry picked from commit 4b66bccab004221b903b43b4c224442bfa3e9ac7) + +Resolves: #1647359 +--- + src/core/dbus.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/core/dbus.c b/src/core/dbus.c +index 256a410215..346a440c5d 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -55,13 +55,12 @@ int bus_send_pending_reload_message(Manager *m) { + if (!m->pending_reload_message) + return 0; + +- /* If we cannot get rid of this message we won't dispatch any +- * D-Bus messages, so that we won't end up wanting to queue +- * another message. */ ++ /* If we cannot get rid of this message we won't dispatch any D-Bus messages, so that we won't end up wanting ++ * to queue another message. */ + + r = sd_bus_send(NULL, m->pending_reload_message, NULL); + if (r < 0) +- log_warning_errno(r, "Failed to send queued message: %m"); ++ log_warning_errno(r, "Failed to send queued message, ignoring: %m"); + + m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); + diff --git a/SOURCES/0037-core-make-sure-we-don-t-throttle-change-signal-gener.patch b/SOURCES/0037-core-make-sure-we-don-t-throttle-change-signal-gener.patch new file mode 100644 index 0000000..603d269 --- /dev/null +++ b/SOURCES/0037-core-make-sure-we-don-t-throttle-change-signal-gener.patch @@ -0,0 +1,114 @@ +From 0412acb95ffac94d5916ee19991cc7194e55953c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 12:48:49 +0100 +Subject: [PATCH] core: make sure we don't throttle change signal generator + when a reload is pending + +Fixes: #10627 +(cherry picked from commit b8d381c47776ea0440af175cbe0c02cb743bde08) + +Resolves: #1647359 +--- + src/core/manager.c | 64 ++++++++++++++++++++++++++++------------------ + 1 file changed, 39 insertions(+), 25 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index a24bfcacdf..3b2fe11e87 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2074,56 +2074,70 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) { + + assert(m); + ++ /* Avoid recursion */ + if (m->dispatching_dbus_queue) + return 0; + +- /* Anything to do at all? */ +- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message) +- return 0; ++ /* When we are reloading, let's not wait with generating signals, since we need to exit the manager as quickly ++ * as we can. There's no point in throttling generation of signals in that case. */ ++ if (MANAGER_IS_RELOADING(m) || m->send_reloading_done || m->pending_reload_message) ++ budget = (unsigned) -1; /* infinite budget in this case */ ++ else { ++ /* Anything to do at all? */ ++ if (!m->dbus_unit_queue && !m->dbus_job_queue) ++ return 0; + +- /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this +- * cycle out, and process things in a later cycle when the queues got a bit emptier. */ +- if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD) +- return 0; ++ /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's ++ * sit this cycle out, and process things in a later cycle when the queues got a bit emptier. */ ++ if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD) ++ return 0; + +- /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't overly +- * full before this call we shouldn't increase it in size too wildly in one step, and we shouldn't monopolize +- * CPU time with generating these messages. Note the difference in counting of this "budget" and the +- * "threshold" above: the "budget" is decreased only once per generated message, regardless how many +- * busses/direct connections it is enqueued on, while the "threshold" is applied to each queued instance of bus +- * message, i.e. if the same message is enqueued to five busses/direct connections it will be counted five +- * times. This difference in counting ("references" vs. "instances") is primarily a result of the fact that +- * it's easier to implement it this way, however it also reflects the thinking that the "threshold" should put +- * a limit on used queue memory, i.e. space, while the "budget" should put a limit on time. Also note that +- * the "threshold" is currently chosen much higher than the "budget". */ +- budget = MANAGER_BUS_MESSAGE_BUDGET; ++ /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't ++ * overly full before this call we shouldn't increase it in size too wildly in one step, and we ++ * shouldn't monopolize CPU time with generating these messages. Note the difference in counting of ++ * this "budget" and the "threshold" above: the "budget" is decreased only once per generated message, ++ * regardless how many busses/direct connections it is enqueued on, while the "threshold" is applied to ++ * each queued instance of bus message, i.e. if the same message is enqueued to five busses/direct ++ * connections it will be counted five times. This difference in counting ("references" ++ * vs. "instances") is primarily a result of the fact that it's easier to implement it this way, ++ * however it also reflects the thinking that the "threshold" should put a limit on used queue memory, ++ * i.e. space, while the "budget" should put a limit on time. Also note that the "threshold" is ++ * currently chosen much higher than the "budget". */ ++ budget = MANAGER_BUS_MESSAGE_BUDGET; ++ } + + m->dispatching_dbus_queue = true; + +- while (budget > 0 && (u = m->dbus_unit_queue)) { ++ while (budget != 0 && (u = m->dbus_unit_queue)) { + + assert(u->in_dbus_queue); + + bus_unit_send_change_signal(u); +- n++, budget--; ++ n++; ++ ++ if (budget != (unsigned) -1) ++ budget--; + } + +- while (budget > 0 && (j = m->dbus_job_queue)) { ++ while (budget != 0 && (j = m->dbus_job_queue)) { + assert(j->in_dbus_queue); + + bus_job_send_change_signal(j); +- n++, budget--; ++ n++; ++ ++ if (budget != (unsigned) -1) ++ budget--; + } + + m->dispatching_dbus_queue = false; + +- if (budget > 0 && m->send_reloading_done) { ++ if (m->send_reloading_done) { + m->send_reloading_done = false; + bus_manager_send_reloading(m, false); +- n++, budget--; ++ n++; + } + +- if (budget > 0 && m->pending_reload_message) { ++ if (m->pending_reload_message) { + bus_send_pending_reload_message(m); + n++; + } diff --git a/SOURCES/0038-proc-cmdline-introduce-PROC_CMDLINE_RD_STRICT.patch b/SOURCES/0038-proc-cmdline-introduce-PROC_CMDLINE_RD_STRICT.patch new file mode 100644 index 0000000..c1be01e --- /dev/null +++ b/SOURCES/0038-proc-cmdline-introduce-PROC_CMDLINE_RD_STRICT.patch @@ -0,0 +1,45 @@ +From 84b15a8a493424efa8c9eaa9a44a23c3c59742bd Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 25 Oct 2018 16:21:26 +0200 +Subject: [PATCH] proc-cmdline: introduce PROC_CMDLINE_RD_STRICT + +Our current set of flags allows an option to be either +use just in initrd or both in initrd and normal system. +This new flag is intended to be used in the case where +you want apply some settings just in initrd or just +in normal system. + +(cherry picked from commit ed58820d7669971762dd887dc117d922c23f2543) + +Related: #1643429 +--- + src/basic/proc-cmdline.c | 3 ++- + src/basic/proc-cmdline.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c +index add481c2ae..530ac37460 100644 +--- a/src/basic/proc-cmdline.c ++++ b/src/basic/proc-cmdline.c +@@ -72,7 +72,8 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, unsigned fla + + if (flags & PROC_CMDLINE_STRIP_RD_PREFIX) + key = q; +- } ++ } else if (in_initrd() && flags & PROC_CMDLINE_RD_STRICT) ++ continue; + + value = strchr(key, '='); + if (value) +diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h +index 4a9e6e0f62..140200dbf4 100644 +--- a/src/basic/proc-cmdline.h ++++ b/src/basic/proc-cmdline.h +@@ -8,6 +8,7 @@ + enum { + PROC_CMDLINE_STRIP_RD_PREFIX = 1, + PROC_CMDLINE_VALUE_OPTIONAL = 2, ++ PROC_CMDLINE_RD_STRICT = 4 + }; + + typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data); diff --git a/SOURCES/0039-debug-generator-introduce-rd.-version-of-all-options.patch b/SOURCES/0039-debug-generator-introduce-rd.-version-of-all-options.patch new file mode 100644 index 0000000..ac7a1b1 --- /dev/null +++ b/SOURCES/0039-debug-generator-introduce-rd.-version-of-all-options.patch @@ -0,0 +1,77 @@ +From 55798355455b9255458d6a705f8766c4dbe3ef73 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 25 Oct 2018 16:34:00 +0200 +Subject: [PATCH] debug-generator: introduce rd.* version of all options + +(cherry picked from commit a7dd6d04b07f58df5c0294743d76df0be0b4b928) + +Resolves: #1643429 +--- + man/systemd-debug-generator.xml | 27 +++++++++++++++++++-------- + src/debug-generator/debug-generator.c | 2 +- + 2 files changed, 20 insertions(+), 9 deletions(-) + +diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml +index d5cf4109b0..fa88e8ac01 100644 +--- a/man/systemd-debug-generator.xml ++++ b/man/systemd-debug-generator.xml +@@ -33,27 +33,38 @@ + that reads the kernel command line and understands three + options: + +- If the option is specified +- and followed by a unit name, this unit is masked for the runtime, +- similar to the effect of ++ If the or ++ option is specified and followed by a unit name, this unit is ++ masked for the runtime, similar to the effect of + systemctl1's + mask command. This is useful to boot with + certain units removed from the initial boot transaction for +- debugging system startup. May be specified more than once. ++ debugging system startup. May be specified more than once. ++ is honored only by initial ++ RAM disk (initrd) while is ++ honored only in the main system. + +- If the option is specified ++ If the or ++ option is specified + and followed by a unit name, a start job for this unit is added to + the initial transaction. This is useful to start one or more +- additional units at boot. May be specified more than once. ++ additional units at boot. May be specified more than once. ++ is honored only by initial ++ RAM disk (initrd) while is ++ honored only in the main system. + +- If the option is ++ If the or ++ option is + specified, the debug shell service + debug-shell.service is pulled into the boot + transaction. It will spawn a debug shell on tty9 during early + system startup. Note that the shell may also be turned on + persistently by enabling it with + systemctl1's +- enable command. ++ enable command. ++ is honored only by initial ++ RAM disk (initrd) while is ++ honored only in the main system. + + systemd-debug-generator implements + systemd.generator7. +diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c +index dd6ab94fa2..800d31cebe 100644 +--- a/src/debug-generator/debug-generator.c ++++ b/src/debug-generator/debug-generator.c +@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) { + + umask(0022); + +- r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); ++ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_RD_STRICT | PROC_CMDLINE_STRIP_RD_PREFIX); + if (r < 0) + log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + diff --git a/SOURCES/0040-chown-recursive-let-s-rework-the-recursive-logic-to-.patch b/SOURCES/0040-chown-recursive-let-s-rework-the-recursive-logic-to-.patch new file mode 100644 index 0000000..c27e8aa --- /dev/null +++ b/SOURCES/0040-chown-recursive-let-s-rework-the-recursive-logic-to-.patch @@ -0,0 +1,213 @@ +From 107d75ca9394481bd045385fc45f2ee65b30ad16 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Oct 2018 11:26:59 +0200 +Subject: [PATCH] chown-recursive: let's rework the recursive logic to use + O_PATH + +That way we can pin a specific inode and analyze it and manipulate it +without it being swapped out beneath our hands. + +Fixes a vulnerability originally found by Jann Horn from Google. + +CVE-2018-15687 +LP: #1796692 +https://bugzilla.redhat.com/show_bug.cgi?id=1639076 + +(cherry-picked from commit 5de6cce58b3e8b79239b6e83653459d91af6e57c) + +Resolves: #1643368 +--- + src/core/chown-recursive.c | 146 ++++++++++++++++++------------------- + 1 file changed, 70 insertions(+), 76 deletions(-) + +diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c +index c4794501c2..27c64489b5 100644 +--- a/src/core/chown-recursive.c ++++ b/src/core/chown-recursive.c +@@ -1,17 +1,19 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + +-#include +-#include + #include ++#include ++#include + +-#include "user-util.h" +-#include "macro.h" +-#include "fd-util.h" +-#include "dirent-util.h" + #include "chown-recursive.h" ++#include "dirent-util.h" ++#include "fd-util.h" ++#include "macro.h" ++#include "stdio-util.h" ++#include "strv.h" ++#include "user-util.h" + +-static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid, gid_t gid) { +- int r; ++static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) { ++ char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + + assert(fd >= 0); + assert(st); +@@ -20,90 +22,82 @@ static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid, + (!gid_is_valid(gid) || st->st_gid == gid)) + return 0; + +- if (name) +- r = fchownat(fd, name, uid, gid, AT_SYMLINK_NOFOLLOW); +- else +- r = fchown(fd, uid, gid); +- if (r < 0) +- return -errno; ++ /* We change ownership through the /proc/self/fd/%i path, so that we have a stable reference that works with ++ * O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */ ++ xsprintf(procfs_path, "/proc/self/fd/%i", fd); + +- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. */ +- if (name) { +- if (!S_ISLNK(st->st_mode)) +- r = fchmodat(fd, name, st->st_mode, 0); +- else /* There's currently no AT_SYMLINK_NOFOLLOW for fchmodat() */ +- r = 0; +- } else +- r = fchmod(fd, st->st_mode); +- if (r < 0) ++ if (chown(procfs_path, uid, gid) < 0) + return -errno; + ++ /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks ++ * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file ++ * systems trying to change the access mode will succeed but has no effect while on others it actively ++ * fails. */ ++ if (!S_ISLNK(st->st_mode)) ++ if (chmod(procfs_path, st->st_mode & 07777) < 0) ++ return -errno; ++ + return 1; + } + + static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gid_t gid) { ++ _cleanup_closedir_ DIR *d = NULL; + bool changed = false; ++ struct dirent *de; + int r; + + assert(fd >= 0); + assert(st); + +- if (S_ISDIR(st->st_mode)) { +- _cleanup_closedir_ DIR *d = NULL; +- struct dirent *de; +- +- d = fdopendir(fd); +- if (!d) { +- r = -errno; +- goto finish; +- } +- fd = -1; +- +- FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) { +- struct stat fst; +- +- if (dot_or_dot_dot(de->d_name)) +- continue; +- +- if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) { +- r = -errno; +- goto finish; +- } +- +- if (S_ISDIR(fst.st_mode)) { +- int subdir_fd; +- +- subdir_fd = openat(dirfd(d), de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); +- if (subdir_fd < 0) { +- r = -errno; +- goto finish; +- } +- +- r = chown_recursive_internal(subdir_fd, &fst, uid, gid); +- if (r < 0) +- goto finish; +- if (r > 0) +- changed = true; +- } else { +- r = chown_one(dirfd(d), de->d_name, &fst, uid, gid); +- if (r < 0) +- goto finish; +- if (r > 0) +- changed = true; +- } ++ d = fdopendir(fd); ++ if (!d) { ++ safe_close(fd); ++ return -errno; ++ } ++ ++ FOREACH_DIRENT_ALL(de, d, return -errno) { ++ _cleanup_close_ int path_fd = -1; ++ struct stat fst; ++ ++ if (dot_or_dot_dot(de->d_name)) ++ continue; ++ ++ /* Let's pin the child inode we want to fix now with an O_PATH fd, so that it cannot be swapped out ++ * while we manipulate it. */ ++ path_fd = openat(dirfd(d), de->d_name, O_PATH|O_CLOEXEC|O_NOFOLLOW); ++ if (path_fd < 0) ++ return -errno; ++ ++ if (fstat(path_fd, &fst) < 0) ++ return -errno; ++ ++ if (S_ISDIR(fst.st_mode)) { ++ int subdir_fd; ++ ++ /* Convert it to a "real" (i.e. non-O_PATH) fd now */ ++ subdir_fd = fd_reopen(path_fd, O_RDONLY|O_CLOEXEC|O_NOATIME); ++ if (subdir_fd < 0) ++ return subdir_fd; ++ ++ r = chown_recursive_internal(subdir_fd, &fst, uid, gid); /* takes possession of subdir_fd even on failure */ ++ if (r < 0) ++ return r; ++ if (r > 0) ++ changed = true; ++ } else { ++ r = chown_one(path_fd, &fst, uid, gid); ++ if (r < 0) ++ return r; ++ if (r > 0) ++ changed = true; + } ++ } + +- r = chown_one(dirfd(d), NULL, st, uid, gid); +- } else +- r = chown_one(fd, NULL, st, uid, gid); ++ r = chown_one(dirfd(d), st, uid, gid); + if (r < 0) +- goto finish; ++ return r; + +- r = r > 0 || changed; +- +-finish: +- safe_close(fd); +- return r; ++ return r > 0 || changed; + } + + int path_chown_recursive(const char *path, uid_t uid, gid_t gid) { +@@ -111,7 +105,7 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) { + struct stat st; + int r; + +- fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); ++ fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (fd < 0) + return -errno; + diff --git a/SOURCES/0041-chown-recursive-also-drop-ACLs-when-recursively-chow.patch b/SOURCES/0041-chown-recursive-also-drop-ACLs-when-recursively-chow.patch new file mode 100644 index 0000000..edf2368 --- /dev/null +++ b/SOURCES/0041-chown-recursive-also-drop-ACLs-when-recursively-chow.patch @@ -0,0 +1,58 @@ +From bbe9ac11d8d4a8511214605509a593fb9f04ffaa Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Oct 2018 11:28:40 +0200 +Subject: [PATCH] chown-recursive: also drop ACLs when recursively chown()ing + +Let's better be safe than sorry and also drop ACLs. + +(cherry-picked from commit f89bc84f3242449cbc308892c87573b131f121df) + +Related: #1643368 +--- + src/core/chown-recursive.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c +index 27c64489b5..447b771267 100644 +--- a/src/core/chown-recursive.c ++++ b/src/core/chown-recursive.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + + #include "chown-recursive.h" + #include "dirent-util.h" +@@ -14,6 +15,7 @@ + + static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; ++ const char *n; + + assert(fd >= 0); + assert(st); +@@ -26,13 +28,19 @@ static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) { + * O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */ + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + ++ /* Drop any ACL if there is one */ ++ FOREACH_STRING(n, "system.posix_acl_access", "system.posix_acl_default") ++ if (removexattr(procfs_path, n) < 0) ++ if (!IN_SET(errno, ENODATA, EOPNOTSUPP, ENOSYS, ENOTTY)) ++ return -errno; ++ + if (chown(procfs_path, uid, gid) < 0) + return -errno; + +- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks +- * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file +- * systems trying to change the access mode will succeed but has no effect while on others it actively +- * fails. */ ++ /* The linux kernel alters the mode in some cases of chown(), as well when we change ACLs. Let's undo this. We ++ * do this only for non-symlinks however. That's because for symlinks the access mode is ignored anyway and ++ * because on some kernels/file systems trying to change the access mode will succeed but has no effect while ++ * on others it actively fails. */ + if (!S_ISLNK(st->st_mode)) + if (chmod(procfs_path, st->st_mode & 07777) < 0) + return -errno; diff --git a/SOURCES/0042-chown-recursive-TAKE_FD-is-your-friend.patch b/SOURCES/0042-chown-recursive-TAKE_FD-is-your-friend.patch new file mode 100644 index 0000000..541b9a2 --- /dev/null +++ b/SOURCES/0042-chown-recursive-TAKE_FD-is-your-friend.patch @@ -0,0 +1,34 @@ +From c9630164b869e109bf2960968fc583449ccf0875 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Oct 2018 11:42:11 +0200 +Subject: [PATCH] chown-recursive: TAKE_FD() is your friend + +(cherry-picked from commit cd6b7d50c337b3676a3d5fc2188ff298dcbdb939) + +Related: #1643368 +--- + src/core/chown-recursive.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c +index 447b771267..7767301f7d 100644 +--- a/src/core/chown-recursive.c ++++ b/src/core/chown-recursive.c +@@ -111,7 +111,6 @@ static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gi + int path_chown_recursive(const char *path, uid_t uid, gid_t gid) { + _cleanup_close_ int fd = -1; + struct stat st; +- int r; + + fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (fd < 0) +@@ -130,8 +129,5 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) { + (!gid_is_valid(gid) || st.st_gid == gid)) + return 0; + +- r = chown_recursive_internal(fd, &st, uid, gid); +- fd = -1; /* we donated the fd to the call, regardless if it succeeded or failed */ +- +- return r; ++ return chown_recursive_internal(TAKE_FD(fd), &st, uid, gid); /* we donate the fd to the call, regardless if it succeeded or failed */ + } diff --git a/SOURCES/0043-test-add-test-case-for-recursive-chown-ing.patch b/SOURCES/0043-test-add-test-case-for-recursive-chown-ing.patch new file mode 100644 index 0000000..7a77368 --- /dev/null +++ b/SOURCES/0043-test-add-test-case-for-recursive-chown-ing.patch @@ -0,0 +1,200 @@ +From b53f89d56a5b7528735ddf335f8b47ab3e1a947a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Oct 2018 11:31:37 +0200 +Subject: [PATCH] test: add test case for recursive chown()ing + +[msekleta: I removed call to log_test_skipped() and replaced it with older construct log_info() + return EXIT_TEST_SKIP] + +(cherry-picked from commit cb9e44db36caefcbb8ee7a12e14217305ed69ff2) + +Related: #1643368 +--- + src/test/meson.build | 5 ++ + src/test/test-chown-rec.c | 162 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 167 insertions(+) + create mode 100644 src/test/test-chown-rec.c + +diff --git a/src/test/meson.build b/src/test/meson.build +index 7da7e3a22c..b982251b1f 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -60,6 +60,11 @@ tests += [ + libmount, + libblkid]], + ++ [['src/test/test-chown-rec.c'], ++ [libcore, ++ libshared], ++ []], ++ + [['src/test/test-job-type.c'], + [libcore, + libshared], +diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c +new file mode 100644 +index 0000000000..f16d4d4ba2 +--- /dev/null ++++ b/src/test/test-chown-rec.c +@@ -0,0 +1,162 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++ ++#include "alloc-util.h" ++#include "chown-recursive.h" ++#include "fileio.h" ++#include "log.h" ++#include "rm-rf.h" ++#include "string-util.h" ++#include "tests.h" ++ ++static const uint8_t acl[] = { ++ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x07, 0x00, ++ 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00, ++ 0xff, 0xff, 0xff, 0xff, ++}; ++ ++static const uint8_t default_acl[] = { ++ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x07, 0x00, ++ 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00, ++ 0xff, 0xff, 0xff, 0xff, ++}; ++ ++static bool has_xattr(const char *p) { ++ char buffer[sizeof(acl) * 4]; ++ ++ if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) { ++ if (IN_SET(errno, EOPNOTSUPP, ENOTTY, ENODATA, ENOSYS)) ++ return false; ++ } ++ ++ return true; ++} ++ ++static void test_chown_recursive(void) { ++ _cleanup_(rm_rf_physical_and_freep) char *t = NULL; ++ struct stat st; ++ const char *p; ++ ++ umask(022); ++ assert_se(mkdtemp_malloc(NULL, &t) >= 0); ++ ++ p = strjoina(t, "/dir"); ++ assert_se(mkdir(p, 0777) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISDIR(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/symlink"); ++ assert_se(symlink("../../", p) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISLNK(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0777); ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/reg"); ++ assert_se(mknod(p, S_IFREG|0777, 0) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISREG(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/sock"); ++ assert_se(mknod(p, S_IFSOCK|0777, 0) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISSOCK(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/fifo"); ++ assert_se(mknod(p, S_IFIFO|0777, 0) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISFIFO(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(!has_xattr(p)); ++ ++ /* We now apply an xattr to the dir, and check it again */ ++ p = strjoina(t, "/dir"); ++ assert_se(setxattr(p, "system.posix_acl_access", acl, sizeof(acl), 0) >= 0); ++ assert_se(setxattr(p, "system.posix_acl_default", default_acl, sizeof(default_acl), 0) >= 0); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISDIR(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0775); /* acl change changed the mode too */ ++ assert_se(st.st_uid == 0); ++ assert_se(st.st_gid == 0); ++ assert_se(has_xattr(p)); ++ ++ assert_se(path_chown_recursive(t, 1, 2) >= 0); ++ ++ p = strjoina(t, "/dir"); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISDIR(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0775); ++ assert_se(st.st_uid == 1); ++ assert_se(st.st_gid == 2); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/symlink"); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISLNK(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0777); ++ assert_se(st.st_uid == 1); ++ assert_se(st.st_gid == 2); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/reg"); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISREG(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 1); ++ assert_se(st.st_gid == 2); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/sock"); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISSOCK(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 1); ++ assert_se(st.st_gid == 2); ++ assert_se(!has_xattr(p)); ++ ++ p = strjoina(t, "/dir/fifo"); ++ assert_se(lstat(p, &st) >= 0); ++ assert_se(S_ISFIFO(st.st_mode)); ++ assert_se((st.st_mode & 07777) == 0755); ++ assert_se(st.st_uid == 1); ++ assert_se(st.st_gid == 2); ++ assert_se(!has_xattr(p)); ++} ++ ++int main(int argc, char *argv[]) { ++ log_set_max_level(LOG_DEBUG); ++ log_parse_environment(); ++ log_open(); ++ ++ if (geteuid() != 0) { ++ log_info("not running as root"); ++ return EXIT_TEST_SKIP; ++ } ++ ++ test_chown_recursive(); ++ ++ return EXIT_SUCCESS; ++} diff --git a/SOURCES/0044-Revert-sysctl.d-request-ECN-on-both-in-and-outgoing-.patch b/SOURCES/0044-Revert-sysctl.d-request-ECN-on-both-in-and-outgoing-.patch new file mode 100644 index 0000000..bdb582c --- /dev/null +++ b/SOURCES/0044-Revert-sysctl.d-request-ECN-on-both-in-and-outgoing-.patch @@ -0,0 +1,32 @@ +From 730ce6562f8a5f4a61d1ed3ffb4d65fa27b728fc Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Fri, 17 Aug 2018 21:31:05 +0200 +Subject: [PATCH] Revert "sysctl.d: request ECN on both in and outgoing + connections" + +Turning on ECN still causes slow or broken network on linux. Our tcp +is not yet ready for wide spread use of ECN. + +This reverts commit 919472741dba6ad0a3f6c2b76d390a02d0e2fdc3. + +(cherry picked from commit 1e190dfd5bb95036f937ef1dc46f43eb0a146612) + +Resolves: #1619790 +--- + sysctl.d/50-default.conf | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index b67ae87ca6..e263cf0628 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -33,9 +33,6 @@ net.ipv4.conf.all.promote_secondaries = 1 + # Fair Queue CoDel packet scheduler to fight bufferbloat + net.core.default_qdisc = fq_codel + +-# Request Explicit Congestion Notification (ECN) on both in and outgoing connections +-net.ipv4.tcp_ecn = 1 +- + # Enable hard and soft link protection + fs.protected_hardlinks = 1 + fs.protected_symlinks = 1 diff --git a/SOURCES/0045-detect-virt-do-not-try-to-read-all-of-proc-cpuinfo.patch b/SOURCES/0045-detect-virt-do-not-try-to-read-all-of-proc-cpuinfo.patch new file mode 100644 index 0000000..9669b1a --- /dev/null +++ b/SOURCES/0045-detect-virt-do-not-try-to-read-all-of-proc-cpuinfo.patch @@ -0,0 +1,84 @@ +From 886e5b028953404f2d924b561c0689d3e50dbbf4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 13 Sep 2018 09:24:36 +0200 +Subject: [PATCH] detect-virt: do not try to read all of /proc/cpuinfo + +Quoting https://github.com/systemd/systemd/issues/10074: +> detect_vm_uml() reads /proc/cpuinfo with read_full_file() +> read_full_file() has a file max limit size of READ_FULL_BYTES_MAX=(4U*1024U*1024U) +> Unfortunately, the size of my /proc/cpuinfo is bigger, approximately: +> echo $(( 4* $(cat /proc/cpuinfo | wc -c))) +> 9918072 +> This causes read_full_file() to fail and the Condition test fallout. + +Let's just read line by line until we find an intersting line. This also +helps if not running under UML, because we avoid reading as much data. + +(cherry picked from commit 6058516a14ada1748313af6783f5b4e7e3006654) + +Resolves: #1631532 +--- + src/basic/virt.c | 38 ++++++++++++++++++++++++++++---------- + 1 file changed, 28 insertions(+), 10 deletions(-) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index d347732bb3..e05b3e6d99 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -11,6 +11,7 @@ + + #include "alloc-util.h" + #include "dirent-util.h" ++#include "def.h" + #include "env-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -259,21 +260,38 @@ static int detect_vm_hypervisor(void) { + } + + static int detect_vm_uml(void) { +- _cleanup_free_ char *cpuinfo_contents = NULL; ++ _cleanup_fclose_ FILE *f = NULL; + int r; + + /* Detect User-Mode Linux by reading /proc/cpuinfo */ +- r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL); +- if (r == -ENOENT) { +- log_debug("/proc/cpuinfo not found, assuming no UML virtualization."); +- return VIRTUALIZATION_NONE; ++ f = fopen("/proc/cpuinfo", "re"); ++ if (!f) { ++ if (errno == ENOENT) { ++ log_debug("/proc/cpuinfo not found, assuming no UML virtualization."); ++ return VIRTUALIZATION_NONE; ++ } ++ return -errno; + } +- if (r < 0) +- return r; + +- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) { +- log_debug("UML virtualization found in /proc/cpuinfo"); +- return VIRTUALIZATION_UML; ++ for (;;) { ++ _cleanup_free_ char *line = NULL; ++ const char *t; ++ ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ t = startswith(line, "vendor_id\t: "); ++ if (t) { ++ if (startswith(t, "User Mode Linux")) { ++ log_debug("UML virtualization found in /proc/cpuinfo"); ++ return VIRTUALIZATION_UML; ++ } ++ ++ break; ++ } + } + + log_debug("UML virtualization not found in /proc/cpuinfo."); diff --git a/SOURCES/0046-sd-bus-unify-three-code-paths-which-free-struct-bus_.patch b/SOURCES/0046-sd-bus-unify-three-code-paths-which-free-struct-bus_.patch new file mode 100644 index 0000000..920053e --- /dev/null +++ b/SOURCES/0046-sd-bus-unify-three-code-paths-which-free-struct-bus_.patch @@ -0,0 +1,166 @@ +From eb141ba81158feb74118da4e7a3f2266b11ffe10 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 9 Jul 2018 08:06:28 +0200 +Subject: [PATCH] sd-bus: unify three code-paths which free struct + bus_container + +We didn't free one of the fields in two of the places. + +$ valgrind --show-leak-kinds=all --leak-check=full \ + build/fuzz-bus-message \ + test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 +... +==14457== HEAP SUMMARY: +==14457== in use at exit: 3 bytes in 1 blocks +==14457== total heap usage: 509 allocs, 508 frees, 51,016 bytes allocated +==14457== +==14457== 3 bytes in 1 blocks are definitely lost in loss record 1 of 1 +==14457== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299) +==14457== by 0x53AFE79: strndup (in /usr/lib64/libc-2.27.so) +==14457== by 0x4F52EB8: free_and_strndup (string-util.c:1039) +==14457== by 0x4F8E1AB: sd_bus_message_peek_type (bus-message.c:4193) +==14457== by 0x4F76CB5: bus_message_dump (bus-dump.c:144) +==14457== by 0x108F12: LLVMFuzzerTestOneInput (fuzz-bus-message.c:24) +==14457== by 0x1090F7: main (fuzz-main.c:34) +==14457== +==14457== LEAK SUMMARY: +==14457== definitely lost: 3 bytes in 1 blocks + +(cherry picked from commit 6d1e0f4fcba8d6f425da3dc91805db95399b3c8b) +Resolves: #1635435 +--- + src/libsystemd/sd-bus/bus-message.c | 64 +++++++++--------- + ...k-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 | Bin 0 -> 534 bytes + 2 files changed, 32 insertions(+), 32 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 7c8bad2bdd..d55cb14843 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -77,19 +77,38 @@ static void message_reset_parts(sd_bus_message *m) { + m->cached_rindex_part_begin = 0; + } + +-static void message_reset_containers(sd_bus_message *m) { +- unsigned i; ++static struct bus_container *message_get_container(sd_bus_message *m) { ++ assert(m); ++ ++ if (m->n_containers == 0) ++ return &m->root_container; ++ ++ assert(m->containers); ++ return m->containers + m->n_containers - 1; ++} ++ ++static void message_free_last_container(sd_bus_message *m) { ++ struct bus_container *c; ++ ++ c = message_get_container(m); ++ ++ free(c->signature); ++ free(c->peeked_signature); ++ free(c->offsets); ++ ++ /* Move to previous container, but not if we are on root container */ ++ if (m->n_containers > 0) ++ m->n_containers--; ++} + ++static void message_reset_containers(sd_bus_message *m) { + assert(m); + +- for (i = 0; i < m->n_containers; i++) { +- free(m->containers[i].signature); +- free(m->containers[i].offsets); +- } ++ while (m->n_containers > 0) ++ message_free_last_container(m); + + m->containers = mfree(m->containers); +- +- m->n_containers = m->containers_allocated = 0; ++ m->containers_allocated = 0; + m->root_container.index = 0; + } + +@@ -112,10 +131,8 @@ static sd_bus_message* message_free(sd_bus_message *m) { + free(m->iovec); + + message_reset_containers(m); +- free(m->root_container.signature); +- free(m->root_container.offsets); +- +- free(m->root_container.peeked_signature); ++ assert(m->n_containers == 0); ++ message_free_last_container(m); + + bus_creds_done(&m->creds); + return mfree(m); +@@ -1113,16 +1130,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message * + return 0; + } + +-static struct bus_container *message_get_container(sd_bus_message *m) { +- assert(m); +- +- if (m->n_containers == 0) +- return &m->root_container; +- +- assert(m->containers); +- return m->containers + m->n_containers - 1; +-} +- + struct bus_body_part *message_append_part(sd_bus_message *m) { + struct bus_body_part *part; + +@@ -4108,13 +4115,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) { + return -EBUSY; + } + +- free(c->signature); +- free(c->peeked_signature); +- free(c->offsets); +- m->n_containers--; ++ message_free_last_container(m); + + c = message_get_container(m); +- + saved = c->index; + c->index = c->saved_index; + r = container_next_item(m, c, &m->rindex); +@@ -4132,16 +4135,13 @@ static void message_quit_container(sd_bus_message *m) { + assert(m->sealed); + assert(m->n_containers > 0); + +- c = message_get_container(m); +- + /* Undo seeks */ ++ c = message_get_container(m); + assert(m->rindex >= c->before); + m->rindex = c->before; + + /* Free container */ +- free(c->signature); +- free(c->offsets); +- m->n_containers--; ++ message_free_last_container(m); + + /* Correct index of new top-level container */ + c = message_get_container(m); +diff --git a/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 +new file mode 100644 +index 0000000000000000000000000000000000000000..c371824ffb604708619fd0713e8fca609bac18f7 +GIT binary patch +literal 534 +zcmZ{h!A`?442GSJP20o?A&zJgm*%pT#&`l!4rxq{&>8YmwQrOs;B(}I_m11m8`nFp`#ek1>oQYVSs`!XH?7Y=}3y9Ye+UliL9^x9s66$8wH+TPdOG`n| +z5Uhx +Date: Wed, 31 Oct 2018 12:50:19 +0100 +Subject: [PATCH] sd-bus: properly initialize containers + +Fixes a SIGSEGV introduced by commit 38a5315a3a6fab745d8c86ff9e486faaf50b28d1. +The same problem doesn't exist upstream, as the container structure +there is initialized using a compound literal, which is zeroed out by +default. + +Related: #1635435 +--- + src/libsystemd/sd-bus/bus-message.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index d55cb14843..780c8c6185 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -2004,6 +2004,7 @@ _public_ int sd_bus_message_open_container( + w = m->containers + m->n_containers++; + w->enclosing = type; + w->signature = TAKE_PTR(signature); ++ w->peeked_signature = NULL; + w->index = 0; + w->array_size = array_size; + w->before = before; diff --git a/SOURCES/0048-cryptsetup-generator-introduce-basic-keydev-support.patch b/SOURCES/0048-cryptsetup-generator-introduce-basic-keydev-support.patch new file mode 100644 index 0000000..d95e2f5 --- /dev/null +++ b/SOURCES/0048-cryptsetup-generator-introduce-basic-keydev-support.patch @@ -0,0 +1,240 @@ +From 0977e6b34fb5f28fc94f1df32261742881fa9bbe Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 30 Aug 2018 08:45:11 +0000 +Subject: [PATCH] cryptsetup-generator: introduce basic keydev support + +Dracut has a support for unlocking encrypted drives with keyfile stored +on the external drive. This support is included in the generated initrd +only if systemd module is not included. + +When systemd is used in initrd then attachment of encrypted drives is +handled by systemd-cryptsetup tools. Our generator has support for +keyfile, however, it didn't support keyfile on the external block +device (keydev). + +This commit introduces basic keydev support. Keydev can be specified per +luks.uuid on the kernel command line. Keydev is automatically mounted +during boot and we look for keyfile in the keydev +mountpoint (i.e. keyfile path is prefixed with the keydev mount point +path). After crypt device is attached we automatically unmount +where keyfile resides. + +Example: + rd.luks.key=70bc876b-f627-4038-9049-3080d79d2165=/key:LABEL=KEYDEV + +(cherry-picked from commit 70f5f48eb891b12e969577b464de61e15a2593da) + +Resolves: #1656869 +--- + man/systemd-cryptsetup-generator.xml | 14 ++++ + src/cryptsetup/cryptsetup-generator.c | 105 +++++++++++++++++++++++++- + 2 files changed, 115 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml +index c37ee76b87..e30d69bfe7 100644 +--- a/man/systemd-cryptsetup-generator.xml ++++ b/man/systemd-cryptsetup-generator.xml +@@ -144,6 +144,20 @@ + to the one specified by rd.luks.key= or + luks.key= of the corresponding UUID, or the + password file that was specified without a UUID. ++ ++ It is also possible to specify an external device which ++ should be mounted before we attempt to unlock the LUKS device. ++ systemd-cryptsetup will use password file stored on that ++ device. Device containing password file is specified by ++ appending colon and a device identifier to the password file ++ path. For example, ++ rd.luks.uuid=b40f1abf-2a53-400a-889a-2eccc27eaa40 ++ rd.luks.key=b40f1abf-2a53-400a-889a-2eccc27eaa40=/keyfile:LABEL=keydev. ++ Hence, in this case, we will attempt to mount file system ++ residing on the block device with label keydev. ++ This syntax is for now only supported on a per-device basis, ++ i.e. you have to specify LUKS device UUID. ++ + rd.luks.key= + is honored only by initial RAM disk + (initrd) while +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index f5a81829b9..8c7a76e789 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -24,6 +24,7 @@ + typedef struct crypto_device { + char *uuid; + char *keyfile; ++ char *keydev; + char *name; + char *options; + bool create; +@@ -37,14 +38,71 @@ static Hashmap *arg_disks = NULL; + static char *arg_default_options = NULL; + static char *arg_default_keyfile = NULL; + ++static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) { ++ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL; ++ _cleanup_fclose_ FILE *f = NULL; ++ int r; ++ ++ assert(name); ++ assert(keydev); ++ assert(unit); ++ assert(mount); ++ ++ r = mkdir_parents("/run/systemd/cryptsetup", 0755); ++ if (r < 0) ++ return r; ++ ++ r = mkdir("/run/systemd/cryptsetup", 0700); ++ if (r < 0) ++ return r; ++ ++ where = strjoin("/run/systemd/cryptsetup/keydev-", name); ++ if (!where) ++ return -ENOMEM; ++ ++ r = mkdir(where, 0700); ++ if (r < 0) ++ return r; ++ ++ r = unit_name_from_path(where, ".mount", &u); ++ if (r < 0) ++ return r; ++ ++ r = generator_open_unit_file(arg_dest, NULL, u, &f); ++ if (r < 0) ++ return r; ++ ++ what = fstab_node_to_udev_node(keydev); ++ if (!what) ++ return -ENOMEM; ++ ++ fprintf(f, ++ "[Unit]\n" ++ "DefaultDependencies=no\n\n" ++ "[Mount]\n" ++ "What=%s\n" ++ "Where=%s\n" ++ "Options=ro\n", what, where); ++ ++ r = fflush_and_check(f); ++ if (r < 0) ++ return r; ++ ++ *unit = TAKE_PTR(u); ++ *mount = TAKE_PTR(where); ++ ++ return 0; ++} ++ + static int create_disk( + const char *name, + const char *device, ++ const char *keydev, + const char *password, + const char *options) { + + _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL, +- *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL; ++ *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *keydev_mount = NULL; + _cleanup_fclose_ FILE *f = NULL; + const char *dmname; + bool noauto, nofail, tmp, swap, netdev; +@@ -94,6 +152,9 @@ static int create_disk( + return log_oom(); + } + ++ if (keydev && !password) ++ return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m"); ++ + r = generator_open_unit_file(arg_dest, NULL, n, &f); + if (r < 0) + return r; +@@ -109,6 +170,20 @@ static int create_disk( + "After=%s\n", + netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target"); + ++ if (keydev) { ++ _cleanup_free_ char *unit = NULL, *p = NULL; ++ ++ r = generate_keydev_mount(name, keydev, &unit, &keydev_mount); ++ if (r < 0) ++ return log_error_errno(r, "Failed to generate keydev mount unit: %m"); ++ ++ p = prefix_root(keydev_mount, password_escaped); ++ if (!p) ++ return log_oom(); ++ ++ free_and_replace(password_escaped, p); ++ } ++ + if (!nofail) + fprintf(f, + "Before=%s\n", +@@ -186,6 +261,11 @@ static int create_disk( + "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", + name_escaped); + ++ if (keydev) ++ fprintf(f, ++ "ExecStartPost=" UMOUNT_PATH " %s\n\n", ++ keydev_mount); ++ + r = fflush_and_check(f); + if (r < 0) + return log_error_errno(r, "Failed to write unit file %s: %m", n); +@@ -221,6 +301,7 @@ static int create_disk( + static void crypt_device_free(crypto_device *d) { + free(d->uuid); + free(d->keyfile); ++ free(d->keydev); + free(d->name); + free(d->options); + free(d); +@@ -309,11 +390,27 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + + r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value); + if (r == 2) { ++ char *c; ++ _cleanup_free_ char *keyfile = NULL, *keydev = NULL; ++ + d = get_crypto_device(uuid); + if (!d) + return log_oom(); + +- free_and_replace(d->keyfile, uuid_value); ++ c = strrchr(uuid_value, ':'); ++ if (!c) ++ /* No keydev specified */ ++ return free_and_replace(d->keyfile, uuid_value); ++ ++ *c = '\0'; ++ keyfile = strdup(uuid_value); ++ keydev = strdup(++c); ++ ++ if (!keyfile || !keydev) ++ return log_oom(); ++ ++ free_and_replace(d->keyfile, keyfile); ++ free_and_replace(d->keydev, keydev); + } else if (free_and_strdup(&arg_default_keyfile, value) < 0) + return log_oom(); + +@@ -394,7 +491,7 @@ static int add_crypttab_devices(void) { + continue; + } + +- r = create_disk(name, device, keyfile, (d && d->options) ? d->options : options); ++ r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options); + if (r < 0) + return r; + +@@ -434,7 +531,7 @@ static int add_proc_cmdline_devices(void) { + else + options = "timeout=0"; + +- r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options); ++ r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options); + if (r < 0) + return r; + } diff --git a/SOURCES/0049-cryptsetup-don-t-use-m-if-there-s-no-error-to-show.patch b/SOURCES/0049-cryptsetup-don-t-use-m-if-there-s-no-error-to-show.patch new file mode 100644 index 0000000..28f8a27 --- /dev/null +++ b/SOURCES/0049-cryptsetup-don-t-use-m-if-there-s-no-error-to-show.patch @@ -0,0 +1,33 @@ +From 95bfd1d2f52698604e44c17dba2082f61b5f8eab Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Oct 2018 22:37:37 +0200 +Subject: [PATCH] cryptsetup: don't use %m if there's no error to show + +We are not the ones receiving an error here, but the ones generating it, +hence we shouldn't show it with %m, that's just confusing, as it +suggests we received an error from some other call. + +(cherry-picked from commit 2abe64666e544be6499f870618185f8819b4c152) + +Related: #1656869 +--- + src/cryptsetup/cryptsetup-generator.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 8c7a76e789..52391bd185 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -152,8 +152,10 @@ static int create_disk( + return log_oom(); + } + +- if (keydev && !password) +- return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m"); ++ if (keydev && !password) { ++ log_error("Key device is specified, but path to the password file is missing."); ++ return -EINVAL; ++ } + + r = generator_open_unit_file(arg_dest, NULL, n, &f); + if (r < 0) diff --git a/SOURCES/0050-cryptsetup-generator-don-t-return-error-if-target-di.patch b/SOURCES/0050-cryptsetup-generator-don-t-return-error-if-target-di.patch new file mode 100644 index 0000000..b9fa960 --- /dev/null +++ b/SOURCES/0050-cryptsetup-generator-don-t-return-error-if-target-di.patch @@ -0,0 +1,38 @@ +From 81df5f597257bd2579246de6182c4949b27396eb Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 4 Sep 2018 19:51:14 +0200 +Subject: [PATCH] cryptsetup-generator: don't return error if target directory + already exists + +(cherry-picked from commit 579875bc4a59b917fa32519e3d96d56dc591ad1e) + +Related: #1656869 +--- + src/cryptsetup/cryptsetup-generator.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 52391bd185..03c513c26e 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -53,16 +53,16 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un + return r; + + r = mkdir("/run/systemd/cryptsetup", 0700); +- if (r < 0) +- return r; ++ if (r < 0 && errno != EEXIST) ++ return -errno; + + where = strjoin("/run/systemd/cryptsetup/keydev-", name); + if (!where) + return -ENOMEM; + + r = mkdir(where, 0700); +- if (r < 0) +- return r; ++ if (r < 0 && errno != EEXIST) ++ return -errno; + + r = unit_name_from_path(where, ".mount", &u); + if (r < 0) diff --git a/SOURCES/0051-cryptsetup-generator-allow-whitespace-characters-in-.patch b/SOURCES/0051-cryptsetup-generator-allow-whitespace-characters-in-.patch new file mode 100644 index 0000000..c67215a --- /dev/null +++ b/SOURCES/0051-cryptsetup-generator-allow-whitespace-characters-in-.patch @@ -0,0 +1,129 @@ +From 2a4d58bb2ab9ba5487785cc167932440a4f0c13d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 4 Sep 2018 20:03:34 +0200 +Subject: [PATCH] cryptsetup-generator: allow whitespace characters in keydev + specification + +For example, =/keyfile:LABEL="KEYFILE FS" previously wouldn't +work, because we truncated label at the first whitespace character, +i.e. LABEL="KEYFILE". + +(cherry-picked from commit 7949dfa73a44ae6524779689483d12243dfbcfdf) + +Related: #1656869 +--- + src/cryptsetup/cryptsetup-generator.c | 64 ++++++++++++++++++--------- + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 03c513c26e..52c1262728 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -5,11 +5,13 @@ + + #include "alloc-util.h" + #include "dropin.h" ++#include "escape.h" + #include "fd-util.h" + #include "fileio.h" + #include "fstab-util.h" + #include "generator.h" + #include "hashmap.h" ++#include "id128-util.h" + #include "log.h" + #include "mkdir.h" + #include "parse-util.h" +@@ -39,7 +41,7 @@ static char *arg_default_options = NULL; + static char *arg_default_keyfile = NULL; + + static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) { +- _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL; ++ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; + +@@ -56,7 +58,11 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un + if (r < 0 && errno != EEXIST) + return -errno; + +- where = strjoin("/run/systemd/cryptsetup/keydev-", name); ++ name_escaped = cescape(name); ++ if (!name_escaped) ++ return -ENOMEM; ++ ++ where = strjoin("/run/systemd/cryptsetup/keydev-", name_escaped); + if (!where) + return -ENOMEM; + +@@ -386,36 +392,52 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + return log_oom(); + + } else if (streq(key, "luks.key")) { ++ size_t n; ++ _cleanup_free_ char *keyfile = NULL, *keydev = NULL; ++ char *c; ++ const char *keyspec; + + if (proc_cmdline_value_missing(key, value)) + return 0; + +- r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value); +- if (r == 2) { +- char *c; +- _cleanup_free_ char *keyfile = NULL, *keydev = NULL; ++ n = strspn(value, LETTERS DIGITS "-"); ++ if (value[n] != '=') { ++ if (free_and_strdup(&arg_default_keyfile, value) < 0) ++ return log_oom(); ++ return 0; ++ } + +- d = get_crypto_device(uuid); +- if (!d) +- return log_oom(); ++ uuid = strndup(value, n); ++ if (!uuid) ++ return log_oom(); + +- c = strrchr(uuid_value, ':'); +- if (!c) +- /* No keydev specified */ +- return free_and_replace(d->keyfile, uuid_value); ++ if (!id128_is_valid(uuid)) { ++ log_warning("Failed to parse luks.key= kernel command line switch. UUID is invalid, ignoring."); ++ return 0; ++ } ++ ++ d = get_crypto_device(uuid); ++ if (!d) ++ return log_oom(); + +- *c = '\0'; +- keyfile = strdup(uuid_value); +- keydev = strdup(++c); ++ keyspec = value + n + 1; ++ c = strrchr(keyspec, ':'); ++ if (c) { ++ *c = '\0'; ++ keyfile = strdup(keyspec); ++ keydev = strdup(c + 1); + + if (!keyfile || !keydev) + return log_oom(); ++ } else { ++ /* No keydev specified */ ++ keyfile = strdup(keyspec); ++ if (!keyfile) ++ return log_oom(); ++ } + +- free_and_replace(d->keyfile, keyfile); +- free_and_replace(d->keydev, keydev); +- } else if (free_and_strdup(&arg_default_keyfile, value) < 0) +- return log_oom(); +- ++ free_and_replace(d->keyfile, keyfile); ++ free_and_replace(d->keydev, keydev); + } else if (streq(key, "luks.name")) { + + if (proc_cmdline_value_missing(key, value)) diff --git a/SOURCES/0052-rules-watch-metadata-changes-on-DASD-devices.patch b/SOURCES/0052-rules-watch-metadata-changes-on-DASD-devices.patch new file mode 100644 index 0000000..984e86c --- /dev/null +++ b/SOURCES/0052-rules-watch-metadata-changes-on-DASD-devices.patch @@ -0,0 +1,25 @@ +From c16785e970b83590fc9de4ea0f7e410470d88db5 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 4 Dec 2018 16:47:36 +0100 +Subject: [PATCH] rules: watch metadata changes on DASD devices + +To make sure the change event is emitted and udev db is updated +after metadata changes. + +(cherry picked from commit 38397c8ce044fdc0138c9919168a856c0e16f720) + +Resolves: #1638676 +--- + rules/60-block.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rules/60-block.rules b/rules/60-block.rules +index 343fc06f85..a1458e9188 100644 +--- a/rules/60-block.rules ++++ b/rules/60-block.rules +@@ -8,4 +8,4 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_ + ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change" + + # watch metadata changes, caused by tools closing the device node which was opened for writing +-ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*", OPTIONS+="watch" ++ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*|dasd*", OPTIONS+="watch" diff --git a/SOURCES/0053-sysctl.d-switch-net.ipv4.conf.all.rp_filter-from-1-t.patch b/SOURCES/0053-sysctl.d-switch-net.ipv4.conf.all.rp_filter-from-1-t.patch new file mode 100644 index 0000000..af96f5f --- /dev/null +++ b/SOURCES/0053-sysctl.d-switch-net.ipv4.conf.all.rp_filter-from-1-t.patch @@ -0,0 +1,41 @@ +From 75c9af80cf3529c76988451e63f98010c86f48f1 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Wed, 28 Nov 2018 11:44:20 +0100 +Subject: [PATCH] sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 to 2 + +This switches the RFC3704 Reverse Path filtering from Strict mode to Loose +mode. The Strict mode breaks some pretty common and reasonable use cases, +such as keeping connections via one default route alive after another one +appears (e.g. plugging an Ethernet cable when connected via Wi-Fi). + +The strict filter also makes it impossible for NetworkManager to do +connectivity check on a newly arriving default route (it starts with a +higher metric and is bumped lower if there's connectivity). + +Kernel's default is 0 (no filter), but a Loose filter is good enough. The +few use cases where a Strict mode could make sense can easily override +this. + +The distributions that don't care about the client use cases and prefer a +strict filter could just ship a custom configuration in +/usr/lib/sysctl.d/ to override this. + +Cherry-picked from: 230450d4e4f1f5fc9fa4295ed9185eea5b6ea16e +Resolves: #1653824 +--- + sysctl.d/50-default.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index e263cf0628..b0645f33e7 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -22,7 +22,7 @@ kernel.sysrq = 16 + kernel.core_uses_pid = 1 + + # Source route verification +-net.ipv4.conf.all.rp_filter = 1 ++net.ipv4.conf.all.rp_filter = 2 + + # Do not accept source routing + net.ipv4.conf.all.accept_source_route = 0 diff --git a/SOURCES/0054-tests-explicitly-enable-user-namespaces-for-TEST-13-.patch b/SOURCES/0054-tests-explicitly-enable-user-namespaces-for-TEST-13-.patch new file mode 100644 index 0000000..bc76352 --- /dev/null +++ b/SOURCES/0054-tests-explicitly-enable-user-namespaces-for-TEST-13-.patch @@ -0,0 +1,36 @@ +From e8ead61e1c0a919a97df64b14dbd572ef7c830d2 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 15 Dec 2018 20:22:31 +0100 +Subject: [PATCH] tests: explicitly enable user namespaces for + TEST-13-NSPAWN-SMOKE + +Cherry-picked from: 67f5c0c776ce9449ad21e9854665573a05141fd4 +--- + test/TEST-13-NSPAWN-SMOKE/test.sh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh +index 6a0cb42eaf..c0789b5d20 100755 +--- a/test/TEST-13-NSPAWN-SMOKE/test.sh ++++ b/test/TEST-13-NSPAWN-SMOKE/test.sh +@@ -18,7 +18,7 @@ test_setup() { + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment +- dracut_install busybox chmod rmdir unshare ip ++ dracut_install busybox chmod rmdir unshare ip sysctl + + cp create-busybox-container $initdir/ + +@@ -63,6 +63,11 @@ if [[ -f /proc/1/ns/cgroup ]]; then + fi + + is_user_ns_supported=no ++# On some systems (e.g. CentOS 7) the default limit for user namespaces ++# is set to 0, which causes the following unshare syscall to fail, even ++# with enabled user namespaces support. By setting this value explicitly ++# we can ensure the user namespaces support to be detected correctly. ++sysctl -w user.max_user_namespaces=10000 + if unshare -U sh -c :; then + is_user_ns_supported=yes + fi diff --git a/SOURCES/0055-nspawn-beef-up-netns-checking-a-bit-for-compat-with-.patch b/SOURCES/0055-nspawn-beef-up-netns-checking-a-bit-for-compat-with-.patch new file mode 100644 index 0000000..2770487 --- /dev/null +++ b/SOURCES/0055-nspawn-beef-up-netns-checking-a-bit-for-compat-with-.patch @@ -0,0 +1,122 @@ +From 2115fcc1e673079fe76e949ac0904267075c25a4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 31 Oct 2018 13:04:20 +0100 +Subject: [PATCH] nspawn: beef up netns checking a bit, for compat with old + kernels + +Fixes: #10544 + +Cherry-picked from: 6619ad889da260cf83079cc74a85d571acd1df5a +--- + src/basic/stat-util.c | 40 +++++++++++++++++++++++++++++++++++---- + src/nspawn/nspawn.c | 8 +++++--- + src/test/test-stat-util.c | 15 +++++++++++++++ + 3 files changed, 56 insertions(+), 7 deletions(-) + +diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c +index 07154e25bb..26aee9bad6 100644 +--- a/src/basic/stat-util.c ++++ b/src/basic/stat-util.c +@@ -204,15 +204,47 @@ int fd_is_network_fs(int fd) { + } + + int fd_is_network_ns(int fd) { ++ struct statfs s; + int r; + +- r = fd_is_fs_type(fd, NSFS_MAGIC); +- if (r <= 0) +- return r; ++ /* Checks whether the specified file descriptor refers to a network namespace. On old kernels there's no nice ++ * way to detect that, hence on those we'll return a recognizable error (EUCLEAN), so that callers can handle ++ * this somewhat nicely. ++ * ++ * This function returns > 0 if the fd definitely refers to a network namespace, 0 if it definitely does not ++ * refer to a network namespace, -EUCLEAN if we can't determine, and other negative error codes on error. */ ++ ++ if (fstatfs(fd, &s) < 0) ++ return -errno; ++ ++ if (!is_fs_type(&s, NSFS_MAGIC)) { ++ /* On really old kernels, there was no "nsfs", and network namespace sockets belonged to procfs ++ * instead. Handle that in a somewhat smart way. */ ++ ++ if (is_fs_type(&s, PROC_SUPER_MAGIC)) { ++ struct statfs t; ++ ++ /* OK, so it is procfs. Let's see if our own network namespace is procfs, too. If so, then the ++ * passed fd might refer to a network namespace, but we can't know for sure. In that case, ++ * return a recognizable error. */ ++ ++ if (statfs("/proc/self/ns/net", &t) < 0) ++ return -errno; ++ ++ if (s.f_type == t.f_type) ++ return -EUCLEAN; /* It's possible, we simply don't know */ ++ } ++ ++ return 0; /* No! */ ++ } + + r = ioctl(fd, NS_GET_NSTYPE); +- if (r < 0) ++ if (r < 0) { ++ if (errno == ENOTTY) /* Old kernels didn't know this ioctl, let's also return a recognizable error in that case */ ++ return -EUCLEAN; ++ + return -errno; ++ } + + return r == CLONE_NEWNET; + } +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 56877bd932..8aec893a69 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -3701,10 +3701,12 @@ static int run(int master, + return log_error_errno(errno, "Cannot open file %s: %m", arg_network_namespace_path); + + r = fd_is_network_ns(netns_fd); +- if (r < 0 && r != -ENOTTY) ++ if (r == -EUCLEAN) ++ log_debug_errno(r, "Cannot determine if passed network namespace path '%s' really refers to a network namespace, assuming it does.", arg_network_namespace_path); ++ else if (r < 0) + return log_error_errno(r, "Failed to check %s fs type: %m", arg_network_namespace_path); +- if (r == 0) { +- log_error("Path %s doesn't refer to a network namespace", arg_network_namespace_path); ++ else if (r == 0) { ++ log_error("Path %s doesn't refer to a network namespace, refusing.", arg_network_namespace_path); + return -EINVAL; + } + } +diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c +index 43f56a6c20..2b0564d8a0 100644 +--- a/src/test/test-stat-util.c ++++ b/src/test/test-stat-util.c +@@ -67,11 +67,26 @@ static void test_path_is_temporary_fs(void) { + assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT); + } + ++static void test_fd_is_network_ns(void) { ++ _cleanup_close_ int fd = -1; ++ assert_se(fd_is_network_ns(STDIN_FILENO) == 0); ++ assert_se(fd_is_network_ns(STDERR_FILENO) == 0); ++ assert_se(fd_is_network_ns(STDOUT_FILENO) == 0); ++ ++ assert_se((fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY)) >= 0); ++ assert_se(IN_SET(fd_is_network_ns(fd), 0, -EUCLEAN)); ++ fd = safe_close(fd); ++ ++ assert_se((fd = open("/proc/self/ns/net", O_CLOEXEC|O_RDONLY)) >= 0); ++ assert_se(IN_SET(fd_is_network_ns(fd), 1, -EUCLEAN)); ++} ++ + int main(int argc, char *argv[]) { + test_files_same(); + test_is_symlink(); + test_path_is_fs_type(); + test_path_is_temporary_fs(); ++ test_fd_is_network_ns(); + + return 0; + } diff --git a/SOURCES/0056-test-Drop-SKIP_INITRD-for-QEMU-based-tests.patch b/SOURCES/0056-test-Drop-SKIP_INITRD-for-QEMU-based-tests.patch new file mode 100644 index 0000000..cea0065 --- /dev/null +++ b/SOURCES/0056-test-Drop-SKIP_INITRD-for-QEMU-based-tests.patch @@ -0,0 +1,93 @@ +From 13d819cc795d8c3695ce7288436ad569366073f6 Mon Sep 17 00:00:00 2001 +From: Michael Biebl +Date: Mon, 16 Jul 2018 11:27:44 +0200 +Subject: [PATCH] test: Drop SKIP_INITRD for QEMU-based tests + +Not all distros support booting without an initrd. E.g. the Debian +kernel builds ext4 as a module and so relies on an initrd to +successfully start the QEMU-based images. + +Cherry-picked from: c2d4da002095fe6f86f89a508a81e48fb6d3196f +--- + test/TEST-08-ISSUE-2730/test.sh | 1 - + test/TEST-09-ISSUE-2691/test.sh | 1 - + test/TEST-10-ISSUE-2467/test.sh | 1 - + test/TEST-11-ISSUE-3166/test.sh | 1 - + test/TEST-13-NSPAWN-SMOKE/test.sh | 2 +- + test/TEST-14-MACHINE-ID/test.sh | 2 +- + 6 files changed, 2 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-08-ISSUE-2730/test.sh b/test/TEST-08-ISSUE-2730/test.sh +index 68159c331f..90bf133c6a 100755 +--- a/test/TEST-08-ISSUE-2730/test.sh ++++ b/test/TEST-08-ISSUE-2730/test.sh +@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730" + TEST_NO_NSPAWN=1 + + . $TEST_BASE_DIR/test-functions +-SKIP_INITRD=yes + QEMU_TIMEOUT=180 + FSTYPE=ext4 + +diff --git a/test/TEST-09-ISSUE-2691/test.sh b/test/TEST-09-ISSUE-2691/test.sh +index 4c3e9496b4..9b5990bc60 100755 +--- a/test/TEST-09-ISSUE-2691/test.sh ++++ b/test/TEST-09-ISSUE-2691/test.sh +@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691" + TEST_NO_NSPAWN=1 + + . $TEST_BASE_DIR/test-functions +-SKIP_INITRD=yes + QEMU_TIMEOUT=90 + + test_setup() { +diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh +index 2f95e9062d..e61f5acd3c 100755 +--- a/test/TEST-10-ISSUE-2467/test.sh ++++ b/test/TEST-10-ISSUE-2467/test.sh +@@ -5,7 +5,6 @@ set -e + TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467" + + . $TEST_BASE_DIR/test-functions +-SKIP_INITRD=yes + + test_setup() { + create_empty_image +diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh +index 4602bdfc98..8aae4d5ed9 100755 +--- a/test/TEST-11-ISSUE-3166/test.sh ++++ b/test/TEST-11-ISSUE-3166/test.sh +@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166" + TEST_NO_NSPAWN=1 + + . $TEST_BASE_DIR/test-functions +-SKIP_INITRD=yes + + test_setup() { + create_empty_image +diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh +index c0789b5d20..a676384bfc 100755 +--- a/test/TEST-13-NSPAWN-SMOKE/test.sh ++++ b/test/TEST-13-NSPAWN-SMOKE/test.sh +@@ -4,7 +4,7 @@ + set -e + TEST_DESCRIPTION="systemd-nspawn smoke test" + TEST_NO_NSPAWN=1 +-SKIP_INITRD=yes ++ + . $TEST_BASE_DIR/test-functions + + test_setup() { +diff --git a/test/TEST-14-MACHINE-ID/test.sh b/test/TEST-14-MACHINE-ID/test.sh +index 7342645bc5..62003b91b6 100755 +--- a/test/TEST-14-MACHINE-ID/test.sh ++++ b/test/TEST-14-MACHINE-ID/test.sh +@@ -4,7 +4,7 @@ + set -e + TEST_DESCRIPTION="/etc/machine-id testing" + TEST_NO_NSPAWN=1 +-SKIP_INITRD=yes ++ + . $TEST_BASE_DIR/test-functions + + test_setup() { diff --git a/SOURCES/0057-meson-rename-Ddebug-to-Ddebug-extra.patch b/SOURCES/0057-meson-rename-Ddebug-to-Ddebug-extra.patch new file mode 100644 index 0000000..19ae06f --- /dev/null +++ b/SOURCES/0057-meson-rename-Ddebug-to-Ddebug-extra.patch @@ -0,0 +1,42 @@ +From 9c1b72de44e68ad80be7c0b98df110e7b127072d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 19 Aug 2018 19:11:30 +0200 +Subject: [PATCH] meson: rename -Ddebug to -Ddebug-extra + +Meson added -Doptimization and -Ddebug options, which obviously causes +a conflict with our -Ddebug options. Let's rename it. + +Fixes #9883. + +Cherry-picked from: 8f6b442a78d0b485f044742ad90b2e8271b4e68e +--- + meson.build | 2 +- + meson_options.txt | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index f308db2631..ebc55872c9 100644 +--- a/meson.build ++++ b/meson.build +@@ -769,7 +769,7 @@ substs.set('DEBUGTTY', get_option('debug-tty')) + + enable_debug_hashmap = false + enable_debug_mmap_cache = false +-foreach name : get_option('debug') ++foreach name : get_option('debug-extra') + if name == 'hashmap' + enable_debug_hashmap = true + elif name == 'mmap-cache' +diff --git a/meson_options.txt b/meson_options.txt +index ab2a658713..5716f45ccf 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -46,7 +46,7 @@ option('debug-shell', type : 'string', value : '/bin/sh', + description : 'path to debug shell binary') + option('debug-tty', type : 'string', value : '/dev/tty9', + description : 'specify the tty device for debug shell') +-option('debug', type : 'array', choices : ['hashmap', 'mmap-cache'], value : [], ++option('debug-extra', type : 'array', choices : ['hashmap', 'mmap-cache'], value : [], + description : 'enable extra debugging') + option('memory-accounting-default', type : 'boolean', + description : 'enable MemoryAccounting= by default') diff --git a/SOURCES/0058-meson-check-whether-gnutls-supports-TCP-fast-open.patch b/SOURCES/0058-meson-check-whether-gnutls-supports-TCP-fast-open.patch new file mode 100644 index 0000000..e0c88dd --- /dev/null +++ b/SOURCES/0058-meson-check-whether-gnutls-supports-TCP-fast-open.patch @@ -0,0 +1,38 @@ +From b6943446f8ffde53ce059b5e869c22bed8926827 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 25 Jun 2018 22:40:40 +0900 +Subject: [PATCH] meson: check whether gnutls supports TCP fast open + +Fixes #9403 + +Cherry-picked from: f02582f69fe1e7663a87ba80bd4f90d5d23ee75f +--- + README | 1 + + meson.build | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/README b/README +index 2cde08c37e..7d06e04800 100644 +--- a/README ++++ b/README +@@ -154,6 +154,7 @@ REQUIREMENTS: + libmicrohttpd (optional) + libpython (optional) + libidn2 or libidn (optional) ++ gnutls >= 3.1.4 (optional, >= 3.5.3 is necessary to support DNS-over-TLS) + elfutils >= 158 (optional) + polkit (optional) + pkg-config +diff --git a/meson.build b/meson.build +index ebc55872c9..d58926c981 100644 +--- a/meson.build ++++ b/meson.build +@@ -1148,7 +1148,7 @@ substs.set('DEFAULT_DNSSEC_MODE', default_dnssec) + + dns_over_tls = get_option('dns-over-tls') + if dns_over_tls != 'false' +- have = conf.get('HAVE_GNUTLS') == 1 ++ have = libgnutls != [] and libgnutls.version().version_compare('>=3.5.3') + if dns_over_tls == 'true' and not have + error('DNS-over-TLS support was requested, but dependencies are not available') + endif diff --git a/SOURCES/0059-unit-don-t-add-Requires-for-tmp.mount.patch b/SOURCES/0059-unit-don-t-add-Requires-for-tmp.mount.patch new file mode 100644 index 0000000..6712934 --- /dev/null +++ b/SOURCES/0059-unit-don-t-add-Requires-for-tmp.mount.patch @@ -0,0 +1,24 @@ +From 03e52d33bbdea731eaa79545bb1d30c5b21abe3d Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Mon, 5 Sep 2016 12:47:09 +0200 +Subject: [PATCH] unit: don't add Requires for tmp.mount + +rhel-only +Resolves: #1619292 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index c9f756c9c7..721d8d60a3 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1421,7 +1421,7 @@ static int unit_add_mount_dependencies(Unit *u) { + if (r < 0) + return r; + +- if (m->fragment_path) { ++ if (m->fragment_path && !streq(m->id, "tmp.mount")) { + r = unit_add_dependency(u, UNIT_REQUIRES, m, true, di.origin_mask); + if (r < 0) + return r; diff --git a/SOURCES/0060-tests-drop-the-precondition-check-for-inherited-flag.patch b/SOURCES/0060-tests-drop-the-precondition-check-for-inherited-flag.patch new file mode 100644 index 0000000..b921532 --- /dev/null +++ b/SOURCES/0060-tests-drop-the-precondition-check-for-inherited-flag.patch @@ -0,0 +1,42 @@ +From 1d43806017a0df257fef8ed6f79e12ee69c5bc20 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 8 Nov 2018 09:40:13 +0100 +Subject: [PATCH] tests: drop the precondition check for inherited flag + +Docker's default capability set has the inherited flag already +set - that breaks tests which expect otherwise. Let's just +drop the check and run the test anyway. + +Fixes #10663 + +Cherry-picked from: c446b8486d9ed18d1bc780948ae9ee8a53fa4c3f +--- + src/test/test-capability.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/src/test/test-capability.c b/src/test/test-capability.c +index af6d808b6d..72975cef94 100644 +--- a/src/test/test-capability.c ++++ b/src/test/test-capability.c +@@ -180,8 +180,6 @@ static void test_update_inherited_set(void) { + + caps = cap_get_proc(); + assert_se(caps); +- assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv)); +- assert(fv == CAP_CLEAR); + + set = (UINT64_C(1) << CAP_CHOWN); + +@@ -197,12 +195,6 @@ static void test_set_ambient_caps(void) { + uint64_t set = 0; + cap_flag_value_t fv; + +- caps = cap_get_proc(); +- assert_se(caps); +- assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv)); +- assert(fv == CAP_CLEAR); +- cap_free(caps); +- + assert_se(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) == 0); + + set = (UINT64_C(1) << CAP_CHOWN); diff --git a/SOURCES/0061-core-when-deserializing-state-always-use-read_line-L.patch b/SOURCES/0061-core-when-deserializing-state-always-use-read_line-L.patch new file mode 100644 index 0000000..9a53203 --- /dev/null +++ b/SOURCES/0061-core-when-deserializing-state-always-use-read_line-L.patch @@ -0,0 +1,234 @@ +From 55a1c766445750aaefe28bd7bea454f5f1cff9bb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Oct 2018 18:36:24 +0200 +Subject: [PATCH] =?UTF-8?q?core:=20when=20deserializing=20state=20always?= + =?UTF-8?q?=20use=20read=5Fline(=E2=80=A6,=20LONG=5FLINE=5FMAX,=20?= + =?UTF-8?q?=E2=80=A6)?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This should be much better than fgets(), as we can read substantially +longer lines and overly long lines result in proper errors. + +Fixes a vulnerability discovered by Jann Horn at Google. + +CVE-2018-15686 +LP: #1796402 +https://bugzilla.redhat.com/show_bug.cgi?id=1639071 + +(cherry picked from commit 8948b3415d762245ebf5e19d80b97d4d8cc208c1) + +Resolves: CVE-2018-15686 +--- + src/core/job.c | 19 +++++++++++-------- + src/core/manager.c | 47 ++++++++++++++++++++-------------------------- + src/core/unit.c | 34 +++++++++++++++++---------------- + src/core/unit.h | 2 +- + 4 files changed, 50 insertions(+), 52 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 734756b666..8552ffb704 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -10,6 +10,7 @@ + #include "dbus-job.h" + #include "dbus.h" + #include "escape.h" ++#include "fileio.h" + #include "job.h" + #include "log.h" + #include "macro.h" +@@ -1091,24 +1092,26 @@ int job_serialize(Job *j, FILE *f) { + } + + int job_deserialize(Job *j, FILE *f) { ++ int r; ++ + assert(j); + assert(f); + + for (;;) { +- char line[LINE_MAX], *l, *v; ++ _cleanup_free_ char *line = NULL; ++ char *l, *v; + size_t k; + +- if (!fgets(line, sizeof(line), f)) { +- if (feof(f)) +- return 0; +- return -errno; +- } ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return log_error_errno(r, "Failed to read serialization line: %m"); ++ if (r == 0) ++ return 0; + +- char_array_0(line); + l = strstrip(line); + + /* End marker */ +- if (l[0] == 0) ++ if (isempty(l)) + return 0; + + k = strcspn(l, "="); +diff --git a/src/core/manager.c b/src/core/manager.c +index 3b2fe11e87..c83e296cf3 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -3144,22 +3144,17 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + m->n_reloading++; + + for (;;) { +- char line[LINE_MAX]; ++ _cleanup_free_ char *line = NULL; + const char *val, *l; + +- if (!fgets(line, sizeof(line), f)) { +- if (feof(f)) +- r = 0; +- else +- r = -errno; +- +- goto finish; +- } ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return log_error_errno(r, "Failed to read serialization line: %m"); ++ if (r == 0) ++ break; + +- char_array_0(line); + l = strstrip(line); +- +- if (l[0] == 0) ++ if (isempty(l)) /* end marker */ + break; + + if ((val = startswith(l, "current-job-id="))) { +@@ -3326,29 +3321,27 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + } + + for (;;) { +- Unit *u; +- char name[UNIT_NAME_MAX+2]; ++ _cleanup_free_ char *line = NULL; + const char* unit_name; ++ Unit *u; + + /* Start marker */ +- if (!fgets(name, sizeof(name), f)) { +- if (feof(f)) +- r = 0; +- else +- r = -errno; +- +- goto finish; +- } ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return log_error_errno(r, "Failed to read serialization line: %m"); ++ if (r == 0) ++ break; + +- char_array_0(name); +- unit_name = strstrip(name); ++ unit_name = strstrip(line); + + r = manager_load_unit(m, unit_name, NULL, NULL, &u); + if (r < 0) { + log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name); +- if (r == -ENOMEM) +- goto finish; +- unit_deserialize_skip(f); ++ ++ r = unit_deserialize_skip(f); ++ if (r < 0) ++ return r; ++ + continue; + } + +diff --git a/src/core/unit.c b/src/core/unit.c +index 721d8d60a3..cc43ddc4f1 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3368,21 +3368,19 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + assert(fds); + + for (;;) { +- char line[LINE_MAX], *l, *v; ++ _cleanup_free_ char *line = NULL; + CGroupIPAccountingMetric m; ++ char *l, *v; + size_t k; + +- if (!fgets(line, sizeof(line), f)) { +- if (feof(f)) +- return 0; +- return -errno; +- } ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return log_error_errno(r, "Failed to read serialization line: %m"); ++ if (r == 0) /* eof */ ++ break; + +- char_array_0(line); + l = strstrip(line); +- +- /* End marker */ +- if (isempty(l)) ++ if (isempty(l)) /* End marker */ + break; + + k = strcspn(l, "="); +@@ -3657,23 +3655,27 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + return 0; + } + +-void unit_deserialize_skip(FILE *f) { ++int unit_deserialize_skip(FILE *f) { ++ int r; + assert(f); + + /* Skip serialized data for this unit. We don't know what it is. */ + + for (;;) { +- char line[LINE_MAX], *l; ++ _cleanup_free_ char *line = NULL; ++ char *l; + +- if (!fgets(line, sizeof line, f)) +- return; ++ r = read_line(f, LONG_LINE_MAX, &line); ++ if (r < 0) ++ return log_error_errno(r, "Failed to read serialization line: %m"); ++ if (r == 0) ++ return 0; + +- char_array_0(line); + l = strstrip(line); + + /* End marker */ + if (isempty(l)) +- return; ++ return 1; + } + } + +diff --git a/src/core/unit.h b/src/core/unit.h +index b3131eba1b..e1a60da244 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -679,7 +679,7 @@ bool unit_can_serialize(Unit *u) _pure_; + + int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs); + int unit_deserialize(Unit *u, FILE *f, FDSet *fds); +-void unit_deserialize_skip(FILE *f); ++int unit_deserialize_skip(FILE *f); + + int unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); + int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *value); diff --git a/SOURCES/0062-core-enforce-a-limit-on-STATUS-texts-recvd-from-serv.patch b/SOURCES/0062-core-enforce-a-limit-on-STATUS-texts-recvd-from-serv.patch new file mode 100644 index 0000000..6d009c4 --- /dev/null +++ b/SOURCES/0062-core-enforce-a-limit-on-STATUS-texts-recvd-from-serv.patch @@ -0,0 +1,44 @@ +From 6abfec31acae53943896b309db4a09a1cecac9a3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Oct 2018 18:37:48 +0200 +Subject: [PATCH] core: enforce a limit on STATUS= texts recvd from services + +Let's better be safe than sorry, and put a limit on what we receive. + +(cherry picked from commit 3eac1bcae9284fb8b18f4b82156c0e85ddb004e5) + +Related: CVE-2018-15686 +--- + src/core/service.c | 8 ++++++-- + src/core/service.h | 2 ++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index db1356c417..db17221888 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3549,8 +3549,12 @@ static void service_notify_message( + _cleanup_free_ char *t = NULL; + + if (!isempty(e)) { +- if (!utf8_is_valid(e)) +- log_unit_warning(u, "Status message in notification message is not UTF-8 clean."); ++ /* Note that this size limit check is mostly paranoia: since the datagram size we are willing ++ * to process is already limited to NOTIFY_BUFFER_MAX, this limit here should never be hit. */ ++ if (strlen(e) > STATUS_TEXT_MAX) ++ log_unit_warning(u, "Status message overly long (%zu > %u), ignoring.", strlen(e), STATUS_TEXT_MAX); ++ else if (!utf8_is_valid(e)) ++ log_unit_warning(u, "Status message in notification message is not UTF-8 clean, ignoring."); + else { + t = strdup(e); + if (!t) +diff --git a/src/core/service.h b/src/core/service.h +index 9c06e91883..a142b09f0d 100644 +--- a/src/core/service.h ++++ b/src/core/service.h +@@ -202,3 +202,5 @@ const char* service_result_to_string(ServiceResult i) _const_; + ServiceResult service_result_from_string(const char *s) _pure_; + + DEFINE_CAST(SERVICE, Service); ++ ++#define STATUS_TEXT_MAX (16U*1024U) diff --git a/SOURCES/0063-travis-enable-Travis-CI-on-CentOS-7.patch b/SOURCES/0063-travis-enable-Travis-CI-on-CentOS-7.patch new file mode 100644 index 0000000..4ba9fb3 --- /dev/null +++ b/SOURCES/0063-travis-enable-Travis-CI-on-CentOS-7.patch @@ -0,0 +1,257 @@ +From 5638e18196be1fabd9e78d4c506402bf700fe569 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 7 Jan 2019 15:49:45 +0100 +Subject: [PATCH] travis: enable Travis CI on CentOS 7 + +(cherry picked from commit 2014cb51b6dfe1f7f0b98e62311398c2bf801c2b) +--- + .travis.yml | 86 ++++++++++----------------------------------- + ci/travis-centos.sh | 69 ++++++++++++++++++++++++++++++++++++ + ci/travis_wait.bash | 61 ++++++++++++++++++++++++++++++++ + 3 files changed, 149 insertions(+), 67 deletions(-) + create mode 100755 ci/travis-centos.sh + create mode 100644 ci/travis_wait.bash + +diff --git a/.travis.yml b/.travis.yml +index d980038181..fc63887324 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -1,77 +1,29 @@ + sudo: required +- + services: + - docker + +-language: c ++env: ++ global: ++ - CI_ROOT="$TRAVIS_BUILD_DIR/ci/" + + jobs: + include: +- - stage: coverity scan +- before_script: +- - sudo apt-get update ++ - stage: Build & test ++ name: CentOS 7 ++ language: bash ++ env: ++ - CENTOS_RELEASE="centos7" ++ - CONT_NAME="systemd-centos-$CENTOS_RELEASE" ++ - DOCKER_EXEC="docker exec -ti $CONT_NAME" ++ before_install: + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version +- - env > .env +- env: +- - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" +- - COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}" +- - COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH" +- # Encrypted token for systemd/systemd Coverity Scan Analysis, +- # generated by "travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=" +- - secure: "lM0IVP2zOG5Ywk3YCbDCQL4WioyzzwtdtpZ+hKDy4BWCZDBJ/FVwIeBsXdMDvlTa3xi+GQ1b7kS2OmTfmG4aSlhU7isuH8SMq1Y4GR5AxfhkR+irUA1A1fntlvhbjIumDGW5wjs0Dt8KogMWS+ZD4eGE59lrVO/TrhMzIe1eHENVLFQJdNq+ZJXU8wxMfHf8lXk0xA8SJTid0XvZBNc4JN6pjJRA8LaOrMNhQYfygFmVQ598kwlu7gf5vbCKFPnIgJAxdIhz12XS9utGohV28IYj9d1DdUGUT+ar3OfADj3X8KFBP4Ymc02pcln3wVgdPtrDbFZh1R9jbmfdXGAH/6tTOJVn8aFySS2Vq9QiBiprWdPsAOLcWMNhnp0lMkASxs9/W26nU7Czo8VbAVWXM1w35plDpnDGR6lk/06dmOZpqu5p3AYr5xIKACIAdPDn0rNpnSWqC750WZ8ZWbHnKuZC5TWML7scVaPiEi7D7rbwqML2rdwx4ZoTZmCHiGByXCIWTfhf0JNQAix5WW3znl+BmDesumPgPj2mX+y6J1WYJrIz12m7qh7KhV/a1ODKM+I91A9rkOA/bPnmhmSSUR7CwgvZt1fC/VwBnaFFtAz9/70kN9Q8tDBXtXidExZwh1e3t5vDG72k3lXwNqpKRvdW3LOxK6lFvqEdMWVUJls=" ++ install: ++ - $CI_ROOT/travis-centos.sh SETUP + script: +- # Copy content of CI_DIR into WORKDIR +- - find $CI_DIR -maxdepth 1 -type f -exec cp -t . {} + +- # Build container for current user +- - $CI_SCRIPT_DIR/build-docker-image.sh +- +- # For kernel version 4.8+ +- - sudo sysctl vsyscall=emulate || true +- # Prepare environment for Coverity tool +- - | +- PLATFORM=`uname` +- export TOOL_BASE="/tmp/coverity-scan-analysis" +- export SCAN_URL="https://scan.coverity.com" +- export UPLOAD_URL="https://scan.coverity.com/builds" +- export TOOL_ARCHIVE="/tmp/cov-analysis-${PLATFORM}.tgz" +- +- # Get Coverity tool +- - $CI_TOOL_DIR/get-coverity.sh +- - TOOL_DIR="$(find $TOOL_BASE -type d -name 'cov-analysis*')" +- +- # Export env variables for Coverity scan +- - env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env +- - | +- docker run -dit --env-file .cov-env \ +- -v ${TOOL_BASE}:${TOOL_BASE}:ro \ +- --name travis_coverity_scan coverity-${TRAVIS_COMMIT}:latest bash +- # Make sure Coverity script is executable +- - docker cp tools/coverity.sh travis_coverity_scan:/usr/local/bin +- # Preconfigure with meson to prevent Coverity from capturing meson metadata +- # Set compiler flag to prevent emit failure +- - docker exec -it travis_coverity_scan sh -c "CFLAGS='-D_Float128=long\ double -D_Float64=double -D_Float64x=long\ double -D_Float32=float -D_Float32x=double' meson cov-build -Dman=false" +- # Run Coverity Analysis +- - docker exec -it travis_coverity_scan coverity.sh build +- - docker exec -it travis_coverity_scan coverity.sh upload +- +-# Specify the order of stages and conditions +-stages: +- - name: coverity scan +- if: type = cron +- +-env: +- global: +- - ADMIN_EMAIL=macermak@redhat.com +- +- - AUTHOR_NAME="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aN\")" +- - AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")" +- +- - CI_DIR="$TRAVIS_BUILD_DIR/travis-ci" +- - CI_TOOL_DIR="$CI_DIR/tools" +- - CI_SCRIPT_DIR="$CI_DIR/scripts" +- +-notifications: +- email: +- recipients: +- - ${ADMIN_EMAIL} ++ - set -e ++ # Build systemd ++ - $CI_ROOT/travis-centos.sh RUN ++ - set +e ++ after_script: ++ - $CI_ROOT/travis-centos.sh CLEANUP +diff --git a/ci/travis-centos.sh b/ci/travis-centos.sh +new file mode 100755 +index 0000000000..60bbdf14c2 +--- /dev/null ++++ b/ci/travis-centos.sh +@@ -0,0 +1,69 @@ ++#!/bin/bash ++ ++# Run this script from the root of the systemd's git repository ++# or set REPO_ROOT to a correct path. ++# ++# Example execution on Fedora: ++# dnf install docker ++# systemctl start docker ++# export CONT_NAME="my-fancy-container" ++# ci/travis-centos.sh SETUP RUN CLEANUP ++ ++PHASES=(${@:-SETUP RUN CLEANUP}) ++CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" ++CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" ++DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" ++DOCKER_RUN="${DOCKER_RUN:-docker run}" ++REPO_ROOT="${REPO_ROOT:-$PWD}" ++ADDITIONAL_DEPS=(yum-utils iputils hostname libasan libubsan clang llvm) ++ ++function info() { ++ echo -e "\033[33;1m$1\033[0m" ++} ++ ++set -e ++ ++source "$(dirname $0)/travis_wait.bash" ++ ++for phase in "${PHASES[@]}"; do ++ case $phase in ++ SETUP) ++ info "Setup phase" ++ info "Using Travis $CENTOS_RELEASE" ++ # Pull a Docker image and start a new container ++ docker pull centos:$CENTOS_RELEASE ++ info "Starting container $CONT_NAME" ++ $DOCKER_RUN -v $REPO_ROOT:/build:rw \ ++ -w /build --privileged=true --name $CONT_NAME \ ++ -dit --net=host centos:$CENTOS_RELEASE /sbin/init ++ # Beautiful workaround for Fedora's version of Docker ++ sleep 1 ++ $DOCKER_EXEC yum makecache ++ # Install necessary build/test requirements ++ $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade ++ $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" ++ $DOCKER_EXEC yum-builddep -y systemd ++ ;; ++ RUN) ++ info "Run phase" ++ # Build systemd ++ $DOCKER_EXEC ./autogen.sh ++ $DOCKER_EXEC ./configure --disable-timesyncd --disable-kdbus --disable-terminal \ ++ --enable-gtk-doc --enable-compat-libs --disable-sysusers \ ++ --disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d ++ $DOCKER_EXEC make ++ if ! $DOCKER_EXEC make check; then ++ $DOCKER_EXEC cat test-suite.log ++ exit 1 ++ fi ++ ;; ++ CLEANUP) ++ info "Cleanup phase" ++ docker stop $CONT_NAME ++ docker rm -f $CONT_NAME ++ ;; ++ *) ++ echo >&2 "Unknown phase '$phase'" ++ exit 1 ++ esac ++done +diff --git a/ci/travis_wait.bash b/ci/travis_wait.bash +new file mode 100644 +index 0000000000..acf6ad15e4 +--- /dev/null ++++ b/ci/travis_wait.bash +@@ -0,0 +1,61 @@ ++# This was borrowed from https://github.com/travis-ci/travis-build/tree/master/lib/travis/build/bash ++# to get around https://github.com/travis-ci/travis-ci/issues/9979. It should probably be removed ++# as soon as Travis CI has started to provide an easy way to export the functions to bash scripts. ++ ++travis_jigger() { ++ local cmd_pid="${1}" ++ shift ++ local timeout="${1}" ++ shift ++ local count=0 ++ ++ echo -e "\\n" ++ ++ while [[ "${count}" -lt "${timeout}" ]]; do ++ count="$((count + 1))" ++ echo -ne "Still running (${count} of ${timeout}): ${*}\\r" ++ sleep 60 ++ done ++ ++ echo -e "\\n${ANSI_RED}Timeout (${timeout} minutes) reached. Terminating \"${*}\"${ANSI_RESET}\\n" ++ kill -9 "${cmd_pid}" ++} ++ ++travis_wait() { ++ local timeout="${1}" ++ ++ if [[ "${timeout}" =~ ^[0-9]+$ ]]; then ++ shift ++ else ++ timeout=20 ++ fi ++ ++ local cmd=("${@}") ++ local log_file="travis_wait_${$}.log" ++ ++ "${cmd[@]}" &>"${log_file}" & ++ local cmd_pid="${!}" ++ ++ travis_jigger "${!}" "${timeout}" "${cmd[@]}" & ++ local jigger_pid="${!}" ++ local result ++ ++ { ++ set +e ++ wait "${cmd_pid}" 2>/dev/null ++ result="${?}" ++ ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}" ++ set -e ++ } ++ ++ if [[ "${result}" -eq 0 ]]; then ++ echo -e "\\n${ANSI_GREEN}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" ++ else ++ echo -e "\\n${ANSI_RED}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" ++ fi ++ ++ echo -e "\\n${ANSI_GREEN}Log:${ANSI_RESET}\\n" ++ cat "${log_file}" ++ ++ return "${result}" ++} diff --git a/SOURCES/0064-travis-RHEL8-support.patch b/SOURCES/0064-travis-RHEL8-support.patch new file mode 100644 index 0000000..0ce198f --- /dev/null +++ b/SOURCES/0064-travis-RHEL8-support.patch @@ -0,0 +1,175 @@ +From 45b0a38b47e07186dfe35095c7d8b1e4c2524d80 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 14 Jan 2019 14:49:32 +0100 +Subject: [PATCH] travis: RHEL8 support + +(cherry picked from commit e5c78840b2b124400f56cb5fbaf2357cd8901218) +--- + .travis.yml | 8 +- + ...ravis-centos.sh => travis-centos-rhel7.sh} | 0 + ci/travis-centos-rhel8.sh | 130 ++++++++++++++++++ + 3 files changed, 135 insertions(+), 3 deletions(-) + rename ci/{travis-centos.sh => travis-centos-rhel7.sh} (100%) + create mode 100755 ci/travis-centos-rhel8.sh + +diff --git a/.travis.yml b/.travis.yml +index fc63887324..1c4e6f9728 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -19,11 +19,13 @@ jobs: + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version + install: +- - $CI_ROOT/travis-centos.sh SETUP ++ - RHEL_VERSION="rhel7" ++ - [ -f meson.build ] && RHEL_VERSION="rhel8" ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP + script: + - set -e + # Build systemd +- - $CI_ROOT/travis-centos.sh RUN ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN + - set +e + after_script: +- - $CI_ROOT/travis-centos.sh CLEANUP ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP +diff --git a/ci/travis-centos.sh b/ci/travis-centos-rhel7.sh +similarity index 100% +rename from ci/travis-centos.sh +rename to ci/travis-centos-rhel7.sh +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +new file mode 100755 +index 0000000000..968603f949 +--- /dev/null ++++ b/ci/travis-centos-rhel8.sh +@@ -0,0 +1,130 @@ ++#!/bin/bash ++ ++# Run this script from the root of the systemd's git repository ++# or set REPO_ROOT to a correct path. ++# ++# Example execution on Fedora: ++# dnf install docker ++# systemctl start docker ++# export CONT_NAME="my-fancy-container" ++# ci/travis-centos.sh SETUP RUN CLEANUP ++ ++PHASES=(${@:-SETUP RUN CLEANUP}) ++CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" ++CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" ++DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" ++DOCKER_RUN="${DOCKER_RUN:-docker run}" ++REPO_ROOT="${REPO_ROOT:-$PWD}" ++ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja-build libasan net-tools strace nc busybox e2fsprogs quota dnsmasq) ++# Repo with additional depencencies to compile newer systemd on CentOS 7 ++COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo" ++COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}" ++ ++function info() { ++ echo -e "\033[33;1m$1\033[0m" ++} ++ ++set -e ++ ++source "$(dirname $0)/travis_wait.bash" ++ ++for phase in "${PHASES[@]}"; do ++ case $phase in ++ SETUP) ++ info "Setup phase" ++ info "Using Travis $CENTOS_RELEASE" ++ # Pull a Docker image and start a new container ++ docker pull centos:$CENTOS_RELEASE ++ info "Starting container $CONT_NAME" ++ $DOCKER_RUN -v $REPO_ROOT:/build:rw \ ++ -w /build --privileged=true --name $CONT_NAME \ ++ -dit --net=host centos:$CENTOS_RELEASE /sbin/init ++ # Beautiful workaround for Fedora's version of Docker ++ sleep 1 ++ $DOCKER_EXEC yum makecache ++ $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH" ++ $DOCKER_EXEC yum -q -y install epel-release yum-utils ++ $DOCKER_EXEC yum-config-manager -q --enable epel ++ $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade ++ # Install necessary build/test requirements ++ $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" ++ $DOCKER_EXEC python3.6 -m ensurepip ++ $DOCKER_EXEC python3.6 -m pip install meson ++ # Create necessary symlinks ++ $DOCKER_EXEC ln --force -s /usr/bin/python3.6 /usr/bin/python3 ++ $DOCKER_EXEC ln --force -s /usr/bin/ninja-build /usr/bin/ninja ++ ;; ++ RUN) ++ info "Run phase" ++ # Build systemd ++ CONFIGURE_OPTS=( ++ # RHEL8 options ++ -Dsysvinit-path=/etc/rc.d/init.d ++ -Drc-local=/etc/rc.d/rc.local ++ -Ddns-servers='' ++ -Ddev-kvm-mode=0666 ++ -Dkmod=true ++ -Dxkbcommon=true ++ -Dblkid=true ++ -Dseccomp=true ++ -Dima=true ++ -Dselinux=true ++ -Dapparmor=false ++ -Dpolkit=true ++ -Dxz=true ++ -Dzlib=true ++ -Dbzip2=true ++ -Dlz4=true ++ -Dpam=true ++ -Dacl=true ++ -Dsmack=true ++ -Dgcrypt=true ++ -Daudit=true ++ -Delfutils=true ++ -Dlibcryptsetup=true ++ -Delfutils=true ++ -Dqrencode=false ++ -Dgnutls=true ++ -Dmicrohttpd=true ++ -Dlibidn2=true ++ -Dlibiptc=true ++ -Dlibcurl=true ++ -Defi=true ++ -Dtpm=true ++ -Dhwdb=true ++ -Dsysusers=true ++ -Ddefault-kill-user-processes=false ++ -Dtests=unsafe ++ -Dinstall-tests=true ++ -Dtty-gid=5 ++ -Dusers-gid=100 ++ -Dnobody-user=nobody ++ -Dnobody-group=nobody ++ -Dsplit-usr=false ++ -Dsplit-bin=true ++ -Db_lto=false ++ -Dnetworkd=false ++ -Dtimesyncd=false ++ -Ddefault-hierarchy=legacy ++ # Custom options ++ -Dslow-tests=true ++ -Dtests=unsafe ++ -Dinstall-tests=true ++ ) ++ docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}" ++ $DOCKER_EXEC ninja -v -C build ++ # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt ++ # and it's pointless to run it on a VM in a Docker container... ++ echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl" ++ $DOCKER_EXEC ninja -C build test ++ ;; ++ CLEANUP) ++ info "Cleanup phase" ++ docker stop $CONT_NAME ++ docker rm -f $CONT_NAME ++ ;; ++ *) ++ echo >&2 "Unknown phase '$phase'" ++ exit 1 ++ esac ++done diff --git a/SOURCES/0065-travis-drop-the-SELinux-Fedora-workaround.patch b/SOURCES/0065-travis-drop-the-SELinux-Fedora-workaround.patch new file mode 100644 index 0000000..de14c0a --- /dev/null +++ b/SOURCES/0065-travis-drop-the-SELinux-Fedora-workaround.patch @@ -0,0 +1,37 @@ +From 2d674d48e9ca48e3bb126f20b59334100d926a23 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 15 Jan 2019 11:03:45 +0100 +Subject: [PATCH] travis: drop the SELinux Fedora workaround + +(cherry picked from commit 90399c456fe8cf726fc04fb7be9e2a01f9ca0eae) +--- + ci/travis-centos-rhel7.sh | 2 +- + ci/travis-centos-rhel8.sh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh +index 60bbdf14c2..b1b3de1cc2 100755 +--- a/ci/travis-centos-rhel7.sh ++++ b/ci/travis-centos-rhel7.sh +@@ -40,7 +40,7 @@ for phase in "${PHASES[@]}"; do + sleep 1 + $DOCKER_EXEC yum makecache + # Install necessary build/test requirements +- $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade ++ $DOCKER_EXEC yum -y upgrade + $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" + $DOCKER_EXEC yum-builddep -y systemd + ;; +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index 968603f949..8eda5e982f 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -45,7 +45,7 @@ for phase in "${PHASES[@]}"; do + $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH" + $DOCKER_EXEC yum -q -y install epel-release yum-utils + $DOCKER_EXEC yum-config-manager -q --enable epel +- $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade ++ $DOCKER_EXEC yum -y upgrade + # Install necessary build/test requirements + $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" + $DOCKER_EXEC python3.6 -m ensurepip diff --git a/SOURCES/0066-travis-fix-syntax-error-in-.travis.yml.patch b/SOURCES/0066-travis-fix-syntax-error-in-.travis.yml.patch new file mode 100644 index 0000000..d26bbfb --- /dev/null +++ b/SOURCES/0066-travis-fix-syntax-error-in-.travis.yml.patch @@ -0,0 +1,24 @@ +From a7f87d13f6f7dd92e1f1f7617df531fa34c70b6d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 15 Jan 2019 14:35:27 +0100 +Subject: [PATCH] travis: fix syntax error in .travis.yml + +(cherry picked from commit 7f9d44f527ea214347f7d3b3b067f84df53feed7) +--- + .travis.yml | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/.travis.yml b/.travis.yml +index 1c4e6f9728..c5c9c345a9 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -19,8 +19,7 @@ jobs: + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version + install: +- - RHEL_VERSION="rhel7" +- - [ -f meson.build ] && RHEL_VERSION="rhel8" ++ - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi + - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP + script: + - set -e diff --git a/SOURCES/0067-travis-reboot-the-container-before-running-tests.patch b/SOURCES/0067-travis-reboot-the-container-before-running-tests.patch new file mode 100644 index 0000000..5f59065 --- /dev/null +++ b/SOURCES/0067-travis-reboot-the-container-before-running-tests.patch @@ -0,0 +1,40 @@ +From 63e71bda5a00c04c16f330cfc0e6f91e7dcead59 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 17 Jan 2019 12:03:10 +0100 +Subject: [PATCH] travis: reboot the container before running tests + +--- + ci/travis-centos-rhel7.sh | 4 ++++ + ci/travis-centos-rhel8.sh | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh +index b1b3de1cc2..73416798ed 100755 +--- a/ci/travis-centos-rhel7.sh ++++ b/ci/travis-centos-rhel7.sh +@@ -52,6 +52,10 @@ for phase in "${PHASES[@]}"; do + --enable-gtk-doc --enable-compat-libs --disable-sysusers \ + --disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d + $DOCKER_EXEC make ++ # Let's install the new systemd and "reboot" the container to avoid ++ # unexpected fails due to incompatibilities with older systemd ++ $DOCKER_EXEC make install ++ docker restart $CONT_NAME + if ! $DOCKER_EXEC make check; then + $DOCKER_EXEC cat test-suite.log + exit 1 +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index 8eda5e982f..1f72d984e0 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -113,6 +113,10 @@ for phase in "${PHASES[@]}"; do + ) + docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}" + $DOCKER_EXEC ninja -v -C build ++ # Let's install the new systemd and "reboot" the container to avoid ++ # unexpected fails due to incompatibilities with older systemd ++ $DOCKER_EXEC ninja -C build install ++ docker restart $CONT_NAME + # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt + # and it's pointless to run it on a VM in a Docker container... + echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl" diff --git a/SOURCES/0068-coredump-remove-duplicate-MESSAGE-prefix-from-messag.patch b/SOURCES/0068-coredump-remove-duplicate-MESSAGE-prefix-from-messag.patch new file mode 100644 index 0000000..5c2ff84 --- /dev/null +++ b/SOURCES/0068-coredump-remove-duplicate-MESSAGE-prefix-from-messag.patch @@ -0,0 +1,35 @@ +From af43906bb0c8f2bb3b135d68d56ea2fa58fa9e60 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 17:33:15 +0100 +Subject: [PATCH] coredump: remove duplicate MESSAGE= prefix from message + +systemd-coredump[9982]: MESSAGE=Process 771 (systemd-journal) of user 0 dumped core. +systemd-coredump[9982]: Coredump diverted to /var/lib/systemd/coredump/core... + +log_dispatch() calls log_dispatch_internal() which calls write_to_journal() +which appends MESSAGE= on its own. + +(cherry-picked from commit 4f62556d71206ac814a020a954b397d4940e14c3) + +Related: #1664976 +--- + src/coredump/coredump.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 20a1cbdd45..d7dd81c1b4 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -789,9 +789,10 @@ log: + return log_oom(); + + if (journald_crash) { +- /* We cannot log to the journal, so just print the MESSAGE. ++ /* We cannot log to the journal, so just print the message. + * The target was set previously to something safe. */ +- log_dispatch(LOG_ERR, 0, core_message); ++ assert(startswith(core_message, "MESSAGE=")); ++ log_dispatch(LOG_ERR, 0, core_message + strlen("MESSAGE=")); + return 0; + } + diff --git a/SOURCES/0069-journald-remove-unnecessary.patch b/SOURCES/0069-journald-remove-unnecessary.patch new file mode 100644 index 0000000..aaffa53 --- /dev/null +++ b/SOURCES/0069-journald-remove-unnecessary.patch @@ -0,0 +1,34 @@ +From 285e4d2ce6a8836ce7bf2e889d43b7272f7ccc1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 17:53:50 +0100 +Subject: [PATCH] journald: remove unnecessary {} + +(cherry-picked from commit bc2762a309132a34db1797d8b5792d5747a94484) + +Related: #1664976 +--- + src/journal/journald-server.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 4f1550ec5b..ce2446a2f1 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1124,8 +1124,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + return log_error_errno(errno, "recvmsg() failed: %m"); + } + +- CMSG_FOREACH(cmsg, &msghdr) { +- ++ CMSG_FOREACH(cmsg, &msghdr) + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_CREDENTIALS && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) +@@ -1143,7 +1142,6 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + fds = (int*) CMSG_DATA(cmsg); + n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + } +- } + + /* And a trailing NUL, just in case */ + s->buffer[n] = 0; diff --git a/SOURCES/0070-journald-do-not-store-the-iovec-entry-for-process-co.patch b/SOURCES/0070-journald-do-not-store-the-iovec-entry-for-process-co.patch new file mode 100644 index 0000000..40af46e --- /dev/null +++ b/SOURCES/0070-journald-do-not-store-the-iovec-entry-for-process-co.patch @@ -0,0 +1,202 @@ +From b6c10945e68949edc6418f48ca7b1b748fefabe1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 18:38:39 +0100 +Subject: [PATCH] journald: do not store the iovec entry for process + commandline on stack + +This fixes a crash where we would read the commandline, whose length is under +control of the sending program, and then crash when trying to create a stack +allocation for it. + +CVE-2018-16864 +https://bugzilla.redhat.com/show_bug.cgi?id=1653855 + +The message actually doesn't get written to disk, because +journal_file_append_entry() returns -E2BIG. + +(cherry-picked from commit 084eeb865ca63887098e0945fb4e93c852b91b0f) + +Resolves: #1664976 +--- + src/basic/io-util.c | 10 ++++++++++ + src/basic/io-util.h | 2 ++ + src/coredump/coredump.c | 31 +++++++++++-------------------- + src/journal/journald-server.c | 25 +++++++++++++++---------- + 4 files changed, 38 insertions(+), 30 deletions(-) + +diff --git a/src/basic/io-util.c b/src/basic/io-util.c +index 1f64cc933b..575398fbe6 100644 +--- a/src/basic/io-util.c ++++ b/src/basic/io-util.c +@@ -8,6 +8,7 @@ + #include + + #include "io-util.h" ++#include "string-util.h" + #include "time-util.h" + + int flush_fd(int fd) { +@@ -252,3 +253,12 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) { + + return q - (const uint8_t*) p; + } ++ ++char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) { ++ char *x; ++ ++ x = strappend(field, value); ++ if (x) ++ iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x); ++ return x; ++} +diff --git a/src/basic/io-util.h b/src/basic/io-util.h +index ed189b5820..792a64ad5e 100644 +--- a/src/basic/io-util.h ++++ b/src/basic/io-util.h +@@ -71,3 +71,5 @@ static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { + #define IOVEC_MAKE(base, len) (struct iovec) IOVEC_INIT(base, len) + #define IOVEC_INIT_STRING(string) IOVEC_INIT((char*) string, strlen(string)) + #define IOVEC_MAKE_STRING(string) (struct iovec) IOVEC_INIT_STRING(string) ++ ++char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index d7dd81c1b4..ffa88f612d 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -1054,19 +1054,10 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd) + return 0; + } + +-static char* set_iovec_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) { +- char *x; +- +- x = strappend(field, value); +- if (x) +- iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x); +- return x; +-} +- + static char* set_iovec_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value) { + char *x; + +- x = set_iovec_field(iovec, n_iovec, field, value); ++ x = set_iovec_string_field(iovec, n_iovec, field, value); + free(value); + return x; + } +@@ -1116,36 +1107,36 @@ static int gather_pid_metadata( + disable_coredumps(); + } + +- set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]); ++ set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]); + } + + if (cg_pid_get_user_unit(pid, &t) >= 0) + set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t); + + /* The next few are mandatory */ +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME])) + return log_oom(); + +- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM])) + return log_oom(); + + if (context[CONTEXT_EXE] && +- !set_iovec_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE])) ++ !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE])) + return log_oom(); + + if (sd_pid_get_session(pid, &t) >= 0) +@@ -1213,7 +1204,7 @@ static int gather_pid_metadata( + iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(t); + + if (safe_atoi(context[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo)) +- set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo)); ++ set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo)); + + return 0; /* we successfully acquired all metadata */ + } +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index ce2446a2f1..8de45552f6 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -753,6 +753,7 @@ static void dispatch_message_real( + pid_t object_pid) { + + char source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)]; ++ _cleanup_free_ char *cmdline1 = NULL, *cmdline2 = NULL; + uid_t journal_uid; + ClientContext *o; + +@@ -769,20 +770,23 @@ static void dispatch_message_real( + IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->uid, uid_t, uid_is_valid, UID_FMT, "_UID"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->gid, gid_t, gid_is_valid, GID_FMT, "_GID"); + +- IOVEC_ADD_STRING_FIELD(iovec, n, c->comm, "_COMM"); +- IOVEC_ADD_STRING_FIELD(iovec, n, c->exe, "_EXE"); +- IOVEC_ADD_STRING_FIELD(iovec, n, c->cmdline, "_CMDLINE"); +- IOVEC_ADD_STRING_FIELD(iovec, n, c->capeff, "_CAP_EFFECTIVE"); ++ IOVEC_ADD_STRING_FIELD(iovec, n, c->comm, "_COMM"); /* At most TASK_COMM_LENGTH (16 bytes) */ ++ IOVEC_ADD_STRING_FIELD(iovec, n, c->exe, "_EXE"); /* A path, so at most PATH_MAX (4096 bytes) */ + +- IOVEC_ADD_SIZED_FIELD(iovec, n, c->label, c->label_size, "_SELINUX_CONTEXT"); ++ if (c->cmdline) ++ /* At most _SC_ARG_MAX (2MB usually), which is too much to put on stack. ++ * Let's use a heap allocation for this one. */ ++ cmdline1 = set_iovec_string_field(iovec, &n, "_CMDLINE=", c->cmdline); + ++ IOVEC_ADD_STRING_FIELD(iovec, n, c->capeff, "_CAP_EFFECTIVE"); /* Read from /proc/.../status */ ++ IOVEC_ADD_SIZED_FIELD(iovec, n, c->label, c->label_size, "_SELINUX_CONTEXT"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "_AUDIT_SESSION"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->loginuid, uid_t, uid_is_valid, UID_FMT, "_AUDIT_LOGINUID"); + +- IOVEC_ADD_STRING_FIELD(iovec, n, c->cgroup, "_SYSTEMD_CGROUP"); ++ IOVEC_ADD_STRING_FIELD(iovec, n, c->cgroup, "_SYSTEMD_CGROUP"); /* A path */ + IOVEC_ADD_STRING_FIELD(iovec, n, c->session, "_SYSTEMD_SESSION"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->owner_uid, uid_t, uid_is_valid, UID_FMT, "_SYSTEMD_OWNER_UID"); +- IOVEC_ADD_STRING_FIELD(iovec, n, c->unit, "_SYSTEMD_UNIT"); ++ IOVEC_ADD_STRING_FIELD(iovec, n, c->unit, "_SYSTEMD_UNIT"); /* Unit names are bounded by UNIT_NAME_MAX */ + IOVEC_ADD_STRING_FIELD(iovec, n, c->user_unit, "_SYSTEMD_USER_UNIT"); + IOVEC_ADD_STRING_FIELD(iovec, n, c->slice, "_SYSTEMD_SLICE"); + IOVEC_ADD_STRING_FIELD(iovec, n, c->user_slice, "_SYSTEMD_USER_SLICE"); +@@ -803,13 +807,14 @@ static void dispatch_message_real( + IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->uid, uid_t, uid_is_valid, UID_FMT, "OBJECT_UID"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->gid, gid_t, gid_is_valid, GID_FMT, "OBJECT_GID"); + ++ /* See above for size limits, only ->cmdline may be large, so use a heap allocation for it. */ + IOVEC_ADD_STRING_FIELD(iovec, n, o->comm, "OBJECT_COMM"); + IOVEC_ADD_STRING_FIELD(iovec, n, o->exe, "OBJECT_EXE"); +- IOVEC_ADD_STRING_FIELD(iovec, n, o->cmdline, "OBJECT_CMDLINE"); +- IOVEC_ADD_STRING_FIELD(iovec, n, o->capeff, "OBJECT_CAP_EFFECTIVE"); ++ if (o->cmdline) ++ cmdline2 = set_iovec_string_field(iovec, &n, "OBJECT_CMDLINE=", o->cmdline); + ++ IOVEC_ADD_STRING_FIELD(iovec, n, o->capeff, "OBJECT_CAP_EFFECTIVE"); + IOVEC_ADD_SIZED_FIELD(iovec, n, o->label, o->label_size, "OBJECT_SELINUX_CONTEXT"); +- + IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "OBJECT_AUDIT_SESSION"); + IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->loginuid, uid_t, uid_is_valid, UID_FMT, "OBJECT_AUDIT_LOGINUID"); + diff --git a/SOURCES/0071-basic-process-util-limit-command-line-lengths-to-_SC.patch b/SOURCES/0071-basic-process-util-limit-command-line-lengths-to-_SC.patch new file mode 100644 index 0000000..f1e9a62 --- /dev/null +++ b/SOURCES/0071-basic-process-util-limit-command-line-lengths-to-_SC.patch @@ -0,0 +1,159 @@ +From 6298317e2d0dffb1ff4ecebedb8709645de36b6a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 18:48:23 +0100 +Subject: [PATCH] basic/process-util: limit command line lengths to _SC_ARG_MAX + +This affects systemd-journald and systemd-coredump. + +Example entry: +$ journalctl -o export -n1 'MESSAGE=Something logged' +__CURSOR=s=976542d120c649f494471be317829ef9;i=34e;b=4871e4c474574ce4a462dfe3f1c37f06;m=c7d0c37dd2;t=57c4ac58f3b98;x=67598e942bd23dc0 +__REALTIME_TIMESTAMP=1544035467475864 +__MONOTONIC_TIMESTAMP=858200964562 +_BOOT_ID=4871e4c474574ce4a462dfe3f1c37f06 +PRIORITY=6 +_UID=1000 +_GID=1000 +_CAP_EFFECTIVE=0 +_SELINUX_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 +_AUDIT_SESSION=1 +_AUDIT_LOGINUID=1000 +_SYSTEMD_OWNER_UID=1000 +_SYSTEMD_UNIT=user@1000.service +_SYSTEMD_SLICE=user-1000.slice +_SYSTEMD_USER_SLICE=-.slice +_SYSTEMD_INVOCATION_ID=1c4a469986d448719cb0f9141a10810e +_MACHINE_ID=08a5690a2eed47cf92ac0a5d2e3cf6b0 +_HOSTNAME=krowka +_TRANSPORT=syslog +SYSLOG_FACILITY=17 +SYSLOG_IDENTIFIER=syslog-caller +MESSAGE=Something logged +_COMM=poc +_EXE=/home/zbyszek/src/systemd-work3/poc +_SYSTEMD_CGROUP=/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service +_SYSTEMD_USER_UNIT=gnome-terminal-server.service +SYSLOG_PID=4108 +SYSLOG_TIMESTAMP=Dec 5 19:44:27 +_PID=4108 +_CMDLINE=./poc AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA> +_SOURCE_REALTIME_TIMESTAMP=1544035467475848 + +$ journalctl -o export -n1 'MESSAGE=Something logged' --output-fields=_CMDLINE|wc + 6 2053 2097410 + +2MB might be hard for some clients to use meaningfully, but OTOH, it is +important to log the full commandline sometimes. For example, when the program +is crashing, the exact argument list is useful. + +(cherry-picked from commit 2d5d2e0cc5171c6795d2a485841474345d9e30ab) + +Related: #1664976 +--- + src/basic/process-util.c | 73 ++++++++++++++-------------------------- + 1 file changed, 25 insertions(+), 48 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index 0a4f917cbd..a20f1e3ccf 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -128,6 +128,13 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + ++ if (max_length == 0) { ++ /* This is supposed to be a safety guard against runaway command lines. */ ++ long l = sysconf(_SC_ARG_MAX); ++ assert(l > 0); ++ max_length = l; ++ } ++ + if (max_length == 1) { + + /* If there's only room for one byte, return the empty string */ +@@ -138,32 +145,6 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + *line = ans; + return 0; + +- } else if (max_length == 0) { +- size_t len = 0, allocated = 0; +- +- while ((c = getc(f)) != EOF) { +- +- if (!GREEDY_REALLOC(ans, allocated, len+3)) { +- free(ans); +- return -ENOMEM; +- } +- +- if (isprint(c)) { +- if (space) { +- ans[len++] = ' '; +- space = false; +- } +- +- ans[len++] = c; +- } else if (len > 0) +- space = true; +- } +- +- if (len > 0) +- ans[len] = '\0'; +- else +- ans = mfree(ans); +- + } else { + bool dotdotdot = false; + size_t left; +@@ -235,34 +216,30 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + if (h < 0) + return h; + +- if (max_length == 0) +- ans = strjoin("[", t, "]"); +- else { +- size_t l; +- +- l = strlen(t); ++ size_t l = strlen(t); + +- if (l + 3 <= max_length) +- ans = strjoin("[", t, "]"); +- else if (max_length <= 6) { ++ if (l + 3 <= max_length) { ++ ans = strjoin("[", t, "]"); ++ if (!ans) ++ return -ENOMEM; + +- ans = new(char, max_length); +- if (!ans) +- return -ENOMEM; ++ } else if (max_length <= 6) { ++ ans = new(char, max_length); ++ if (!ans) ++ return -ENOMEM; + +- memcpy(ans, "[...]", max_length-1); +- ans[max_length-1] = 0; +- } else { +- t[max_length - 6] = 0; ++ memcpy(ans, "[...]", max_length-1); ++ ans[max_length-1] = 0; ++ } else { ++ t[max_length - 6] = 0; + +- /* Chop off final spaces */ +- delete_trailing_chars(t, WHITESPACE); ++ /* Chop off final spaces */ ++ delete_trailing_chars(t, WHITESPACE); + +- ans = strjoin("[", t, "...]"); +- } ++ ans = strjoin("[", t, "...]"); ++ if (!ans) ++ return -ENOMEM; + } +- if (!ans) +- return -ENOMEM; + } + + *line = ans; diff --git a/SOURCES/0072-coredump-fix-message-when-we-fail-to-save-a-journald.patch b/SOURCES/0072-coredump-fix-message-when-we-fail-to-save-a-journald.patch new file mode 100644 index 0000000..0041902 --- /dev/null +++ b/SOURCES/0072-coredump-fix-message-when-we-fail-to-save-a-journald.patch @@ -0,0 +1,33 @@ +From 04326c02ca80666e66a5da8e6a46c2fc4476000c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 21:34:24 +0100 +Subject: [PATCH] coredump: fix message when we fail to save a journald + coredump + +If creation of the message failed, we'd write a bogus entry: +systemd-coredump[1400]: Cannot store coredump of 416 (systemd-journal): No space left on device +systemd-coredump[1400]: MESSAGE=Process 416 (systemd-journal) of user 0 dumped core. +systemd-coredump[1400]: Coredump diverted to + +(cherry-picked from commit f0136e09221364f931c3a3b715da4e4d3ee9f2ac) + +Related: #1664976 +--- + src/coredump/coredump.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index ffa88f612d..2a130e8838 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -783,8 +783,8 @@ log: + core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], + " (", context[CONTEXT_COMM], ") of user ", + context[CONTEXT_UID], " dumped core.", +- journald_crash ? "\nCoredump diverted to " : NULL, +- journald_crash ? filename : NULL); ++ journald_crash && filename ? "\nCoredump diverted to " : NULL, ++ journald_crash && filename ? filename : NULL); + if (!core_message) + return log_oom(); + diff --git a/SOURCES/0073-procfs-util-expose-functionality-to-query-total-memo.patch b/SOURCES/0073-procfs-util-expose-functionality-to-query-total-memo.patch new file mode 100644 index 0000000..8d9285f --- /dev/null +++ b/SOURCES/0073-procfs-util-expose-functionality-to-query-total-memo.patch @@ -0,0 +1,104 @@ +From 60b831ef50e435b66ddd99e635a5112e121c7cb3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 22 Jan 2019 15:43:07 +0100 +Subject: [PATCH] procfs-util: expose functionality to query total memory + +procfs_memory_get_current is renamed to procfs_memory_get_used, because +"current" can mean anything, including total memory, used memory, and free +memory, as long as the value is up to date. + +No functional change. + +(cherry-picked from commit c482724aa5c5d0b1391fcf958a9a3ea6ce73a085) + +Related: #1664976 +--- + src/basic/procfs-util.c | 9 +++++---- + src/basic/procfs-util.h | 5 ++++- + src/cgtop/cgtop.c | 2 +- + src/core/cgroup.c | 2 +- + src/test/test-procfs-util.c | 2 +- + 5 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c +index a159e344b3..7aaf95bfce 100644 +--- a/src/basic/procfs-util.c ++++ b/src/basic/procfs-util.c +@@ -201,13 +201,11 @@ int procfs_cpu_get_usage(nsec_t *ret) { + return 0; + } + +-int procfs_memory_get_current(uint64_t *ret) { ++int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) { + uint64_t mem_total = UINT64_MAX, mem_free = UINT64_MAX; + _cleanup_fclose_ FILE *f = NULL; + int r; + +- assert(ret); +- + f = fopen("/proc/meminfo", "re"); + if (!f) + return -errno; +@@ -262,6 +260,9 @@ int procfs_memory_get_current(uint64_t *ret) { + if (mem_free > mem_total) + return -EINVAL; + +- *ret = (mem_total - mem_free) * 1024U; ++ if (ret_total) ++ *ret_total = mem_total * 1024U; ++ if (ret_used) ++ *ret_used = (mem_total - mem_free) * 1024U; + return 0; + } +diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h +index f697ed92bc..5a44e9eff7 100644 +--- a/src/basic/procfs-util.h ++++ b/src/basic/procfs-util.h +@@ -11,4 +11,7 @@ int procfs_tasks_get_current(uint64_t *ret); + + int procfs_cpu_get_usage(nsec_t *ret); + +-int procfs_memory_get_current(uint64_t *ret); ++int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used); ++static inline int procfs_memory_get_used(uint64_t *ret) { ++ return procfs_memory_get(NULL, ret); ++} +diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c +index 8dda08ab4c..792b13a43d 100644 +--- a/src/cgtop/cgtop.c ++++ b/src/cgtop/cgtop.c +@@ -297,7 +297,7 @@ static int process( + } else if (streq(controller, "memory")) { + + if (is_root_cgroup(path)) { +- r = procfs_memory_get_current(&g->memory); ++ r = procfs_memory_get_used(&g->memory); + if (r < 0) + return r; + } else { +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index bb02436203..62ab41a288 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2402,7 +2402,7 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) { + + /* The root cgroup doesn't expose this information, let's get it from /proc instead */ + if (unit_has_root_cgroup(u)) +- return procfs_memory_get_current(ret); ++ return procfs_memory_get_used(ret); + + if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0) + return -ENODATA; +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index 08af380cc7..1d0612985b 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -18,7 +18,7 @@ int main(int argc, char *argv[]) { + assert_se(procfs_cpu_get_usage(&nsec) >= 0); + log_info("Current system CPU time: %s", format_timespan(buf, sizeof(buf), nsec/NSEC_PER_USEC, 1)); + +- assert_se(procfs_memory_get_current(&v) >= 0); ++ assert_se(procfs_memory_get_used(&v) >= 0); + log_info("Current memory usage: %s", format_bytes(buf, sizeof(buf), v)); + + assert_se(procfs_tasks_get_current(&v) >= 0); diff --git a/SOURCES/0074-basic-prioq-add-prioq_peek_item.patch b/SOURCES/0074-basic-prioq-add-prioq_peek_item.patch new file mode 100644 index 0000000..828bff6 --- /dev/null +++ b/SOURCES/0074-basic-prioq-add-prioq_peek_item.patch @@ -0,0 +1,114 @@ +From ee14a2bd3d95b5d15e4d72ee2582b366e5009a86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 26 Jan 2019 11:27:18 +0100 +Subject: [PATCH] basic/prioq: add prioq_peek_item() + +(cherry-picked from commit ef21b3b5bf824e652addf850bcfd9374c7b33ce8) + +Related: #1664976 +--- + src/basic/prioq.c | 7 +++---- + src/basic/prioq.h | 8 +++++++- + src/test/test-prioq.c | 23 +++++++++++++++++------ + 3 files changed, 27 insertions(+), 11 deletions(-) + +diff --git a/src/basic/prioq.c b/src/basic/prioq.c +index ef28a086d1..0bf58c1f16 100644 +--- a/src/basic/prioq.c ++++ b/src/basic/prioq.c +@@ -259,15 +259,14 @@ int prioq_reshuffle(Prioq *q, void *data, unsigned *idx) { + return 1; + } + +-void *prioq_peek(Prioq *q) { +- ++void *prioq_peek_by_index(Prioq *q, unsigned idx) { + if (!q) + return NULL; + +- if (q->n_items <= 0) ++ if (idx >= q->n_items) + return NULL; + +- return q->items[0].data; ++ return q->items[idx].data; + } + + void *prioq_pop(Prioq *q) { +diff --git a/src/basic/prioq.h b/src/basic/prioq.h +index e036175260..c381523525 100644 +--- a/src/basic/prioq.h ++++ b/src/basic/prioq.h +@@ -18,8 +18,14 @@ int prioq_put(Prioq *q, void *data, unsigned *idx); + int prioq_remove(Prioq *q, void *data, unsigned *idx); + int prioq_reshuffle(Prioq *q, void *data, unsigned *idx); + +-void *prioq_peek(Prioq *q) _pure_; ++void *prioq_peek_by_index(Prioq *q, unsigned idx) _pure_; ++static inline void *prioq_peek(Prioq *q) { ++ return prioq_peek_by_index(q, 0); ++} + void *prioq_pop(Prioq *q); + ++#define PRIOQ_FOREACH_ITEM(q, p) \ ++ for (unsigned _i = 0; (p = prioq_peek_by_index(q, _i)); _i++) ++ + unsigned prioq_size(Prioq *q) _pure_; + bool prioq_isempty(Prioq *q) _pure_; +diff --git a/src/test/test-prioq.c b/src/test/test-prioq.c +index 89c41d8ce7..ece13808ed 100644 +--- a/src/test/test-prioq.c ++++ b/src/test/test-prioq.c +@@ -87,6 +87,7 @@ static void test_struct(void) { + Set *s; + unsigned previous = 0, i; + int r; ++ struct test *t; + + srand(0); + +@@ -96,9 +97,12 @@ static void test_struct(void) { + s = set_new(&test_hash_ops); + assert_se(s); + +- for (i = 0; i < SET_SIZE; i++) { +- struct test *t; ++ assert_se(prioq_peek(q) == NULL); ++ assert_se(prioq_peek_by_index(q, 0) == NULL); ++ assert_se(prioq_peek_by_index(q, 1) == NULL); ++ assert_se(prioq_peek_by_index(q, (unsigned) -1) == NULL); + ++ for (i = 0; i < SET_SIZE; i++) { + t = new0(struct test, 1); + assert_se(t); + t->value = (unsigned) rand(); +@@ -112,9 +116,18 @@ static void test_struct(void) { + } + } + +- for (;;) { +- struct test *t; ++ for (i = 0; i < SET_SIZE; i++) ++ assert_se(prioq_peek_by_index(q, i)); ++ assert_se(prioq_peek_by_index(q, SET_SIZE) == NULL); ++ ++ unsigned count = 0; ++ PRIOQ_FOREACH_ITEM(q, t) { ++ assert_se(t); ++ count++; ++ } ++ assert_se(count == SET_SIZE); + ++ for (;;) { + t = set_steal_first(s); + if (!t) + break; +@@ -126,8 +139,6 @@ static void test_struct(void) { + } + + for (i = 0; i < SET_SIZE * 3 / 4; i++) { +- struct test *t; +- + assert_se(prioq_size(q) == (SET_SIZE * 3 / 4) - i); + + t = prioq_pop(q); diff --git a/SOURCES/0075-journal-limit-the-number-of-entries-in-the-cache-bas.patch b/SOURCES/0075-journal-limit-the-number-of-entries-in-the-cache-bas.patch new file mode 100644 index 0000000..d2bcd3b --- /dev/null +++ b/SOURCES/0075-journal-limit-the-number-of-entries-in-the-cache-bas.patch @@ -0,0 +1,81 @@ +From de72fa6b0582b95216215cc1400412fe91bc8ba3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 22 Jan 2019 16:12:52 +0100 +Subject: [PATCH] journal: limit the number of entries in the cache based on + available memory + +This is far from perfect, but should give mostly reasonable values. My +assumption is that if somebody has a few hundred MB of memory, they are +unlikely to have thousands of processes logging. A hundred would already be a +lot. So let's scale the cache size propritionally to the total memory size, +with clamping on both ends. + +The formula gives 64 cache entries for each GB of RAM. + +(cherry-picked from commit b12a480829c5ca8f4d4fa9cde8716b5f2f12a3ad) + +Related: #1664976 +--- + src/journal/journald-context.c | 35 ++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c +index ce07de1bfb..0f0dc1de4d 100644 +--- a/src/journal/journald-context.c ++++ b/src/journal/journald-context.c +@@ -14,6 +14,7 @@ + #include "journal-util.h" + #include "journald-context.h" + #include "process-util.h" ++#include "procfs-util.h" + #include "string-util.h" + #include "syslog-util.h" + #include "unaligned.h" +@@ -58,7 +59,37 @@ + /* Keep at most 16K entries in the cache. (Note though that this limit may be violated if enough streams pin entries in + * the cache, in which case we *do* permit this limit to be breached. That's safe however, as the number of stream + * clients itself is limited.) */ +-#define CACHE_MAX (16*1024) ++#define CACHE_MAX_FALLBACK 128U ++#define CACHE_MAX_MAX (16*1024U) ++#define CACHE_MAX_MIN 64U ++ ++static size_t cache_max(void) { ++ static size_t cached = -1; ++ ++ if (cached == (size_t) -1) { ++ uint64_t mem_total; ++ int r; ++ ++ r = procfs_memory_get(&mem_total, NULL); ++ if (r < 0) { ++ log_warning_errno(r, "Cannot query /proc/meminfo for MemTotal: %m"); ++ cached = CACHE_MAX_FALLBACK; ++ } else { ++ /* Cache entries are usually a few kB, but the process cmdline is controlled by the ++ * user and can be up to _SC_ARG_MAX, usually 2MB. Let's say that approximately up to ++ * 1/8th of memory may be used by the cache. ++ * ++ * In the common case, this formula gives 64 cache entries for each GB of RAM. ++ */ ++ long l = sysconf(_SC_ARG_MAX); ++ assert(l > 0); ++ ++ cached = CLAMP(mem_total / 8 / (uint64_t) l, CACHE_MAX_MIN, CACHE_MAX_MAX); ++ } ++ } ++ ++ return cached; ++} + + static int client_context_compare(const void *a, const void *b) { + const ClientContext *x = a, *y = b; +@@ -587,7 +618,7 @@ static int client_context_get_internal( + return 0; + } + +- client_context_try_shrink_to(s, CACHE_MAX-1); ++ client_context_try_shrink_to(s, cache_max()-1); + + r = client_context_new(s, pid, &c); + if (r < 0) diff --git a/SOURCES/0076-journald-periodically-drop-cache-for-all-dead-PIDs.patch b/SOURCES/0076-journald-periodically-drop-cache-for-all-dead-PIDs.patch new file mode 100644 index 0000000..cad2d3e --- /dev/null +++ b/SOURCES/0076-journald-periodically-drop-cache-for-all-dead-PIDs.patch @@ -0,0 +1,77 @@ +From 8da81d2aba2768ced497790cc05b9f73c6268833 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 22 Jan 2019 17:30:48 +0100 +Subject: [PATCH] journald: periodically drop cache for all dead PIDs + +In normal use, this allow us to drop dead entries from the cache and reduces +the cache size so that we don't evict entries unnecessarily. The time limit is +there mostly to serve as a guard against malicious logging from many different +PIDs. + +(cherry-picked from commit 91714a7f427a6c9c5c3be8b3819fee45050028f3) + +Related: #1664976 +--- + src/journal/journald-context.c | 28 ++++++++++++++++++++++++++-- + src/journal/journald-server.h | 2 ++ + 2 files changed, 28 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c +index 0f0dc1de4d..51f79fd803 100644 +--- a/src/journal/journald-context.c ++++ b/src/journal/journald-context.c +@@ -541,15 +541,39 @@ refresh: + } + + static void client_context_try_shrink_to(Server *s, size_t limit) { ++ ClientContext *c; ++ usec_t t; ++ + assert(s); + ++ /* Flush any cache entries for PIDs that have already moved on. Don't do this ++ * too often, since it's a slow process. */ ++ t = now(CLOCK_MONOTONIC); ++ if (s->last_cache_pid_flush + MAX_USEC < t) { ++ unsigned n = prioq_size(s->client_contexts_lru), idx = 0; ++ ++ /* We do a number of iterations based on the initial size of the prioq. When we remove an ++ * item, a new item is moved into its places, and items to the right might be reshuffled. ++ */ ++ for (unsigned i = 0; i < n; i++) { ++ c = prioq_peek_by_index(s->client_contexts_lru, idx); ++ ++ assert(c->n_ref == 0); ++ ++ if (!pid_is_unwaited(c->pid)) ++ client_context_free(s, c); ++ else ++ idx ++; ++ } ++ ++ s->last_cache_pid_flush = t; ++ } ++ + /* Bring the number of cache entries below the indicated limit, so that we can create a new entry without + * breaching the limit. Note that we only flush out entries that aren't pinned here. This means the number of + * cache entries may very well grow beyond the limit, if all entries stored remain pinned. */ + + while (hashmap_size(s->client_contexts) > limit) { +- ClientContext *c; +- + c = prioq_pop(s->client_contexts_lru); + if (!c) + break; /* All remaining entries are pinned, give up */ +diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h +index 983be8bb89..c6c9b1fb1d 100644 +--- a/src/journal/journald-server.h ++++ b/src/journal/journald-server.h +@@ -163,6 +163,8 @@ struct Server { + Hashmap *client_contexts; + Prioq *client_contexts_lru; + ++ usec_t last_cache_pid_flush; ++ + ClientContext *my_context; /* the context of journald itself */ + ClientContext *pid1_context; /* the context of PID 1 */ + }; diff --git a/SOURCES/0077-process-util-don-t-use-overly-large-buffer-to-store-.patch b/SOURCES/0077-process-util-don-t-use-overly-large-buffer-to-store-.patch new file mode 100644 index 0000000..3e583ff --- /dev/null +++ b/SOURCES/0077-process-util-don-t-use-overly-large-buffer-to-store-.patch @@ -0,0 +1,71 @@ +From 9b9b6d8c7b10c069d36f85bd17f144011282cb58 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 22 Jan 2019 14:29:50 +0100 +Subject: [PATCH] process-util: don't use overly large buffer to store process + command line + +Allocate new string as a return value and free our "scratch pad" +buffer that is potentially much larger than needed (up to +_SC_ARG_MAX). + +Fixes #11502 + +(cherry-picked from commit eb1ec489eef8a32918bbfc56a268c9d10464584d) + +Related: #1664976 +--- + src/basic/process-util.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index a20f1e3ccf..aa3eff779a 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -101,7 +101,8 @@ int get_process_comm(pid_t pid, char **ret) { + int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) { + _cleanup_fclose_ FILE *f = NULL; + bool space = false; +- char *k, *ans = NULL; ++ char *k; ++ _cleanup_free_ char *ans = NULL; + const char *p; + int c; + +@@ -142,7 +143,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + if (!ans) + return -ENOMEM; + +- *line = ans; ++ *line = TAKE_PTR(ans); + return 0; + + } else { +@@ -207,7 +208,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + _cleanup_free_ char *t = NULL; + int h; + +- free(ans); ++ ans = mfree(ans); + + if (!comm_fallback) + return -ENOENT; +@@ -240,9 +241,18 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * + if (!ans) + return -ENOMEM; + } ++ ++ *line = TAKE_PTR(ans); ++ return 0; + } + +- *line = ans; ++ k = realloc(ans, strlen(ans) + 1); ++ if (!k) ++ return -ENOMEM; ++ ++ ans = NULL; ++ *line = k; ++ + return 0; + } + diff --git a/SOURCES/0078-Revert-sysctl.d-switch-net.ipv4.conf.all.rp_filter-f.patch b/SOURCES/0078-Revert-sysctl.d-switch-net.ipv4.conf.all.rp_filter-f.patch new file mode 100644 index 0000000..8897b48 --- /dev/null +++ b/SOURCES/0078-Revert-sysctl.d-switch-net.ipv4.conf.all.rp_filter-f.patch @@ -0,0 +1,26 @@ +From 47b256d63ac092137fe44e27560a14ee4aa5b7c8 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Fri, 8 Feb 2019 10:54:34 +0100 +Subject: [PATCH] Revert "sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 + to 2" + +This reverts commit 75c9af80cf3529c76988451e63f98010c86f48f1. + +Resolves: #1653824 +--- + sysctl.d/50-default.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index b0645f33e7..e263cf0628 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -22,7 +22,7 @@ kernel.sysrq = 16 + kernel.core_uses_pid = 1 + + # Source route verification +-net.ipv4.conf.all.rp_filter = 2 ++net.ipv4.conf.all.rp_filter = 1 + + # Do not accept source routing + net.ipv4.conf.all.accept_source_route = 0 diff --git a/SOURCES/0079-journal-fix-syslog_parse_identifier.patch b/SOURCES/0079-journal-fix-syslog_parse_identifier.patch new file mode 100644 index 0000000..4d6b283 --- /dev/null +++ b/SOURCES/0079-journal-fix-syslog_parse_identifier.patch @@ -0,0 +1,68 @@ +From d355618518f26bd045df81a52dade79ac3079f3f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 8 Aug 2018 15:06:36 +0900 +Subject: [PATCH] journal: fix syslog_parse_identifier() + +Fixes #9829. + +(cherry-picked from commit a6aadf4ae0bae185dc4c414d492a4a781c80ffe5) + +Resolves: #1664978 +--- + src/journal/journald-syslog.c | 6 +++--- + src/journal/test-journal-syslog.c | 10 ++++++++-- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c +index 9dea116722..97711ac7a3 100644 +--- a/src/journal/journald-syslog.c ++++ b/src/journal/journald-syslog.c +@@ -194,7 +194,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) + e = l; + l--; + +- if (p[l-1] == ']') { ++ if (l > 0 && p[l-1] == ']') { + size_t k = l-1; + + for (;;) { +@@ -219,8 +219,8 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) + if (t) + *identifier = t; + +- if (strchr(WHITESPACE, p[e])) +- e++; ++ e += strspn(p + e, WHITESPACE); ++ + *buf = p + e; + return e; + } +diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c +index 9ba86f6c8a..05f759817e 100644 +--- a/src/journal/test-journal-syslog.c ++++ b/src/journal/test-journal-syslog.c +@@ -5,8 +5,8 @@ + #include "macro.h" + #include "string-util.h" + +-static void test_syslog_parse_identifier(const char* str, +- const char *ident, const char*pid, int ret) { ++static void test_syslog_parse_identifier(const char *str, ++ const char *ident, const char *pid, int ret) { + const char *buf = str; + _cleanup_free_ char *ident2 = NULL, *pid2 = NULL; + int ret2; +@@ -21,7 +21,13 @@ static void test_syslog_parse_identifier(const char* str, + int main(void) { + test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11); + test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6); ++ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7); + test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0); ++ test_syslog_parse_identifier(":", "", NULL, 1); ++ test_syslog_parse_identifier(": ", "", NULL, 3); ++ test_syslog_parse_identifier("pidu:", "pidu", NULL, 5); ++ test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6); ++ test_syslog_parse_identifier("pidu : ", NULL, NULL, 0); + + return 0; + } diff --git a/SOURCES/0080-journald-set-a-limit-on-the-number-of-fields-1k.patch b/SOURCES/0080-journald-set-a-limit-on-the-number-of-fields-1k.patch new file mode 100644 index 0000000..dca08e6 --- /dev/null +++ b/SOURCES/0080-journald-set-a-limit-on-the-number-of-fields-1k.patch @@ -0,0 +1,54 @@ +From 9f53d3cded6cf7eccb40c810dfb8fd6e101c7a3b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 22:45:02 +0100 +Subject: [PATCH] journald: set a limit on the number of fields (1k) + +We allocate a iovec entry for each field, so with many short entries, +our memory usage and processing time can be large, even with a relatively +small message size. Let's refuse overly long entries. + +CVE-2018-16865 +https://bugzilla.redhat.com/show_bug.cgi?id=1653861 + +What from I can see, the problem is not from an alloca, despite what the CVE +description says, but from the attack multiplication that comes from creating +many very small iovecs: (void* + size_t) for each three bytes of input message. + +(cherry-picked from commit 052c57f132f04a3cf4148f87561618da1a6908b4) + +Resolves: #1664977 +--- + src/journal/journal-file.h | 3 +++ + src/journal/journald-native.c | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h +index c8114ee2d0..cd8a48a364 100644 +--- a/src/journal/journal-file.h ++++ b/src/journal/journal-file.h +@@ -165,6 +165,9 @@ int journal_file_open_reliably( + * files without adding too many zeros. */ + #define OFSfmt "%06"PRIx64 + ++/* The maximum number of fields in an entry */ ++#define ENTRY_FIELD_COUNT_MAX 1024 ++ + static inline bool VALID_REALTIME(uint64_t u) { + /* This considers timestamps until the year 3112 valid. That should be plenty room... */ + return u > 0 && u < (1ULL << 55); +diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c +index 5ff22a10af..951d092053 100644 +--- a/src/journal/journald-native.c ++++ b/src/journal/journald-native.c +@@ -140,6 +140,11 @@ static int server_process_entry( + } + + /* A property follows */ ++ if (n > ENTRY_FIELD_COUNT_MAX) { ++ log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry."); ++ r = 1; ++ goto finish; ++ } + + /* n existing properties, 1 new, +1 for _TRANSPORT */ + if (!GREEDY_REALLOC(iovec, m, diff --git a/SOURCES/0081-journald-when-processing-a-native-message-bail-more-.patch b/SOURCES/0081-journald-when-processing-a-native-message-bail-more-.patch new file mode 100644 index 0000000..1f5f6c1 --- /dev/null +++ b/SOURCES/0081-journald-when-processing-a-native-message-bail-more-.patch @@ -0,0 +1,205 @@ +From ed028441cc2ef0ffb9771d7266d40f18910f0ae1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 22:50:39 +0100 +Subject: [PATCH] journald: when processing a native message, bail more quickly + on overbig messages + +We'd first parse all or most of the message, and only then consider if it +is not too large. Also, when encountering a single field over the limit, +we'd still process the preceding part of the message. Let's be stricter, +and check size limits early, and let's refuse the whole message if it fails +any of the size limits. + +(cherry-picked from commit 964ef920ea6735d39f856b05fd8ef451a09a6a1d) + +Related: #1664977 +--- + src/journal/journald-native.c | 65 ++++++++++++++++++++--------------- + 1 file changed, 37 insertions(+), 28 deletions(-) + +diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c +index 951d092053..110ab3641c 100644 +--- a/src/journal/journald-native.c ++++ b/src/journal/journald-native.c +@@ -109,7 +109,7 @@ static int server_process_entry( + int priority = LOG_INFO; + pid_t object_pid = 0; + const char *p; +- int r = 0; ++ int r = 1; + + p = buffer; + +@@ -121,8 +121,7 @@ static int server_process_entry( + if (!e) { + /* Trailing noise, let's ignore it, and flush what we collected */ + log_debug("Received message with trailing noise, ignoring."); +- r = 1; /* finish processing of the message */ +- break; ++ break; /* finish processing of the message */ + } + + if (e == p) { +@@ -132,8 +131,7 @@ static int server_process_entry( + } + + if (IN_SET(*p, '.', '#')) { +- /* Ignore control commands for now, and +- * comments too. */ ++ /* Ignore control commands for now, and comments too. */ + *remaining -= (e - p) + 1; + p = e + 1; + continue; +@@ -142,7 +140,6 @@ static int server_process_entry( + /* A property follows */ + if (n > ENTRY_FIELD_COUNT_MAX) { + log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry."); +- r = 1; + goto finish; + } + +@@ -152,7 +149,7 @@ static int server_process_entry( + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS + + client_context_extra_fields_n_iovec(context))) { + r = log_oom(); +- break; ++ goto finish; + } + + q = memchr(p, '=', e - p); +@@ -161,6 +158,16 @@ static int server_process_entry( + size_t l; + + l = e - p; ++ if (l > DATA_SIZE_MAX) { ++ log_debug("Received text block of %zu bytes is too large, ignoring entry.", l); ++ goto finish; ++ } ++ ++ if (entry_size + l + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */ ++ log_debug("Entry is too big (%zu bytes after processing %zu entries), ignoring entry.", ++ entry_size + l, n + 1); ++ goto finish; ++ } + + /* If the field name starts with an underscore, skip the variable, since that indicates + * a trusted field */ +@@ -178,7 +185,7 @@ static int server_process_entry( + p = e + 1; + continue; + } else { +- uint64_t l; ++ uint64_t l, total; + char *k; + + if (*remaining < e - p + 1 + sizeof(uint64_t) + 1) { +@@ -187,10 +194,16 @@ static int server_process_entry( + } + + l = unaligned_read_le64(e + 1); +- + if (l > DATA_SIZE_MAX) { +- log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l); +- break; ++ log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring entry.", l); ++ goto finish; ++ } ++ ++ total = (e - p) + 1 + l; ++ if (entry_size + total + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */ ++ log_debug("Entry is too big (%"PRIu64"bytes after processing %zu fields), ignoring.", ++ entry_size + total, n + 1); ++ goto finish; + } + + if ((uint64_t) *remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || +@@ -199,7 +212,7 @@ static int server_process_entry( + break; + } + +- k = malloc((e - p) + 1 + l); ++ k = malloc(total); + if (!k) { + log_oom(); + break; +@@ -228,15 +241,8 @@ static int server_process_entry( + } + } + +- if (n <= 0) { +- r = 1; ++ if (n <= 0) + goto finish; +- } +- +- if (!client_context_test_priority(context, priority)) { +- r = 0; +- goto finish; +- } + + tn = n++; + iovec[tn] = IOVEC_MAKE_STRING("_TRANSPORT=journal"); +@@ -247,6 +253,11 @@ static int server_process_entry( + goto finish; + } + ++ r = 0; /* Success, we read the message. */ ++ ++ if (!client_context_test_priority(context, priority)) ++ goto finish; ++ + if (message) { + if (s->forward_to_syslog) + server_forward_syslog(s, syslog_fixup_facility(priority), identifier, message, ucred, tv); +@@ -318,15 +329,13 @@ void server_process_native_file( + bool sealed; + int r; + +- /* Data is in the passed fd, since it didn't fit in a +- * datagram. */ ++ /* Data is in the passed fd, probably it didn't fit in a datagram. */ + + assert(s); + assert(fd >= 0); + + /* If it's a memfd, check if it is sealed. If so, we can just +- * use map it and use it, and do not need to copy the data +- * out. */ ++ * mmap it and use it, and do not need to copy the data out. */ + sealed = memfd_get_sealed(fd) > 0; + + if (!sealed && (!ucred || ucred->uid != 0)) { +@@ -397,7 +406,7 @@ void server_process_native_file( + ssize_t n; + + if (fstatvfs(fd, &vfs) < 0) { +- log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m"); ++ log_error_errno(errno, "Failed to stat file system of passed file, not processing it: %m"); + return; + } + +@@ -407,7 +416,7 @@ void server_process_native_file( + * https://github.com/systemd/systemd/issues/1822 + */ + if (vfs.f_flag & ST_MANDLOCK) { +- log_error("Received file descriptor from file system with mandatory locking enabled, refusing."); ++ log_error("Received file descriptor from file system with mandatory locking enabled, not processing it."); + return; + } + +@@ -420,13 +429,13 @@ void server_process_native_file( + * and so is SMB. */ + r = fd_nonblock(fd, true); + if (r < 0) { +- log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m"); ++ log_error_errno(r, "Failed to make fd non-blocking, not processing it: %m"); + return; + } + + /* The file is not sealed, we can't map the file here, since + * clients might then truncate it and trigger a SIGBUS for +- * us. So let's stupidly read it */ ++ * us. So let's stupidly read it. */ + + p = malloc(st.st_size); + if (!p) { diff --git a/SOURCES/0082-journald-lower-the-maximum-entry-size-limit-to-for-n.patch b/SOURCES/0082-journald-lower-the-maximum-entry-size-limit-to-for-n.patch new file mode 100644 index 0000000..0a61460 --- /dev/null +++ b/SOURCES/0082-journald-lower-the-maximum-entry-size-limit-to-for-n.patch @@ -0,0 +1,37 @@ +From a4d1779b5ee28b1c27c509a1baebf881943cad1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 5 Dec 2018 22:52:53 +0100 +Subject: [PATCH] =?UTF-8?q?journald:=20lower=20the=20maximum=20entry=20siz?= + =?UTF-8?q?e=20limit=20to=20=C2=BD=20for=20non-sealed=20fds?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We immediately read the whole contents into memory, making thigs much more +expensive. Sealed fds should be used instead since they are more efficient +on our side. + +(cherry-picked from commit 6670c9de196c8e2d5e84a8890cbb68f70c4db6e3) + +Related: #1664977 +--- + src/journal/journald-native.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c +index 110ab3641c..da62448ca6 100644 +--- a/src/journal/journald-native.c ++++ b/src/journal/journald-native.c +@@ -380,8 +380,10 @@ void server_process_native_file( + if (st.st_size <= 0) + return; + +- if (st.st_size > ENTRY_SIZE_MAX) { +- log_error("File passed too large. Ignoring."); ++ /* When !sealed, set a lower memory limit. We have to read the file, ++ * effectively doubling memory use. */ ++ if (st.st_size > ENTRY_SIZE_MAX / (sealed ? 1 : 2)) { ++ log_error("File passed too large (%"PRIu64" bytes). Ignoring.", (uint64_t) st.st_size); + return; + } + diff --git a/SOURCES/0083-httpd-use-a-cleanup-function-to-call-MHD_destroy_res.patch b/SOURCES/0083-httpd-use-a-cleanup-function-to-call-MHD_destroy_res.patch new file mode 100644 index 0000000..bf124e4 --- /dev/null +++ b/SOURCES/0083-httpd-use-a-cleanup-function-to-call-MHD_destroy_res.patch @@ -0,0 +1,198 @@ +From c9290315ce840ed1001b897220f3f733811ffc66 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Dec 2018 12:13:10 +0100 +Subject: [PATCH] =?UTF-8?q?=C2=B5httpd:=20use=20a=20cleanup=20function=20t?= + =?UTF-8?q?o=20call=20MHD=5Fdestroy=5Fresponse?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +(cherry-picked from commit d101fb24eb1c58c97f2adce1f69f4b61a788933a) + +Related: #1664977 +--- + src/journal-remote/journal-gatewayd.c | 53 +++++++-------------------- + src/journal-remote/microhttpd-util.c | 11 ++---- + src/journal-remote/microhttpd-util.h | 2 + + 3 files changed, 19 insertions(+), 47 deletions(-) + +diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c +index 9e77e314ff..3a167ab890 100644 +--- a/src/journal-remote/journal-gatewayd.c ++++ b/src/journal-remote/journal-gatewayd.c +@@ -451,7 +451,7 @@ static int request_handler_entries( + struct MHD_Connection *connection, + void *connection_cls) { + +- struct MHD_Response *response; ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL; + RequestMeta *m = connection_cls; + int r; + +@@ -493,11 +493,7 @@ static int request_handler_entries( + return respond_oom(connection); + + MHD_add_response_header(response, "Content-Type", mime_types[m->mode]); +- +- r = MHD_queue_response(connection, MHD_HTTP_OK, response); +- MHD_destroy_response(response); +- +- return r; ++ return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + + static int output_field(FILE *f, OutputMode m, const char *d, size_t l) { +@@ -609,7 +605,7 @@ static int request_handler_fields( + const char *field, + void *connection_cls) { + +- struct MHD_Response *response; ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL; + RequestMeta *m = connection_cls; + int r; + +@@ -632,11 +628,7 @@ static int request_handler_fields( + return respond_oom(connection); + + MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]); +- +- r = MHD_queue_response(connection, MHD_HTTP_OK, response); +- MHD_destroy_response(response); +- +- return r; ++ return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + + static int request_handler_redirect( +@@ -644,8 +636,7 @@ static int request_handler_redirect( + const char *target) { + + char *page; +- struct MHD_Response *response; +- int ret; ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL; + + assert(connection); + assert(target); +@@ -661,11 +652,7 @@ static int request_handler_redirect( + + MHD_add_response_header(response, "Content-Type", "text/html"); + MHD_add_response_header(response, "Location", target); +- +- ret = MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response); +- MHD_destroy_response(response); +- +- return ret; ++ return MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response); + } + + static int request_handler_file( +@@ -673,8 +660,7 @@ static int request_handler_file( + const char *path, + const char *mime_type) { + +- struct MHD_Response *response; +- int ret; ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL; + _cleanup_close_ int fd = -1; + struct stat st; + +@@ -692,15 +678,10 @@ static int request_handler_file( + response = MHD_create_response_from_fd_at_offset64(st.st_size, fd, 0); + if (!response) + return respond_oom(connection); +- +- fd = -1; ++ TAKE_FD(fd); + + MHD_add_response_header(response, "Content-Type", mime_type); +- +- ret = MHD_queue_response(connection, MHD_HTTP_OK, response); +- MHD_destroy_response(response); +- +- return ret; ++ return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + + static int get_virtualization(char **v) { +@@ -737,14 +718,13 @@ static int request_handler_machine( + struct MHD_Connection *connection, + void *connection_cls) { + +- struct MHD_Response *response; ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL; + RequestMeta *m = connection_cls; + int r; + _cleanup_free_ char* hostname = NULL, *os_name = NULL; + uint64_t cutoff_from = 0, cutoff_to = 0, usage = 0; +- char *json; + sd_id128_t mid, bid; +- _cleanup_free_ char *v = NULL; ++ _cleanup_free_ char *v = NULL, *json = NULL; + + assert(connection); + assert(m); +@@ -793,21 +773,16 @@ static int request_handler_machine( + usage, + cutoff_from, + cutoff_to); +- + if (r < 0) + return respond_oom(connection); + + response = MHD_create_response_from_buffer(strlen(json), json, MHD_RESPMEM_MUST_FREE); +- if (!response) { +- free(json); ++ if (!response) + return respond_oom(connection); +- } ++ TAKE_PTR(json); + + MHD_add_response_header(response, "Content-Type", "application/json"); +- r = MHD_queue_response(connection, MHD_HTTP_OK, response); +- MHD_destroy_response(response); +- +- return r; ++ return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + + static int request_handler( +diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c +index 34dd9ea555..2ae5172fe9 100644 +--- a/src/journal-remote/microhttpd-util.c ++++ b/src/journal-remote/microhttpd-util.c +@@ -32,21 +32,16 @@ static int mhd_respond_internal(struct MHD_Connection *connection, + const char *buffer, + size_t size, + enum MHD_ResponseMemoryMode mode) { +- struct MHD_Response *response; +- int r; +- + assert(connection); + +- response = MHD_create_response_from_buffer(size, (char*) buffer, mode); ++ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response ++ = MHD_create_response_from_buffer(size, (char*) buffer, mode); + if (!response) + return MHD_NO; + + log_debug("Queueing response %u: %s", code, buffer); + MHD_add_response_header(response, "Content-Type", "text/plain"); +- r = MHD_queue_response(connection, code, response); +- MHD_destroy_response(response); +- +- return r; ++ return MHD_queue_response(connection, code, response); + } + + int mhd_respond(struct MHD_Connection *connection, +diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h +index a50a2a75c7..26909082a1 100644 +--- a/src/journal-remote/microhttpd-util.h ++++ b/src/journal-remote/microhttpd-util.h +@@ -73,3 +73,5 @@ int check_permissions(struct MHD_Connection *connection, int *code, char **hostn + * interesting events without overwhelming detail. + */ + int setup_gnutls_logger(char **categories); ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct MHD_Response*, MHD_destroy_response); diff --git a/SOURCES/0084-journal-remote-verify-entry-length-from-header.patch b/SOURCES/0084-journal-remote-verify-entry-length-from-header.patch new file mode 100644 index 0000000..13ec049 --- /dev/null +++ b/SOURCES/0084-journal-remote-verify-entry-length-from-header.patch @@ -0,0 +1,109 @@ +From ad18012c46724aa097f37015a8036a4343206efe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Dec 2018 12:47:14 +0100 +Subject: [PATCH] journal-remote: verify entry length from header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Calling mhd_respond(), which ulimately calls MHD_queue_response() is +ineffective at point, becuase MHD_queue_response() immediately returns +MHD_NO signifying an error, because the connection is in state +MHD_CONNECTION_CONTINUE_SENT. + +As Christian Grothoff kindly explained: +> You are likely calling MHD_queue_repsonse() too late: once you are +> receiving upload_data, HTTP forces you to process it all. At this time, +> MHD has already sent "100 continue" and cannot take it back (hence you +> get MHD_NO!). +> +> In your request handler, the first time when you are called for a +> connection (and when hence *upload_data_size == 0 and upload_data == +> NULL) you must check the content-length header and react (with +> MHD_queue_response) based on this (to prevent MHD from automatically +> generating 100 continue). + +If we ever encounter this kind of error, print a warning and immediately +abort the connection. (The alternative would be to keep reading the data, +but ignore it, and return an error after we get to the end of data. +That is possible, but of course puts additional load on both the +sender and reciever, and doesn't seem important enough just to return +a good error message.) + +Note that sending of the error does not work (the connection is always aborted +when MHD_queue_response is used with MHD_RESPMEM_MUST_FREE, as in this case) +with libµhttpd 0.59, but works with 0.61: +https://src.fedoraproject.org/rpms/libmicrohttpd/pull-request/1 + +(cherry-picked from commit 7fdb237f5473cb8fc2129e57e8a0039526dcb4fd) + +Related: #1664977 +--- + src/journal-remote/journal-remote-main.c | 34 +++++++++++++++++------- + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c +index 8fda9d1499..e9b3702e8a 100644 +--- a/src/journal-remote/journal-remote-main.c ++++ b/src/journal-remote/journal-remote-main.c +@@ -210,16 +210,14 @@ static int process_http_upload( + journal_remote_server_global->seal); + if (r == -EAGAIN) + break; +- else if (r < 0) { +- log_warning("Failed to process data for connection %p", connection); ++ if (r < 0) { + if (r == -E2BIG) +- return mhd_respondf(connection, +- r, MHD_HTTP_PAYLOAD_TOO_LARGE, +- "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes."); ++ log_warning_errno(r, "Entry is too above maximum of %u, aborting connection %p.", ++ DATA_SIZE_MAX, connection); + else +- return mhd_respondf(connection, +- r, MHD_HTTP_UNPROCESSABLE_ENTITY, +- "Processing failed: %m."); ++ log_warning_errno(r, "Failed to process data, aborting connection %p: %m", ++ connection); ++ return MHD_NO; + } + } + +@@ -253,6 +251,7 @@ static int request_handler( + const char *header; + int r, code, fd; + _cleanup_free_ char *hostname = NULL; ++ size_t len; + + assert(connection); + assert(connection_cls); +@@ -272,12 +271,27 @@ static int request_handler( + if (!streq(url, "/upload")) + return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found."); + +- header = MHD_lookup_connection_value(connection, +- MHD_HEADER_KIND, "Content-Type"); ++ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Type"); + if (!header || !streq(header, "application/vnd.fdo.journal")) + return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE, + "Content-Type: application/vnd.fdo.journal is required."); + ++ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length"); ++ if (!header) ++ return mhd_respond(connection, MHD_HTTP_LENGTH_REQUIRED, ++ "Content-Length header is required."); ++ r = safe_atozu(header, &len); ++ if (r < 0) ++ return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED, ++ "Content-Length: %s cannot be parsed: %m", header); ++ ++ if (len > ENTRY_SIZE_MAX) ++ /* When serialized, an entry of maximum size might be slightly larger, ++ * so this does not correspond exactly to the limit in journald. Oh well. ++ */ ++ return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE, ++ "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX); ++ + { + const union MHD_ConnectionInfo *ci; + diff --git a/SOURCES/0085-journal-remote-set-a-limit-on-the-number-of-fields-i.patch b/SOURCES/0085-journal-remote-set-a-limit-on-the-number-of-fields-i.patch new file mode 100644 index 0000000..6ba3347 --- /dev/null +++ b/SOURCES/0085-journal-remote-set-a-limit-on-the-number-of-fields-i.patch @@ -0,0 +1,56 @@ +From fde3fa3e9c0330c7de645ce2140f9dd39640a693 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Dec 2018 10:48:10 +0100 +Subject: [PATCH] journal-remote: set a limit on the number of fields in a + message + +Existing use of E2BIG is replaced with ENOBUFS (entry too long), and E2BIG is +reused for the new error condition (too many fields). + +This matches the change done for systemd-journald, hence forming the second +part of the fix for CVE-2018-16865 +(https://bugzilla.redhat.com/show_bug.cgi?id=1653861). + +(cherry-picked from commit ef4d6abe7c7fab6cbff975b32e76b09feee56074) + +Resolves: #1664977 +--- + src/journal-remote/journal-remote-main.c | 7 +++++-- + src/journal-remote/journal-remote.c | 5 ++++- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c +index e9b3702e8a..5b0bbba310 100644 +--- a/src/journal-remote/journal-remote-main.c ++++ b/src/journal-remote/journal-remote-main.c +@@ -211,9 +211,12 @@ static int process_http_upload( + if (r == -EAGAIN) + break; + if (r < 0) { +- if (r == -E2BIG) +- log_warning_errno(r, "Entry is too above maximum of %u, aborting connection %p.", ++ if (r == -ENOBUFS) ++ log_warning_errno(r, "Entry is above the maximum of %u, aborting connection %p.", + DATA_SIZE_MAX, connection); ++ else if (r == -E2BIG) ++ log_warning_errno(r, "Entry with more fields than the maximum of %u, aborting connection %p.", ++ ENTRY_FIELD_COUNT_MAX, connection); + else + log_warning_errno(r, "Failed to process data, aborting connection %p: %m", + connection); +diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c +index beb75a1cb4..67e3a70c06 100644 +--- a/src/journal-remote/journal-remote.c ++++ b/src/journal-remote/journal-remote.c +@@ -408,7 +408,10 @@ int journal_remote_handle_raw_source( + log_debug("%zu active sources remaining", s->active); + return 0; + } else if (r == -E2BIG) { +- log_notice_errno(E2BIG, "Entry too big, skipped"); ++ log_notice("Entry with too many fields, skipped"); ++ return 1; ++ } else if (r == -ENOBUFS) { ++ log_notice("Entry too big, skipped"); + return 1; + } else if (r == -EAGAIN) { + return 0; diff --git a/SOURCES/0086-journald-correctly-attribute-log-messages-also-with-.patch b/SOURCES/0086-journald-correctly-attribute-log-messages-also-with-.patch new file mode 100644 index 0000000..f9463d5 --- /dev/null +++ b/SOURCES/0086-journald-correctly-attribute-log-messages-also-with-.patch @@ -0,0 +1,54 @@ +From 7c52627446e32df64ad4cd3ac56ad515d0233cea Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 14 Dec 2018 15:17:27 +0100 +Subject: [PATCH] journald: correctly attribute log messages also with + cgroupsv1 + +With cgroupsv1 a zombie process is migrated to root cgroup in all +hierarchies. This was changed for unified hierarchy and /proc/PID/cgroup +reports cgroup to which process belonged before it exited. + +Be more suspicious about cgroup path reported by the kernel and use +unit_id provided by the log client if the kernel reports that process is +running in the root cgroup. + +Users tend to care the most about 'log->unit_id' mapping so systemctl +status can correctly report last log lines. Also we wouldn't be able to +infer anything useful from "/" path anyway. + +See: https://github.com/torvalds/linux/commit/2e91fa7f6d451e3ea9fec999065d2fd199691f9d + +(cherry picked from commit 672773b63a4ebf95242b27e63071b93073ebc1f5) + +Resolves: #1658115 +--- + src/journal/journald-context.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c +index 51f79fd803..dba3525ed8 100644 +--- a/src/journal/journald-context.c ++++ b/src/journal/journald-context.c +@@ -13,6 +13,8 @@ + #include "io-util.h" + #include "journal-util.h" + #include "journald-context.h" ++#include "parse-util.h" ++#include "path-util.h" + #include "process-util.h" + #include "procfs-util.h" + #include "string-util.h" +@@ -281,9 +283,11 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u + + /* Try to acquire the current cgroup path */ + r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t); +- if (r < 0) { ++ if (r < 0 || empty_or_root(t)) { + +- /* If that didn't work, we use the unit ID passed in as fallback, if we have nothing cached yet */ ++ /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted() ++ * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup ++ * on cgroupsv1 and we want to be able to map log messages from them too. */ + if (unit_id && !c->unit) { + c->unit = strdup(unit_id); + if (c->unit) diff --git a/SOURCES/0087-test-replace-echo-with-socat.patch b/SOURCES/0087-test-replace-echo-with-socat.patch new file mode 100644 index 0000000..bbd76ed --- /dev/null +++ b/SOURCES/0087-test-replace-echo-with-socat.patch @@ -0,0 +1,50 @@ +From bf7631e7c0a7d1cac2f071ce998d5c669aa5abd7 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 29 Jan 2019 19:33:15 +0100 +Subject: [PATCH] test: replace echo with socat + +The original version of the test used netcat along with a standard +AF_UNIX socket, which caused issues across different netcat +implementations. The AF_UNIX socket was then replaced by a FIFO with a +simple echo, which, however, suffers from the same issue (some echo +implementations don't check if the write() was successful). + +Let's revert back to the AF_UNIX socket, but replace netcat with socat, +which, hopefully, resolves the main issue. + +Relevant commit: 9b45c2bf02a43e3e1b42de1ab0c3fe29c64dc5f5 + +(cherry picked from commit b35d6d828b3216d022e565820d9971cb0f7746c1) +--- + test/TEST-10-ISSUE-2467/test.sh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh +index e61f5acd3c..0e61236686 100755 +--- a/test/TEST-10-ISSUE-2467/test.sh ++++ b/test/TEST-10-ISSUE-2467/test.sh +@@ -17,7 +17,7 @@ test_setup() { + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment +- dracut_install true rm ++ dracut_install true rm socat + + # setup the testsuite service + cat >$initdir/etc/systemd/system/testsuite.service <<'EOF' +@@ -29,13 +29,13 @@ After=multi-user.target + Type=oneshot + StandardOutput=tty + StandardError=tty +-ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo > /run/test.ctl; >/testok' ++ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; printf x > test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok' + TimeoutStartSec=10s + EOF + + cat >$initdir/etc/systemd/system/test.socket <<'EOF' + [Socket] +-ListenFIFO=/run/test.ctl ++ListenStream=/run/test.ctl + EOF + + cat > $initdir/etc/systemd/system/test.service <<'EOF' diff --git a/SOURCES/0088-test-network-ignore-tunnel-devices-automatically-add.patch b/SOURCES/0088-test-network-ignore-tunnel-devices-automatically-add.patch new file mode 100644 index 0000000..6ec6833 --- /dev/null +++ b/SOURCES/0088-test-network-ignore-tunnel-devices-automatically-add.patch @@ -0,0 +1,25 @@ +From ce123e87018b0345f1027950397f8556bfabb622 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 6 Feb 2019 12:02:15 +0100 +Subject: [PATCH] test-network: ignore tunnel devices automatically added by + kernel + +Fixes #10934. + +(cherry picked from commit e327272d795453f68a4c30ba21eb0e887516cf68) +--- + test/test-execute/exec-privatenetwork-yes.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service +index a38d24912f..8f5cbadf04 100644 +--- a/test/test-execute/exec-privatenetwork-yes.service ++++ b/test/test-execute/exec-privatenetwork-yes.service +@@ -2,6 +2,6 @@ + Description=Test for PrivateNetwork + + [Service] +-ExecStart=/bin/sh -x -c '! ip link | grep ": " | grep -Ev ": (lo|sit0@.*):"' ++ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"' + Type=oneshot + PrivateNetwork=yes diff --git a/SOURCES/0089-rules-add-elevator-kernel-command-line-parameter.patch b/SOURCES/0089-rules-add-elevator-kernel-command-line-parameter.patch new file mode 100644 index 0000000..e289826 --- /dev/null +++ b/SOURCES/0089-rules-add-elevator-kernel-command-line-parameter.patch @@ -0,0 +1,42 @@ +From 1255584bb0a595fb555af7e14230ab1b7aa6adcd Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 12 Feb 2019 16:58:16 +0100 +Subject: [PATCH] rules: add elevator= kernel command line parameter + +Kernel removed the elevator= option, so let's reintroduce +it for rhel8 via udev rule. + +rhel-only +Resolves: #1670126 +--- + rules/40-elevator.rules | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + create mode 100644 rules/40-elevator.rules + +diff --git a/rules/40-elevator.rules b/rules/40-elevator.rules +new file mode 100644 +index 0000000000..dbe8fc81a4 +--- /dev/null ++++ b/rules/40-elevator.rules +@@ -0,0 +1,20 @@ ++# We aren't adding devices skip the elevator check ++ACTION!="add", GOTO="sched_out" ++ ++SUBSYSTEM!="block", GOTO="sched_out" ++ENV{DEVTYPE}!="disk", GOTO="sched_out" ++ ++# Technically, dm-multipath can be configured to use an I/O scheduler. ++# However, there are races between the 'add' uevent and the linking in ++# of the queue/scheduler sysfs file. For now, just skip dm- devices. ++KERNEL=="dm-*|md*", GOTO="sched_out" ++ ++# Skip bio-based devices, which don't support an I/O scheduler. ++ATTR{queue/scheduler}=="none", GOTO="sched_out" ++ ++# If elevator= is specified on the kernel command line, change the ++# scheduler to the one specified. ++IMPORT{cmdline}="elevator" ++ENV{elevator}!="", ATTR{queue/scheduler}="$env{elevator}" ++ ++LABEL="sched_out" +\ No newline at end of file diff --git a/SOURCES/0090-rule-syntax-check-allow-PROGRAM-as-an-assignment.patch b/SOURCES/0090-rule-syntax-check-allow-PROGRAM-as-an-assignment.patch new file mode 100644 index 0000000..e7de777 --- /dev/null +++ b/SOURCES/0090-rule-syntax-check-allow-PROGRAM-as-an-assignment.patch @@ -0,0 +1,33 @@ +From 1dd326b6dd0a23d1a9ee1c567962c6d5d4ef03ca Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 30 Jan 2019 12:22:41 +0100 +Subject: [PATCH] rule-syntax-check: allow PROGRAM as an assignment + +(cherry picked from commit ed2dc503da57b0110819563e0d1c85d023435e07) +--- + test/rule-syntax-check.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py +index 706d93632e..c7c0a1a656 100755 +--- a/test/rule-syntax-check.py ++++ b/test/rule-syntax-check.py +@@ -17,6 +17,8 @@ if not rules_files: + + quoted_string_re = r'"(?:[^\\"]|\\.)*"' + no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$') ++# PROGRAM can also be specified as an assignment. ++program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$') + args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$') + no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$') + args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$') +@@ -51,7 +53,8 @@ for path in rules_files: + for clause_match in comma_separated_group_re.finditer(line): + clause = clause_match.group().strip() + if not (no_args_tests.match(clause) or args_tests.match(clause) or +- no_args_assign.match(clause) or args_assign.match(clause)): ++ no_args_assign.match(clause) or args_assign.match(clause) or ++ program_assign.match(clause)): + + print('Invalid line {}:{}: {}'.format(path, lineno, line)) + print(' clause:', clause) diff --git a/SOURCES/0091-rules-implement-new-memory-hotplug-policy.patch b/SOURCES/0091-rules-implement-new-memory-hotplug-policy.patch new file mode 100644 index 0000000..6df4d74 --- /dev/null +++ b/SOURCES/0091-rules-implement-new-memory-hotplug-policy.patch @@ -0,0 +1,50 @@ +From c95026c6979bb6f8dc52a6392318bc16615ace77 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 30 Jan 2019 10:36:53 +0100 +Subject: [PATCH] rules: implement new memory hotplug policy + +Our new policy is based on following motivations (assumptions), + * we want to allow the system to use hotplugged memory + * we want memory ballon inflation to work as expected in VMs (going for small + to big in terms of memory footprint) + * we want to allow memory hotplug and memory hot-unplug on high-end + enterprise server (we assume that node0 will have sufficient memory + resources and marking all memory as movable shouldn't be a problem) + +Policy: + * nevert online memory on s390 (on both physical and z/VM) + * mark memory as "online_movable" on physical machines + * mark memory as "online" in VMs + +If you have the feeling that all this is very wrong and we shouldn't +encode complex policies in udev rules you are absolutely right. However, +for now, we don't have any better place where to put it. In ideal world +we would have a user-space daemon that would be able to configure the +system wrt. to currently present HW and user-defined policy. + +Resolves: #1670728 +--- + rules/40-redhat.rules | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 8ac96933c3..17b33682bd 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -4,7 +4,15 @@ + SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1" + + # Memory hotadd request +-SUBSYSTEM=="memory", ACTION=="add", PROGRAM=="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online" ++SUBSYSTEM!="memory", GOTO="memory_hotplug_end" ++ACTION!="add", GOTO="memory_hotplug_end" ++PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end" ++ ++ENV{.state}="online" ++PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable" ++ATTR{state}=="offline", ATTR{state}="$env{.state}" ++ ++LABEL="memory_hotplug_end" + + # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded + ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge" diff --git a/SOURCES/0092-LGTM-make-LGTM.com-use-meson-from-pip.patch b/SOURCES/0092-LGTM-make-LGTM.com-use-meson-from-pip.patch new file mode 100644 index 0000000..5f0f220 --- /dev/null +++ b/SOURCES/0092-LGTM-make-LGTM.com-use-meson-from-pip.patch @@ -0,0 +1,27 @@ +From 9123fecee040fc961905f5c2e56152443907015a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 24 Jul 2018 01:37:29 +0900 +Subject: [PATCH] LGTM: make LGTM.com use meson from pip + +(cherry picked from commit 55d651d8f69919b98cdc062e312e4454c34428ef) +--- + .lgtm.yml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + create mode 100644 .lgtm.yml + +diff --git a/.lgtm.yml b/.lgtm.yml +new file mode 100644 +index 0000000000..37f9c4335c +--- /dev/null ++++ b/.lgtm.yml +@@ -0,0 +1,10 @@ ++extraction: ++ cpp: ++ prepare: ++ packages: ++ - python3-pip ++ - python3-setuptools ++ - python3-wheel ++ after_prepare: ++ - pip3 install meson ++ - export PATH="$HOME/.local/bin/:$PATH" diff --git a/SOURCES/0093-lgtm-use-python3.patch b/SOURCES/0093-lgtm-use-python3.patch new file mode 100644 index 0000000..f6913c7 --- /dev/null +++ b/SOURCES/0093-lgtm-use-python3.patch @@ -0,0 +1,21 @@ +From dbb6c3db4a9e38dd13525b073b2de1b5eac0ef7d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 8 Dec 2018 20:51:56 +0900 +Subject: [PATCH] lgtm: use python3 + +(cherry picked from commit fc1c09e1dfd2073fb49c4e7bb87102c88a551876) +--- + .lgtm.yml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/.lgtm.yml b/.lgtm.yml +index 37f9c4335c..5948d8c2bc 100644 +--- a/.lgtm.yml ++++ b/.lgtm.yml +@@ -8,3 +8,6 @@ extraction: + after_prepare: + - pip3 install meson + - export PATH="$HOME/.local/bin/:$PATH" ++ python: ++ python_setup: ++ version: 3 diff --git a/SOURCES/0094-tools-use-print-function-in-Python-3-code.patch b/SOURCES/0094-tools-use-print-function-in-Python-3-code.patch new file mode 100644 index 0000000..cc654f7 --- /dev/null +++ b/SOURCES/0094-tools-use-print-function-in-Python-3-code.patch @@ -0,0 +1,73 @@ +From 5adeea95a7310d97b98821322b51794a46199417 Mon Sep 17 00:00:00 2001 +From: Lucas Werkmeister +Date: Sat, 25 Aug 2018 18:41:42 +0200 +Subject: [PATCH] tools: use print function in Python 3 code + +This GDB script was converted to use Python 3 along with all other +Python scripts in commit b95f5528cc, but still used the Python 2 print +statement syntax instead of the Python 3 print function. Fix that. + +We also add the Python 2 compatibility statement, just in case some GDB +still uses Python 2 instead of Python 3. +--- + tools/gdb-sd_dump_hashmaps.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py +index e6ddd14ea7..ea15160107 100644 +--- a/tools/gdb-sd_dump_hashmaps.py ++++ b/tools/gdb-sd_dump_hashmaps.py +@@ -2,6 +2,8 @@ + # -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ + # SPDX-License-Identifier: LGPL-2.1+ + ++from __future__ import print_function ++ + import gdb + + class sd_dump_hashmaps(gdb.Command): +@@ -19,7 +21,7 @@ class sd_dump_hashmaps(gdb.Command): + ulong_t = gdb.lookup_type("unsigned long") + debug_offset = gdb.parse_and_eval("(unsigned long)&((HashmapBase*)0)->debug") + +- print "type, hash, indirect, entries, max_entries, buckets, creator" ++ print("type, hash, indirect, entries, max_entries, buckets, creator") + while d: + h = gdb.parse_and_eval("(HashmapBase*)((char*)%d - %d)" % (int(d.cast(ulong_t)), debug_offset)) + +@@ -34,7 +36,7 @@ class sd_dump_hashmaps(gdb.Command): + + t = ["plain", "ordered", "set"][int(h["type"])] + +- print "{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"]) ++ print("{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"])) + + if arg != "" and n_entries > 0: + dib_raw_addr = storage_ptr + (all_entry_sizes[h["type"]] * n_buckets) +@@ -46,10 +48,10 @@ class sd_dump_hashmaps(gdb.Command): + + for dib in sorted(iter(histogram)): + if dib != 255: +- print "{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries) ++ print("{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries)) + else: +- print "{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets) +- print "mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries) ++ print("{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets)) ++ print("mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries)) + + blocks = [] + current_len = 1 +@@ -70,9 +72,9 @@ class sd_dump_hashmaps(gdb.Command): + if len(blocks) > 1 and blocks[0][0] == blocks[0][1] and blocks[-1][0] == n_buckets - 1: + blocks[0][1] += blocks[-1][1] + blocks = blocks[0:-1] +- print "max block: {}".format(max(blocks, key=lambda a: a[1])) +- print "sum block lens: {}".format(sum(b[1] for b in blocks)) +- print "mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks))) ++ print("max block: {}".format(max(blocks, key=lambda a: a[1]))) ++ print("sum block lens: {}".format(sum(b[1] for b in blocks))) ++ print("mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks)))) + + d = d["debug_list_next"] + diff --git a/SOURCES/0095-lgtm-add-a-custom-query-for-catching-the-use-of-fget.patch b/SOURCES/0095-lgtm-add-a-custom-query-for-catching-the-use-of-fget.patch new file mode 100644 index 0000000..5cd8a9f --- /dev/null +++ b/SOURCES/0095-lgtm-add-a-custom-query-for-catching-the-use-of-fget.patch @@ -0,0 +1,44 @@ +From c9fdcd0693ac63bc4b7326e248854617d9573bd6 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 26 Oct 2018 09:19:09 +0000 +Subject: [PATCH] lgtm: add a custom query for catching the use of fgets + +As everybody knows, nodoby really reads CODING_STYLE (especially +the last paragraph :-)) so let's utilize LGTM to help us catch the +use of fgets. + +(cherry picked from commit f86c1da28340f2a2afd34d72c9f416a2a94219a8) +--- + .lgtm/cpp-queries/fgets.ql | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + create mode 100644 .lgtm/cpp-queries/fgets.ql + +diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql +new file mode 100644 +index 0000000000..82de8c4482 +--- /dev/null ++++ b/.lgtm/cpp-queries/fgets.ql +@@ -0,0 +1,23 @@ ++/** ++ * @name Use of fgets() ++ * @description fgets() is dangerous to call. Use read_line() instead. ++ * @kind problem ++ * @problem.severity error ++ * @precision high ++ * @id cpp/fgets ++ * @tags reliability ++ * security ++ */ ++import cpp ++ ++ ++predicate dangerousFunction(Function function) { ++ exists (string name | name = function.getQualifiedName() | ++ name = "fgets") ++} ++ ++ ++from FunctionCall call, Function target ++where call.getTarget() = target ++ and dangerousFunction(target) ++select call, target.getQualifiedName() + " is potentially dangerous" diff --git a/SOURCES/0096-lgtm-drop-redundant-newlines.patch b/SOURCES/0096-lgtm-drop-redundant-newlines.patch new file mode 100644 index 0000000..933e01f --- /dev/null +++ b/SOURCES/0096-lgtm-drop-redundant-newlines.patch @@ -0,0 +1,28 @@ +From d26406cc3f2c186691ce0a09052d3c39d15cc722 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 26 Oct 2018 10:25:36 +0000 +Subject: [PATCH] lgtm: drop redundant newlines + +(cherry picked from commit 845702c63863add5606a7a7f00a959ffdcf89635) +--- + .lgtm/cpp-queries/fgets.ql | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql +index 82de8c4482..a4181e4f3d 100644 +--- a/.lgtm/cpp-queries/fgets.ql ++++ b/.lgtm/cpp-queries/fgets.ql +@@ -10,13 +10,11 @@ + */ + import cpp + +- + predicate dangerousFunction(Function function) { + exists (string name | name = function.getQualifiedName() | + name = "fgets") + } + +- + from FunctionCall call, Function target + where call.getTarget() = target + and dangerousFunction(target) diff --git a/SOURCES/0097-rules-add-the-rule-that-adds-elevator-kernel-command.patch b/SOURCES/0097-rules-add-the-rule-that-adds-elevator-kernel-command.patch new file mode 100644 index 0000000..c9a43e0 --- /dev/null +++ b/SOURCES/0097-rules-add-the-rule-that-adds-elevator-kernel-command.patch @@ -0,0 +1,24 @@ +From 16d1f6e5122038fa24392e166a0a88c6cab41dd0 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Tue, 26 Feb 2019 15:22:38 +0100 +Subject: [PATCH] rules: add the rule that adds elevator= kernel command line + parameter + +rhel-only +Resolves: #1670126 +--- + rules/meson.build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rules/meson.build b/rules/meson.build +index e04a18aca6..b6aae596b6 100644 +--- a/rules/meson.build ++++ b/rules/meson.build +@@ -2,6 +2,7 @@ + + rules = files(''' + 40-redhat.rules ++ 40-elevator.rules + 60-block.rules + 60-cdrom_id.rules + 60-drm.rules diff --git a/SOURCES/0098-test-add-TEST-24-UNIT-TESTS-running-all-basic-tests-.patch b/SOURCES/0098-test-add-TEST-24-UNIT-TESTS-running-all-basic-tests-.patch new file mode 100644 index 0000000..40c595d --- /dev/null +++ b/SOURCES/0098-test-add-TEST-24-UNIT-TESTS-running-all-basic-tests-.patch @@ -0,0 +1,176 @@ +From e4ff044489f43d2c7e1ecbdfb88692d87d63bd2a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 19 Sep 2018 14:30:29 +0900 +Subject: [PATCH] test: add TEST-24-UNIT-TESTS running all basic tests under + containers + +(cherry picked from commit 3f6f58e03a7d22154aabe036439e7f2fb4849570) +--- + test/TEST-24-UNIT-TESTS/Makefile | 1 + + test/TEST-24-UNIT-TESTS/test.sh | 106 +++++++++++++++++++++++++++ + test/TEST-24-UNIT-TESTS/testsuite.sh | 34 +++++++++ + 3 files changed, 141 insertions(+) + create mode 120000 test/TEST-24-UNIT-TESTS/Makefile + create mode 100755 test/TEST-24-UNIT-TESTS/test.sh + create mode 100755 test/TEST-24-UNIT-TESTS/testsuite.sh + +diff --git a/test/TEST-24-UNIT-TESTS/Makefile b/test/TEST-24-UNIT-TESTS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-24-UNIT-TESTS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-24-UNIT-TESTS/test.sh b/test/TEST-24-UNIT-TESTS/test.sh +new file mode 100755 +index 0000000000..014ee52277 +--- /dev/null ++++ b/test/TEST-24-UNIT-TESTS/test.sh +@@ -0,0 +1,106 @@ ++#!/bin/bash ++# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- ++# ex: ts=8 sw=4 sts=4 et filetype=sh ++set -e ++TEST_DESCRIPTION="Run unit tests under containers" ++RUN_IN_UNPRIVILEGED_CONTAINER=yes ++ ++. $TEST_BASE_DIR/test-functions ++ ++check_result_nspawn() { ++ local _ret=1 ++ [[ -e $TESTDIR/$1/testok ]] && _ret=0 ++ if [[ -s $TESTDIR/$1/failed ]]; then ++ _ret=$(($_ret+1)) ++ echo "=== Failed test log ===" ++ cat $TESTDIR/$1/failed ++ else ++ if [[ -s $TESTDIR/$1/skipped ]]; then ++ echo "=== Skipped test log ==" ++ cat $TESTDIR/$1/skipped ++ fi ++ if [[ -s $TESTDIR/$1/testok ]]; then ++ echo "=== Passed tests ===" ++ cat $TESTDIR/$1/testok ++ fi ++ fi ++ cp -a $TESTDIR/$1/var/log/journal $TESTDIR ++ [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) ++ return $_ret ++} ++ ++check_result_qemu() { ++ local _ret=1 ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ [[ -e $TESTDIR/root/testok ]] && _ret=0 ++ if [[ -s $TESTDIR/root/failed ]]; then ++ _ret=$(($_ret+1)) ++ echo "=== Failed test log ===" ++ cat $TESTDIR/root/failed ++ else ++ if [[ -s $TESTDIR/root/skipped ]]; then ++ echo "=== Skipped test log ==" ++ cat $TESTDIR/root/skipped ++ fi ++ if [[ -s $TESTDIR/root/testok ]]; then ++ echo "=== Passed tests ===" ++ cat $TESTDIR/root/testok ++ fi ++ fi ++ cp -a $TESTDIR/root/var/log/journal $TESTDIR ++ umount $TESTDIR/root ++ [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) ++ return $_ret ++} ++ ++test_setup() { ++ if type -P meson && [[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then ++ dfatal "Needs to be built with -Dinstall-tests=true" ++ exit 1 ++ fi ++ ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ # Create what will eventually be our root filesystem onto an overlay ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ for i in getfacl dirname basename capsh cut rev stat mktemp rmdir ionice unshare uname tr awk getent diff xzcat lz4cat; do ++ inst_binary $i ++ done ++ ++ inst /etc/hosts ++ ++ setup_basic_environment ++ install_keymaps yes ++ install_zoneinfo ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < /$NAME.log 2>&1 ++ ret=$? ++ if (( $ret && $ret != 77 )); then ++ echo "$NAME failed with $ret" ++ echo $NAME >> /failed-tests ++ echo "--- $NAME begin ---" >> /failed ++ cat /$NAME.log >> /failed ++ echo "--- $NAME end ---" >> /failed ++ elif (( $ret == 77 )); then ++ echo "$NAME skipped" ++ echo $NAME >> /skipped-tests ++ echo "--- $NAME begin ---" >> /skipped ++ cat /$NAME.log >> /skipped ++ echo "--- $NAME end ---" >> /skipped ++ else ++ echo "$NAME OK" ++ echo $NAME >> /testok ++ fi ++ ++ systemd-cat echo "--- $NAME ---" ++ systemd-cat cat /$NAME.log ++done ++ ++exit 0 diff --git a/SOURCES/0099-tests-create-the-asan-wrapper-automatically-if-syste.patch b/SOURCES/0099-tests-create-the-asan-wrapper-automatically-if-syste.patch new file mode 100644 index 0000000..ee842ff --- /dev/null +++ b/SOURCES/0099-tests-create-the-asan-wrapper-automatically-if-syste.patch @@ -0,0 +1,53 @@ +From 34a38e3632fc504b55847fb9658788ccf5d42dad Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Thu, 5 Jul 2018 04:09:30 +0000 +Subject: [PATCH] tests: create the asan wrapper automatically if systemd has + been built with ASAN + +(cherry picked from commit ec9181d2ce4c0ad8b1c70b16a2b02a2667b1cc05) +--- + test/test-functions | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index e69420aeca..4417301be9 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -28,6 +28,27 @@ STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" + STATEFILE="$STATEDIR/.testdir" + TESTLOG="$STATEDIR/test.log" + ++is_built_with_asan() { ++ if ! type -P objdump >/dev/null; then ++ ddebug "Failed to find objdump. Assuming systemd hasn't been built with ASAN." ++ return 1 ++ fi ++ ++ # Borrowed from https://github.com/google/oss-fuzz/blob/cd9acd02f9d3f6e80011cc1e9549be526ce5f270/infra/base-images/base-runner/bad_build_check#L182 ++ local _asan_calls=$(objdump -dC $BUILD_DIR/systemd | egrep "callq\s+[0-9a-f]+\s+<__asan" -c) ++ if (( $_asan_calls < 1000 )); then ++ return 1 ++ else ++ return 0 ++ fi ++} ++ ++IS_BUILT_WITH_ASAN=$(is_built_with_asan && echo yes || echo no) ++ ++if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then ++ STRIP_BINARIES=no ++fi ++ + function find_qemu_bin() { + # SUSE and Red Hat call the binary qemu-kvm. Debian and Gentoo call it kvm. + # Either way, only use this version if we aren't running in KVM, because +@@ -217,6 +238,9 @@ setup_basic_environment() { + strip_binaries + install_depmod_files + generate_module_dependencies ++ if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then ++ create_asan_wrapper ++ fi + } + + setup_selinux() { diff --git a/SOURCES/0100-tests-add-a-wrapper-for-when-systemd-is-built-with-A.patch b/SOURCES/0100-tests-add-a-wrapper-for-when-systemd-is-built-with-A.patch new file mode 100644 index 0000000..0d49374 --- /dev/null +++ b/SOURCES/0100-tests-add-a-wrapper-for-when-systemd-is-built-with-A.patch @@ -0,0 +1,63 @@ +From 3d0342f0c47c293f10d417ba429ff50436d30ddb Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Tue, 3 Jul 2018 03:25:53 +0000 +Subject: [PATCH] tests: add a wrapper for when systemd is built with ASAN + +(cherry picked from commit 1786fae3668fa94359ee58a8c11031dc46459255) +--- + test/test-functions | 35 ++++++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index 4417301be9..a6f88e4545 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -21,7 +21,7 @@ if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then + ROOTLIBDIR=/usr/lib/systemd + fi + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" +@@ -317,6 +317,39 @@ EOF + chmod 0755 $_valgrind_wrapper + } + ++create_asan_wrapper() { ++ local _asan_wrapper=$initdir/$ROOTLIBDIR/systemd-under-asan ++ ddebug "Create $_asan_wrapper" ++ cat >$_asan_wrapper <>/etc/systemd/system.conf ++ ++# ASAN and syscall filters aren't compatible with each other. ++find / -name '*.service' -type f | xargs sed -i 's/^\\(MemoryDeny\\|SystemCall\\)/#\\1/' ++ ++export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log ++exec $ROOTLIBDIR/systemd "\$@" ++EOF ++ ++ chmod 0755 $_asan_wrapper ++} ++ + create_strace_wrapper() { + local _strace_wrapper=$initdir/$ROOTLIBDIR/systemd-under-strace + ddebug "Create $_strace_wrapper" diff --git a/SOURCES/0101-tests-redirect-ASAN-reports-on-journald-to-a-file.patch b/SOURCES/0101-tests-redirect-ASAN-reports-on-journald-to-a-file.patch new file mode 100644 index 0000000..0f0925a --- /dev/null +++ b/SOURCES/0101-tests-redirect-ASAN-reports-on-journald-to-a-file.patch @@ -0,0 +1,29 @@ +From d0d284178c1ceb2bd13c9b501008c4458a58fe37 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Tue, 3 Jul 2018 19:29:42 +0000 +Subject: [PATCH] tests: redirect ASAN reports on journald to a file + +Otherwise, they will end up in /dev/null. + +(cherry picked from commit 88ed0f261ba8164a689395ddee8b92d00e073515) +--- + test/test-functions | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index a6f88e4545..822136913b 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -343,6 +343,12 @@ echo DefaultEnvironment=\$DEFAULT_ENVIRONMENT >>/etc/systemd/system.conf + # ASAN and syscall filters aren't compatible with each other. + find / -name '*.service' -type f | xargs sed -i 's/^\\(MemoryDeny\\|SystemCall\\)/#\\1/' + ++# The redirection of ASAN reports to a file prevents them from ending up in /dev/null. ++# But, apparently, sometimes it doesn't work: https://github.com/google/sanitizers/issues/886. ++JOURNALD_CONF_DIR=/etc/systemd/system/systemd-journald.service.d ++mkdir -p "\$JOURNALD_CONF_DIR" ++printf "[Service]\nEnvironment=ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd-journald.asan.log\n" >"\$JOURNALD_CONF_DIR/env.conf" ++ + export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log + exec $ROOTLIBDIR/systemd "\$@" + EOF diff --git a/SOURCES/0102-tests-use-the-asan-wrapper-to-boot-a-VM-container-if.patch b/SOURCES/0102-tests-use-the-asan-wrapper-to-boot-a-VM-container-if.patch new file mode 100644 index 0000000..5a2ede9 --- /dev/null +++ b/SOURCES/0102-tests-use-the-asan-wrapper-to-boot-a-VM-container-if.patch @@ -0,0 +1,51 @@ +From 26b213f1dc3d869bc8b22607b2e1b5f27717ddc1 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Thu, 5 Jul 2018 15:14:07 +0000 +Subject: [PATCH] tests: use the asan wrapper to boot a VM/container if systemd + is built with ASAN + +(cherry picked from commit 016fa3b9e8c3550d49f659c49b5ff4d93337aefe) +--- + test/test-functions | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/test/test-functions b/test/test-functions +index 822136913b..76eef8aa4d 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -21,6 +21,8 @@ if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then + ROOTLIBDIR=/usr/lib/systemd + fi + ++PATH_TO_INIT=$ROOTLIBDIR/systemd ++ + BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + +@@ -47,6 +49,8 @@ IS_BUILT_WITH_ASAN=$(is_built_with_asan && echo yes || echo no) + + if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then + STRIP_BINARIES=no ++ SKIP_INITRD=yes ++ PATH_TO_INIT=$ROOTLIBDIR/systemd-under-asan + fi + + function find_qemu_bin() { +@@ -142,7 +146,7 @@ KERNEL_APPEND="$PARAMS \ + root=/dev/sda1 \ + raid=noautodetect \ + loglevel=2 \ +-init=$ROOTLIBDIR/systemd \ ++init=$PATH_TO_INIT \ + console=ttyS0 \ + selinux=0 \ + printk.devkmsg=on \ +@@ -186,7 +190,7 @@ $KERNEL_APPEND \ + run_nspawn() { + [[ -d /run/systemd/system ]] || return 1 + +- local _nspawn_cmd="$BUILD_DIR/systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND" ++ local _nspawn_cmd="$BUILD_DIR/systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $PATH_TO_INIT $KERNEL_APPEND" + if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then + _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd" + fi diff --git a/SOURCES/0103-tests-allow-passing-additional-arguments-to-nspawn-v.patch b/SOURCES/0103-tests-allow-passing-additional-arguments-to-nspawn-v.patch new file mode 100644 index 0000000..54b09cb --- /dev/null +++ b/SOURCES/0103-tests-allow-passing-additional-arguments-to-nspawn-v.patch @@ -0,0 +1,24 @@ +From 164ead52f895785e0461ef205c5be317b400b0ff Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Thu, 5 Jul 2018 16:30:52 +0000 +Subject: [PATCH] tests: allow passing additional arguments to nspawn via + NSPAWN_ARGUMENTS + +(cherry picked from commit 57916ea352b85153ecbed803d52861ca8b933dd3) +--- + test/test-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index 76eef8aa4d..8164858c2a 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -190,7 +190,7 @@ $KERNEL_APPEND \ + run_nspawn() { + [[ -d /run/systemd/system ]] || return 1 + +- local _nspawn_cmd="$BUILD_DIR/systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $PATH_TO_INIT $KERNEL_APPEND" ++ local _nspawn_cmd="$BUILD_DIR/systemd-nspawn $NSPAWN_ARGUMENTS --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $PATH_TO_INIT $KERNEL_APPEND" + if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then + _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd" + fi diff --git a/SOURCES/0104-tests-also-run-TEST-01-BASIC-in-an-unprivileged-cont.patch b/SOURCES/0104-tests-also-run-TEST-01-BASIC-in-an-unprivileged-cont.patch new file mode 100644 index 0000000..6a693ca --- /dev/null +++ b/SOURCES/0104-tests-also-run-TEST-01-BASIC-in-an-unprivileged-cont.patch @@ -0,0 +1,86 @@ +From 91bd0b915aa17f44625a0c0ce84ed73b6d33968e Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Thu, 30 Aug 2018 07:01:18 +0300 +Subject: [PATCH] tests: also run TEST-01-BASIC in an unprivileged container + (#9957) + +This should make it much easier to catch regressions like +https://github.com/systemd/systemd/issues/9914 and +https://github.com/systemd/systemd/issues/8535. + +(cherry picked from commit 746fbd9c34af5ed8b6d9aa7a9cbd7cac63a3afce) +--- + test/TEST-01-BASIC/test.sh | 1 + + test/test-functions | 23 +++++++++++++++++------ + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh +index 8b21ba05d3..1d2f833478 100755 +--- a/test/TEST-01-BASIC/test.sh ++++ b/test/TEST-01-BASIC/test.sh +@@ -3,6 +3,7 @@ + # ex: ts=8 sw=4 sts=4 et filetype=sh + set -e + TEST_DESCRIPTION="Basic systemd setup" ++RUN_IN_UNPRIVILEGED_CONTAINER=yes + + . $TEST_BASE_DIR/test-functions + +diff --git a/test/test-functions b/test/test-functions +index 8164858c2a..670c2625f7 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -190,7 +190,7 @@ $KERNEL_APPEND \ + run_nspawn() { + [[ -d /run/systemd/system ]] || return 1 + +- local _nspawn_cmd="$BUILD_DIR/systemd-nspawn $NSPAWN_ARGUMENTS --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $PATH_TO_INIT $KERNEL_APPEND" ++ local _nspawn_cmd="$BUILD_DIR/systemd-nspawn $NSPAWN_ARGUMENTS --register=no --kill-signal=SIGKILL --directory=$TESTDIR/$1 $PATH_TO_INIT $KERNEL_APPEND" + if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then + _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd" + fi +@@ -450,9 +450,9 @@ EOF + + check_result_nspawn() { + ret=1 +- [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0 +- [[ -f $TESTDIR/nspawn-root/failed ]] && cp -a $TESTDIR/nspawn-root/failed $TESTDIR +- cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR ++ [[ -e $TESTDIR/$1/testok ]] && ret=0 ++ [[ -f $TESTDIR/$1/failed ]] && cp -a $TESTDIR/$1/failed $TESTDIR ++ cp -a $TESTDIR/$1/var/log/journal $TESTDIR + [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed + ls -l $TESTDIR/journal/*/*.journal + test -s $TESTDIR/failed && ret=$(($ret+1)) +@@ -662,6 +662,9 @@ setup_nspawn_root() { + cp -ar $initdir $TESTDIR/nspawn-root + # we don't mount in the nspawn root + rm -f $TESTDIR/nspawn-root/etc/fstab ++ if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then ++ cp -ar $TESTDIR/nspawn-root $TESTDIR/unprivileged-nspawn-root ++ fi + } + + setup_basic_dirs() { +@@ -1478,11 +1481,19 @@ test_run() { + fi + fi + if [ -z "$TEST_NO_NSPAWN" ]; then +- if run_nspawn; then +- check_result_nspawn || return 1 ++ if run_nspawn "nspawn-root"; then ++ check_result_nspawn "nspawn-root" || return 1 + else + dwarn "can't run systemd-nspawn, skipping" + fi ++ ++ if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then ++ if NSPAWN_ARGUMENTS="-U --private-network $NSPAWN_ARGUMENTS" run_nspawn "unprivileged-nspawn-root"; then ++ check_result_nspawn "unprivileged-nspawn-root" || return 1 ++ else ++ dwarn "can't run systemd-nspawn, skipping" ++ fi ++ fi + fi + return 0 + } diff --git a/SOURCES/0105-test-don-t-overwrite-TESTDIR-if-already-set.patch b/SOURCES/0105-test-don-t-overwrite-TESTDIR-if-already-set.patch new file mode 100644 index 0000000..8667710 --- /dev/null +++ b/SOURCES/0105-test-don-t-overwrite-TESTDIR-if-already-set.patch @@ -0,0 +1,30 @@ +From 9cf9680910544638129bf083bca902881d9ab5bc Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 12 Mar 2019 22:44:25 +0100 +Subject: [PATCH] test: don't overwrite TESTDIR if already set + +(cherry picked from commit 3f50fff536d715aee5e5195ec60e2af047b73c7f) +--- + test/test-functions | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/test/test-functions b/test/test-functions +index 670c2625f7..af9d16140f 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -711,8 +711,13 @@ inst_libs() { + + import_testdir() { + [[ -e $STATEFILE ]] && . $STATEFILE +- if [[ -z "$TESTDIR" ]] || [[ ! -d "$TESTDIR" ]]; then +- TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX) ++ if [[ ! -d "$TESTDIR" ]]; then ++ if [[ -z "$TESTDIR" ]]; then ++ TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX) ++ else ++ mkdir -p "$TESTDIR" ++ fi ++ + echo "TESTDIR=\"$TESTDIR\"" > $STATEFILE + export TESTDIR + fi diff --git a/SOURCES/0106-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch b/SOURCES/0106-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch new file mode 100644 index 0000000..c3d7fc9 --- /dev/null +++ b/SOURCES/0106-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch @@ -0,0 +1,48 @@ +From 94b18b8123b5d957ed84e4aa8e268b60f5427821 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 17 Jul 2018 11:32:40 -0700 +Subject: [PATCH] bus-socket: Fix line_begins() to accept word matching full + string + +The switch to memory_startswith() changed the logic to only look for a space or +NUL byte after the matched word, but matching the full size should also be +acceptable. + +This changed the behavior of parsing of "AUTH\r\n", where m will be set to 4, +since even though the word will match, the check for it being followed by ' ' +or NUL will make line_begins() return false. + +Tested: + +- Using netcat to connect to the private socket directly: + $ echo -ne '\0AUTH\r\n' | sudo nc -U /run/systemd/private + REJECTED EXTERNAL ANONYMOUS + +- Running the Ignition blackbox test: + $ sudo sh -c 'PATH=$PWD/bin/amd64:$PATH ./tests.test' + PASS + +Fixes: d27b725abf64a19a6b2f99332b663f17ad046771 +(cherry picked from commit 3f10c66270b74530339b3f466c43874bb40c210f) + +Resolves: #1692991 +--- + src/libsystemd/sd-bus/bus-socket.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index b147a3843a..a5513d1ab5 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -248,10 +248,7 @@ static bool line_begins(const char *s, size_t m, const char *word) { + const char *p; + + p = memory_startswith(s, m, word); +- if (!p) +- return false; +- +- return IN_SET(*p, 0, ' '); ++ return p && (p == (s + m) || *p == ' '); + } + + static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) { diff --git a/SOURCES/0107-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch b/SOURCES/0107-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch new file mode 100644 index 0000000..025e2e0 --- /dev/null +++ b/SOURCES/0107-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch @@ -0,0 +1,49 @@ +From ac9c51b72213bcea3dc9cea330d4c5fce9c4470e Mon Sep 17 00:00:00 2001 +From: Riccardo Schirone +Date: Mon, 4 Feb 2019 14:29:09 +0100 +Subject: [PATCH] Refuse dbus message paths longer than BUS_PATH_SIZE_MAX + limit. + +Even though the dbus specification does not enforce any length limit on the +path of a dbus message, having to analyze too long strings in PID1 may be +time-consuming and it may have security impacts. + +In any case, the limit is set so high that real-life applications should not +have a problem with it. + +(cherry-picked from commit 61397a60d98e368a5720b37e83f3169e3eb511c4) + +Related: #1678641 +--- + src/libsystemd/sd-bus/bus-internal.c | 2 +- + src/libsystemd/sd-bus/bus-internal.h | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c +index 7bb653338d..35e0b668ee 100644 +--- a/src/libsystemd/sd-bus/bus-internal.c ++++ b/src/libsystemd/sd-bus/bus-internal.c +@@ -45,7 +45,7 @@ bool object_path_is_valid(const char *p) { + if (slash) + return false; + +- return true; ++ return (q - p) <= BUS_PATH_SIZE_MAX; + } + + char* object_path_startswith(const char *a, const char *b) { +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 2087ef8eeb..90e6028983 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -333,6 +333,10 @@ struct sd_bus { + + #define BUS_MESSAGE_SIZE_MAX (128*1024*1024) + #define BUS_AUTH_SIZE_MAX (64*1024) ++/* Note that the D-Bus specification states that bus paths shall have no size limit. We enforce here one ++ * anyway, since truly unbounded strings are a security problem. The limit we pick is relatively large however, ++ * to not clash unnecessarily with real-life applications. */ ++#define BUS_PATH_SIZE_MAX (64*1024) + + #define BUS_CONTAINER_DEPTH 128 + diff --git a/SOURCES/0108-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch b/SOURCES/0108-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch new file mode 100644 index 0000000..47e911d --- /dev/null +++ b/SOURCES/0108-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch @@ -0,0 +1,189 @@ +From 5eb96e51ca2ce0e90e90ecb9f78e8305f51fa5dd Mon Sep 17 00:00:00 2001 +From: Riccardo Schirone +Date: Mon, 4 Feb 2019 14:29:28 +0100 +Subject: [PATCH] Allocate temporary strings to hold dbus paths on the heap + +Paths are limited to BUS_PATH_SIZE_MAX but the maximum size is anyway too big +to be allocated on the stack, so let's switch to the heap where there is a +clear way to understand if the allocation fails. + +(cherry-picked from commit f519a19bcd5afe674a9b8fc462cd77d8bad403c1) + +Related: #1678641 +--- + src/libsystemd/sd-bus/bus-objects.c | 68 +++++++++++++++++++++++------ + 1 file changed, 54 insertions(+), 14 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c +index a18ff88b07..53bf0fd620 100644 +--- a/src/libsystemd/sd-bus/bus-objects.c ++++ b/src/libsystemd/sd-bus/bus-objects.c +@@ -1134,7 +1134,8 @@ static int object_manager_serialize_path_and_fallbacks( + const char *path, + sd_bus_error *error) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -1150,7 +1151,12 @@ static int object_manager_serialize_path_and_fallbacks( + return 0; + + /* Second, add fallback vtables registered for any of the prefixes */ +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_manager_serialize_path(bus, reply, prefix, path, true, error); + if (r < 0) +@@ -1346,6 +1352,7 @@ static int object_find_and_run( + } + + int bus_process_object(sd_bus *bus, sd_bus_message *m) { ++ _cleanup_free_ char *prefix = NULL; + int r; + size_t pl; + bool found_object = false; +@@ -1370,9 +1377,12 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) { + assert(m->member); + + pl = strlen(m->path); +- do { +- char prefix[pl+1]; ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; + ++ do { + bus->nodes_modified = false; + + r = object_find_and_run(bus, m, m->path, false, &found_object); +@@ -1499,9 +1509,15 @@ static int bus_find_parent_object_manager(sd_bus *bus, struct node **out, const + + n = hashmap_get(bus->nodes, path); + if (!n) { +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; ++ ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; + +- prefix = alloca(strlen(path) + 1); + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + n = hashmap_get(bus->nodes, prefix); + if (n) +@@ -2090,8 +2106,9 @@ _public_ int sd_bus_emit_properties_changed_strv( + const char *interface, + char **names) { + ++ _cleanup_free_ char *prefix = NULL; + bool found_interface = false; +- char *prefix; ++ size_t pl; + int r; + + assert_return(bus, -EINVAL); +@@ -2112,6 +2129,12 @@ _public_ int sd_bus_emit_properties_changed_strv( + + BUS_DONT_DESTROY(bus); + ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + do { + bus->nodes_modified = false; + +@@ -2121,7 +2144,6 @@ _public_ int sd_bus_emit_properties_changed_strv( + if (bus->nodes_modified) + continue; + +- prefix = alloca(strlen(path) + 1); + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names); + if (r != 0) +@@ -2253,7 +2275,8 @@ static int object_added_append_all_prefix( + + static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *path) { + _cleanup_set_free_ Set *s = NULL; +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2298,7 +2321,12 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_added_append_all_prefix(bus, m, s, prefix, path, true); + if (r < 0) +@@ -2437,7 +2465,8 @@ static int object_removed_append_all_prefix( + + static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char *path) { + _cleanup_set_free_ Set *s = NULL; +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2469,7 +2498,12 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = object_removed_append_all_prefix(bus, m, s, prefix, path, true); + if (r < 0) +@@ -2619,7 +2653,8 @@ static int interfaces_added_append_one( + const char *path, + const char *interface) { + +- char *prefix; ++ _cleanup_free_ char *prefix = NULL; ++ size_t pl; + int r; + + assert(bus); +@@ -2633,7 +2668,12 @@ static int interfaces_added_append_one( + if (bus->nodes_modified) + return 0; + +- prefix = alloca(strlen(path) + 1); ++ pl = strlen(path); ++ assert(pl <= BUS_PATH_SIZE_MAX); ++ prefix = new(char, pl + 1); ++ if (!prefix) ++ return -ENOMEM; ++ + OBJECT_PATH_FOREACH_PREFIX(prefix, path) { + r = interfaces_added_append_one_prefix(bus, m, prefix, path, interface, true); + if (r != 0) diff --git a/SOURCES/0109-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch b/SOURCES/0109-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch new file mode 100644 index 0000000..7311983 --- /dev/null +++ b/SOURCES/0109-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch @@ -0,0 +1,55 @@ +From f2f784ac5e4b7d0e20eadf97049eaec8c685e5fe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 13 Feb 2019 16:51:22 +0100 +Subject: [PATCH] sd-bus: if we receive an invalid dbus message, ignore and + proceeed + +dbus-daemon might have a slightly different idea of what a valid msg is +than us (for example regarding valid msg and field sizes). Let's hence +try to proceed if we can and thus drop messages rather than fail the +connection if we fail to validate a message. + +Hopefully the differences in what is considered valid are not visible +for real-life usecases, but are specific to exploit attempts only. + +(cherry-picked from commit 6d586a13717ae057aa1b4127400c3de61cd5b9e7) + +Related: #1678641 +--- + src/libsystemd/sd-bus/bus-socket.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index a5513d1ab5..17cfa8e1fd 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1078,7 +1078,7 @@ static int bus_socket_read_message_need(sd_bus *bus, size_t *need) { + } + + static int bus_socket_make_message(sd_bus *bus, size_t size) { +- sd_bus_message *t; ++ sd_bus_message *t = NULL; + void *b; + int r; + +@@ -1103,7 +1103,9 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + bus->fds, bus->n_fds, + NULL, + &t); +- if (r < 0) { ++ if (r == -EBADMSG) ++ log_debug_errno(r, "Received invalid message from connection %s, dropping.", strna(bus->description)); ++ else if (r < 0) { + free(b); + return r; + } +@@ -1114,7 +1116,8 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + bus->fds = NULL; + bus->n_fds = 0; + +- bus->rqueue[bus->rqueue_size++] = t; ++ if (t) ++ bus->rqueue[bus->rqueue_size++] = t; + + return 1; + } diff --git a/SOURCES/0110-meson-drop-misplaced-Wl-undefined-argument.patch b/SOURCES/0110-meson-drop-misplaced-Wl-undefined-argument.patch new file mode 100644 index 0000000..f630599 --- /dev/null +++ b/SOURCES/0110-meson-drop-misplaced-Wl-undefined-argument.patch @@ -0,0 +1,49 @@ +From 0ed1150ccf8837ca85cbb8d5a42fe81b5efeac32 Mon Sep 17 00:00:00 2001 +From: Jussi Pakkanen +Date: Sat, 6 Apr 2019 21:59:06 +0200 +Subject: [PATCH] meson: drop misplaced -Wl,--undefined argument + +Ld's man page says the following: + + -u symbol + --undefined=symbol + + Force symbol to be entered in the output file as an undefined symbol. Doing + this may, for example, trigger linking of additional modules from standard + libraries. -u may be repeated with different option arguments to enter + additional undefined symbols. This option is equivalent to the "EXTERN" + linker script command. + + If this option is being used to force additional modules to be pulled into + the link, and if it is an error for the symbol to remain undefined, then the + option --require-defined should be used instead. + +This would imply that it always requires an argument, which this does not +pass. Thus it will grab the next argument on the command line as its +argument. Before it took one of the many -lrt args (presumably) and now it +grabs something other random linker argument and things break. + +[zj: this line was added in the first version of the meson configuration back +in 5c23128daba7236a6080383b2a5649033cfef85c. AFAICT, this was a mistake. No +such flag appeared in Makefile.am at the time.] + +https://github.com/mesonbuild/meson/issues/5113 +(cherry picked from commit 700805f6c546f2adb79059614f3747f7b5474325) +--- + meson.build | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index d58926c981..f2d67b7e02 100644 +--- a/meson.build ++++ b/meson.build +@@ -1436,8 +1436,7 @@ foreach tuple : [['myhostname', 'ENABLE_MYHOSTNAME'], + # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned + link_args : ['-Wl,-z,nodelete', + '-shared', +- '-Wl,--version-script=' + version_script_arg, +- '-Wl,--undefined'], ++ '-Wl,--version-script=' + version_script_arg], + link_with : [libsystemd_static, + libbasic], + dependencies : [threads, diff --git a/SOURCES/0111-Revert-core-one-step-back-again-for-nspawn-we-actual.patch b/SOURCES/0111-Revert-core-one-step-back-again-for-nspawn-we-actual.patch new file mode 100644 index 0000000..290f3c8 --- /dev/null +++ b/SOURCES/0111-Revert-core-one-step-back-again-for-nspawn-we-actual.patch @@ -0,0 +1,40 @@ +From 9d0046ceca10911361137d6496987cb15ffff132 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 25 Jun 2015 09:20:59 +0200 +Subject: [PATCH] Revert "core: one step back again, for nspawn we actually + can't wait for cgroups running empty since systemd will get exactly zero + notifications about it" + +This reverts commit 743970d2ea6d08aa7c7bff8220f6b7702f2b1db7. + +RHEL-only +https://bugzilla.redhat.com/show_bug.cgi?id=1141137 +https://github.com/systemd/systemd/pull/350 + +Resolves: #1703485 +--- + src/core/unit.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index cc43ddc4f1..d298afb0d4 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4579,16 +4579,7 @@ int unit_kill_context( + + } else if (r > 0) { + +- /* FIXME: For now, on the legacy hierarchy, we will not wait for the cgroup members to die if +- * we are running in a container or if this is a delegation unit, simply because cgroup +- * notification is unreliable in these cases. It doesn't work at all in containers, and outside +- * of containers it can be confused easily by left-over directories in the cgroup — which +- * however should not exist in non-delegated units. On the unified hierarchy that's different, +- * there we get proper events. Hence rely on them. */ +- +- if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0 || +- (detect_container() == 0 && !unit_cgroup_delegate(u))) +- wait_for_exit = true; ++ wait_for_exit = true; + + if (send_sighup) { + set_free(pid_set); diff --git a/SOURCES/0112-tree-wide-shorten-error-logging-a-bit.patch b/SOURCES/0112-tree-wide-shorten-error-logging-a-bit.patch new file mode 100644 index 0000000..6640966 --- /dev/null +++ b/SOURCES/0112-tree-wide-shorten-error-logging-a-bit.patch @@ -0,0 +1,795 @@ +From 9bf05059882a8bc80d33877a315e2bd66fe9e1b5 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 7 Aug 2018 10:14:30 +0900 +Subject: [PATCH] tree-wide: shorten error logging a bit + +Continuation of 4027f96aa08c73f109aa46b89842ca0e25c9c0e9. + +(cherry picked from commit 4ae25393f37b96b2b753562a349d68947ab1ad3d) + +Resolves: #1697893 +--- + src/analyze/analyze.c | 30 ++++------ + src/core/dbus-manager.c | 4 +- + src/core/transaction.c | 18 ++---- + src/hostname/hostnamectl.c | 5 +- + src/libsystemd/sd-bus/test-bus-server.c | 6 +- + src/locale/localectl.c | 14 ++--- + src/locale/localed.c | 5 +- + src/login/loginctl.c | 75 +++++++++--------------- + src/login/logind-action.c | 6 +- + src/login/logind-core.c | 4 +- + src/machine/machinectl.c | 78 +++++++++---------------- + src/nspawn/nspawn-register.c | 16 ++--- + src/resolve/resolvectl.c | 6 +- + src/run/run.c | 18 ++---- + src/sulogin-shell/sulogin-shell.c | 4 +- + src/timedate/timedatectl.c | 16 ++--- + 16 files changed, 112 insertions(+), 193 deletions(-) + +diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c +index de0fe6eba8..dc7d2ab0f6 100644 +--- a/src/analyze/analyze.c ++++ b/src/analyze/analyze.c +@@ -156,10 +156,8 @@ static int bus_get_uint64_property(sd_bus *bus, const char *path, const char *in + &error, + 't', val); + +- if (r < 0) { +- log_error("Failed to parse reply: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse reply: %s", bus_error_message(&error, -r)); + + return 0; + } +@@ -181,10 +179,8 @@ static int bus_get_unit_property_strv(sd_bus *bus, const char *path, const char + property, + &error, + strv); +- if (r < 0) { +- log_error("Failed to get unit property %s: %s", property, bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get unit property %s: %s", property, bus_error_message(&error, -r)); + + return 0; + } +@@ -368,10 +364,8 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { + "ListUnits", + &error, &reply, + NULL); +- if (r < 0) { +- log_error("Failed to list units: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)"); + if (r < 0) +@@ -967,10 +961,8 @@ static int list_dependencies(sd_bus *bus, const char *name) { + &error, + &reply, + "s"); +- if (r < 0) { +- log_error("Failed to get ID: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get ID: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "s", &id); + if (r < 0) +@@ -1229,10 +1221,8 @@ static int dot(int argc, char *argv[], void *userdata) { + &error, + &reply, + ""); +- if (r < 0) { +- log_error("Failed to list units: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)"); + if (r < 0) +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index d39c9b28c4..b3c011b0df 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -1298,9 +1298,9 @@ int verify_run_space_and_log(const char *message) { + + r = verify_run_space(message, &error); + if (r < 0) +- log_error_errno(r, "%s", bus_error_message(&error, r)); ++ return log_error_errno(r, "%s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) { +diff --git a/src/core/transaction.c b/src/core/transaction.c +index 1c7efb207a..045930838b 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -695,10 +695,8 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error + if (r >= 0) + break; + +- if (r != -EAGAIN) { +- log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error_message(e, r)); +- return r; +- } ++ if (r != -EAGAIN) ++ return log_warning_errno(r, "Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error_message(e, r)); + + /* Let's see if the resulting transaction ordering + * graph is still cyclic... */ +@@ -712,10 +710,8 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error + if (r >= 0) + break; + +- if (r != -EAGAIN) { +- log_warning("Requested transaction contains unmergeable jobs: %s", bus_error_message(e, r)); +- return r; +- } ++ if (r != -EAGAIN) ++ return log_warning_errno(r, "Requested transaction contains unmergeable jobs: %s", bus_error_message(e, r)); + + /* Seventh step: an entry got dropped, let's garbage + * collect its dependencies. */ +@@ -731,10 +727,8 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error + + /* Ninth step: check whether we can actually apply this */ + r = transaction_is_destructive(tr, mode, e); +- if (r < 0) { +- log_notice("Requested transaction contradicts existing jobs: %s", bus_error_message(e, r)); +- return r; +- } ++ if (r < 0) ++ return log_notice_errno(r, "Requested transaction contradicts existing jobs: %s", bus_error_message(e, r)); + + /* Tenth step: apply changes */ + r = transaction_apply(tr, m, mode); +diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c +index 8587f5c59f..fa4292c1fc 100644 +--- a/src/hostname/hostnamectl.c ++++ b/src/hostname/hostnamectl.c +@@ -227,8 +227,9 @@ static int set_simple_string(sd_bus *bus, const char *method, const char *value) + &error, NULL, + "sb", value, arg_ask_password); + if (r < 0) +- log_error("Could not set property: %s", bus_error_message(&error, -r)); +- return r; ++ return log_error_errno(r, "Could not set property: %s", bus_error_message(&error, -r)); ++ ++ return 0; + } + + static int set_hostname(int argc, char **argv, void *userdata) { +diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c +index 31b54e252c..f33acda338 100644 +--- a/src/libsystemd/sd-bus/test-bus-server.c ++++ b/src/libsystemd/sd-bus/test-bus-server.c +@@ -130,10 +130,8 @@ static int client(struct context *c) { + return log_error_errno(r, "Failed to allocate method call: %m"); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); + + return 0; + } +diff --git a/src/locale/localectl.c b/src/locale/localectl.c +index b3ad2820d9..ebc6a8ca8a 100644 +--- a/src/locale/localectl.c ++++ b/src/locale/localectl.c +@@ -184,10 +184,8 @@ static int set_locale(int argc, char **argv, void *userdata) { + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, NULL); +- if (r < 0) { +- log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); + + return 0; + } +@@ -229,9 +227,9 @@ static int set_vconsole_keymap(int argc, char **argv, void *userdata) { + NULL, + "ssbb", map, toggle_map, arg_convert, arg_ask_password); + if (r < 0) +- log_error("Failed to set keymap: %s", bus_error_message(&error, -r)); ++ return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r)); + +- return r; ++ return 0; + } + + static int list_vconsole_keymaps(int argc, char **argv, void *userdata) { +@@ -273,9 +271,9 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) { + "ssssbb", layout, model, variant, options, + arg_convert, arg_ask_password); + if (r < 0) +- log_error("Failed to set keymap: %s", bus_error_message(&error, -r)); ++ return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r)); + +- return r; ++ return 0; + } + + static int list_x11_keymaps(int argc, char **argv, void *userdata) { +diff --git a/src/locale/localed.c b/src/locale/localed.c +index b8f95b69a6..253973fd49 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -103,8 +103,9 @@ static int vconsole_reload(sd_bus *bus) { + "ss", "systemd-vconsole-setup.service", "replace"); + + if (r < 0) +- log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); +- return r; ++ return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); ++ ++ return 0; + } + + static int vconsole_convert_to_x11_and_emit(Context *c, sd_bus_message *m) { +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index be55fdbfd8..9b3fed928b 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -856,10 +856,9 @@ static int show_session(int argc, char *argv[], void *userdata) { + session = getenv("XDG_SESSION_ID"); + if (session) { + r = get_session_path(bus, session, &error, &path); +- if (r < 0) { +- log_error("Failed to get session path: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get session path: %s", bus_error_message(&error, r)); ++ + p = path; + } + +@@ -868,10 +867,8 @@ static int show_session(int argc, char *argv[], void *userdata) { + + for (i = 1; i < argc; i++) { + r = get_session_path(bus, argv[i], &error, &path); +- if (r < 0) { +- log_error("Failed to get session path: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get session path: %s", bus_error_message(&error, r)); + + if (properties) + r = show_properties(bus, path, &new_line); +@@ -924,10 +921,8 @@ static int show_user(int argc, char *argv[], void *userdata) { + "GetUser", + &error, &reply, + "u", (uint32_t) uid); +- if (r < 0) { +- log_error("Failed to get user: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get user: %s", bus_error_message(&error, r)); + + r = sd_bus_message_read(reply, "o", &path); + if (r < 0) +@@ -979,10 +974,8 @@ static int show_seat(int argc, char *argv[], void *userdata) { + "GetSeat", + &error, &reply, + "s", argv[i]); +- if (r < 0) { +- log_error("Failed to get seat: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get seat: %s", bus_error_message(&error, r)); + + r = sd_bus_message_read(reply, "o", &path); + if (r < 0) +@@ -1036,10 +1029,8 @@ static int activate(int argc, char *argv[], void *userdata) { + "ActivateSession", + &error, NULL, + "s", argv[i]); +- if (r < 0) { +- log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1068,10 +1059,8 @@ static int kill_session(int argc, char *argv[], void *userdata) { + "KillSession", + &error, NULL, + "ssi", argv[i], arg_kill_who, arg_signal); +- if (r < 0) { +- log_error("Could not kill session: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not kill session: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1121,10 +1110,8 @@ static int enable_linger(int argc, char *argv[], void *userdata) { + "SetUserLinger", + &error, NULL, + "ubb", (uint32_t) uid, b, true); +- if (r < 0) { +- log_error("Could not enable linger: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not enable linger: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1155,10 +1142,8 @@ static int terminate_user(int argc, char *argv[], void *userdata) { + "TerminateUser", + &error, NULL, + "u", (uint32_t) uid); +- if (r < 0) { +- log_error("Could not terminate user: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not terminate user: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1192,10 +1177,8 @@ static int kill_user(int argc, char *argv[], void *userdata) { + "KillUser", + &error, NULL, + "ui", (uint32_t) uid, arg_signal); +- if (r < 0) { +- log_error("Could not kill user: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not kill user: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1222,10 +1205,8 @@ static int attach(int argc, char *argv[], void *userdata) { + &error, NULL, + "ssb", argv[1], argv[i], true); + +- if (r < 0) { +- log_error("Could not attach device: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not attach device: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1250,9 +1231,9 @@ static int flush_devices(int argc, char *argv[], void *userdata) { + &error, NULL, + "b", true); + if (r < 0) +- log_error("Could not flush devices: %s", bus_error_message(&error, -r)); ++ return log_error_errno(r, "Could not flush devices: %s", bus_error_message(&error, -r)); + +- return r; ++ return 0; + } + + static int lock_sessions(int argc, char *argv[], void *userdata) { +@@ -1274,9 +1255,9 @@ static int lock_sessions(int argc, char *argv[], void *userdata) { + &error, NULL, + NULL); + if (r < 0) +- log_error("Could not lock sessions: %s", bus_error_message(&error, -r)); ++ return log_error_errno(r, "Could not lock sessions: %s", bus_error_message(&error, -r)); + +- return r; ++ return 0; + } + + static int terminate_seat(int argc, char *argv[], void *userdata) { +@@ -1299,10 +1280,8 @@ static int terminate_seat(int argc, char *argv[], void *userdata) { + "TerminateSeat", + &error, NULL, + "s", argv[i]); +- if (r < 0) { +- log_error("Could not terminate seat: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not terminate seat: %s", bus_error_message(&error, -r)); + } + + return 0; +diff --git a/src/login/logind-action.c b/src/login/logind-action.c +index 08e41af81a..317e9ef384 100644 +--- a/src/login/logind-action.c ++++ b/src/login/logind-action.c +@@ -152,10 +152,8 @@ int manager_handle_action( + log_info("%s", message_table[handle]); + + r = bus_manager_shutdown_or_sleep_now_or_later(m, target, inhibit_operation, &error); +- if (r < 0) { +- log_error("Failed to execute operation: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); + + return 1; + } +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index 511e3acf8f..cff5536ac0 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -522,9 +522,9 @@ int manager_spawn_autovt(Manager *m, unsigned int vtnr) { + NULL, + "ss", name, "fail"); + if (r < 0) +- log_error("Failed to start %s: %s", name, bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to start %s: %s", name, bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static bool manager_is_docked(Manager *m) { +diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c +index d656681daf..e177841c88 100644 +--- a/src/machine/machinectl.c ++++ b/src/machine/machinectl.c +@@ -773,10 +773,8 @@ static int show_machine(int argc, char *argv[], void *userdata) { + &error, + &reply, + "s", argv[i]); +- if (r < 0) { +- log_error("Could not get path to machine: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not get path to machine: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "o", &path); + if (r < 0) +@@ -1118,10 +1116,8 @@ static int show_image(int argc, char *argv[], void *userdata) { + &error, + &reply, + "s", argv[i]); +- if (r < 0) { +- log_error("Could not get path to image: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not get path to image: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "o", &path); + if (r < 0) +@@ -1158,10 +1154,8 @@ static int kill_machine(int argc, char *argv[], void *userdata) { + &error, + NULL, + "ssi", argv[i], arg_kill_who, arg_signal); +- if (r < 0) { +- log_error("Could not kill machine: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not kill machine: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1200,10 +1194,8 @@ static int terminate_machine(int argc, char *argv[], void *userdata) { + &error, + NULL, + "s", argv[i]); +- if (r < 0) { +- log_error("Could not terminate machine: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not terminate machine: %s", bus_error_message(&error, -r)); + } + + return 0; +@@ -1285,10 +1277,8 @@ static int bind_mount(int argc, char *argv[], void *userdata) { + argv[3], + arg_read_only, + arg_mkdir); +- if (r < 0) { +- log_error("Failed to bind mount: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, -r)); + + return 0; + } +@@ -1459,10 +1449,8 @@ static int login_machine(int argc, char *argv[], void *userdata) { + &error, + &reply, + "s", machine); +- if (r < 0) { +- log_error("Failed to get login PTY: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get login PTY: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "hs", &master, NULL); + if (r < 0) +@@ -1615,10 +1603,8 @@ static int rename_image(int argc, char *argv[], void *userdata) { + &error, + NULL, + "ss", argv[1], argv[2]); +- if (r < 0) { +- log_error("Could not rename image: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not rename image: %s", bus_error_message(&error, -r)); + + return 0; + } +@@ -1681,10 +1667,8 @@ static int read_only_image(int argc, char *argv[], void *userdata) { + &error, + NULL, + "sb", argv[1], b); +- if (r < 0) { +- log_error("Could not mark image read-only: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not mark image read-only: %s", bus_error_message(&error, -r)); + + return 0; + } +@@ -1773,10 +1757,8 @@ static int start_machine(int argc, char *argv[], void *userdata) { + &error, + &reply, + "ss", unit, "fail"); +- if (r < 0) { +- log_error("Failed to start unit: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to start unit: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "o", &object); + if (r < 0) +@@ -1855,10 +1837,8 @@ static int enable_machine(int argc, char *argv[], void *userdata) { + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to enable or disable unit: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to enable or disable unit: %s", bus_error_message(&error, -r)); + + if (streq(argv[0], "enable")) { + r = sd_bus_message_read(reply, "b", NULL); +@@ -1993,10 +1973,8 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) { + return log_error_errno(r, "Failed to request match: %m"); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to transfer image: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to transfer image: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "uo", &id, NULL); + if (r < 0) +@@ -2430,10 +2408,8 @@ static int list_transfers(int argc, char *argv[], void *userdata) { + &error, + &reply, + NULL); +- if (r < 0) { +- log_error("Could not get transfers: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not get transfers: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_enter_container(reply, 'a', "(usssdo)"); + if (r < 0) +@@ -2528,10 +2504,8 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) { + &error, + NULL, + "u", id); +- if (r < 0) { +- log_error("Could not cancel transfer: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Could not cancel transfer: %s", bus_error_message(&error, -r)); + } + + return 0; +diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c +index 93185ecaaa..85f3cf1c01 100644 +--- a/src/nspawn/nspawn-register.c ++++ b/src/nspawn/nspawn-register.c +@@ -195,10 +195,8 @@ int register_machine( + r = sd_bus_call(bus, m, 0, &error, NULL); + } + +- if (r < 0) { +- log_error("Failed to register machine: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r)); + + return 0; + } +@@ -242,10 +240,8 @@ int terminate_machine(sd_bus *bus, pid_t pid) { + &error, + NULL, + NULL); +- if (r < 0) { ++ if (r < 0) + log_debug("Failed to terminate machine: %s", bus_error_message(&error, r)); +- return 0; +- } + + return 0; + } +@@ -336,10 +332,8 @@ int allocate_scope( + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to allocate scope: %s", bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to allocate scope: %s", bus_error_message(&error, r)); + + r = sd_bus_message_read(reply, "o", &object); + if (r < 0) +diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c +index e96c13fea6..cf1ec323a4 100644 +--- a/src/resolve/resolvectl.c ++++ b/src/resolve/resolvectl.c +@@ -274,10 +274,8 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a + ts = now(CLOCK_MONOTONIC); + + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); +- if (r < 0) { +- log_error("%s: resolve call failed: %s", pretty, bus_error_message(&error, r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "%s: resolve call failed: %s", pretty, bus_error_message(&error, r)); + + ts = now(CLOCK_MONOTONIC) - ts; + +diff --git a/src/run/run.c b/src/run/run.c +index 2910fcb272..9ad44e7b57 100644 +--- a/src/run/run.c ++++ b/src/run/run.c +@@ -940,10 +940,8 @@ static int start_transient_service( + &error, + &pty_reply, + "s", arg_host); +- if (r < 0) { +- log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, -r)); + + r = sd_bus_message_read(pty_reply, "hs", &master, &s); + if (r < 0) +@@ -1219,10 +1217,8 @@ static int start_transient_scope( + polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to start transient scope unit: %s", bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, -r)); + + if (arg_nice_set) { + if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0) +@@ -1437,10 +1433,8 @@ static int start_transient_trigger( + polkit_agent_open_if_enabled(arg_transport, arg_ask_password); + + r = sd_bus_call(bus, m, 0, &error, &reply); +- if (r < 0) { +- log_error("Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r)); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r)); + + r = sd_bus_message_read(reply, "o", &object); + if (r < 0) +diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c +index d0e5a89f1f..5db3592d6f 100644 +--- a/src/sulogin-shell/sulogin-shell.c ++++ b/src/sulogin-shell/sulogin-shell.c +@@ -59,9 +59,9 @@ static int start_default_target(sd_bus *bus) { + "ss", "default.target", "isolate"); + + if (r < 0) +- log_error("Failed to start default target: %s", bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to start default target: %s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int fork_wait(const char* const cmdline[]) { +diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c +index befc8cb723..a541b01920 100644 +--- a/src/timedate/timedatectl.c ++++ b/src/timedate/timedatectl.c +@@ -204,9 +204,9 @@ static int set_time(int argc, char **argv, void *userdata) { + NULL, + "xbb", (int64_t) t, relative, interactive); + if (r < 0) +- log_error("Failed to set time: %s", bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to set time: %s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int set_timezone(int argc, char **argv, void *userdata) { +@@ -225,9 +225,9 @@ static int set_timezone(int argc, char **argv, void *userdata) { + NULL, + "sb", argv[1], arg_ask_password); + if (r < 0) +- log_error("Failed to set time zone: %s", bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to set time zone: %s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int set_local_rtc(int argc, char **argv, void *userdata) { +@@ -250,9 +250,9 @@ static int set_local_rtc(int argc, char **argv, void *userdata) { + NULL, + "bbb", b, arg_adjust_system_clock, arg_ask_password); + if (r < 0) +- log_error("Failed to set local RTC: %s", bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to set local RTC: %s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int set_ntp(int argc, char **argv, void *userdata) { +@@ -275,9 +275,9 @@ static int set_ntp(int argc, char **argv, void *userdata) { + NULL, + "bb", b, arg_ask_password); + if (r < 0) +- log_error("Failed to set ntp: %s", bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to set ntp: %s", bus_error_message(&error, r)); + +- return r; ++ return 0; + } + + static int list_timezones(int argc, char **argv, void *userdata) { diff --git a/SOURCES/0113-nspawn-simplify-machine-terminate-bus-call.patch b/SOURCES/0113-nspawn-simplify-machine-terminate-bus-call.patch new file mode 100644 index 0000000..85be590 --- /dev/null +++ b/SOURCES/0113-nspawn-simplify-machine-terminate-bus-call.patch @@ -0,0 +1,98 @@ +From 74640adc3e79064ab34f7ced59e231603c58f07c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Oct 2018 22:54:57 +0200 +Subject: [PATCH] nspawn: simplify machine terminate bus call + +We have the machine name anyway, let's use TerminateMachine() on +machined's Manager object directly with it. That way it's a single +method call only, instead of two, to terminate the machine. + +(cherry picked from commit 11d81e506ed68c6c5cebe319dc57a9a2fc4319c5) + +Resolves: #1697893 +--- + src/nspawn/nspawn-register.c | 34 +++++++--------------------------- + src/nspawn/nspawn-register.h | 2 +- + src/nspawn/nspawn.c | 2 +- + 3 files changed, 9 insertions(+), 29 deletions(-) + +diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c +index 85f3cf1c01..e459cb63ec 100644 +--- a/src/nspawn/nspawn-register.c ++++ b/src/nspawn/nspawn-register.c +@@ -201,10 +201,11 @@ int register_machine( + return 0; + } + +-int terminate_machine(sd_bus *bus, pid_t pid) { ++int terminate_machine( ++ sd_bus *bus, ++ const char *machine_name) { ++ + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; +- const char *path; + int r; + + assert(bus); +@@ -214,32 +215,11 @@ int terminate_machine(sd_bus *bus, pid_t pid) { + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", +- "GetMachineByPID", +- &error, +- &reply, +- "u", +- (uint32_t) pid); +- if (r < 0) { +- /* Note that the machine might already have been +- * cleaned up automatically, hence don't consider it a +- * failure if we cannot get the machine object. */ +- log_debug("Failed to get machine: %s", bus_error_message(&error, r)); +- return 0; +- } +- +- r = sd_bus_message_read(reply, "o", &path); +- if (r < 0) +- return bus_log_parse_error(r); +- +- r = sd_bus_call_method( +- bus, +- "org.freedesktop.machine1", +- path, +- "org.freedesktop.machine1.Machine", +- "Terminate", ++ "TerminateMachine", + &error, + NULL, +- NULL); ++ "s", ++ machine_name); + if (r < 0) + log_debug("Failed to terminate machine: %s", bus_error_message(&error, r)); + +diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h +index 30807b9687..ddd8b053a3 100644 +--- a/src/nspawn/nspawn-register.h ++++ b/src/nspawn/nspawn-register.h +@@ -8,6 +8,6 @@ + #include "nspawn-mount.h" + + int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service); +-int terminate_machine(sd_bus *bus, pid_t pid); ++int terminate_machine(sd_bus *bus, const char *machine_name); + + int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties); +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 8aec893a69..c4943f6eb7 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -4066,7 +4066,7 @@ static int run(int master, + + /* Kill if it is not dead yet anyway */ + if (arg_register && !arg_keep_unit && bus) +- terminate_machine(bus, *pid); ++ terminate_machine(bus, arg_machine); + + /* Normally redundant, but better safe than sorry */ + (void) kill(*pid, SIGKILL); diff --git a/SOURCES/0114-nspawn-merge-two-variable-declaration-lines.patch b/SOURCES/0114-nspawn-merge-two-variable-declaration-lines.patch new file mode 100644 index 0000000..d96da2e --- /dev/null +++ b/SOURCES/0114-nspawn-merge-two-variable-declaration-lines.patch @@ -0,0 +1,27 @@ +From 45085ba5ef810dc527f439fe165c5d393443bda9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Oct 2018 22:56:20 +0200 +Subject: [PATCH] nspawn: merge two variable declaration lines + +(cherry picked from commit df61bc5e4aa19f9b211dbe8414343b44361e442c) + +Resolves: #1697893 +--- + src/nspawn/nspawn-register.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c +index e459cb63ec..0d45cce66e 100644 +--- a/src/nspawn/nspawn-register.c ++++ b/src/nspawn/nspawn-register.c +@@ -236,9 +236,8 @@ int allocate_scope( + int kill_signal, + char **properties) { + ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; + _cleanup_free_ char *scope = NULL; + const char *description, *object; diff --git a/SOURCES/0115-nspawn-rework-how-we-allocate-kill-scopes.patch b/SOURCES/0115-nspawn-rework-how-we-allocate-kill-scopes.patch new file mode 100644 index 0000000..c8cb5c3 --- /dev/null +++ b/SOURCES/0115-nspawn-rework-how-we-allocate-kill-scopes.patch @@ -0,0 +1,125 @@ +From 37c1da056b63323514d71d2832a01ea916f004cc Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Oct 2018 22:56:40 +0200 +Subject: [PATCH] nspawn: rework how we allocate/kill scopes + +Fixes: #6347 +(cherry picked from commit 1d78fea2d6230e0aafa2603abc8f1f51966ef134) + +Resolves: #1697893 +--- + src/nspawn/nspawn-register.c | 64 +++++++++++++++++++++++++++++++++++- + src/nspawn/nspawn-register.h | 1 + + src/nspawn/nspawn.c | 8 +++-- + 3 files changed, 70 insertions(+), 3 deletions(-) + +diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c +index 0d45cce66e..a7cdfc1c7d 100644 +--- a/src/nspawn/nspawn-register.c ++++ b/src/nspawn/nspawn-register.c +@@ -274,10 +274,12 @@ int allocate_scope( + + description = strjoina("Container ", machine_name); + +- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)", ++ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)", + "PIDs", "au", 1, pid, + "Description", "s", description, + "Delegate", "b", 1, ++ "CollectMode", "s", "inactive-or-failed", ++ "AddRef", "b", 1, + "Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice); + if (r < 0) + return bus_log_create_error(r); +@@ -324,3 +326,63 @@ int allocate_scope( + + return 0; + } ++ ++int terminate_scope( ++ sd_bus *bus, ++ const char *machine_name) { ++ ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_free_ char *scope = NULL; ++ int r; ++ ++ r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope); ++ if (r < 0) ++ return log_error_errno(r, "Failed to mangle scope name: %m"); ++ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "AbandonScope", ++ &error, ++ NULL, ++ "s", ++ scope); ++ if (r < 0) { ++ log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r)); ++ sd_bus_error_free(&error); ++ } ++ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "KillUnit", ++ &error, ++ NULL, ++ "ssi", ++ scope, ++ "all", ++ (int32_t) SIGKILL); ++ if (r < 0) { ++ log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r)); ++ sd_bus_error_free(&error); ++ } ++ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "UnrefUnit", ++ &error, ++ NULL, ++ "s", ++ scope); ++ if (r < 0) ++ log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r)); ++ ++ return 0; ++} +diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h +index ddd8b053a3..05f5776f23 100644 +--- a/src/nspawn/nspawn-register.h ++++ b/src/nspawn/nspawn-register.h +@@ -11,3 +11,4 @@ int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const cha + int terminate_machine(sd_bus *bus, const char *machine_name); + + int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties); ++int terminate_scope(sd_bus *bus, const char *machine_name); +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index c4943f6eb7..b40411dcd0 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -4065,8 +4065,12 @@ static int run(int master, + putc('\n', stdout); + + /* Kill if it is not dead yet anyway */ +- if (arg_register && !arg_keep_unit && bus) +- terminate_machine(bus, arg_machine); ++ if (bus) { ++ if (arg_register) ++ terminate_machine(bus, arg_machine); ++ else if (!arg_keep_unit) ++ terminate_scope(bus, arg_machine); ++ } + + /* Normally redundant, but better safe than sorry */ + (void) kill(*pid, SIGKILL); diff --git a/SOURCES/0116-unit-enqueue-cgroup-empty-check-event-if-the-last-re.patch b/SOURCES/0116-unit-enqueue-cgroup-empty-check-event-if-the-last-re.patch new file mode 100644 index 0000000..6e68a8c --- /dev/null +++ b/SOURCES/0116-unit-enqueue-cgroup-empty-check-event-if-the-last-re.patch @@ -0,0 +1,31 @@ +From 7b629b3a853c3b1e4e6a916a080996960343d7f2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Oct 2018 23:04:51 +0200 +Subject: [PATCH] unit: enqueue cgroup empty check event if the last ref on a + unit is dropped + +(cherry picked from commit e5c36295d81971ef75d9c6f98f0890b92a4a353f) + +Resolves: #1697893 +--- + src/core/dbus-unit.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index ae0410414e..c5bca10979 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -1746,7 +1746,13 @@ static int bus_unit_track_handler(sd_bus_track *t, void *userdata) { + + u->bus_track = sd_bus_track_unref(u->bus_track); /* make sure we aren't called again */ + ++ /* If the client that tracks us disappeared, then there's reason to believe that the cgroup is empty now too, ++ * let's see */ ++ unit_add_to_cgroup_empty_queue(u); ++ ++ /* Also add the unit to the GC queue, after all if the client left it might be time to GC this unit */ + unit_add_to_gc_queue(u); ++ + return 0; + } + diff --git a/SOURCES/0117-Revert-journal-remove-journal-audit-socket.patch b/SOURCES/0117-Revert-journal-remove-journal-audit-socket.patch new file mode 100644 index 0000000..bf88fc8 --- /dev/null +++ b/SOURCES/0117-Revert-journal-remove-journal-audit-socket.patch @@ -0,0 +1,75 @@ +From 7b87977aaa9017c7307cc0645c019b9abd4654d6 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 2 May 2019 14:08:39 +0200 +Subject: [PATCH] Revert "journal: remove journal audit socket" + +This reverts commit 8618ef2fb30b4139c9bec4e45fb499cd8192a87f. + +Resolves: #1699287 +--- + units/meson.build | 2 ++ + units/systemd-journald-audit.socket | 22 ++++++++++++++++++++++ + units/systemd-journald.service.in | 4 ++-- + 3 files changed, 26 insertions(+), 2 deletions(-) + create mode 100644 units/systemd-journald-audit.socket + +diff --git a/units/meson.build b/units/meson.build +index e54a84ccbf..e4ac6ced64 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -89,6 +89,8 @@ units = [ + 'sockets.target.wants/'], + ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], + ['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], ++ ['systemd-journald-audit.socket', '', ++ 'sockets.target.wants/'], + ['systemd-journald-dev-log.socket', '', + 'sockets.target.wants/'], + ['systemd-journald.socket', '', +diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket +new file mode 100644 +index 0000000000..cb8b774963 +--- /dev/null ++++ b/units/systemd-journald-audit.socket +@@ -0,0 +1,22 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++ ++[Unit] ++Description=Journal Audit Socket ++Documentation=man:systemd-journald.service(8) man:journald.conf(5) ++DefaultDependencies=no ++Before=sockets.target ++ConditionSecurity=audit ++ConditionCapability=CAP_AUDIT_READ ++ ++[Socket] ++Service=systemd-journald.service ++ReceiveBuffer=128M ++ListenNetlink=audit 1 ++PassCredentials=yes +diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in +index 2d5fd0120d..4eab2fa841 100644 +--- a/units/systemd-journald.service.in ++++ b/units/systemd-journald.service.in +@@ -12,12 +12,12 @@ Description=Journal Service + Documentation=man:systemd-journald.service(8) man:journald.conf(5) + DefaultDependencies=no + Requires=systemd-journald.socket +-After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket ++After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket + Before=sysinit.target + + [Service] + Type=notify +-Sockets=systemd-journald.socket systemd-journald-dev-log.socket ++Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket + ExecStart=@rootlibexecdir@/systemd-journald + Restart=always + RestartSec=0 diff --git a/SOURCES/0118-journal-don-t-enable-systemd-journald-audit.socket-b.patch b/SOURCES/0118-journal-don-t-enable-systemd-journald-audit.socket-b.patch new file mode 100644 index 0000000..d2fc72e --- /dev/null +++ b/SOURCES/0118-journal-don-t-enable-systemd-journald-audit.socket-b.patch @@ -0,0 +1,39 @@ +From 7a650ee8d3faf79fd5ef866b69741880a3a42b8d Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 2 May 2019 14:11:54 +0200 +Subject: [PATCH] journal: don't enable systemd-journald-audit.socket by + default + +Resolves: #1699287 +--- + units/meson.build | 3 +-- + units/systemd-journald.service.in | 2 +- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/units/meson.build b/units/meson.build +index e4ac6ced64..e118d81888 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -89,8 +89,7 @@ units = [ + 'sockets.target.wants/'], + ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], + ['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], +- ['systemd-journald-audit.socket', '', +- 'sockets.target.wants/'], ++ ['systemd-journald-audit.socket', ''], + ['systemd-journald-dev-log.socket', '', + 'sockets.target.wants/'], + ['systemd-journald.socket', '', +diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in +index 4eab2fa841..e109b25792 100644 +--- a/units/systemd-journald.service.in ++++ b/units/systemd-journald.service.in +@@ -17,7 +17,7 @@ Before=sysinit.target + + [Service] + Type=notify +-Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket ++Sockets=systemd-journald.socket systemd-journald-dev-log.socket + ExecStart=@rootlibexecdir@/systemd-journald + Restart=always + RestartSec=0 diff --git a/SOURCES/0119-logs-show-use-grey-color-for-de-emphasizing-journal-.patch b/SOURCES/0119-logs-show-use-grey-color-for-de-emphasizing-journal-.patch new file mode 100644 index 0000000..8290ff9 --- /dev/null +++ b/SOURCES/0119-logs-show-use-grey-color-for-de-emphasizing-journal-.patch @@ -0,0 +1,49 @@ +From 67b548434f258224239e41672478a0038d5c9d30 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 5 Dec 2018 18:42:32 +0100 +Subject: [PATCH] logs-show: use grey color for de-emphasizing journal log + output + +(cherry picked from commit 67df9b7a06d749fdd84f19f7d75ccf0d743f6d72) + +Resolves: #1695601 +--- + src/basic/terminal-util.h | 2 ++ + src/shared/logs-show.c | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h +index c0bd0e67a6..0055b72343 100644 +--- a/src/basic/terminal-util.h ++++ b/src/basic/terminal-util.h +@@ -18,6 +18,7 @@ + #define ANSI_MAGENTA "\x1B[0;35m" + #define ANSI_CYAN "\x1B[0;36m" + #define ANSI_WHITE "\x1B[0;37m" ++#define ANSI_GREY "\x1B[0;2;37m" + + /* Bold/highlighted */ + #define ANSI_HIGHLIGHT_BLACK "\x1B[0;1;30m" +@@ -129,6 +130,7 @@ DEFINE_ANSI_FUNC(highlight_yellow, HIGHLIGHT_YELLOW); + DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE); + DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA); + DEFINE_ANSI_FUNC(normal, NORMAL); ++DEFINE_ANSI_FUNC(grey, GREY); + + DEFINE_ANSI_FUNC_UNDERLINE(underline, UNDERLINE, NORMAL); + DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT_UNDERLINE, HIGHLIGHT); +diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c +index 33afbe2f7f..c66e39d2fe 100644 +--- a/src/shared/logs-show.c ++++ b/src/shared/logs-show.c +@@ -170,6 +170,10 @@ static bool print_multiline( + color_on = ANSI_HIGHLIGHT; + color_off = ANSI_NORMAL; + highlight_on = ANSI_HIGHLIGHT_RED; ++ } else if (priority >= LOG_DEBUG) { ++ color_on = ANSI_GREY; ++ color_off = ANSI_NORMAL; ++ highlight_on = ANSI_HIGHLIGHT_RED; + } + } + diff --git a/SOURCES/0120-units-add-Install-section-to-tmp.mount.patch b/SOURCES/0120-units-add-Install-section-to-tmp.mount.patch new file mode 100644 index 0000000..bafbf50 --- /dev/null +++ b/SOURCES/0120-units-add-Install-section-to-tmp.mount.patch @@ -0,0 +1,24 @@ +From bb3d205bea1c83cbd0e27b504f5f1faa884fb602 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 22 Jan 2019 10:28:42 +0100 +Subject: [PATCH] units: add [Install] section to tmp.mount + +rhel-only + +Resolves: #1667065 +--- + units/tmp.mount | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/units/tmp.mount b/units/tmp.mount +index 742d86385c..b558047030 100644 +--- a/units/tmp.mount ++++ b/units/tmp.mount +@@ -22,3 +22,7 @@ What=tmpfs + Where=/tmp + Type=tmpfs + Options=mode=1777,strictatime,nosuid,nodev ++ ++# Make 'systemctl enable tmp.mount' work: ++[Install] ++WantedBy=local-fs.target diff --git a/SOURCES/0121-nss-do-not-modify-errno-when-NSS_STATUS_NOTFOUND-or-.patch b/SOURCES/0121-nss-do-not-modify-errno-when-NSS_STATUS_NOTFOUND-or-.patch new file mode 100644 index 0000000..fcfeb37 --- /dev/null +++ b/SOURCES/0121-nss-do-not-modify-errno-when-NSS_STATUS_NOTFOUND-or-.patch @@ -0,0 +1,957 @@ +From 34bb0461192c9feba0c0f05a8baf8fefcd9d835e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Jul 2018 23:00:00 +0900 +Subject: [PATCH] nss: do not modify errno when NSS_STATUS_NOTFOUND or + NSS_STATUS_SUCCESS + +This also adds PROTECT_ERRNO for all nss module functions. + +C.f. glibc NSS documents https://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html +and discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=23410. + +Fixes #9585. + +(cherry picked from commit 06202b9e659e5cc72aeecc5200155b7c012fccbc) + +Resolves: #1691691 +--- + src/nss-myhostname/nss-myhostname.c | 16 +++--- + src/nss-mymachines/nss-mymachines.c | 88 ++++++++++++----------------- + src/nss-resolve/nss-resolve.c | 87 +++++++++++++--------------- + src/nss-systemd/nss-systemd.c | 74 +++++++++--------------- + 4 files changed, 108 insertions(+), 157 deletions(-) + +diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c +index f82ce59f2c..5abc0c91bf 100644 +--- a/src/nss-myhostname/nss-myhostname.c ++++ b/src/nss-myhostname/nss-myhostname.c +@@ -45,6 +45,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + char *r_name; + unsigned n; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -64,7 +65,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + + n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses); + if (n_addresses <= 0) { +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -81,7 +81,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + + /* We respond to our local host name, our hostname suffixed with a single dot. */ + if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) { +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -157,8 +156,8 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + if (ttlp) + *ttlp = 0; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -286,8 +285,8 @@ static enum nss_status fill_in_hostent( + if (canonp) + *canonp = r_name; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -309,6 +308,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + uint32_t local_address_ipv4 = 0; + int n_addresses = 0; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -334,7 +334,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + + n_addresses = local_gateways(NULL, 0, af, &addresses); + if (n_addresses <= 0) { +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -350,7 +349,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + } + + if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) { +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -393,6 +391,7 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r( + bool additional_from_hostname = false; + unsigned n; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(addr); +@@ -455,7 +454,6 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r( + } + } + +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + +diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c +index 8d6caa0ada..9b81cd9ad1 100644 +--- a/src/nss-mymachines/nss-mymachines.c ++++ b/src/nss-mymachines/nss-mymachines.c +@@ -80,6 +80,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r( + char *r_name; + int n_ifindices, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -126,7 +127,6 @@ enum nss_status _nss_mymachines_gethostbyname4_r( + goto fail; + + if (c <= 0) { +- *errnop = ESRCH; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -200,8 +200,8 @@ enum nss_status _nss_mymachines_gethostbyname4_r( + if (ttlp) + *ttlp = 0; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -230,6 +230,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r( + size_t l, idx, ms, alen; + int r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -278,7 +279,6 @@ enum nss_status _nss_mymachines_gethostbyname3_r( + goto fail; + + if (c <= 0) { +- *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } +@@ -364,8 +364,8 @@ enum nss_status _nss_mymachines_gethostbyname3_r( + if (canonp) + *canonp = r_name; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -394,6 +394,7 @@ enum nss_status _nss_mymachines_getpwnam_r( + size_t l; + int r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -401,28 +402,28 @@ enum nss_status _nss_mymachines_getpwnam_r( + + p = startswith(name, "vu-"); + if (!p) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + e = strrchr(p, '-'); + if (!e || e == p) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */ +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = parse_uid(e + 1, &uid); + if (r < 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + machine = strndupa(p, e - p); + if (!machine_name_is_valid(machine)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) + /* Make sure we can't deadlock if we are invoked by dbus-daemon. This way, it won't be able to resolve + * these UIDs, but that should be unproblematic as containers should never be able to connect to a bus + * running on the host. */ +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = sd_bus_open_system(&bus); + if (r < 0) +@@ -439,7 +440,7 @@ enum nss_status _nss_mymachines_getpwnam_r( + machine, (uint32_t) uid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -450,7 +451,7 @@ enum nss_status _nss_mymachines_getpwnam_r( + + /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */ + if (mapped < HOST_UID_LIMIT || mapped == uid) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + l = strlen(name); + if (buflen < l+1) { +@@ -468,13 +469,8 @@ enum nss_status _nss_mymachines_getpwnam_r( + pwd->pw_dir = (char*) "/"; + pwd->pw_shell = (char*) "/sbin/nologin"; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -493,17 +489,18 @@ enum nss_status _nss_mymachines_getpwuid_r( + uint32_t mapped; + int r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + if (!uid_is_valid(uid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* We consider all uids < 65536 host uids */ + if (uid < HOST_UID_LIMIT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = sd_bus_open_system(&bus); + if (r < 0) +@@ -520,7 +517,7 @@ enum nss_status _nss_mymachines_getpwuid_r( + (uint32_t) uid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -530,7 +527,7 @@ enum nss_status _nss_mymachines_getpwuid_r( + goto fail; + + if (mapped == uid) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) { + *errnop = ERANGE; +@@ -545,13 +542,8 @@ enum nss_status _nss_mymachines_getpwuid_r( + pwd->pw_dir = (char*) "/"; + pwd->pw_shell = (char*) "/sbin/nologin"; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -574,6 +566,7 @@ enum nss_status _nss_mymachines_getgrnam_r( + size_t l; + int r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -581,25 +574,25 @@ enum nss_status _nss_mymachines_getgrnam_r( + + p = startswith(name, "vg-"); + if (!p) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + e = strrchr(p, '-'); + if (!e || e == p) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */ +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = parse_gid(e + 1, &gid); + if (r < 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + machine = strndupa(p, e - p); + if (!machine_name_is_valid(machine)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = sd_bus_open_system(&bus); + if (r < 0) +@@ -616,7 +609,7 @@ enum nss_status _nss_mymachines_getgrnam_r( + machine, (uint32_t) gid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -626,7 +619,7 @@ enum nss_status _nss_mymachines_getgrnam_r( + goto fail; + + if (mapped < HOST_GID_LIMIT || mapped == gid) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + l = sizeof(char*) + strlen(name) + 1; + if (buflen < l) { +@@ -642,13 +635,8 @@ enum nss_status _nss_mymachines_getgrnam_r( + gr->gr_passwd = (char*) "*"; /* locked */ + gr->gr_mem = (char**) buffer; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -667,17 +655,18 @@ enum nss_status _nss_mymachines_getgrgid_r( + uint32_t mapped; + int r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + if (!gid_is_valid(gid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* We consider all gids < 65536 host gids */ + if (gid < HOST_GID_LIMIT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + r = sd_bus_open_system(&bus); + if (r < 0) +@@ -694,7 +683,7 @@ enum nss_status _nss_mymachines_getgrgid_r( + (uint32_t) gid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -704,7 +693,7 @@ enum nss_status _nss_mymachines_getgrgid_r( + goto fail; + + if (mapped == gid) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (buflen < sizeof(char*) + 1) { + *errnop = ERANGE; +@@ -722,13 +711,8 @@ enum nss_status _nss_mymachines_getgrgid_r( + gr->gr_passwd = (char*) "*"; /* locked */ + gr->gr_mem = (char**) buffer; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c +index eb3d2d977f..b2bb698ded 100644 +--- a/src/nss-resolve/nss-resolve.c ++++ b/src/nss-resolve/nss-resolve.c +@@ -108,6 +108,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( + char *r_name; + int c, r, i = 0; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -140,20 +141,15 @@ enum nss_status _nss_resolve_gethostbyname4_r( + + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); + if (r < 0) { +- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } ++ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") || ++ !bus_error_shall_fallback(&error)) ++ goto not_found; + + /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails, + allowing falling back to other nss modules. Treat all other error conditions as + NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this + case so that the nsswitch.conf configuration can distuingish such executed but + negative replies from complete failure to talk to resolved). */ +- if (!bus_error_shall_fallback(&error)) +- ret = NSS_STATUS_NOTFOUND; +- + goto fail; + } + +@@ -162,11 +158,8 @@ enum nss_status _nss_resolve_gethostbyname4_r( + r = c; + goto fail; + } +- if (c == 0) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } ++ if (c == 0) ++ goto not_found; + + if (isempty(canonical)) + canonical = name; +@@ -247,8 +240,8 @@ enum nss_status _nss_resolve_gethostbyname4_r( + if (ttlp) + *ttlp = 0; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -258,6 +251,10 @@ fail: + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; ++ ++not_found: ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; + } + + enum nss_status _nss_resolve_gethostbyname3_r( +@@ -278,6 +275,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( + const char *canonical; + int c, r, i = 0; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -318,14 +316,9 @@ enum nss_status _nss_resolve_gethostbyname3_r( + + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); + if (r < 0) { +- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } +- +- if (!bus_error_shall_fallback(&error)) +- ret = NSS_STATUS_NOTFOUND; ++ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") || ++ !bus_error_shall_fallback(&error)) ++ goto not_found; + + goto fail; + } +@@ -335,11 +328,8 @@ enum nss_status _nss_resolve_gethostbyname3_r( + r = c; + goto fail; + } +- if (c == 0) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } ++ if (c == 0) ++ goto not_found; + + if (isempty(canonical)) + canonical = name; +@@ -427,23 +417,27 @@ enum nss_status _nss_resolve_gethostbyname3_r( + result->h_length = alen; + result->h_addr_list = (char**) r_addr_list; + +- /* Explicitly reset all error variables */ +- *errnop = 0; +- *h_errnop = NETDB_SUCCESS; +- h_errno = 0; +- + if (ttlp) + *ttlp = 0; + + if (canonp) + *canonp = r_name; + ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ ++ *h_errnop = NETDB_SUCCESS; ++ h_errno = 0; ++ + return NSS_STATUS_SUCCESS; + + fail: + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; ++ ++not_found: ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; + } + + enum nss_status _nss_resolve_gethostbyaddr2_r( +@@ -464,6 +458,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + const char *n; + int r, ifindex; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(addr); +@@ -516,14 +511,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + + r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply); + if (r < 0) { +- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } +- +- if (!bus_error_shall_fallback(&error)) +- ret = NSS_STATUS_NOTFOUND; ++ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") || ++ !bus_error_shall_fallback(&error)) ++ goto not_found; + + goto fail; + } +@@ -549,11 +539,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + if (r < 0) + return r; + +- if (c <= 0) { +- *errnop = ESRCH; +- *h_errnop = HOST_NOT_FOUND; +- return NSS_STATUS_NOTFOUND; +- } ++ if (c <= 0) ++ goto not_found; + + ms += ALIGN(len) + /* the address */ + 2 * sizeof(char*) + /* pointers to the address, plus trailing NULL */ +@@ -612,8 +599,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + if (ttlp) + *ttlp = 0; + +- /* Explicitly reset all error variables */ +- *errnop = 0; ++ /* Explicitly reset both *h_errnop and h_errno to work around ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */ + *h_errnop = NETDB_SUCCESS; + h_errno = 0; + +@@ -623,6 +610,10 @@ fail: + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; ++ ++not_found: ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; + } + + NSS_GETHOSTBYNAME_FALLBACKS(resolve); +diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c +index f516b84c63..f554828d49 100644 +--- a/src/nss-systemd/nss-systemd.c ++++ b/src/nss-systemd/nss-systemd.c +@@ -145,6 +145,7 @@ enum nss_status _nss_systemd_getpwnam_r( + size_t l; + int bypass, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); +@@ -153,26 +154,24 @@ enum nss_status _nss_systemd_getpwnam_r( + /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't + * generate EINVAL here, because it isn't really out business to complain about invalid user names. */ + if (!valid_user_group_name(name)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */ + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { + if (streq(name, root_passwd.pw_name)) { + *pwd = root_passwd; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + if (synthesize_nobody() && + streq(name, nobody_passwd.pw_name)) { + *pwd = nobody_passwd; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + } + + /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */ + if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); + if (bypass <= 0) { +@@ -184,7 +183,7 @@ enum nss_status _nss_systemd_getpwnam_r( + if (bypass > 0) { + r = direct_lookup_name(name, (uid_t*) &translated); + if (r == -ENOENT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + if (r < 0) + goto fail; + } else { +@@ -199,7 +198,7 @@ enum nss_status _nss_systemd_getpwnam_r( + name); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -225,13 +224,8 @@ enum nss_status _nss_systemd_getpwnam_r( + pwd->pw_dir = (char*) DYNAMIC_USER_DIR; + pwd->pw_shell = (char*) DYNAMIC_USER_SHELL; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -251,31 +245,30 @@ enum nss_status _nss_systemd_getpwuid_r( + size_t l; + int bypass, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + if (!uid_is_valid(uid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */ + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { + if (uid == root_passwd.pw_uid) { + *pwd = root_passwd; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + if (synthesize_nobody() && + uid == nobody_passwd.pw_uid) { + *pwd = nobody_passwd; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + } + + if (!uid_is_dynamic(uid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); + if (bypass <= 0) { +@@ -287,7 +280,7 @@ enum nss_status _nss_systemd_getpwuid_r( + if (bypass > 0) { + r = direct_lookup_uid(uid, &direct); + if (r == -ENOENT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + if (r < 0) + goto fail; + +@@ -305,7 +298,7 @@ enum nss_status _nss_systemd_getpwuid_r( + (uint32_t) uid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -331,13 +324,8 @@ enum nss_status _nss_systemd_getpwuid_r( + pwd->pw_dir = (char*) DYNAMIC_USER_DIR; + pwd->pw_shell = (char*) DYNAMIC_USER_SHELL; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -358,31 +346,30 @@ enum nss_status _nss_systemd_getgrnam_r( + size_t l; + int bypass, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(name); + assert(gr); + + if (!valid_user_group_name(name)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* Synthesize records for root and nobody, in case they are missing form /etc/group */ + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { + if (streq(name, root_group.gr_name)) { + *gr = root_group; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + if (synthesize_nobody() && + streq(name, nobody_group.gr_name)) { + *gr = nobody_group; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + } + + if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); + if (bypass <= 0) { +@@ -394,7 +381,7 @@ enum nss_status _nss_systemd_getgrnam_r( + if (bypass > 0) { + r = direct_lookup_name(name, (uid_t*) &translated); + if (r == -ENOENT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + if (r < 0) + goto fail; + } else { +@@ -409,7 +396,7 @@ enum nss_status _nss_systemd_getgrnam_r( + name); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -433,13 +420,8 @@ enum nss_status _nss_systemd_getgrnam_r( + gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD; + gr->gr_mem = (char**) buffer; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -459,31 +441,30 @@ enum nss_status _nss_systemd_getgrgid_r( + size_t l; + int bypass, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + if (!gid_is_valid(gid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + /* Synthesize records for root and nobody, in case they are missing from /etc/group */ + if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { + if (gid == root_group.gr_gid) { + *gr = root_group; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + if (synthesize_nobody() && + gid == nobody_group.gr_gid) { + *gr = nobody_group; +- *errnop = 0; + return NSS_STATUS_SUCCESS; + } + } + + if (!gid_is_dynamic(gid)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); + if (bypass <= 0) { +@@ -495,7 +476,7 @@ enum nss_status _nss_systemd_getgrgid_r( + if (bypass > 0) { + r = direct_lookup_uid(gid, &direct); + if (r == -ENOENT) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + if (r < 0) + goto fail; + +@@ -513,7 +494,7 @@ enum nss_status _nss_systemd_getgrgid_r( + (uint32_t) gid); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER)) +- goto not_found; ++ return NSS_STATUS_NOTFOUND; + + goto fail; + } +@@ -537,13 +518,8 @@ enum nss_status _nss_systemd_getgrgid_r( + gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD; + gr->gr_mem = (char**) buffer; + +- *errnop = 0; + return NSS_STATUS_SUCCESS; + +-not_found: +- *errnop = 0; +- return NSS_STATUS_NOTFOUND; +- + fail: + *errnop = -r; + return NSS_STATUS_UNAVAIL; +@@ -598,6 +574,7 @@ static void systemd_endent(GetentData *data) { + } + + static enum nss_status nss_systemd_endent(GetentData *p) { ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert_se(pthread_mutex_lock(&p->mutex) == 0); +@@ -668,6 +645,7 @@ static enum nss_status systemd_setent(GetentData *p) { + uid_t id; + int bypass, r; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(p); +@@ -750,6 +728,7 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz + UserEntry *p; + size_t len; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(result); +@@ -778,7 +757,6 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz + break; + } + if (!p) { +- *errnop = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto finalize; + } +@@ -801,6 +779,7 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size + UserEntry *p; + size_t len; + ++ PROTECT_ERRNO; + BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); + + assert(result); +@@ -827,7 +806,6 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size + break; + } + if (!p) { +- *errnop = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto finalize; + } diff --git a/SOURCES/0122-util.h-add-new-UNPROTECT_ERRNO-macro.patch b/SOURCES/0122-util.h-add-new-UNPROTECT_ERRNO-macro.patch new file mode 100644 index 0000000..5691001 --- /dev/null +++ b/SOURCES/0122-util.h-add-new-UNPROTECT_ERRNO-macro.patch @@ -0,0 +1,103 @@ +From b05795bd3d8afcdcb765639a636ada8d36a2ee79 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 18 Jan 2019 20:04:13 +0100 +Subject: [PATCH] util.h: add new UNPROTECT_ERRNO macro + +THis is inspired by #11395, but much simpler. + +(cherry picked from commit 840f606d88fef2f5d240b2d759ce7b951354d5bb) + +Resolves: #1691691 +--- + src/basic/util.h | 9 +++++++++ + src/test/test-fs-util.c | 6 +++--- + src/test/test-util.c | 25 +++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 3 deletions(-) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 9699d228f9..27b5a09782 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -134,11 +134,20 @@ static inline void *mempset(void *s, int c, size_t n) { + } + + static inline void _reset_errno_(int *saved_errno) { ++ if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */ ++ return; ++ + errno = *saved_errno; + } + + #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno + ++#define UNPROTECT_ERRNO \ ++ do { \ ++ errno = _saved_errno_; \ ++ _saved_errno_ = -1; \ ++ } while (false) ++ + static inline int negative_errno(void) { + /* This helper should be used to shut up gcc if you know 'errno' is + * negative. Instead of "return -errno;", use "return negative_errno();" +diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c +index fc650b513e..7b7990bb70 100644 +--- a/src/test/test-fs-util.c ++++ b/src/test/test-fs-util.c +@@ -322,11 +322,11 @@ static void test_unlink_noerrno(void) { + + { + PROTECT_ERRNO; +- errno = -42; ++ errno = 42; + assert_se(unlink_noerrno(name) >= 0); +- assert_se(errno == -42); ++ assert_se(errno == 42); + assert_se(unlink_noerrno(name) < 0); +- assert_se(errno == -42); ++ assert_se(errno == 42); + } + } + +diff --git a/src/test/test-util.c b/src/test/test-util.c +index 4d3e5c5b94..df60d89115 100644 +--- a/src/test/test-util.c ++++ b/src/test/test-util.c +@@ -164,6 +164,30 @@ static void test_protect_errno(void) { + assert_se(errno == 12); + } + ++static void test_unprotect_errno_inner_function(void) { ++ PROTECT_ERRNO; ++ ++ errno = 2222; ++} ++ ++static void test_unprotect_errno(void) { ++ log_info("/* %s */", __func__); ++ ++ errno = 4711; ++ ++ PROTECT_ERRNO; ++ ++ errno = 815; ++ ++ UNPROTECT_ERRNO; ++ ++ assert_se(errno == 4711); ++ ++ test_unprotect_errno_inner_function(); ++ ++ assert_se(errno == 4711); ++} ++ + static void test_in_set(void) { + assert_se(IN_SET(1, 1)); + assert_se(IN_SET(1, 1, 2, 3, 4)); +@@ -307,6 +331,7 @@ int main(int argc, char *argv[]) { + test_div_round_up(); + test_u64log2(); + test_protect_errno(); ++ test_unprotect_errno(); + test_in_set(); + test_log2i(); + test_raw_clone(); diff --git a/SOURCES/0123-nss-unportect-errno-before-writing-to-NSS-errnop.patch b/SOURCES/0123-nss-unportect-errno-before-writing-to-NSS-errnop.patch new file mode 100644 index 0000000..8ed4d22 --- /dev/null +++ b/SOURCES/0123-nss-unportect-errno-before-writing-to-NSS-errnop.patch @@ -0,0 +1,367 @@ +From ecc4a34067ed7c03b9ee710aa5e5976fded48c2a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 18 Jan 2019 20:13:55 +0100 +Subject: [PATCH] nss: unportect errno before writing to NSS' *errnop + +Fixes: #11321 +(cherry picked from commit cdccd29f39cd20cb2a8b71e50445eb839f076331) + +Resolves: #1691691 +--- + src/nss-myhostname/nss-myhostname.c | 13 +++++++++++++ + src/nss-mymachines/nss-mymachines.c | 13 +++++++++++++ + src/nss-resolve/nss-resolve.c | 8 ++++++++ + src/nss-systemd/nss-systemd.c | 10 ++++++++++ + 4 files changed, 44 insertions(+) + +diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c +index 5abc0c91bf..e491351dee 100644 +--- a/src/nss-myhostname/nss-myhostname.c ++++ b/src/nss-myhostname/nss-myhostname.c +@@ -74,6 +74,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + } else { + hn = gethostname_malloc(); + if (!hn) { ++ UNPROTECT_ERRNO; + *errnop = ENOMEM; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; +@@ -96,6 +97,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r( + l = strlen(canonical); + ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2); + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -186,6 +188,8 @@ static enum nss_status fill_in_hostent( + assert(errnop); + assert(h_errnop); + ++ PROTECT_ERRNO; ++ + alen = FAMILY_ADDRESS_SIZE(af); + + for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++) +@@ -202,6 +206,7 @@ static enum nss_status fill_in_hostent( + (c > 0 ? c+1 : 2) * sizeof(char*); + + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -321,6 +326,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + af = AF_INET; + + if (!IN_SET(af, AF_INET, AF_INET6)) { ++ UNPROTECT_ERRNO; + *errnop = EAFNOSUPPORT; + *h_errnop = NO_DATA; + return NSS_STATUS_UNAVAIL; +@@ -343,6 +349,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + } else { + hn = gethostname_malloc(); + if (!hn) { ++ UNPROTECT_ERRNO; + *errnop = ENOMEM; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; +@@ -362,6 +369,8 @@ enum nss_status _nss_myhostname_gethostbyname3_r( + local_address_ipv4 = LOCALADDRESS_IPV4; + } + ++ UNPROTECT_ERRNO; ++ + return fill_in_hostent( + canonical, additional, + af, +@@ -401,12 +410,14 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r( + assert(h_errnop); + + if (!IN_SET(af, AF_INET, AF_INET6)) { ++ UNPROTECT_ERRNO; + *errnop = EAFNOSUPPORT; + *h_errnop = NO_DATA; + return NSS_STATUS_UNAVAIL; + } + + if (len != FAMILY_ADDRESS_SIZE(af)) { ++ UNPROTECT_ERRNO; + *errnop = EINVAL; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; +@@ -461,6 +472,7 @@ found: + if (!canonical || additional_from_hostname) { + hn = gethostname_malloc(); + if (!hn) { ++ UNPROTECT_ERRNO; + *errnop = ENOMEM; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; +@@ -472,6 +484,7 @@ found: + additional = hn; + } + ++ UNPROTECT_ERRNO; + return fill_in_hostent( + canonical, additional, + af, +diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c +index 9b81cd9ad1..af9f0bf41f 100644 +--- a/src/nss-mymachines/nss-mymachines.c ++++ b/src/nss-mymachines/nss-mymachines.c +@@ -134,6 +134,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r( + l = strlen(name); + ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c; + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -208,6 +209,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + *h_errnop = NO_DATA; + return NSS_STATUS_UNAVAIL; +@@ -289,6 +291,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r( + ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*); + + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -372,6 +375,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + *h_errnop = NO_DATA; + return NSS_STATUS_UNAVAIL; +@@ -455,6 +459,7 @@ enum nss_status _nss_mymachines_getpwnam_r( + + l = strlen(name); + if (buflen < l+1) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -472,6 +477,7 @@ enum nss_status _nss_mymachines_getpwnam_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -530,6 +536,7 @@ enum nss_status _nss_mymachines_getpwuid_r( + return NSS_STATUS_NOTFOUND; + + if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -545,6 +552,7 @@ enum nss_status _nss_mymachines_getpwuid_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -623,6 +631,7 @@ enum nss_status _nss_mymachines_getgrnam_r( + + l = sizeof(char*) + strlen(name) + 1; + if (buflen < l) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -638,6 +647,7 @@ enum nss_status _nss_mymachines_getgrnam_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -696,12 +706,14 @@ enum nss_status _nss_mymachines_getgrgid_r( + return NSS_STATUS_NOTFOUND; + + if (buflen < sizeof(char*) + 1) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + memzero(buffer, sizeof(char*)); + if (snprintf(buffer + sizeof(char*), buflen - sizeof(char*), "vg-%s-" GID_FMT, machine, (gid_t) mapped) >= (int) buflen) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -714,6 +726,7 @@ enum nss_status _nss_mymachines_getgrgid_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c +index b2bb698ded..145dbdd60c 100644 +--- a/src/nss-resolve/nss-resolve.c ++++ b/src/nss-resolve/nss-resolve.c +@@ -167,6 +167,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( + l = strlen(canonical); + ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c; + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -248,6 +249,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; +@@ -340,6 +342,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( + ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*); + + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -431,6 +434,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; +@@ -468,12 +472,14 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + assert(h_errnop); + + if (!IN_SET(af, AF_INET, AF_INET6)) { ++ UNPROTECT_ERRNO; + *errnop = EAFNOSUPPORT; + *h_errnop = NO_DATA; + return NSS_STATUS_UNAVAIL; + } + + if (len != FAMILY_ADDRESS_SIZE(af)) { ++ UNPROTECT_ERRNO; + *errnop = EINVAL; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; +@@ -547,6 +553,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + c * sizeof(char*); /* pointers to aliases, plus trailing NULL */ + + if (buflen < ms) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_TRYAGAIN; +@@ -607,6 +614,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + *h_errnop = NO_RECOVERY; + return ret; +diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c +index f554828d49..f8db27ae27 100644 +--- a/src/nss-systemd/nss-systemd.c ++++ b/src/nss-systemd/nss-systemd.c +@@ -210,6 +210,7 @@ enum nss_status _nss_systemd_getpwnam_r( + + l = strlen(name); + if (buflen < l+1) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -227,6 +228,7 @@ enum nss_status _nss_systemd_getpwnam_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -310,6 +312,7 @@ enum nss_status _nss_systemd_getpwuid_r( + + l = strlen(translated) + 1; + if (buflen < l) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -327,6 +330,7 @@ enum nss_status _nss_systemd_getpwuid_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -408,6 +412,7 @@ enum nss_status _nss_systemd_getgrnam_r( + + l = sizeof(char*) + strlen(name) + 1; + if (buflen < l) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -423,6 +428,7 @@ enum nss_status _nss_systemd_getgrnam_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -506,6 +512,7 @@ enum nss_status _nss_systemd_getgrgid_r( + + l = sizeof(char*) + strlen(translated) + 1; + if (buflen < l) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } +@@ -521,6 +528,7 @@ enum nss_status _nss_systemd_getgrgid_r( + return NSS_STATUS_SUCCESS; + + fail: ++ UNPROTECT_ERRNO; + *errnop = -r; + return NSS_STATUS_UNAVAIL; + } +@@ -740,6 +748,7 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz + LIST_FOREACH(entries, p, getpwent_data.position) { + len = strlen(p->name) + 1; + if (buflen < len) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + ret = NSS_STATUS_TRYAGAIN; + goto finalize; +@@ -791,6 +800,7 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size + LIST_FOREACH(entries, p, getgrent_data.position) { + len = sizeof(char*) + strlen(p->name) + 1; + if (buflen < len) { ++ UNPROTECT_ERRNO; + *errnop = ERANGE; + ret = NSS_STATUS_TRYAGAIN; + goto finalize; diff --git a/SOURCES/0124-seccomp-reduce-logging-about-failure-to-add-syscall-.patch b/SOURCES/0124-seccomp-reduce-logging-about-failure-to-add-syscall-.patch new file mode 100644 index 0000000..a08a943 --- /dev/null +++ b/SOURCES/0124-seccomp-reduce-logging-about-failure-to-add-syscall-.patch @@ -0,0 +1,309 @@ +From da8ea9abbacf381513896a7064a1fa0067b3d549 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 24 Sep 2018 16:59:12 +0200 +Subject: [PATCH] seccomp: reduce logging about failure to add syscall to + seccomp + +Our logs are full of: +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldstat() / -10037, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call get_thread_area() / -10076, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call set_thread_area() / -10079, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldfstat() / -10034, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldolduname() / -10036, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call oldlstat() / -10035, ignoring: Numerical argument out of domain +Sep 19 09:22:10 autopkgtest systemd[690]: Failed to add rule for system call waitpid() / -10073, ignoring: Numerical argument out of domain +... +This is pointless and makes debug logs hard to read. Let's keep the logs +in test code, but disable it in nspawn and pid1. This is done through a function +parameter because those functions operate recursively and it's not possible to +make the caller to log meaningfully. + +There should be no functional change, except the skipped debug logs. + +(cherry-picked from commit b54f36c604472ffe08830ec4306fa2885b4a5424) + +Resolves: #1658691 +--- + src/core/execute.c | 6 ++-- + src/nspawn/nspawn-seccomp.c | 4 +-- + src/shared/seccomp-util.c | 57 ++++++++++++++++++++----------------- + src/shared/seccomp-util.h | 6 ++-- + src/test/test-seccomp.c | 16 +++++------ + 5 files changed, 47 insertions(+), 42 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 8ac69d1a0f..ffb92ddfc7 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1415,7 +1415,7 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_ + return r; + } + +- return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action); ++ return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false); + } + + static int apply_syscall_archs(const Unit *u, const ExecContext *c) { +@@ -1498,7 +1498,7 @@ static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) { + if (skip_seccomp_unavailable(u, "ProtectKernelModules=")) + return 0; + +- return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM)); ++ return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM), false); + } + + static int apply_private_devices(const Unit *u, const ExecContext *c) { +@@ -1513,7 +1513,7 @@ static int apply_private_devices(const Unit *u, const ExecContext *c) { + if (skip_seccomp_unavailable(u, "PrivateDevices=")) + return 0; + +- return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM)); ++ return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM), false); + } + + static int apply_restrict_namespaces(const Unit *u, const ExecContext *c) { +diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c +index eb1964bb6d..b56c5b04a8 100644 +--- a/src/nspawn/nspawn-seccomp.c ++++ b/src/nspawn/nspawn-seccomp.c +@@ -148,7 +148,7 @@ static int seccomp_add_default_syscall_filter( + if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0) + continue; + +- r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist); ++ r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false); + if (r < 0) + /* If the system call is not known on this architecture, then that's fine, let's ignore it */ + log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", whitelist[i].name, seccomp_arch_to_string(arch)); +@@ -157,7 +157,7 @@ static int seccomp_add_default_syscall_filter( + } + + STRV_FOREACH(p, syscall_whitelist) { +- r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist); ++ r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false); + if (r < 0) + log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch)); + else +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index c433cb90dc..92910acf0e 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -857,11 +857,9 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name) { + return NULL; + } + +-static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude); +- +-int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude) { +- int r; ++static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, bool log_missing); + ++int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude, bool log_missing) { + assert(seccomp); + assert(name); + +@@ -877,32 +875,36 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, + return -EINVAL; + } + +- r = seccomp_add_syscall_filter_set(seccomp, other, action, exclude); +- if (r < 0) +- return r; ++ return seccomp_add_syscall_filter_set(seccomp, other, action, exclude, log_missing); ++ + } else { +- int id; ++ int id, r; + + id = seccomp_syscall_resolve_name(name); + if (id == __NR_SCMP_ERROR) { +- log_debug("System call %s is not known, ignoring.", name); ++ if (log_missing) ++ log_debug("System call %s is not known, ignoring.", name); + return 0; + } + + r = seccomp_rule_add_exact(seccomp, action, id, 0); +- if (r < 0) ++ if (r < 0) { + /* If the system call is not known on this architecture, then that's fine, let's ignore it */ +- log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", name, id); +- } ++ if (log_missing) ++ log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", ++ name, id); ++ } + +- return 0; ++ return 0; ++ } + } + + static int seccomp_add_syscall_filter_set( + scmp_filter_ctx seccomp, + const SyscallFilterSet *set, + uint32_t action, +- char **exclude) { ++ char **exclude, ++ bool log_missing) { + + const char *sys; + int r; +@@ -911,7 +913,7 @@ static int seccomp_add_syscall_filter_set( + assert(set); + + NULSTR_FOREACH(sys, set->value) { +- r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude); ++ r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing); + if (r < 0) + return r; + } +@@ -919,7 +921,7 @@ static int seccomp_add_syscall_filter_set( + return 0; + } + +-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) { ++int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing) { + uint32_t arch; + int r; + +@@ -937,7 +939,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter + if (r < 0) + return r; + +- r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL); ++ r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing); + if (r < 0) { + log_debug_errno(r, "Failed to add filter set, ignoring: %m"); + continue; +@@ -953,7 +955,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter + return 0; + } + +-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action) { ++int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing) { + uint32_t arch; + int r; + +@@ -966,7 +968,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u + SECCOMP_FOREACH_LOCAL_ARCH(arch) { + _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; + Iterator i; +- void *id, *val; ++ void *syscall_id, *val; + + log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch)); + +@@ -974,20 +976,23 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u + if (r < 0) + return r; + +- HASHMAP_FOREACH_KEY(val, id, set, i) { ++ HASHMAP_FOREACH_KEY(val, syscall_id, set, i) { + uint32_t a = action; +- int e = PTR_TO_INT(val); ++ int id = PTR_TO_INT(syscall_id) - 1; ++ int error = PTR_TO_INT(val); + +- if (action != SCMP_ACT_ALLOW && e >= 0) +- a = SCMP_ACT_ERRNO(e); ++ if (action != SCMP_ACT_ALLOW && error >= 0) ++ a = SCMP_ACT_ERRNO(error); + +- r = seccomp_rule_add_exact(seccomp, a, PTR_TO_INT(id) - 1, 0); ++ r = seccomp_rule_add_exact(seccomp, a, id, 0); + if (r < 0) { + /* If the system call is not known on this architecture, then that's fine, let's ignore it */ + _cleanup_free_ char *n = NULL; + +- n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1); +- log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", strna(n), PTR_TO_INT(id) - 1); ++ n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id); ++ if (log_missing) ++ log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", ++ strna(n), id); + } + } + +diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h +index eac857afb9..d8a36c4e21 100644 +--- a/src/shared/seccomp-util.h ++++ b/src/shared/seccomp-util.h +@@ -58,10 +58,10 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name); + + int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); + +-int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude); ++int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude, bool log_missing); + +-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action); +-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action); ++int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing); ++int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing); + + typedef enum SeccompParseFlags { + SECCOMP_PARSE_INVERT = 1 << 0, +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index d82cb5c1c5..d177515ac7 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -104,11 +104,11 @@ static void test_filter_sets(void) { + if (pid == 0) { /* Child? */ + int fd; + +- /* if we look at the default set (or one that includes it), whitelist instead of blacklist */ ++ /* If we look at the default set (or one that includes it), whitelist instead of blacklist */ + if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE)) +- r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW); ++ r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true); + else +- r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN)); ++ r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true); + if (r < 0) + _exit(EXIT_FAILURE); + +@@ -515,7 +515,7 @@ static void test_load_syscall_filter_set_raw(void) { + assert_se(access("/", F_OK) >= 0); + assert_se(poll(NULL, 0, 0) == 0); + +- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL) >= 0); ++ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL, true) >= 0); + assert_se(access("/", F_OK) >= 0); + assert_se(poll(NULL, 0, 0) == 0); + +@@ -526,7 +526,7 @@ static void test_load_syscall_filter_set_raw(void) { + assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0); + #endif + +- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0); ++ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0); + + assert_se(access("/", F_OK) < 0); + assert_se(errno == EUCLEAN); +@@ -542,7 +542,7 @@ static void test_load_syscall_filter_set_raw(void) { + assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0); + #endif + +- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0); ++ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0); + + assert_se(access("/", F_OK) < 0); + assert_se(errno == EILSEQ); +@@ -558,7 +558,7 @@ static void test_load_syscall_filter_set_raw(void) { + assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0); + #endif + +- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0); ++ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0); + + assert_se(access("/", F_OK) < 0); + assert_se(errno == EILSEQ); +@@ -575,7 +575,7 @@ static void test_load_syscall_filter_set_raw(void) { + assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0); + #endif + +- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0); ++ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0); + + assert_se(access("/", F_OK) < 0); + assert_se(errno == EILSEQ); diff --git a/SOURCES/0125-format-table-when-duplicating-a-cell-also-copy-the-c.patch b/SOURCES/0125-format-table-when-duplicating-a-cell-also-copy-the-c.patch new file mode 100644 index 0000000..efd330b --- /dev/null +++ b/SOURCES/0125-format-table-when-duplicating-a-cell-also-copy-the-c.patch @@ -0,0 +1,25 @@ +From f18db51fffbcecc2d7a30b2317c8a7a43b613757 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 21:16:23 +0100 +Subject: [PATCH] format-table: when duplicating a cell, also copy the color + +(cherry picked from commit 13b0d4d7bdb674d0e51a6d595abd1e7bf2691bf9) + +Related: #1689832 +--- + src/basic/format-table.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 94e796d1ca..3429d9a071 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -414,6 +414,8 @@ static int table_dedup_cell(Table *t, TableCell *cell) { + if (!nd) + return -ENOMEM; + ++ nd->color = od->color; ++ + table_data_unref(od); + t->data[i] = nd; + diff --git a/SOURCES/0126-format-table-optionally-make-specific-cells-clickabl.patch b/SOURCES/0126-format-table-optionally-make-specific-cells-clickabl.patch new file mode 100644 index 0000000..b4fdf1f --- /dev/null +++ b/SOURCES/0126-format-table-optionally-make-specific-cells-clickabl.patch @@ -0,0 +1,203 @@ +From 4ffba0dd993bc461df18fcf59591fc71ab6e6cc8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 6 Nov 2018 12:06:14 +0100 +Subject: [PATCH] format-table: optionally make specific cells clickable links + +(cherry picked from commit 165ca5663e9859083c70d793a6b4aa4f3b2af24c) + +Related: #1689832 +--- + src/basic/format-table.c | 79 +++++++++++++++++++++++++++++++++++----- + src/basic/format-table.h | 1 + + 2 files changed, 71 insertions(+), 9 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 3429d9a071..ac5d66eda2 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -9,6 +9,7 @@ + #include "gunicode.h" + #include "pager.h" + #include "parse-util.h" ++#include "pretty-print.h" + #include "string-util.h" + #include "terminal-util.h" + #include "time-util.h" +@@ -58,6 +59,7 @@ typedef struct TableData { + unsigned align_percent; /* 0 … 100, where to pad with spaces when expanding is needed. 0: left-aligned, 100: right-aligned */ + + const char *color; /* ANSI color string to use for this cell. When written to terminal should not move cursor. Will automatically be reset after the cell */ ++ char *url; /* A URL to use for a clickable hyperlink */ + char *formatted; /* A cached textual representation of the cell data, before ellipsation/alignment */ + + union { +@@ -182,6 +184,8 @@ static TableData *table_data_unref(TableData *d) { + return NULL; + + free(d->formatted); ++ free(d->url); ++ + return mfree(d); + } + +@@ -392,6 +396,7 @@ int table_dup_cell(Table *t, TableCell *cell) { + } + + static int table_dedup_cell(Table *t, TableCell *cell) { ++ _cleanup_free_ char *curl = NULL; + TableData *nd, *od; + size_t i; + +@@ -410,11 +415,25 @@ static int table_dedup_cell(Table *t, TableCell *cell) { + + assert(od->n_ref > 1); + +- nd = table_data_new(od->type, od->data, od->minimum_width, od->maximum_width, od->weight, od->align_percent, od->ellipsize_percent); ++ if (od->url) { ++ curl = strdup(od->url); ++ if (!curl) ++ return -ENOMEM; ++ } ++ ++ nd = table_data_new( ++ od->type, ++ od->data, ++ od->minimum_width, ++ od->maximum_width, ++ od->weight, ++ od->align_percent, ++ od->ellipsize_percent); + if (!nd) + return -ENOMEM; + + nd->color = od->color; ++ nd->url = TAKE_PTR(curl); + + table_data_unref(od); + t->data[i] = nd; +@@ -542,6 +561,26 @@ int table_set_color(Table *t, TableCell *cell, const char *color) { + return 0; + } + ++int table_set_url(Table *t, TableCell *cell, const char *url) { ++ _cleanup_free_ char *copy = NULL; ++ int r; ++ ++ assert(t); ++ assert(cell); ++ ++ if (url) { ++ copy = strdup(url); ++ if (!copy) ++ return -ENOMEM; ++ } ++ ++ r = table_dedup_cell(t, cell); ++ if (r < 0) ++ return r; ++ ++ return free_and_replace(table_get_data(t, cell)->url, copy); ++} ++ + int table_add_many_internal(Table *t, TableDataType first_type, ...) { + TableDataType type; + va_list ap; +@@ -884,11 +923,13 @@ static int table_data_requested_width(TableData *d, size_t *ret) { + return 0; + } + +-static char *align_string_mem(const char *str, size_t new_length, unsigned percent) { +- size_t w = 0, space, lspace, old_length; ++static char *align_string_mem(const char *str, const char *url, size_t new_length, unsigned percent) { ++ size_t w = 0, space, lspace, old_length, clickable_length; ++ _cleanup_free_ char *clickable = NULL; + const char *p; + char *ret; + size_t i; ++ int r; + + /* As with ellipsize_mem(), 'old_length' is a byte size while 'new_length' is a width in character cells */ + +@@ -897,6 +938,15 @@ static char *align_string_mem(const char *str, size_t new_length, unsigned perce + + old_length = strlen(str); + ++ if (url) { ++ r = terminal_urlify(url, str, &clickable); ++ if (r < 0) ++ return NULL; ++ ++ clickable_length = strlen(clickable); ++ } else ++ clickable_length = old_length; ++ + /* Determine current width on screen */ + p = str; + while (p < str + old_length) { +@@ -913,23 +963,23 @@ static char *align_string_mem(const char *str, size_t new_length, unsigned perce + + /* Already wider than the target, if so, don't do anything */ + if (w >= new_length) +- return strndup(str, old_length); ++ return clickable ? TAKE_PTR(clickable) : strdup(str); + + /* How much spaces shall we add? An how much on the left side? */ + space = new_length - w; + lspace = space * percent / 100U; + +- ret = new(char, space + old_length + 1); ++ ret = new(char, space + clickable_length + 1); + if (!ret) + return NULL; + + for (i = 0; i < lspace; i++) + ret[i] = ' '; +- memcpy(ret + lspace, str, old_length); +- for (i = lspace + old_length; i < space + old_length; i++) ++ memcpy(ret + lspace, clickable ?: str, clickable_length); ++ for (i = lspace + clickable_length; i < space + clickable_length; i++) + ret[i] = ' '; + +- ret[space + old_length] = 0; ++ ret[space + clickable_length] = 0; + return ret; + } + +@@ -1184,13 +1234,24 @@ int table_print(Table *t, FILE *f) { + } else if (l < width[j]) { + /* Field is shorter than allocated space. Let's align with spaces */ + +- buffer = align_string_mem(field, width[j], d->align_percent); ++ buffer = align_string_mem(field, d->url, width[j], d->align_percent); + if (!buffer) + return -ENOMEM; + + field = buffer; + } + ++ if (l >= width[j] && d->url) { ++ _cleanup_free_ char *clickable = NULL; ++ ++ r = terminal_urlify(d->url, field, &clickable); ++ if (r < 0) ++ return r; ++ ++ free_and_replace(buffer, clickable); ++ field = buffer; ++ } ++ + if (j > 0) + fputc(' ', f); /* column separator */ + +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 6dc2d16052..9978a8baf2 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -42,6 +42,7 @@ int table_set_weight(Table *t, TableCell *cell, unsigned weight); + int table_set_align_percent(Table *t, TableCell *cell, unsigned percent); + int table_set_ellipsize_percent(Table *t, TableCell *cell, unsigned percent); + int table_set_color(Table *t, TableCell *cell, const char *color); ++int table_set_url(Table *t, TableCell *cell, const char *color); + + int table_add_many_internal(Table *t, TableDataType first_type, ...); + #define table_add_many(t, ...) table_add_many_internal(t, __VA_ARGS__, _TABLE_DATA_TYPE_MAX) diff --git a/SOURCES/0127-format-table-before-outputting-a-color-check-if-colo.patch b/SOURCES/0127-format-table-before-outputting-a-color-check-if-colo.patch new file mode 100644 index 0000000..8a57493 --- /dev/null +++ b/SOURCES/0127-format-table-before-outputting-a-color-check-if-colo.patch @@ -0,0 +1,40 @@ +From 02b72c15a53f694f65a377206fba478db91432cd Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 6 Nov 2018 18:37:21 +0100 +Subject: [PATCH] format-table: before outputting a color, check if colors are + available + +This is in many cases redundant, as a similar check is done by various +callers already, but in other cases (where we read the color from a +static table for example), it's nice to let the color check be done by +the table code itself, and since it doesn't hurt in the other cases just +do it again. + +(cherry picked from commit a22318e55492af721879d8692ed039144696bb08) + +Related: #1689832 +--- + src/basic/format-table.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index ac5d66eda2..17be7285cd 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -1255,13 +1255,13 @@ int table_print(Table *t, FILE *f) { + if (j > 0) + fputc(' ', f); /* column separator */ + +- if (d->color) ++ if (d->color && colors_enabled()) + fputs(d->color, f); + + fputs(field, f); + +- if (d->color) +- fputs(ansi_normal(), f); ++ if (d->color && colors_enabled()) ++ fputs(ANSI_NORMAL, f); + } + + fputc('\n', f); diff --git a/SOURCES/0128-format-table-add-option-to-store-format-percent-and-.patch b/SOURCES/0128-format-table-add-option-to-store-format-percent-and-.patch new file mode 100644 index 0000000..7e5e8ac --- /dev/null +++ b/SOURCES/0128-format-table-add-option-to-store-format-percent-and-.patch @@ -0,0 +1,147 @@ +From 85ccda9eabb6b89e644cedd9faafb5dbe97e8341 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 7 Nov 2018 15:25:51 +0100 +Subject: [PATCH] format-table: add option to store/format percent and uint64_t + values in cells + +(cherry picked from commit a4661181fa702a8bff4644210ba7ea14bea51a4a) + +Related: #1689832 +--- + src/basic/format-table.c | 48 ++++++++++++++++++++++++++++++++++++++++ + src/basic/format-table.h | 2 ++ + src/basic/macro.h | 9 ++++++++ + 3 files changed, 59 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 17be7285cd..64b9eb4108 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -70,6 +70,8 @@ typedef struct TableData { + uint64_t size; + char string[0]; + uint32_t uint32; ++ uint64_t uint64; ++ int percent; /* we use 'int' as datatype for percent values in order to match the result of parse_percent() */ + /* … add more here as we start supporting more cell data types … */ + }; + } TableData; +@@ -235,11 +237,15 @@ static size_t table_data_size(TableDataType type, const void *data) { + return sizeof(usec_t); + + case TABLE_SIZE: ++ case TABLE_UINT64: + return sizeof(uint64_t); + + case TABLE_UINT32: + return sizeof(uint32_t); + ++ case TABLE_PERCENT: ++ return sizeof(int); ++ + default: + assert_not_reached("Uh? Unexpected cell type"); + } +@@ -599,6 +605,8 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { + uint64_t size; + usec_t usec; + uint32_t uint32; ++ uint64_t uint64; ++ int percent; + bool b; + } buffer; + +@@ -633,6 +641,16 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { + data = &buffer.uint32; + break; + ++ case TABLE_UINT64: ++ buffer.uint64 = va_arg(ap, uint64_t); ++ data = &buffer.uint64; ++ break; ++ ++ case TABLE_PERCENT: ++ buffer.percent = va_arg(ap, int); ++ data = &buffer.percent; ++ break; ++ + case _TABLE_DATA_TYPE_MAX: + /* Used as end marker */ + va_end(ap); +@@ -772,6 +790,12 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t + return 1; + return 0; + ++ case TABLE_UINT64: ++ return CMP(a->uint64, b->uint64); ++ ++ case TABLE_PERCENT: ++ return CMP(a->percent, b->percent); ++ + default: + ; + } +@@ -894,6 +918,30 @@ static const char *table_data_format(TableData *d) { + break; + } + ++ case TABLE_UINT64: { ++ _cleanup_free_ char *p; ++ ++ p = new(char, DECIMAL_STR_WIDTH(d->uint64) + 1); ++ if (!p) ++ return NULL; ++ ++ sprintf(p, "%" PRIu64, d->uint64); ++ d->formatted = TAKE_PTR(p); ++ break; ++ } ++ ++ case TABLE_PERCENT: { ++ _cleanup_free_ char *p; ++ ++ p = new(char, DECIMAL_STR_WIDTH(d->percent) + 2); ++ if (!p) ++ return NULL; ++ ++ sprintf(p, "%i%%" , d->percent); ++ d->formatted = TAKE_PTR(p); ++ break; ++ } ++ + default: + assert_not_reached("Unexpected type?"); + } +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 9978a8baf2..2db2084062 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -15,6 +15,8 @@ typedef enum TableDataType { + TABLE_TIMESPAN, + TABLE_SIZE, + TABLE_UINT32, ++ TABLE_UINT64, ++ TABLE_PERCENT, + _TABLE_DATA_TYPE_MAX, + _TABLE_DATA_TYPE_INVALID = -1, + } TableDataType; +diff --git a/src/basic/macro.h b/src/basic/macro.h +index d1365f7058..79ab02b27a 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -222,6 +222,15 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { + UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \ + }) + ++#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b)) ++#define __CMP(aq, a, bq, b) \ ++ ({ \ ++ const typeof(a) UNIQ_T(A, aq) = (a); \ ++ const typeof(b) UNIQ_T(B, bq) = (b); \ ++ UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 : \ ++ UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0; \ ++ }) ++ + #undef CLAMP + #define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) + #define __CLAMP(xq, x, lowq, low, highq, high) \ diff --git a/SOURCES/0129-format-table-optionally-allow-reversing-the-sort-ord.patch b/SOURCES/0129-format-table-optionally-allow-reversing-the-sort-ord.patch new file mode 100644 index 0000000..53d0100 --- /dev/null +++ b/SOURCES/0129-format-table-optionally-allow-reversing-the-sort-ord.patch @@ -0,0 +1,77 @@ +From 75130d739d206715a09619c7b7bf62613dab1d2b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 7 Nov 2018 17:41:32 +0100 +Subject: [PATCH] format-table: optionally allow reversing the sort order for a + column + +(cherry picked from commit a2c73e2d3823e878de7a7ee193631108c5fc5be0) + +Related: #1689832 +--- + src/basic/format-table.c | 22 +++++++++++++++++++++- + src/basic/format-table.h | 1 + + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 64b9eb4108..a3ff527e91 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -107,6 +107,8 @@ struct Table { + + size_t *sort_map; /* The columns to order rows by, in order of preference. */ + size_t n_sort_map; ++ ++ bool *reverse_map; + }; + + Table *table_new_raw(size_t n_columns) { +@@ -215,6 +217,7 @@ Table *table_unref(Table *t) { + free(t->data); + free(t->display_map); + free(t->sort_map); ++ free(t->reverse_map); + + return mfree(t); + } +@@ -836,7 +839,7 @@ static int table_data_compare(const void *x, const void *y, void *userdata) { + + r = cell_data_compare(d, *a, dd, *b); + if (r != 0) +- return r; ++ return t->reverse_map && t->reverse_map[t->sort_map[i]] ? -r : r; + } + + /* Order identical lines by the order there were originally added in */ +@@ -1356,3 +1359,20 @@ size_t table_get_columns(Table *t) { + assert(t->n_columns > 0); + return t->n_columns; + } ++ ++int table_set_reverse(Table *t, size_t column, bool b) { ++ assert(t); ++ assert(column < t->n_columns); ++ ++ if (!t->reverse_map) { ++ if (!b) ++ return 0; ++ ++ t->reverse_map = new0(bool, t->n_columns); ++ if (!t->reverse_map) ++ return -ENOMEM; ++ } ++ ++ t->reverse_map[column] = b; ++ return 0; ++} +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 2db2084062..07cb2351cb 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -53,6 +53,7 @@ void table_set_header(Table *table, bool b); + void table_set_width(Table *t, size_t width); + int table_set_display(Table *t, size_t first_column, ...); + int table_set_sort(Table *t, size_t first_column, ...); ++int table_set_reverse(Table *t, size_t column, bool b); + + int table_print(Table *t, FILE *f); + int table_format(Table *t, char **ret); diff --git a/SOURCES/0130-format-table-add-table_update-to-update-existing-ent.patch b/SOURCES/0130-format-table-add-table_update-to-update-existing-ent.patch new file mode 100644 index 0000000..258fca3 --- /dev/null +++ b/SOURCES/0130-format-table-add-table_update-to-update-existing-ent.patch @@ -0,0 +1,77 @@ +From a53afb337985f8f1c7fe8f620fe30cec87f554d5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 21:17:47 +0100 +Subject: [PATCH] format-table: add table_update() to update existing entries + +(cherry picked from commit 27e730e6d0a7709c17ccef170f10846e92dca2a0) + +Related: #1689832 +--- + src/basic/format-table.c | 40 ++++++++++++++++++++++++++++++++++++++++ + src/basic/format-table.h | 2 ++ + 2 files changed, 42 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index a3ff527e91..302642d748 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -590,6 +590,46 @@ int table_set_url(Table *t, TableCell *cell, const char *url) { + return free_and_replace(table_get_data(t, cell)->url, copy); + } + ++int table_update(Table *t, TableCell *cell, TableDataType type, const void *data) { ++ _cleanup_free_ char *curl = NULL; ++ TableData *nd, *od; ++ size_t i; ++ ++ assert(t); ++ assert(cell); ++ ++ i = TABLE_CELL_TO_INDEX(cell); ++ if (i >= t->n_cells) ++ return -ENXIO; ++ ++ assert_se(od = t->data[i]); ++ ++ if (od->url) { ++ curl = strdup(od->url); ++ if (!curl) ++ return -ENOMEM; ++ } ++ ++ nd = table_data_new( ++ type, ++ data, ++ od->minimum_width, ++ od->maximum_width, ++ od->weight, ++ od->align_percent, ++ od->ellipsize_percent); ++ if (!nd) ++ return -ENOMEM; ++ ++ nd->color = od->color; ++ nd->url = TAKE_PTR(curl); ++ ++ table_data_unref(od); ++ t->data[i] = nd; ++ ++ return 0; ++} ++ + int table_add_many_internal(Table *t, TableDataType first_type, ...) { + TableDataType type; + va_list ap; +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 07cb2351cb..4273c8c49b 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -46,6 +46,8 @@ int table_set_ellipsize_percent(Table *t, TableCell *cell, unsigned percent); + int table_set_color(Table *t, TableCell *cell, const char *color); + int table_set_url(Table *t, TableCell *cell, const char *color); + ++int table_update(Table *t, TableCell *cell, TableDataType type, const void *data); ++ + int table_add_many_internal(Table *t, TableDataType first_type, ...); + #define table_add_many(t, ...) table_add_many_internal(t, __VA_ARGS__, _TABLE_DATA_TYPE_MAX) + diff --git a/SOURCES/0131-format-table-add-an-API-for-getting-the-cell-at-a-sp.patch b/SOURCES/0131-format-table-add-an-API-for-getting-the-cell-at-a-sp.patch new file mode 100644 index 0000000..1e6698e --- /dev/null +++ b/SOURCES/0131-format-table-add-an-API-for-getting-the-cell-at-a-sp.patch @@ -0,0 +1,47 @@ +From ecc27a3bf5935cebc63aa4e3b650861d1f0ef97f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 21:21:09 +0100 +Subject: [PATCH] format-table: add an API for getting the cell at a specific + row/column + +(cherry picked from commit 9314ead7853a1479fc60eb2ae7e3d0a77b7eba7c) + +Related: #1689832 +--- + src/basic/format-table.c | 15 +++++++++++++++ + src/basic/format-table.h | 2 ++ + 2 files changed, 17 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 302642d748..809a4be284 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -1416,3 +1416,18 @@ int table_set_reverse(Table *t, size_t column, bool b) { + t->reverse_map[column] = b; + return 0; + } ++ ++TableCell *table_get_cell(Table *t, size_t row, size_t column) { ++ size_t i; ++ ++ assert(t); ++ ++ if (column >= t->n_columns) ++ return NULL; ++ ++ i = row * t->n_columns + column; ++ if (i >= t->n_cells) ++ return NULL; ++ ++ return TABLE_INDEX_TO_CELL(i); ++} +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 4273c8c49b..40fea79f78 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -66,3 +66,5 @@ static inline TableCell* TABLE_HEADER_CELL(size_t i) { + + size_t table_get_rows(Table *t); + size_t table_get_columns(Table *t); ++ ++TableCell *table_get_cell(Table *t, size_t row, size_t column); diff --git a/SOURCES/0132-format-table-always-underline-header-line.patch b/SOURCES/0132-format-table-always-underline-header-line.patch new file mode 100644 index 0000000..9eb9495 --- /dev/null +++ b/SOURCES/0132-format-table-always-underline-header-line.patch @@ -0,0 +1,41 @@ +From cb35bd029dedf39b7be4945d57176a5b1aa03da9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 21:39:28 +0100 +Subject: [PATCH] format-table: always underline header line + +(cherry picked from commit 30d98de00c68440ff4d77d851b4b3323c34027da) + +Related: #1689832 +--- + src/basic/format-table.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 809a4be284..3fcb97475c 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -1343,15 +1343,22 @@ int table_print(Table *t, FILE *f) { + field = buffer; + } + ++ if (row == t->data) /* underline header line fully, including the column separator */ ++ fputs(ansi_underline(), f); ++ + if (j > 0) + fputc(' ', f); /* column separator */ + +- if (d->color && colors_enabled()) ++ if (d->color && colors_enabled()) { ++ if (row == t->data) /* first undo header underliner */ ++ fputs(ANSI_NORMAL, f); ++ + fputs(d->color, f); ++ } + + fputs(field, f); + +- if (d->color && colors_enabled()) ++ if (colors_enabled() && (d->color || row == t->data)) + fputs(ANSI_NORMAL, f); + } + diff --git a/SOURCES/0133-format-table-add-calls-to-query-the-data-in-a-specif.patch b/SOURCES/0133-format-table-add-calls-to-query-the-data-in-a-specif.patch new file mode 100644 index 0000000..669a19c --- /dev/null +++ b/SOURCES/0133-format-table-add-calls-to-query-the-data-in-a-specif.patch @@ -0,0 +1,54 @@ +From c4f60df10a2716c94d30462a118f60d916d537a2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 9 Nov 2018 11:38:12 +0100 +Subject: [PATCH] format-table: add calls to query the data in a specific cell + +(cherry picked from commit 62d99b39709f903f8a66a9aae757deb5546a53eb) + +Related: #1689832 +--- + src/basic/format-table.c | 22 ++++++++++++++++++++++ + src/basic/format-table.h | 3 +++ + 2 files changed, 25 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 3fcb97475c..0a1777e9a2 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -1438,3 +1438,25 @@ TableCell *table_get_cell(Table *t, size_t row, size_t column) { + + return TABLE_INDEX_TO_CELL(i); + } ++ ++const void *table_get(Table *t, TableCell *cell) { ++ TableData *d; ++ ++ assert(t); ++ ++ d = table_get_data(t, cell); ++ if (!d) ++ return NULL; ++ ++ return d->data; ++} ++ ++const void* table_get_at(Table *t, size_t row, size_t column) { ++ TableCell *cell; ++ ++ cell = table_get_cell(t, row, column); ++ if (!cell) ++ return NULL; ++ ++ return table_get(t, cell); ++} +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 40fea79f78..a2bb2e0846 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -68,3 +68,6 @@ size_t table_get_rows(Table *t); + size_t table_get_columns(Table *t); + + TableCell *table_get_cell(Table *t, size_t row, size_t column); ++ ++const void *table_get(Table *t, TableCell *cell); ++const void *table_get_at(Table *t, size_t row, size_t column); diff --git a/SOURCES/0134-format-table-make-sure-we-never-call-memcmp-with-NUL.patch b/SOURCES/0134-format-table-make-sure-we-never-call-memcmp-with-NUL.patch new file mode 100644 index 0000000..8b022b0 --- /dev/null +++ b/SOURCES/0134-format-table-make-sure-we-never-call-memcmp-with-NUL.patch @@ -0,0 +1,47 @@ +From 4339aa85279d268a671a656f142445559be771b7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 14 Nov 2018 18:39:37 +0100 +Subject: [PATCH] format-table: make sure we never call memcmp() with NULL + parameters + +(cherry picked from commit 88db94fa57c9a5b1a0b926c49d3624fc84c88090) + +Related: #1689832 +--- + src/basic/format-table.c | 2 +- + src/basic/util.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 0a1777e9a2..5517adad82 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -291,7 +291,7 @@ static bool table_data_matches( + if (k != l) + return false; + +- return memcmp(data, d->data, l) == 0; ++ return memcmp_safe(data, d->data, l) == 0; + } + + static TableData *table_data_new( +diff --git a/src/basic/util.h b/src/basic/util.h +index 27b5a09782..b68ef25ed8 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -123,6 +123,15 @@ static inline void memcpy_safe(void *dst, const void *src, size_t n) { + memcpy(dst, src, n); + } + ++/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */ ++static inline int memcmp_safe(const void *s1, const void *s2, size_t n) { ++ if (n == 0) ++ return 0; ++ assert(s1); ++ assert(s2); ++ return memcmp(s1, s2, n); ++} ++ + int on_ac_power(void); + + #define memzero(x,l) (memset((x), 0, (l))) diff --git a/SOURCES/0135-format-table-use-right-field-for-display.patch b/SOURCES/0135-format-table-use-right-field-for-display.patch new file mode 100644 index 0000000..eba9ee4 --- /dev/null +++ b/SOURCES/0135-format-table-use-right-field-for-display.patch @@ -0,0 +1,29 @@ +From d4c1d109a883fbc5695cf10c79e61bedbe788829 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 3 Dec 2018 20:28:15 +0100 +Subject: [PATCH] format-table: use right field for display + +Since .timespan and .timestamp are unionized on top of each other this +doesn't actually matter, but it is still more correct to address it +under it's correct name. + +(cherry picked from commit c93d372d7ceda0b080487fa35d3638ef3d8507cb) + +Related: #1689832 +--- + src/basic/format-table.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 5517adad82..cfb8aadbda 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -928,7 +928,7 @@ static const char *table_data_format(TableData *d) { + if (!p) + return NULL; + +- if (!format_timespan(p, FORMAT_TIMESPAN_MAX, d->timestamp, 0)) ++ if (!format_timespan(p, FORMAT_TIMESPAN_MAX, d->timespan, 0)) + return "n/a"; + + d->formatted = TAKE_PTR(p); diff --git a/SOURCES/0136-format-table-add-option-to-uppercase-cells-on-displa.patch b/SOURCES/0136-format-table-add-option-to-uppercase-cells-on-displa.patch new file mode 100644 index 0000000..0c0523c --- /dev/null +++ b/SOURCES/0136-format-table-add-option-to-uppercase-cells-on-displa.patch @@ -0,0 +1,165 @@ +From 1d3c6e3c0937ac56a51594a3b6908a801fa9ac5c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 3 Dec 2018 21:36:26 +0100 +Subject: [PATCH] format-table: add option to uppercase cells on display + +This adds a per-cell option for uppercasing displayed strings. +Implicitly turn this on for the header row. The fact that we format the +table header in uppercase is a formatting thing after all, hence should +be applied by the formatter, i.e. the table display code. + +Moreover, this provides us with the benefit that we can more nicely +reuse the specified table headers as JSON field names, like we already +do: json field names are usually not uppercase. + +(cherry picked from commit 359abf6dd05aa6bca3438e9c969ed904bd3d447d) + +Related: #1689832 +--- + src/basic/format-table.c | 62 ++++++++++++++++++++++++++++++++-------- + src/basic/format-table.h | 1 + + 2 files changed, 51 insertions(+), 12 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index cfb8aadbda..fe2201ee5f 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -1,5 +1,6 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include + #include + + #include "alloc-util.h" +@@ -58,6 +59,8 @@ typedef struct TableData { + unsigned ellipsize_percent; /* 0 … 100, where to place the ellipsis when compression is needed */ + unsigned align_percent; /* 0 … 100, where to pad with spaces when expanding is needed. 0: left-aligned, 100: right-aligned */ + ++ bool uppercase; /* Uppercase string on display */ ++ + const char *color; /* ANSI color string to use for this cell. When written to terminal should not move cursor. Will automatically be reset after the cell */ + char *url; /* A URL to use for a clickable hyperlink */ + char *formatted; /* A cached textual representation of the cell data, before ellipsation/alignment */ +@@ -132,6 +135,7 @@ Table *table_new_raw(size_t n_columns) { + Table *table_new_internal(const char *first_header, ...) { + _cleanup_(table_unrefp) Table *t = NULL; + size_t n_columns = 1; ++ const char *h; + va_list ap; + int r; + +@@ -139,8 +143,6 @@ Table *table_new_internal(const char *first_header, ...) { + + va_start(ap, first_header); + for (;;) { +- const char *h; +- + h = va_arg(ap, const char*); + if (!h) + break; +@@ -153,19 +155,18 @@ Table *table_new_internal(const char *first_header, ...) { + if (!t) + return NULL; + +- r = table_add_cell(t, NULL, TABLE_STRING, first_header); +- if (r < 0) +- return NULL; +- + va_start(ap, first_header); +- for (;;) { +- const char *h; ++ for (h = first_header; h; h = va_arg(ap, const char*)) { ++ TableCell *cell; + +- h = va_arg(ap, const char*); +- if (!h) +- break; ++ r = table_add_cell(t, &cell, TABLE_STRING, h); ++ if (r < 0) { ++ va_end(ap); ++ return NULL; ++ } + +- r = table_add_cell(t, NULL, TABLE_STRING, h); ++ /* Make the table header uppercase */ ++ r = table_set_uppercase(t, cell, true); + if (r < 0) { + va_end(ap); + return NULL; +@@ -443,6 +444,7 @@ static int table_dedup_cell(Table *t, TableCell *cell) { + + nd->color = od->color; + nd->url = TAKE_PTR(curl); ++ nd->uppercase = od->uppercase; + + table_data_unref(od); + t->data[i] = nd; +@@ -590,6 +592,27 @@ int table_set_url(Table *t, TableCell *cell, const char *url) { + return free_and_replace(table_get_data(t, cell)->url, copy); + } + ++int table_set_uppercase(Table *t, TableCell *cell, bool b) { ++ TableData *d; ++ int r; ++ ++ assert(t); ++ assert(cell); ++ ++ r = table_dedup_cell(t, cell); ++ if (r < 0) ++ return r; ++ ++ assert_se(d = table_get_data(t, cell)); ++ ++ if (d->uppercase == b) ++ return 0; ++ ++ d->formatted = mfree(d->formatted); ++ d->uppercase = b; ++ return 1; ++} ++ + int table_update(Table *t, TableCell *cell, TableDataType type, const void *data) { + _cleanup_free_ char *curl = NULL; + TableData *nd, *od; +@@ -623,6 +646,7 @@ int table_update(Table *t, TableCell *cell, TableDataType type, const void *data + + nd->color = od->color; + nd->url = TAKE_PTR(curl); ++ nd->uppercase = od->uppercase; + + table_data_unref(od); + t->data[i] = nd; +@@ -902,6 +926,20 @@ static const char *table_data_format(TableData *d) { + return ""; + + case TABLE_STRING: ++ if (d->uppercase) { ++ char *p, *q; ++ ++ d->formatted = new(char, strlen(d->string) + 1); ++ if (!d->formatted) ++ return NULL; ++ ++ for (p = d->string, q = d->formatted; *p; p++, q++) ++ *q = (char) toupper((unsigned char) *p); ++ *q = 0; ++ ++ return d->formatted; ++ } ++ + return d->string; + + case TABLE_BOOLEAN: +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index a2bb2e0846..5a076b5383 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -45,6 +45,7 @@ int table_set_align_percent(Table *t, TableCell *cell, unsigned percent); + int table_set_ellipsize_percent(Table *t, TableCell *cell, unsigned percent); + int table_set_color(Table *t, TableCell *cell, const char *color); + int table_set_url(Table *t, TableCell *cell, const char *color); ++int table_set_uppercase(Table *t, TableCell *cell, bool b); + + int table_update(Table *t, TableCell *cell, TableDataType type, const void *data); + diff --git a/SOURCES/0137-format-table-never-try-to-reuse-cells-that-have-colo.patch b/SOURCES/0137-format-table-never-try-to-reuse-cells-that-have-colo.patch new file mode 100644 index 0000000..c1200ce --- /dev/null +++ b/SOURCES/0137-format-table-never-try-to-reuse-cells-that-have-colo.patch @@ -0,0 +1,36 @@ +From a064e883c7cc28b8d561a7fea56b139d8e7d2286 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 3 Dec 2018 21:39:39 +0100 +Subject: [PATCH] format-table: never try to reuse cells that have + color/url/uppercase set + +The table cell reusing code is supposed to be an internal memory +optimization, and not more. This means behaviour should be the same as +if we wouldn't reuse cells. + +(cherry picked from commit 94a80afed42a8b36d69a229bf44ba690f8f59a78) + +Related: #1689832 +--- + src/basic/format-table.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index fe2201ee5f..844b92f41c 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -286,6 +286,14 @@ static bool table_data_matches( + if (d->ellipsize_percent != ellipsize_percent) + return false; + ++ /* If a color/url/uppercase flag is set, refuse to merge */ ++ if (d->color) ++ return false; ++ if (d->url) ++ return false; ++ if (d->uppercase) ++ return false; ++ + k = table_data_size(type, data); + l = table_data_size(d->type, d->data); + diff --git a/SOURCES/0138-locale-util-add-logic-to-output-smiley-emojis-at-var.patch b/SOURCES/0138-locale-util-add-logic-to-output-smiley-emojis-at-var.patch new file mode 100644 index 0000000..6205811 --- /dev/null +++ b/SOURCES/0138-locale-util-add-logic-to-output-smiley-emojis-at-var.patch @@ -0,0 +1,207 @@ +From bc00d9db41a87b7a4b92c46f277e62ad58768420 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 6 Nov 2018 17:59:58 +0100 +Subject: [PATCH] locale-util: add logic to output smiley emojis at various + happiness levels + +(cherry picked from commit 5f1b0cc6d064f7847982e7b680cab3d080aef52e) + +Conflicts: + doc/ENVIRONMENT.md + src/basic/locale-util.c + src/basic/locale-util.h + src/test/test-locale-util.c + +Related: #1689832 +--- + doc/ENVIRONMENT.md | 5 +++ + src/basic/locale-util.c | 81 ++++++++++++++++++++++++++++--------- + src/basic/locale-util.h | 12 ++++++ + src/test/test-locale-util.c | 12 +++++- + 4 files changed, 90 insertions(+), 20 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 85d26fe28c..1e648be640 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -37,6 +37,11 @@ All tools: + useful for debugging, in order to test generators and other code against + specific kernel command lines. + ++* `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will ++ not output graphical smiley emojis, but ASCII alternatives instead. Note that ++ this only controls use of Unicode emoji glyphs, and has no effect on other ++ Unicode glyphs. ++ + systemctl: + + * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus +diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c +index 3ad352f22f..7cd143ea6f 100644 +--- a/src/basic/locale-util.c ++++ b/src/basic/locale-util.c +@@ -16,6 +16,7 @@ + + #include "def.h" + #include "dirent-util.h" ++#include "env-util.h" + #include "fd-util.h" + #include "hashmap.h" + #include "locale-util.h" +@@ -347,6 +348,24 @@ bool keymap_is_valid(const char *name) { + return true; + } + ++static bool emoji_enabled(void) { ++ static int cached_emoji_enabled = -1; ++ ++ if (cached_emoji_enabled < 0) { ++ int val; ++ ++ val = getenv_bool("SYSTEMD_EMOJI"); ++ if (val < 0) ++ cached_emoji_enabled = ++ is_locale_utf8() && ++ !STRPTR_IN_SET(getenv("TERM"), "dumb", "linux"); ++ else ++ cached_emoji_enabled = val; ++ } ++ ++ return cached_emoji_enabled; ++} ++ + const char *special_glyph(SpecialGlyph code) { + + /* A list of a number of interesting unicode glyphs we can use to decorate our output. It's probably wise to be +@@ -359,32 +378,56 @@ const char *special_glyph(SpecialGlyph code) { + static const char* const draw_table[2][_SPECIAL_GLYPH_MAX] = { + /* ASCII fallback */ + [false] = { +- [TREE_VERTICAL] = "| ", +- [TREE_BRANCH] = "|-", +- [TREE_RIGHT] = "`-", +- [TREE_SPACE] = " ", +- [TRIANGULAR_BULLET] = ">", +- [BLACK_CIRCLE] = "*", +- [ARROW] = "->", +- [MDASH] = "-", +- [ELLIPSIS] = "..." ++ [TREE_VERTICAL] = "| ", ++ [TREE_BRANCH] = "|-", ++ [TREE_RIGHT] = "`-", ++ [TREE_SPACE] = " ", ++ [TRIANGULAR_BULLET] = ">", ++ [BLACK_CIRCLE] = "*", ++ [BULLET] = "*", ++ [ARROW] = "->", ++ [MDASH] = "-", ++ [ELLIPSIS] = "...", ++ [MU] = "u", ++ [CHECK_MARK] = "+", ++ [CROSS_MARK] = "-", ++ [ECSTATIC_SMILEY] = ":-]", ++ [HAPPY_SMILEY] = ":-}", ++ [SLIGHTLY_HAPPY_SMILEY] = ":-)", ++ [NEUTRAL_SMILEY] = ":-|", ++ [SLIGHTLY_UNHAPPY_SMILEY] = ":-(", ++ [UNHAPPY_SMILEY] = ":-{️", ++ [DEPRESSED_SMILEY] = ":-[", + }, + + /* UTF-8 */ + [true] = { +- [TREE_VERTICAL] = "\342\224\202 ", /* │ */ +- [TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ +- [TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ +- [TREE_SPACE] = " ", /* */ +- [TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */ +- [BLACK_CIRCLE] = "\342\227\217", /* ● */ +- [ARROW] = "\342\206\222", /* → */ +- [MDASH] = "\342\200\223", /* – */ +- [ELLIPSIS] = "\342\200\246", /* … */ ++ [TREE_VERTICAL] = "\342\224\202 ", /* │ */ ++ [TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ ++ [TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ ++ [TREE_SPACE] = " ", /* */ ++ [TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */ ++ [BLACK_CIRCLE] = "\342\227\217", /* ● */ ++ [BULLET] = "\342\200\242", /* • */ ++ [ARROW] = "\342\206\222", /* → */ ++ [MDASH] = "\342\200\223", /* – */ ++ [ELLIPSIS] = "\342\200\246", /* … */ ++ [MU] = "\316\274", /* μ */ ++ [CHECK_MARK] = "\342\234\223", /* ✓ */ ++ [CROSS_MARK] = "\342\234\227", /* ✗ */ ++ [ECSTATIC_SMILEY] = "\360\237\230\207", /* 😇 */ ++ [HAPPY_SMILEY] = "\360\237\230\200", /* 😀 */ ++ [SLIGHTLY_HAPPY_SMILEY] = "\360\237\231\202", /* 🙂 */ ++ [NEUTRAL_SMILEY] = "\360\237\230\220", /* 😐 */ ++ [SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201", /* 🙁 */ ++ [UNHAPPY_SMILEY] = "\360\237\230\250", /* 😨️️ */ ++ [DEPRESSED_SMILEY] = "\360\237\244\242", /* 🤢 */ + }, + }; + +- return draw_table[is_locale_utf8()][code]; ++ assert(code < _SPECIAL_GLYPH_MAX); ++ ++ return draw_table[code >= _SPECIAL_GLYPH_FIRST_SMILEY ? emoji_enabled() : is_locale_utf8()][code]; + } + + static const char * const locale_variable_table[_VARIABLE_LC_MAX] = { +diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h +index 775fe8bc72..368675f286 100644 +--- a/src/basic/locale-util.h ++++ b/src/basic/locale-util.h +@@ -45,9 +45,21 @@ typedef enum { + TREE_SPACE, + TRIANGULAR_BULLET, + BLACK_CIRCLE, ++ BULLET, + ARROW, + MDASH, + ELLIPSIS, ++ MU, ++ CHECK_MARK, ++ CROSS_MARK, ++ _SPECIAL_GLYPH_FIRST_SMILEY, ++ ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_SMILEY, ++ HAPPY_SMILEY, ++ SLIGHTLY_HAPPY_SMILEY, ++ NEUTRAL_SMILEY, ++ SLIGHTLY_UNHAPPY_SMILEY, ++ UNHAPPY_SMILEY, ++ DEPRESSED_SMILEY, + _SPECIAL_GLYPH_MAX + } SpecialGlyph; + +diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c +index 8ffae8ca03..0c3f6a62ed 100644 +--- a/src/test/test-locale-util.c ++++ b/src/test/test-locale-util.c +@@ -65,7 +65,7 @@ static void test_keymaps(void) { + + #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x)) + static void dump_special_glyphs(void) { +- assert_cc(ELLIPSIS + 1 == _SPECIAL_GLYPH_MAX); ++ assert_cc(DEPRESSED_SMILEY + 1 == _SPECIAL_GLYPH_MAX); + + log_info("/* %s */", __func__); + +@@ -80,6 +80,16 @@ static void dump_special_glyphs(void) { + dump_glyph(ARROW); + dump_glyph(MDASH); + dump_glyph(ELLIPSIS); ++ dump_glyph(MU); ++ dump_glyph(CHECK_MARK); ++ dump_glyph(CROSS_MARK); ++ dump_glyph(ECSTATIC_SMILEY); ++ dump_glyph(HAPPY_SMILEY); ++ dump_glyph(SLIGHTLY_HAPPY_SMILEY); ++ dump_glyph(NEUTRAL_SMILEY); ++ dump_glyph(SLIGHTLY_UNHAPPY_SMILEY); ++ dump_glyph(UNHAPPY_SMILEY); ++ dump_glyph(DEPRESSED_SMILEY); + } + + int main(int argc, char *argv[]) { diff --git a/SOURCES/0139-analyze-add-new-security-verb.patch b/SOURCES/0139-analyze-add-new-security-verb.patch new file mode 100644 index 0000000..d8ea17b --- /dev/null +++ b/SOURCES/0139-analyze-add-new-security-verb.patch @@ -0,0 +1,2310 @@ +From f5bd75fb574b9be80879fda5a889ddfd2b706248 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 09:32:17 +0100 +Subject: [PATCH] analyze: add new security verb + +(cherry picked from commit ec16f3b6dd8b03e3ce6eff1fa9f21432208ef42b) + +Conflicts: + src/analyze/analyze.c + +Resolves: #1689832 +--- + src/analyze/analyze-security.c | 2078 ++++++++++++++++++++++++++++++++ + src/analyze/analyze-security.h | 12 + + src/analyze/analyze.c | 16 + + src/analyze/meson.build | 2 + + src/basic/format-table.c | 1 - + src/basic/macro.h | 13 +- + src/basic/terminal-util.c | 53 +- + src/basic/terminal-util.h | 1 + + 8 files changed, 2150 insertions(+), 26 deletions(-) + create mode 100644 src/analyze/analyze-security.c + create mode 100644 src/analyze/analyze-security.h + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +new file mode 100644 +index 0000000000..541fc0d97a +--- /dev/null ++++ b/src/analyze/analyze-security.c +@@ -0,0 +1,2078 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++#include ++ ++#include "analyze-security.h" ++#include "bus-error.h" ++#include "bus-unit-util.h" ++#include "bus-util.h" ++#include "env-util.h" ++#include "format-table.h" ++#include "in-addr-util.h" ++#include "locale-util.h" ++#include "macro.h" ++#include "parse-util.h" ++#include "path-util.h" ++#include "seccomp-util.h" ++#include "set.h" ++#include "stdio-util.h" ++#include "strv.h" ++#include "terminal-util.h" ++#include "unit-def.h" ++#include "unit-name.h" ++ ++struct security_info { ++ char *id; ++ char *type; ++ char *load_state; ++ char *fragment_path; ++ bool default_dependencies; ++ ++ uint64_t ambient_capabilities; ++ uint64_t capability_bounding_set; ++ ++ char *user; ++ char **supplementary_groups; ++ bool dynamic_user; ++ ++ bool ip_address_deny_all; ++ bool ip_address_allow_localhost; ++ bool ip_address_allow_other; ++ ++ char *keyring_mode; ++ bool lock_personality; ++ bool memory_deny_write_execute; ++ bool no_new_privileges; ++ char *notify_access; ++ ++ bool private_devices; ++ bool private_mounts; ++ bool private_network; ++ bool private_tmp; ++ bool private_users; ++ ++ bool protect_control_groups; ++ bool protect_kernel_modules; ++ bool protect_kernel_tunables; ++ ++ char *protect_home; ++ char *protect_system; ++ ++ bool remove_ipc; ++ ++ bool restrict_address_family_inet; ++ bool restrict_address_family_unix; ++ bool restrict_address_family_netlink; ++ bool restrict_address_family_packet; ++ bool restrict_address_family_other; ++ ++ uint64_t restrict_namespaces; ++ bool restrict_realtime; ++ ++ char *root_directory; ++ char *root_image; ++ ++ bool delegate; ++ char *device_policy; ++ bool device_allow_non_empty; ++ ++ char **system_call_architectures; ++ ++ bool system_call_filter_whitelist; ++ Set *system_call_filter; ++ ++ uint32_t _umask; ++}; ++ ++struct security_assessor { ++ const char *id; ++ const char *description_good; ++ const char *description_bad; ++ const char *description_na; ++ const char *url; ++ uint64_t weight; ++ uint64_t range; ++ int (*assess)(const struct security_assessor *a, const struct security_info *info, const void *data, uint64_t *ret_badness, char **ret_description); ++ size_t offset; ++ uint64_t parameter; ++ bool default_dependencies_only; ++}; ++ ++static void security_info_free(struct security_info *i) { ++ if (!i) ++ return; ++ ++ free(i->id); ++ free(i->type); ++ free(i->load_state); ++ free(i->fragment_path); ++ ++ free(i->user); ++ ++ free(i->protect_home); ++ free(i->protect_system); ++ ++ free(i->root_directory); ++ free(i->root_image); ++ ++ free(i->keyring_mode); ++ free(i->notify_access); ++ ++ free(i->device_policy); ++ ++ strv_free(i->supplementary_groups); ++ strv_free(i->system_call_architectures); ++ ++ set_free_free(i->system_call_filter); ++} ++ ++static bool security_info_runs_privileged(const struct security_info *i) { ++ assert(i); ++ ++ if (STRPTR_IN_SET(i->user, "0", "root")) ++ return true; ++ ++ if (i->dynamic_user) ++ return false; ++ ++ return isempty(i->user); ++} ++ ++static int assess_bool( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ const bool *b = data; ++ ++ assert(b); ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = a->parameter ? *b : !*b; ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_user( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ _cleanup_free_ char *d = NULL; ++ uint64_t b; ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (streq_ptr(info->user, NOBODY_USER_NAME)) { ++ d = strdup("Service runs under as '" NOBODY_USER_NAME "' user, which should not be used for services"); ++ b = 9; ++ } else if (info->dynamic_user && !STR_IN_SET(info->user, "0", "root")) { ++ d = strdup("Service runs under a transient non-root user identity"); ++ b = 0; ++ } else if (info->user && !STR_IN_SET(info->user, "0", "root", "")) { ++ d = strdup("Service runs under a static non-root user identity"); ++ b = 0; ++ } else { ++ *ret_badness = 10; ++ *ret_description = NULL; ++ return 0; ++ } ++ ++ if (!d) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = TAKE_PTR(d); ++ ++ return 0; ++} ++ ++static int assess_protect_home( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ const char *description; ++ uint64_t badness; ++ char *copy; ++ int r; ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ badness = 10; ++ description = "Service has full access to home directories"; ++ ++ r = parse_boolean(info->protect_home); ++ if (r < 0) { ++ if (streq_ptr(info->protect_home, "read-only")) { ++ badness = 5; ++ description = "Service has read-only access to home directories"; ++ } else if (streq_ptr(info->protect_home, "tmpfs")) { ++ badness = 1; ++ description = "Service has access to fake empty home directories"; ++ } ++ } else if (r > 0) { ++ badness = 0; ++ description = "Service has no access to home directories"; ++ } ++ ++ copy = strdup(description); ++ if (!copy) ++ return log_oom(); ++ ++ *ret_badness = badness; ++ *ret_description = copy; ++ ++ return 0; ++} ++ ++static int assess_protect_system( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ const char *description; ++ uint64_t badness; ++ char *copy; ++ int r; ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ badness = 10; ++ description = "Service has full access the OS file hierarchy"; ++ ++ r = parse_boolean(info->protect_system); ++ if (r < 0) { ++ if (streq_ptr(info->protect_system, "full")) { ++ badness = 3; ++ description = "Service has very limited write access to OS file hierarchy"; ++ } else if (streq_ptr(info->protect_system, "strict")) { ++ badness = 0; ++ description = "Service has strict read-only access to the OS file hierarchy"; ++ } ++ } else if (r > 0) { ++ badness = 5; ++ description = "Service has limited write access to the OS file hierarchy"; ++ } ++ ++ copy = strdup(description); ++ if (!copy) ++ return log_oom(); ++ ++ *ret_badness = badness; ++ *ret_description = copy; ++ ++ return 0; ++} ++ ++static int assess_root_directory( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = ++ (isempty(info->root_directory) || ++ path_equal(info->root_directory, "/")) && ++ (isempty(info->root_image) || ++ path_equal(info->root_image, "/")); ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_capability_bounding_set( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = !!(info->capability_bounding_set & a->parameter); ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_umask( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ char *copy = NULL; ++ const char *d; ++ uint64_t b; ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (!FLAGS_SET(info->_umask, 0002)) { ++ d = "Files created by service are world-writable by default"; ++ b = 10; ++ } else if (!FLAGS_SET(info->_umask, 0004)) { ++ d = "Files created by service are world-readable by default"; ++ b = 5; ++ } else if (!FLAGS_SET(info->_umask, 0020)) { ++ d = "Files created by service are group-writable by default"; ++ b = 2; ++ } else if (!FLAGS_SET(info->_umask, 0040)) { ++ d = "Files created by service are group-readable by default"; ++ b = 1; ++ } else { ++ d = "Files created by service are accessible only by service's own user by default"; ++ b = 0; ++ } ++ ++ copy = strdup(d); ++ if (!copy) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = copy; ++ ++ return 0; ++} ++ ++static int assess_keyring_mode( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = !streq_ptr(info->keyring_mode, "private"); ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_notify_access( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = streq_ptr(info->notify_access, "all"); ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_remove_ipc( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (security_info_runs_privileged(info)) ++ *ret_badness = UINT64_MAX; ++ else ++ *ret_badness = !info->remove_ipc; ++ ++ *ret_description = NULL; ++ return 0; ++} ++ ++static int assess_supplementary_groups( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (security_info_runs_privileged(info)) ++ *ret_badness = UINT64_MAX; ++ else ++ *ret_badness = !strv_isempty(info->supplementary_groups); ++ ++ *ret_description = NULL; ++ return 0; ++} ++ ++static int assess_restrict_namespaces( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = !!(info->restrict_namespaces & a->parameter); ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static int assess_system_call_architectures( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ char *d; ++ uint64_t b; ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (strv_isempty(info->system_call_architectures)) { ++ b = 10; ++ d = strdup("Service may execute system calls with all ABIs"); ++ } else if (strv_equal(info->system_call_architectures, STRV_MAKE("native"))) { ++ b = 0; ++ d = strdup("Service may execute system calls only with native ABI"); ++ } else { ++ b = 8; ++ d = strdup("Service may execute system calls with multiple ABIs"); ++ } ++ ++ if (!d) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = d; ++ ++ return 0; ++} ++ ++static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterSet *f) { ++ const char *syscall; ++ ++ NULSTR_FOREACH(syscall, f->value) { ++ bool b; ++ ++ if (syscall[0] == '@') { ++ const SyscallFilterSet *g; ++ assert_se(g = syscall_filter_set_find(syscall)); ++ b = syscall_names_in_filter(s, whitelist, g); ++ } else { ++#if HAVE_SECCOMP ++ int id; ++ ++ /* Let's see if the system call actually exists on this platform, before complaining */ ++ id = seccomp_syscall_resolve_name(syscall); ++ if (id < 0) ++ continue; ++#endif ++ ++ b = set_contains(s, syscall); ++ } ++ ++ if (whitelist == b) { ++ log_debug("Offending syscall filter item: %s", syscall); ++ return true; /* bad! */ ++ } ++ } ++ ++ return false; ++} ++ ++static int assess_system_call_filter( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ const SyscallFilterSet *f; ++ char *d = NULL; ++ uint64_t b; ++ ++ assert(a); ++ assert(info); ++ assert(ret_badness); ++ assert(ret_description); ++ ++ assert(a->parameter < _SYSCALL_FILTER_SET_MAX); ++ f = syscall_filter_sets + a->parameter; ++ ++ if (!info->system_call_filter_whitelist && set_isempty(info->system_call_filter)) { ++ d = strdup("Service does not filter system calls"); ++ b = 10; ++ } else { ++ bool bad; ++ ++ log_debug("Analyzing system call filter, checking against: %s", f->name); ++ bad = syscall_names_in_filter(info->system_call_filter, info->system_call_filter_whitelist, f); ++ log_debug("Result: %s", bad ? "bad" : "good"); ++ ++ if (info->system_call_filter_whitelist) { ++ if (bad) { ++ (void) asprintf(&d, "System call whitelist defined for service, and %s is included", f->name); ++ b = 9; ++ } else { ++ (void) asprintf(&d, "System call whitelist defined for service, and %s is not included", f->name); ++ b = 0; ++ } ++ } else { ++ if (bad) { ++ (void) asprintf(&d, "System call blacklist defined for service, and %s is not included", f->name); ++ b = 10; ++ } else { ++ (void) asprintf(&d, "System call blacklist defined for service, and %s is included", f->name); ++ b = 5; ++ } ++ } ++ } ++ ++ if (!d) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = d; ++ ++ return 0; ++} ++ ++static int assess_ip_address_allow( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ char *d = NULL; ++ uint64_t b; ++ ++ assert(info); ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (!info->ip_address_deny_all) { ++ d = strdup("Service does not define an IP address whitelist"); ++ b = 10; ++ } else if (info->ip_address_allow_other) { ++ d = strdup("Service defines IP address whitelist with non-localhost entries"); ++ b = 5; ++ } else if (info->ip_address_allow_localhost) { ++ d = strdup("Service defines IP address whitelits with only localhost entries"); ++ b = 2; ++ } else { ++ d = strdup("Service blocks all IP address ranges"); ++ b = 0; ++ } ++ ++ if (!d) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = d; ++ ++ return 0; ++} ++ ++static int assess_device_allow( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ char *d = NULL; ++ uint64_t b; ++ ++ assert(info); ++ assert(ret_badness); ++ assert(ret_description); ++ ++ if (STRPTR_IN_SET(info->device_policy, "strict", "closed")) { ++ ++ if (info->device_allow_non_empty) { ++ d = strdup("Service has a device ACL with some special devices"); ++ b = 5; ++ } else { ++ d = strdup("Service has a minimal device ACL"); ++ b = 0; ++ } ++ } else { ++ d = strdup("Service has no device ACL"); ++ b = 10; ++ } ++ ++ if (!d) ++ return log_oom(); ++ ++ *ret_badness = b; ++ *ret_description = d; ++ ++ return 0; ++} ++ ++static int assess_ambient_capabilities( ++ const struct security_assessor *a, ++ const struct security_info *info, ++ const void *data, ++ uint64_t *ret_badness, ++ char **ret_description) { ++ ++ assert(ret_badness); ++ assert(ret_description); ++ ++ *ret_badness = info->ambient_capabilities != 0; ++ *ret_description = NULL; ++ ++ return 0; ++} ++ ++static const struct security_assessor security_assessor_table[] = { ++ { ++ .id = "User=/DynamicUser=", ++ .description_bad = "Service runs as root user", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#User=", ++ .weight = 2000, ++ .range = 10, ++ .assess = assess_user, ++ }, ++ { ++ .id = "SupplementaryGroups=", ++ .description_good = "Service has no supplementary groups", ++ .description_bad = "Service runs with supplementary groups", ++ .description_na = "Service runs as root, option does not matter", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SupplementaryGroups=", ++ .weight = 200, ++ .range = 1, ++ .assess = assess_supplementary_groups, ++ }, ++ { ++ .id = "PrivateDevices=", ++ .description_good = "Service has no access to hardware devices", ++ .description_bad = "Service potentially has access to hardware devices", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateDevices=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, private_devices), ++ }, ++ { ++ .id = "PrivateMounts=", ++ .description_good = "Service cannot install system mounts", ++ .description_bad = "Service may install system mounts", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateMounts=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, private_mounts), ++ }, ++ { ++ .id = "PrivateNetwork=", ++ .description_good = "Service has no access to the host's network", ++ .description_bad = "Service has access to the host's network", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateNetwork=", ++ .weight = 2500, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, private_network), ++ }, ++ { ++ .id = "PrivateTmp=", ++ .description_good = "Service has no access to other software's temporary files", ++ .description_bad = "Service has access to other software's temporary files", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, private_tmp), ++ .default_dependencies_only = true, ++ }, ++ { ++ .id = "PrivateUsers=", ++ .description_good = "Service does not have access to other users", ++ .description_bad = "Service has access to other users", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateUsers=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, private_users), ++ }, ++ { ++ .id = "ProtectControlGroups=", ++ .description_good = "Service cannot modify the control group file system", ++ .description_bad = "Service may modify to the control group file system", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectControlGroups=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, protect_control_groups), ++ }, ++ { ++ .id = "ProtectKernelModules=", ++ .description_good = "Service cannot load or read kernel modules", ++ .description_bad = "Service may load or read kernel modules", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectKernelModules=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, protect_kernel_modules), ++ }, ++ { ++ .id = "ProtectKernelTunables=", ++ .description_good = "Service cannot alter kernel tunables (/proc/sys, …)", ++ .description_bad = "Service may alter kernel tunables", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectKernelTunables=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, protect_kernel_tunables), ++ }, ++ { ++ .id = "ProtectHome=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_protect_home, ++ .default_dependencies_only = true, ++ }, ++ { ++ .id = "ProtectSystem=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectSystem=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_protect_system, ++ .default_dependencies_only = true, ++ }, ++ { ++ .id = "RootDirectory=/RootImage=", ++ .description_good = "Service has its own root directory/image", ++ .description_bad = "Service runs within the host's root directory", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RootDirectory=", ++ .weight = 200, ++ .range = 1, ++ .assess = assess_root_directory, ++ .default_dependencies_only = true, ++ }, ++ { ++ .id = "LockPersonality=", ++ .description_good = "Service cannot change ABI personality", ++ .description_bad = "Service may change ABI personality", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LockPersonality=", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, lock_personality), ++ }, ++ { ++ .id = "MemoryDenyWriteExecute=", ++ .description_good = "Service cannot create writable executable memory mappings", ++ .description_bad = "Service may create writable executable memory mappings", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#MemoryDenyWriteExecute=", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, memory_deny_write_execute), ++ }, ++ { ++ .id = "NoNewPrivileges=", ++ .description_good = "Service processes cannot acquire new privileges", ++ .description_bad = "Service processes may acquire new privileges", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#NoNewPrivileges=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, no_new_privileges), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_ADMIN", ++ .description_good = "Service has no administrator privileges", ++ .description_bad = "Service has administrator privileges", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = UINT64_C(1) << CAP_SYS_ADMIN, ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP)", ++ .description_good = "Service cannot change UID/GID identities/capabilities", ++ .description_bad = "Service may change UID/GID identities/capabilities", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SETUID)| ++ (UINT64_C(1) << CAP_SETGID)| ++ (UINT64_C(1) << CAP_SETPCAP), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_PTRACE", ++ .description_good = "Service has no ptrace() debugging abilities", ++ .description_bad = "Service has ptrace() debugging abilities", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_PTRACE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_TIME", ++ .description_good = "Service processes cannot change the system clock", ++ .description_bad = "Service processes may change the system clock", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = UINT64_C(1) << CAP_SYS_TIME, ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_NET_ADMIN", ++ .description_good = "Service has no network configuration privileges", ++ .description_bad = "Service has network configuration privileges", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_NET_ADMIN), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_RAWIO", ++ .description_good = "Service has no raw I/O access", ++ .description_bad = "Service has raw I/O access", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_RAWIO), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_MODULE", ++ .description_good = "Service cannot load kernel modules", ++ .description_bad = "Service may load kernel modules", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_MODULE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_AUDIT_*", ++ .description_good = "Service has no audit subsystem access", ++ .description_bad = "Service has audit subsystem access", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_AUDIT_CONTROL) | ++ (UINT64_C(1) << CAP_AUDIT_READ) | ++ (UINT64_C(1) << CAP_AUDIT_WRITE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYSLOG", ++ .description_good = "Service has no access to kernel logging", ++ .description_bad = "Service has access to kernel logging", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYSLOG), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_(NICE|RESOURCE)", ++ .description_good = "Service has no privileges to change resource use parameters", ++ .description_bad = "Service has privileges to change resource use parameters", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_NICE) | ++ (UINT64_C(1) << CAP_SYS_RESOURCE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_MKNOD", ++ .description_good = "Service cannot create device nodes", ++ .description_bad = "Service may create device nodes", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_MKNOD), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_(CHOWN|FSETID|SETFCAP)", ++ .description_good = "Service cannot change file ownership/access mode/capabilities", ++ .description_bad = "Service may change file ownership/access mode/capabilities unrestricted", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_CHOWN) | ++ (UINT64_C(1) << CAP_FSETID) | ++ (UINT64_C(1) << CAP_SETFCAP), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER)", ++ .description_good = "Service cannot override UNIX file/IPC permission checks", ++ .description_bad = "Service may override UNIX file/IPC permission checks", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_DAC_OVERRIDE) | ++ (UINT64_C(1) << CAP_DAC_READ_SEARCH) | ++ (UINT64_C(1) << CAP_FOWNER) | ++ (UINT64_C(1) << CAP_IPC_OWNER), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_KILL", ++ .description_good = "Service cannot send UNIX signals to arbitrary processes", ++ .description_bad = "Service may send UNIX signals to arbitrary processes", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_KILL), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_NET_(BIND_SERVICE|BROADCAST|RAW)", ++ .description_good = "Service has no elevated networking privileges", ++ .description_bad = "Service has elevated networking privileges", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_NET_BIND_SERVICE) | ++ (UINT64_C(1) << CAP_NET_BROADCAST) | ++ (UINT64_C(1) << CAP_NET_RAW), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_BOOT", ++ .description_good = "Service cannot issue reboot()", ++ .description_bad = "Service may issue reboot()", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_BOOT), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_MAC_*", ++ .description_good = "Service cannot adjust SMACK MAC", ++ .description_bad = "Service may adjust SMACK MAC", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_MAC_ADMIN)| ++ (UINT64_C(1) << CAP_MAC_OVERRIDE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE", ++ .description_good = "Service cannot mark files immutable", ++ .description_bad = "Service may mark files immutable", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 75, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_LINUX_IMMUTABLE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_IPC_LOCK", ++ .description_good = "Service cannot lock memory into RAM", ++ .description_bad = "Service may lock memory into RAM", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 50, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_IPC_LOCK), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_CHROOT", ++ .description_good = "Service cannot issue chroot()", ++ .description_bad = "Service may issue chroot()", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 50, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_CHROOT), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_BLOCK_SUSPEND", ++ .description_good = "Service cannot establish wake locks", ++ .description_bad = "Service may establish wake locks", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_BLOCK_SUSPEND), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_WAKE_ALARM", ++ .description_good = "Service cannot program timers that wake up the system", ++ .description_bad = "Service may program timers that wake up the system", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_WAKE_ALARM), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_LEASE", ++ .description_good = "Service cannot create file leases", ++ .description_bad = "Service may create file leases", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_LEASE), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG", ++ .description_good = "Service cannot issue vhangup()", ++ .description_bad = "Service may issue vhangup()", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_TTY_CONFIG), ++ }, ++ { ++ .id = "CapabilityBoundingSet=~CAP_SYS_PACCT", ++ .description_good = "Service cannot use acct()", ++ .description_bad = "Service may use acct()", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_capability_bounding_set, ++ .parameter = (UINT64_C(1) << CAP_SYS_PACCT), ++ }, ++ { ++ .id = "UMask=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#UMask=", ++ .weight = 100, ++ .range = 10, ++ .assess = assess_umask, ++ }, ++ { ++ .id = "KeyringMode=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#KeyringMode=", ++ .description_good = "Service doesn't share key material with other services", ++ .description_bad = "Service shares key material with other service", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_keyring_mode, ++ }, ++ { ++ .id = "NotifyAccess=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#NotifyAccess=", ++ .description_good = "Service child processes cannot alter service state", ++ .description_bad = "Service child processes may alter service state", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_notify_access, ++ }, ++ { ++ .id = "RemoveIPC=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RemoveIPC=", ++ .description_good = "Service user cannot leave SysV IPC objects around", ++ .description_bad = "Service user may leave SysV IPC objects around", ++ .description_na = "Service runs as root, option does not apply", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_remove_ipc, ++ .offset = offsetof(struct security_info, remove_ipc), ++ }, ++ { ++ .id = "Delegate=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Delegate=", ++ .description_good = "Service does not maintain its own delegated control group subtree", ++ .description_bad = "Service maintains its own delegated control group subtree", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, delegate), ++ .parameter = true, /* invert! */ ++ }, ++ { ++ .id = "RestrictRealtime=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictRealtime=", ++ .description_good = "Service realtime scheduling access is restricted", ++ .description_bad = "Service may acquire realtime scheduling", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_realtime), ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWUSER", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create user namespaces", ++ .description_bad = "Service may create user namespaces", ++ .weight = 1500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWUSER, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWNS", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create file system namespaces", ++ .description_bad = "Service may create file system namespaces", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWNS, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWIPC", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create IPC namespaces", ++ .description_bad = "Service may create IPC namespaces", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWIPC, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWPID", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create process namespaces", ++ .description_bad = "Service may create process namespaces", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWPID, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWCGROUP", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create cgroup namespaces", ++ .description_bad = "Service may create cgroup namespaces", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWCGROUP, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWNET", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create network namespaces", ++ .description_bad = "Service may create network namespaces", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWNET, ++ }, ++ { ++ .id = "RestrictNamespaces=~CLONE_NEWUTS", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", ++ .description_good = "Service cannot create hostname namespaces", ++ .description_bad = "Service may create hostname namespaces", ++ .weight = 100, ++ .range = 1, ++ .assess = assess_restrict_namespaces, ++ .parameter = CLONE_NEWUTS, ++ }, ++ { ++ .id = "RestrictAddressFamilies=~AF_(INET|INET6)", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=", ++ .description_good = "Service cannot allocate Internet sockets", ++ .description_bad = "Service may allocate Internet sockets", ++ .weight = 1500, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_address_family_inet), ++ }, ++ { ++ .id = "RestrictAddressFamilies=~AF_UNIX", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=", ++ .description_good = "Service cannot allocate local sockets", ++ .description_bad = "Service may allocate local sockets", ++ .weight = 25, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_address_family_unix), ++ }, ++ { ++ .id = "RestrictAddressFamilies=~AF_NETLINK", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=", ++ .description_good = "Service cannot allocate netlink sockets", ++ .description_bad = "Service may allocate netlink sockets", ++ .weight = 200, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_address_family_netlink), ++ }, ++ { ++ .id = "RestrictAddressFamilies=~AF_PACKET", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=", ++ .description_good = "Service cannot allocate packet sockets", ++ .description_bad = "Service may allocate packet sockets", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_address_family_packet), ++ }, ++ { ++ .id = "RestrictAddressFamilies=~…", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=", ++ .description_good = "Service cannot allocate exotic sockets", ++ .description_bad = "Service may allocate exotic sockets", ++ .weight = 1250, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_address_family_other), ++ }, ++ { ++ .id = "SystemCallArchitectures=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallArchitectures=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_architectures, ++ }, ++ { ++ .id = "SystemCallFilter=~@swap", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_SWAP, ++ }, ++ { ++ .id = "SystemCallFilter=~@obsolete", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 250, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_OBSOLETE, ++ }, ++ { ++ .id = "SystemCallFilter=~@clock", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_CLOCK, ++ }, ++ { ++ .id = "SystemCallFilter=~@cpu-emulation", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 250, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_CPU_EMULATION, ++ }, ++ { ++ .id = "SystemCallFilter=~@debug", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_DEBUG, ++ }, ++ { ++ .id = "SystemCallFilter=~@mount", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_MOUNT, ++ }, ++ { ++ .id = "SystemCallFilter=~@module", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_MODULE, ++ }, ++ { ++ .id = "SystemCallFilter=~@raw-io", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_RAW_IO, ++ }, ++ { ++ .id = "SystemCallFilter=~@reboot", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_REBOOT, ++ }, ++ { ++ .id = "SystemCallFilter=~@privileged", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 700, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_PRIVILEGED, ++ }, ++ { ++ .id = "SystemCallFilter=~@resources", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=", ++ .weight = 700, ++ .range = 10, ++ .assess = assess_system_call_filter, ++ .parameter = SYSCALL_FILTER_SET_RESOURCES, ++ }, ++ { ++ .id = "IPAddressDeny=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#IPAddressDeny=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_ip_address_allow, ++ }, ++ { ++ .id = "DeviceAllow=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DeviceAllow=", ++ .weight = 1000, ++ .range = 10, ++ .assess = assess_device_allow, ++ }, ++ { ++ .id = "AmbientCapabilities=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#AmbientCapabilities=", ++ .description_good = "Service process does not receive ambient capabilities", ++ .description_bad = "Service process receives ambient capabilities", ++ .weight = 500, ++ .range = 1, ++ .assess = assess_ambient_capabilities, ++ }, ++}; ++ ++static int assess(const struct security_info *info, Table *overview_table, AnalyzeSecurityFlags flags) { ++ static const struct { ++ uint64_t exposure; ++ const char *name; ++ const char *color; ++ SpecialGlyph smiley; ++ } badness_table[] = { ++ { 100, "DANGEROUS", ANSI_HIGHLIGHT_RED, DEPRESSED_SMILEY }, ++ { 90, "UNSAFE", ANSI_HIGHLIGHT_RED, UNHAPPY_SMILEY }, ++ { 75, "EXPOSED", ANSI_HIGHLIGHT_YELLOW, SLIGHTLY_UNHAPPY_SMILEY }, ++ { 50, "MEDIUM", NULL, NEUTRAL_SMILEY }, ++ { 10, "OK", ANSI_HIGHLIGHT_GREEN, SLIGHTLY_HAPPY_SMILEY }, ++ { 1, "SAFE", ANSI_HIGHLIGHT_GREEN, HAPPY_SMILEY }, ++ { 0, "PERFECT", ANSI_HIGHLIGHT_GREEN, ECSTATIC_SMILEY }, ++ }; ++ ++ uint64_t badness_sum = 0, weight_sum = 0, exposure; ++ _cleanup_(table_unrefp) Table *details_table = NULL; ++ size_t i; ++ int r; ++ ++ if (!FLAGS_SET(flags, ANALYZE_SECURITY_SHORT)) { ++ details_table = table_new("", "NAME", "DESCRIPTION", "WEIGHT", "BADNESS", "RANGE", "EXPOSURE"); ++ if (!details_table) ++ return log_oom(); ++ ++ (void) table_set_sort(details_table, 3, 1, (size_t) -1); ++ (void) table_set_reverse(details_table, 3, true); ++ ++ if (getenv_bool("SYSTEMD_ANALYZE_DEBUG") <= 0) ++ (void) table_set_display(details_table, 0, 1, 2, 6, (size_t) -1); ++ } ++ ++ for (i = 0; i < ELEMENTSOF(security_assessor_table); i++) { ++ const struct security_assessor *a = security_assessor_table + i; ++ _cleanup_free_ char *d = NULL; ++ uint64_t badness; ++ void *data; ++ ++ data = (uint8_t*) info + a->offset; ++ ++ if (a->default_dependencies_only && !info->default_dependencies) { ++ badness = UINT64_MAX; ++ d = strdup("Service runs in special boot phase, option does not apply"); ++ if (!d) ++ return log_oom(); ++ } else { ++ r = a->assess(a, info, data, &badness, &d); ++ if (r < 0) ++ return r; ++ } ++ ++ assert(a->range > 0); ++ ++ if (badness != UINT64_MAX) { ++ assert(badness <= a->range); ++ ++ badness_sum += DIV_ROUND_UP(badness * a->weight, a->range); ++ weight_sum += a->weight; ++ } ++ ++ if (details_table) { ++ const char *checkmark, *description, *color = NULL; ++ TableCell *cell; ++ ++ if (badness == UINT64_MAX) { ++ checkmark = " "; ++ description = a->description_na; ++ color = NULL; ++ } else if (badness == a->range) { ++ checkmark = special_glyph(CROSS_MARK); ++ description = a->description_bad; ++ color = ansi_highlight_red(); ++ } else if (badness == 0) { ++ checkmark = special_glyph(CHECK_MARK); ++ description = a->description_good; ++ color = ansi_highlight_green(); ++ } else { ++ checkmark = special_glyph(CROSS_MARK); ++ description = NULL; ++ color = ansi_highlight_red(); ++ } ++ ++ if (d) ++ description = d; ++ ++ r = table_add_cell_full(details_table, &cell, TABLE_STRING, checkmark, 1, 1, 0, 0, 0); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ if (color) ++ (void) table_set_color(details_table, cell, color); ++ ++ r = table_add_cell(details_table, &cell, TABLE_STRING, a->id); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ if (a->url) ++ (void) table_set_url(details_table, cell, a->url); ++ ++ r = table_add_cell(details_table, NULL, TABLE_STRING, description); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ ++ r = table_add_cell(details_table, &cell, TABLE_UINT64, &a->weight); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_align_percent(details_table, cell, 100); ++ ++ r = table_add_cell(details_table, &cell, TABLE_UINT64, &badness); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_align_percent(details_table, cell, 100); ++ ++ r = table_add_cell(details_table, &cell, TABLE_UINT64, &a->range); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_align_percent(details_table, cell, 100); ++ ++ r = table_add_cell(details_table, &cell, TABLE_EMPTY, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_align_percent(details_table, cell, 100); ++ } ++ } ++ ++ if (details_table) { ++ size_t row; ++ ++ for (row = 1; row < table_get_rows(details_table); row++) { ++ char buf[DECIMAL_STR_MAX(uint64_t) + 1 + DECIMAL_STR_MAX(uint64_t) + 1]; ++ const uint64_t *weight, *badness, *range; ++ TableCell *cell; ++ uint64_t x; ++ ++ assert_se(weight = table_get_at(details_table, row, 3)); ++ assert_se(badness = table_get_at(details_table, row, 4)); ++ assert_se(range = table_get_at(details_table, row, 5)); ++ ++ if (*badness == UINT64_MAX || *badness == 0) ++ continue; ++ ++ assert_se(cell = table_get_cell(details_table, row, 6)); ++ ++ x = DIV_ROUND_UP(DIV_ROUND_UP(*badness * *weight * 100U, *range), weight_sum); ++ xsprintf(buf, "%" PRIu64 ".%" PRIu64, x / 10, x % 10); ++ ++ r = table_update(details_table, cell, TABLE_STRING, buf); ++ if (r < 0) ++ return log_error_errno(r, "Failed to update cell in table: %m"); ++ } ++ ++ r = table_print(details_table, stdout); ++ if (r < 0) ++ return log_error_errno(r, "Failed to output table: %m"); ++ } ++ ++ exposure = DIV_ROUND_UP(badness_sum * 100U, weight_sum); ++ ++ for (i = 0; i < ELEMENTSOF(badness_table); i++) ++ if (exposure >= badness_table[i].exposure) ++ break; ++ ++ assert(i < ELEMENTSOF(badness_table)); ++ ++ if (details_table) { ++ _cleanup_free_ char *clickable = NULL; ++ const char *name; ++ ++ /* If we shall output the details table, also print the brief summary underneath */ ++ ++ if (info->fragment_path) { ++ r = terminal_urlify_path(info->fragment_path, info->id, &clickable); ++ if (r < 0) ++ return log_oom(); ++ ++ name = clickable; ++ } else ++ name = info->id; ++ ++ printf("\n%s %sOverall exposure level for %s%s: %s%" PRIu64 ".%" PRIu64 " %s%s %s\n", ++ special_glyph(ARROW), ++ ansi_highlight(), ++ name, ++ ansi_normal(), ++ colors_enabled() ? strempty(badness_table[i].color) : "", ++ exposure / 10, exposure % 10, ++ badness_table[i].name, ++ ansi_normal(), ++ special_glyph(badness_table[i].smiley)); ++ } ++ ++ fflush(stdout); ++ ++ if (overview_table) { ++ char buf[DECIMAL_STR_MAX(uint64_t) + 1 + DECIMAL_STR_MAX(uint64_t) + 1]; ++ TableCell *cell; ++ ++ r = table_add_cell(overview_table, &cell, TABLE_STRING, info->id); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ if (info->fragment_path) { ++ _cleanup_free_ char *url = NULL; ++ ++ r = file_url_from_path(info->fragment_path, &url); ++ if (r < 0) ++ return log_error_errno(r, "Failed to generate URL from path: %m"); ++ ++ (void) table_set_url(overview_table, cell, url); ++ } ++ ++ xsprintf(buf, "%" PRIu64 ".%" PRIu64, exposure / 10, exposure % 10); ++ r = table_add_cell(overview_table, &cell, TABLE_STRING, buf); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_align_percent(overview_table, cell, 100); ++ ++ r = table_add_cell(overview_table, &cell, TABLE_STRING, badness_table[i].name); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ (void) table_set_color(overview_table, cell, strempty(badness_table[i].color)); ++ ++ r = table_add_cell(overview_table, NULL, TABLE_STRING, special_glyph(badness_table[i].smiley)); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add cell to table: %m"); ++ } ++ ++ return 0; ++} ++ ++static int property_read_restrict_address_families( ++ sd_bus *bus, ++ const char *member, ++ sd_bus_message *m, ++ sd_bus_error *error, ++ void *userdata) { ++ ++ struct security_info *info = userdata; ++ int whitelist, r; ++ ++ assert(bus); ++ assert(member); ++ assert(m); ++ ++ r = sd_bus_message_enter_container(m, 'r', "bas"); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_read(m, "b", &whitelist); ++ if (r < 0) ++ return r; ++ ++ info->restrict_address_family_inet = ++ info->restrict_address_family_unix = ++ info->restrict_address_family_netlink = ++ info->restrict_address_family_packet = ++ info->restrict_address_family_other = whitelist; ++ ++ r = sd_bus_message_enter_container(m, 'a', "s"); ++ if (r < 0) ++ return r; ++ ++ for (;;) { ++ const char *name; ++ ++ r = sd_bus_message_read(m, "s", &name); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ if (STR_IN_SET(name, "AF_INET", "AF_INET6")) ++ info->restrict_address_family_inet = !whitelist; ++ else if (streq(name, "AF_UNIX")) ++ info->restrict_address_family_unix = !whitelist; ++ else if (streq(name, "AF_NETLINK")) ++ info->restrict_address_family_netlink = !whitelist; ++ else if (streq(name, "AF_PACKET")) ++ info->restrict_address_family_packet = !whitelist; ++ else ++ info->restrict_address_family_other = !whitelist; ++ } ++ ++ r = sd_bus_message_exit_container(m); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_message_exit_container(m); ++} ++ ++static int property_read_system_call_filter( ++ sd_bus *bus, ++ const char *member, ++ sd_bus_message *m, ++ sd_bus_error *error, ++ void *userdata) { ++ ++ struct security_info *info = userdata; ++ int whitelist, r; ++ ++ assert(bus); ++ assert(member); ++ assert(m); ++ ++ r = sd_bus_message_enter_container(m, 'r', "bas"); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_read(m, "b", &whitelist); ++ if (r < 0) ++ return r; ++ ++ info->system_call_filter_whitelist = whitelist; ++ ++ r = sd_bus_message_enter_container(m, 'a', "s"); ++ if (r < 0) ++ return r; ++ ++ for (;;) { ++ const char *name; ++ ++ r = sd_bus_message_read(m, "s", &name); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ r = set_ensure_allocated(&info->system_call_filter, &string_hash_ops); ++ if (r < 0) ++ return r; ++ ++ r = set_put_strdup(info->system_call_filter, name); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_bus_message_exit_container(m); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_message_exit_container(m); ++} ++ ++static int property_read_ip_address_allow( ++ sd_bus *bus, ++ const char *member, ++ sd_bus_message *m, ++ sd_bus_error *error, ++ void *userdata) { ++ ++ struct security_info *info = userdata; ++ bool deny_ipv4 = false, deny_ipv6 = false; ++ int r; ++ ++ assert(bus); ++ assert(member); ++ assert(m); ++ ++ r = sd_bus_message_enter_container(m, 'a', "(iayu)"); ++ if (r < 0) ++ return r; ++ ++ for (;;) { ++ const void *data; ++ size_t size; ++ int32_t family; ++ uint32_t prefixlen; ++ ++ r = sd_bus_message_enter_container(m, 'r', "iayu"); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ r = sd_bus_message_read(m, "i", &family); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_read_array(m, 'y', &data, &size); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_read(m, "u", &prefixlen); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_exit_container(m); ++ if (r < 0) ++ return r; ++ ++ if (streq(member, "IPAddressAllow")) { ++ union in_addr_union u; ++ ++ if (family == AF_INET && size == 4 && prefixlen == 8) ++ memcpy(&u.in, data, size); ++ else if (family == AF_INET6 && size == 16 && prefixlen == 128) ++ memcpy(&u.in6, data, size); ++ else { ++ info->ip_address_allow_other = true; ++ continue; ++ } ++ ++ if (in_addr_is_localhost(family, &u)) ++ info->ip_address_allow_localhost = true; ++ else ++ info->ip_address_allow_other = true; ++ } else { ++ assert(streq(member, "IPAddressDeny")); ++ ++ if (family == AF_INET && size == 4 && prefixlen == 0) ++ deny_ipv4 = true; ++ else if (family == AF_INET6 && size == 16 && prefixlen == 0) ++ deny_ipv6 = true; ++ } ++ } ++ ++ info->ip_address_deny_all = deny_ipv4 && deny_ipv6; ++ ++ return sd_bus_message_exit_container(m); ++} ++ ++static int property_read_device_allow( ++ sd_bus *bus, ++ const char *member, ++ sd_bus_message *m, ++ sd_bus_error *error, ++ void *userdata) { ++ ++ struct security_info *info = userdata; ++ size_t n = 0; ++ int r; ++ ++ assert(bus); ++ assert(member); ++ assert(m); ++ ++ r = sd_bus_message_enter_container(m, 'a', "(ss)"); ++ if (r < 0) ++ return r; ++ ++ for (;;) { ++ const char *name, *policy; ++ ++ r = sd_bus_message_read(m, "(ss)", &name, &policy); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ n++; ++ } ++ ++ info->device_allow_non_empty = n > 0; ++ ++ return sd_bus_message_exit_container(m); ++} ++ ++static int acquire_security_info(sd_bus *bus, const char *name, struct security_info *info, AnalyzeSecurityFlags flags) { ++ ++ static const struct bus_properties_map security_map[] = { ++ { "AmbientCapabilities", "t", NULL, offsetof(struct security_info, ambient_capabilities) }, ++ { "CapabilityBoundingSet", "t", NULL, offsetof(struct security_info, capability_bounding_set) }, ++ { "DefaultDependencies", "b", NULL, offsetof(struct security_info, default_dependencies) }, ++ { "Delegate", "b", NULL, offsetof(struct security_info, delegate) }, ++ { "DeviceAllow", "a(ss)", property_read_device_allow, 0 }, ++ { "DevicePolicy", "s", NULL, offsetof(struct security_info, device_policy) }, ++ { "DynamicUser", "b", NULL, offsetof(struct security_info, dynamic_user) }, ++ { "FragmentPath", "s", NULL, offsetof(struct security_info, fragment_path) }, ++ { "IPAddressAllow", "a(iayu)", property_read_ip_address_allow, 0 }, ++ { "IPAddressDeny", "a(iayu)", property_read_ip_address_allow, 0 }, ++ { "Id", "s", NULL, offsetof(struct security_info, id) }, ++ { "KeyringMode", "s", NULL, offsetof(struct security_info, keyring_mode) }, ++ { "LoadState", "s", NULL, offsetof(struct security_info, load_state) }, ++ { "LockPersonality", "b", NULL, offsetof(struct security_info, lock_personality) }, ++ { "MemoryDenyWriteExecute", "b", NULL, offsetof(struct security_info, memory_deny_write_execute) }, ++ { "NoNewPrivileges", "b", NULL, offsetof(struct security_info, no_new_privileges) }, ++ { "NotifyAccess", "s", NULL, offsetof(struct security_info, notify_access) }, ++ { "PrivateDevices", "b", NULL, offsetof(struct security_info, private_devices) }, ++ { "PrivateMounts", "b", NULL, offsetof(struct security_info, private_mounts) }, ++ { "PrivateNetwork", "b", NULL, offsetof(struct security_info, private_network) }, ++ { "PrivateTmp", "b", NULL, offsetof(struct security_info, private_tmp) }, ++ { "PrivateUsers", "b", NULL, offsetof(struct security_info, private_users) }, ++ { "PrivateUsers", "b", NULL, offsetof(struct security_info, private_users) }, ++ { "ProtectControlGroups", "b", NULL, offsetof(struct security_info, protect_control_groups) }, ++ { "ProtectHome", "s", NULL, offsetof(struct security_info, protect_home) }, ++ { "ProtectKernelModules", "b", NULL, offsetof(struct security_info, protect_kernel_modules) }, ++ { "ProtectKernelTunables", "b", NULL, offsetof(struct security_info, protect_kernel_tunables) }, ++ { "ProtectSystem", "s", NULL, offsetof(struct security_info, protect_system) }, ++ { "RemoveIPC", "b", NULL, offsetof(struct security_info, remove_ipc) }, ++ { "RestrictAddressFamilies", "(bas)", property_read_restrict_address_families, 0 }, ++ { "RestrictNamespaces", "t", NULL, offsetof(struct security_info, restrict_namespaces) }, ++ { "RestrictRealtime", "b", NULL, offsetof(struct security_info, restrict_realtime) }, ++ { "RootDirectory", "s", NULL, offsetof(struct security_info, root_directory) }, ++ { "RootImage", "s", NULL, offsetof(struct security_info, root_image) }, ++ { "SupplementaryGroups", "as", NULL, offsetof(struct security_info, supplementary_groups) }, ++ { "SystemCallArchitectures", "as", NULL, offsetof(struct security_info, system_call_architectures) }, ++ { "SystemCallFilter", "(as)", property_read_system_call_filter, 0 }, ++ { "Type", "s", NULL, offsetof(struct security_info, type) }, ++ { "UMask", "u", NULL, offsetof(struct security_info, _umask) }, ++ { "User", "s", NULL, offsetof(struct security_info, user) }, ++ {} ++ }; ++ ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_free_ char *path = NULL; ++ int r; ++ ++ /* Note: this mangles *info on failure! */ ++ ++ assert(bus); ++ assert(name); ++ assert(info); ++ ++ path = unit_dbus_path_from_name(name); ++ if (!path) ++ return log_oom(); ++ ++ r = bus_map_all_properties(bus, ++ "org.freedesktop.systemd1", ++ path, ++ security_map, ++ BUS_MAP_STRDUP|BUS_MAP_BOOLEAN_AS_BOOL, ++ &error, ++ NULL, ++ info); ++ if (r < 0) ++ return log_error_errno(r, "Failed to get unit properties: %s", bus_error_message(&error, r)); ++ ++ if (!streq_ptr(info->load_state, "loaded")) { ++ ++ if (FLAGS_SET(flags, ANALYZE_SECURITY_ONLY_LOADED)) ++ return -EMEDIUMTYPE; ++ ++ if (streq_ptr(info->load_state, "not-found")) ++ log_error("Unit %s not found, cannot analyze.", name); ++ else if (streq_ptr(info->load_state, "masked")) ++ log_error("Unit %s is masked, cannot analyze.", name); ++ else ++ log_error("Unit %s not loaded properly, cannot analyze.", name); ++ ++ return -EINVAL; ++ } ++ ++ if (FLAGS_SET(flags, ANALYZE_SECURITY_ONLY_LONG_RUNNING) && streq_ptr(info->type, "oneshot")) ++ return -EMEDIUMTYPE; ++ ++ if (info->private_devices || ++ info->private_tmp || ++ info->protect_control_groups || ++ info->protect_kernel_tunables || ++ info->protect_kernel_modules || ++ !streq_ptr(info->protect_home, "no") || ++ !streq_ptr(info->protect_system, "no") || ++ info->root_image) ++ info->private_mounts = true; ++ ++ if (info->protect_kernel_modules) ++ info->capability_bounding_set &= ~(UINT64_C(1) << CAP_SYS_MODULE); ++ ++ if (info->private_devices) ++ info->capability_bounding_set &= ~((UINT64_C(1) << CAP_MKNOD) | ++ (UINT64_C(1) << CAP_SYS_RAWIO)); ++ ++ return 0; ++} ++ ++static int analyze_security_one(sd_bus *bus, const char *name, Table* overview_table, AnalyzeSecurityFlags flags) { ++ _cleanup_(security_info_free) struct security_info info = { ++ .default_dependencies = true, ++ .capability_bounding_set = UINT64_MAX, ++ .restrict_namespaces = UINT64_MAX, ++ ._umask = 0002, ++ }; ++ int r; ++ ++ assert(bus); ++ assert(name); ++ ++ r = acquire_security_info(bus, name, &info, flags); ++ if (r == -EMEDIUMTYPE) /* Ignore this one because not loaded or Type is oneshot */ ++ return 0; ++ if (r < 0) ++ return r; ++ ++ r = assess(&info, overview_table, flags); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++int analyze_security(sd_bus *bus, char **units, AnalyzeSecurityFlags flags) { ++ _cleanup_(table_unrefp) Table *overview_table = NULL; ++ int ret = 0, r; ++ ++ assert(bus); ++ ++ if (strv_length(units) != 1) { ++ overview_table = table_new("UNIT", "EXPOSURE", "PREDICATE", "HAPPY"); ++ if (!overview_table) ++ return log_oom(); ++ } ++ ++ if (strv_isempty(units)) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; ++ _cleanup_strv_free_ char **list = NULL; ++ size_t allocated = 0, n = 0; ++ char **i; ++ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "ListUnits", ++ &error, &reply, ++ NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r)); ++ ++ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)"); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ for (;;) { ++ UnitInfo info; ++ char *copy = NULL; ++ ++ r = bus_parse_unit_info(reply, &info); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ if (r == 0) ++ break; ++ ++ if (!endswith(info.id, ".service")) ++ continue; ++ ++ if (!GREEDY_REALLOC(list, allocated, n+2)) ++ return log_oom(); ++ ++ copy = strdup(info.id); ++ if (!copy) ++ return log_oom(); ++ ++ list[n++] = copy; ++ list[n] = NULL; ++ } ++ ++ strv_sort(list); ++ ++ flags |= ANALYZE_SECURITY_SHORT|ANALYZE_SECURITY_ONLY_LOADED|ANALYZE_SECURITY_ONLY_LONG_RUNNING; ++ ++ STRV_FOREACH(i, list) { ++ r = analyze_security_one(bus, *i, overview_table, flags); ++ if (r < 0 && ret >= 0) ++ ret = r; ++ } ++ ++ } else { ++ char **i; ++ ++ STRV_FOREACH(i, units) { ++ _cleanup_free_ char *mangled = NULL, *instance = NULL; ++ const char *name; ++ ++ if (!FLAGS_SET(flags, ANALYZE_SECURITY_SHORT) && i != units) { ++ putc('\n', stdout); ++ fflush(stdout); ++ } ++ ++ r = unit_name_mangle_with_suffix(*i, 0, ".service", &mangled); ++ if (r < 0) ++ return log_error_errno(r, "Failed to mangle unit name '%s': %m", *i); ++ ++ if (!endswith(mangled, ".service")) { ++ log_error("Unit %s is not a service unit, refusing.", *i); ++ return -EINVAL; ++ } ++ ++ if (unit_name_is_valid(mangled, UNIT_NAME_TEMPLATE)) { ++ r = unit_name_replace_instance(mangled, "test-instance", &instance); ++ if (r < 0) ++ return log_oom(); ++ ++ name = instance; ++ } else ++ name = mangled; ++ ++ r = analyze_security_one(bus, name, overview_table, flags); ++ if (r < 0 && ret >= 0) ++ ret = r; ++ } ++ } ++ ++ if (overview_table) { ++ if (!FLAGS_SET(flags, ANALYZE_SECURITY_SHORT)) { ++ putc('\n', stdout); ++ fflush(stdout); ++ } ++ ++ r = table_print(overview_table, stdout); ++ if (r < 0) ++ return log_error_errno(r, "Failed to output table: %m"); ++ } ++ ++ return ret; ++} +diff --git a/src/analyze/analyze-security.h b/src/analyze/analyze-security.h +new file mode 100644 +index 0000000000..c00ae7c80a +--- /dev/null ++++ b/src/analyze/analyze-security.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++#include "sd-bus.h" ++ ++typedef enum AnalyzeSecurityFlags { ++ ANALYZE_SECURITY_SHORT = 1 << 0, ++ ANALYZE_SECURITY_ONLY_LOADED = 1 << 1, ++ ANALYZE_SECURITY_ONLY_LONG_RUNNING = 1 << 2, ++} AnalyzeSecurityFlags; ++ ++int analyze_security(sd_bus *bus, char **units, AnalyzeSecurityFlags flags); +diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c +index dc7d2ab0f6..c30a133fc0 100644 +--- a/src/analyze/analyze.c ++++ b/src/analyze/analyze.c +@@ -11,6 +11,7 @@ + #include "sd-bus.h" + + #include "alloc-util.h" ++#include "analyze-security.h" + #include "analyze-verify.h" + #include "bus-error.h" + #include "bus-unit-util.h" +@@ -1659,6 +1660,19 @@ static int do_verify(int argc, char *argv[], void *userdata) { + return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators); + } + ++static int do_security(int argc, char *argv[], void *userdata) { ++ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; ++ int r; ++ ++ r = acquire_bus(&bus, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to create bus connection: %m"); ++ ++ (void) pager_open(arg_no_pager, false); ++ ++ return analyze_security(bus, strv_skip(argv, 1), 0); ++} ++ + static int help(int argc, char *argv[], void *userdata) { + + (void) pager_open(arg_no_pager, false); +@@ -1696,6 +1710,7 @@ static int help(int argc, char *argv[], void *userdata) { + " verify FILE... Check unit files for correctness\n" + " calendar SPEC... Validate repetitive calendar time events\n" + " service-watchdogs [BOOL] Get/set service watchdog state\n" ++ " security [UNIT...] Analyze security of unit\n" + , program_invocation_short_name); + + /* When updating this list, including descriptions, apply +@@ -1884,6 +1899,7 @@ int main(int argc, char *argv[]) { + { "verify", 2, VERB_ANY, 0, do_verify }, + { "calendar", 2, VERB_ANY, 0, test_calendar }, + { "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs }, ++ { "security", VERB_ANY, VERB_ANY, 0, do_security }, + {} + }; + +diff --git a/src/analyze/meson.build b/src/analyze/meson.build +index 3a69a259b1..4db4dfa552 100644 +--- a/src/analyze/meson.build ++++ b/src/analyze/meson.build +@@ -4,4 +4,6 @@ systemd_analyze_sources = files(''' + analyze.c + analyze-verify.c + analyze-verify.h ++ analyze-security.c ++ analyze-security.h + '''.split()) +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index 844b92f41c..c541e92b3c 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -10,7 +10,6 @@ + #include "gunicode.h" + #include "pager.h" + #include "parse-util.h" +-#include "pretty-print.h" + #include "string-util.h" + #include "terminal-util.h" + #include "time-util.h" +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 79ab02b27a..0fe6a62aa8 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -249,12 +249,13 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { + * computation should be possible in the given type. Therefore, we use + * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the + * quotient and the remainder, so both should be equally fast. */ +-#define DIV_ROUND_UP(_x, _y) \ +- __extension__ ({ \ +- const typeof(_x) __x = (_x); \ +- const typeof(_y) __y = (_y); \ +- (__x / __y + !!(__x % __y)); \ +- }) ++#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, (x), UNIQ, (y)) ++#define __DIV_ROUND_UP(xq, x, yq, y) \ ++ ({ \ ++ const typeof(x) UNIQ_T(X, xq) = (x); \ ++ const typeof(y) UNIQ_T(Y, yq) = (y); \ ++ (UNIQ_T(X, xq) / UNIQ_T(Y, yq) + !!(UNIQ_T(X, xq) % UNIQ_T(Y, yq))); \ ++ }) + + #define assert_message_se(expr, message) \ + do { \ +diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c +index f4af0e6522..e2bbe8187d 100644 +--- a/src/basic/terminal-util.c ++++ b/src/basic/terminal-util.c +@@ -1320,10 +1320,38 @@ int terminal_urlify(const char *url, const char *text, char **ret) { + return 0; + } + +-int terminal_urlify_path(const char *path, const char *text, char **ret) { ++int file_url_from_path(const char *path, char **ret) { + _cleanup_free_ char *absolute = NULL; + struct utsname u; +- const char *url; ++ char *url = NULL; ++ int r; ++ ++ if (uname(&u) < 0) ++ return -errno; ++ ++ if (!path_is_absolute(path)) { ++ r = path_make_absolute_cwd(path, &absolute); ++ if (r < 0) ++ return r; ++ ++ path = absolute; ++ } ++ ++ /* As suggested by https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda, let's include the local ++ * hostname here. Note that we don't use gethostname_malloc() or gethostname_strict() since we are interested ++ * in the raw string the kernel has set, whatever it may be, under the assumption that terminals are not overly ++ * careful with validating the strings either. */ ++ ++ url = strjoin("file://", u.nodename, path); ++ if (!url) ++ return -ENOMEM; ++ ++ *ret = url; ++ return 0; ++} ++ ++int terminal_urlify_path(const char *path, const char *text, char **ret) { ++ _cleanup_free_ char *url = NULL; + int r; + + assert(path); +@@ -1348,27 +1376,14 @@ int terminal_urlify_path(const char *path, const char *text, char **ret) { + return 0; + } + +- if (uname(&u) < 0) +- return -errno; +- +- if (!path_is_absolute(path)) { +- r = path_make_absolute_cwd(path, &absolute); +- if (r < 0) +- return r; +- +- path = absolute; +- } +- +- /* As suggested by https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda, let's include the local +- * hostname here. Note that we don't use gethostname_malloc() or gethostname_strict() since we are interested +- * in the raw string the kernel has set, whatever it may be, under the assumption that terminals are not overly +- * careful with validating the strings either. */ +- +- url = strjoina("file://", u.nodename, path); ++ r = file_url_from_path(path, &url); ++ if (r < 0) ++ return r; + + return terminal_urlify(url, text, ret); + } + ++ + static int cat_file(const char *filename, bool newline) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *urlified = NULL; +diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h +index 0055b72343..3f23ecfd3d 100644 +--- a/src/basic/terminal-util.h ++++ b/src/basic/terminal-util.h +@@ -154,6 +154,7 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode); + int vt_default_utf8(void); + int vt_reset_keyboard(int fd); + ++int file_url_from_path(const char *path, char **ret); + int terminal_urlify(const char *url, const char *text, char **ret); + int terminal_urlify_path(const char *path, const char *text, char **ret); + diff --git a/SOURCES/0140-tests-add-a-rudimentary-fuzzer-for-server_process_sy.patch b/SOURCES/0140-tests-add-a-rudimentary-fuzzer-for-server_process_sy.patch new file mode 100644 index 0000000..83c8577 --- /dev/null +++ b/SOURCES/0140-tests-add-a-rudimentary-fuzzer-for-server_process_sy.patch @@ -0,0 +1,66 @@ +From 86cf4118a04afbc67d0231f8b53cf3629258032a Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 3 Sep 2018 06:18:26 +0300 +Subject: [PATCH] tests: add a rudimentary fuzzer for + server_process_syslog_message (#9979) + +(cherry picked from commit a70f343cacf03ac51cdefb0d2e7651b04fd2e23a) + +Resolves: #1696224 +--- + src/fuzz/fuzz-journald-syslog.c | 29 +++++++++++++++++++++++++++++ + src/fuzz/meson.build | 5 +++++ + 2 files changed, 34 insertions(+) + create mode 100644 src/fuzz/fuzz-journald-syslog.c + +diff --git a/src/fuzz/fuzz-journald-syslog.c b/src/fuzz/fuzz-journald-syslog.c +new file mode 100644 +index 0000000000..7730f60875 +--- /dev/null ++++ b/src/fuzz/fuzz-journald-syslog.c +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "alloc-util.h" ++#include "fuzz.h" ++#include "journald-server.h" ++#include "journald-syslog.h" ++#include "sd-event.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ Server s = {}; ++ char *label = NULL; ++ size_t label_len = 0; ++ struct ucred *ucred = NULL; ++ struct timeval *tv = NULL; ++ ++ if (size == 0) ++ return 0; ++ ++ assert_se(sd_event_default(&s.event) >= 0); ++ s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; ++ s.buffer = memdup_suffix0(data, size); ++ assert_se(s.buffer); ++ s.buffer_size = size + 1; ++ s.storage = STORAGE_NONE; ++ server_process_syslog_message(&s, s.buffer, size, ucred, tv, label, label_len); ++ server_done(&s); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index ad44778889..28770b68b8 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -19,6 +19,11 @@ fuzzers += [ + libshared], + [libmount]], + ++ [['src/fuzz/fuzz-journald-syslog.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journal-remote.c'], + [libsystemd_journal_remote, + libshared], diff --git a/SOURCES/0141-journald-make-it-clear-that-dev_kmsg_record-modifies.patch b/SOURCES/0141-journald-make-it-clear-that-dev_kmsg_record-modifies.patch new file mode 100644 index 0000000..6078dd4 --- /dev/null +++ b/SOURCES/0141-journald-make-it-clear-that-dev_kmsg_record-modifies.patch @@ -0,0 +1,30 @@ +From 7e902f1e31bfdd6542343c1656dae3b6853228a6 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 10 Aug 2018 12:45:42 +0000 +Subject: [PATCH] journald: make it clear that dev_kmsg_record modifies the + string passed to it + +The function replaces a couple commas, a semicolon and the final newline with +zero bytes in the string passed to it. The 'const' seems to have been added +by accident during a bulk edit (more specifically 3b3154df7e2773332bb814). + +(cherry picked from commit 1e0c5fc2a76e4f3d508331f410899c50493e1fc9) + +Resolves: #1696224 +--- + src/journal/journald-kmsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index e9aff13168..7ad673362a 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -93,7 +93,7 @@ static bool is_us(const char *identifier, const char *pid) { + streq(identifier, program_invocation_short_name); + } + +-static void dev_kmsg_record(Server *s, const char *p, size_t l) { ++static void dev_kmsg_record(Server *s, char *p, size_t l) { + + _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL; + struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS]; diff --git a/SOURCES/0142-journald-free-the-allocated-memory-before-returning-.patch b/SOURCES/0142-journald-free-the-allocated-memory-before-returning-.patch new file mode 100644 index 0000000..e1aab73 --- /dev/null +++ b/SOURCES/0142-journald-free-the-allocated-memory-before-returning-.patch @@ -0,0 +1,28 @@ +From d8600cb5319060f294049a81320f5de4c48cf5d5 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 10 Aug 2018 12:52:07 +0000 +Subject: [PATCH] journald: free the allocated memory before returning from + dev_kmsg_record + +This fixes a minor memory leak. + +(cherry picked from commit 30eddcd51b8a472e05d3b8d1f0b89fbd3e094d71) + +Resolves: #1696224 +--- + src/journal/journald-kmsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 7ad673362a..7644bebfc8 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -191,7 +191,7 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { + + e = memchr(k, '\n', l); + if (!e) +- return; ++ goto finish; + + *e = 0; + diff --git a/SOURCES/0143-tests-rework-the-code-fuzzing-journald.patch b/SOURCES/0143-tests-rework-the-code-fuzzing-journald.patch new file mode 100644 index 0000000..3c86a94 --- /dev/null +++ b/SOURCES/0143-tests-rework-the-code-fuzzing-journald.patch @@ -0,0 +1,89 @@ +From 452aefc33ab5ebe9c3725d7680ce16399b486a9b Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 3 Sep 2018 06:46:24 +0000 +Subject: [PATCH] tests: rework the code fuzzing journald + +This should make it easier to add a new fuzzer without a lot of +duplication. + +(cherry picked from commit b1bd453f36b9428b6bf9feba31fa0a2b36143e9c) + +Resolves: #1696224 +--- + src/fuzz/fuzz-journald-syslog.c | 23 ++--------------------- + src/fuzz/fuzz-journald.h | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 21 deletions(-) + create mode 100644 src/fuzz/fuzz-journald.h + +diff --git a/src/fuzz/fuzz-journald-syslog.c b/src/fuzz/fuzz-journald-syslog.c +index 7730f60875..100f0ce691 100644 +--- a/src/fuzz/fuzz-journald-syslog.c ++++ b/src/fuzz/fuzz-journald-syslog.c +@@ -1,29 +1,10 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + +-#include "alloc-util.h" + #include "fuzz.h" +-#include "journald-server.h" ++#include "fuzz-journald.h" + #include "journald-syslog.h" +-#include "sd-event.h" + + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { +- Server s = {}; +- char *label = NULL; +- size_t label_len = 0; +- struct ucred *ucred = NULL; +- struct timeval *tv = NULL; +- +- if (size == 0) +- return 0; +- +- assert_se(sd_event_default(&s.event) >= 0); +- s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; +- s.buffer = memdup_suffix0(data, size); +- assert_se(s.buffer); +- s.buffer_size = size + 1; +- s.storage = STORAGE_NONE; +- server_process_syslog_message(&s, s.buffer, size, ucred, tv, label, label_len); +- server_done(&s); +- ++ fuzz_journald_processing_function(data, size, server_process_syslog_message); + return 0; + } +diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h +new file mode 100644 +index 0000000000..e66ef54c9b +--- /dev/null ++++ b/src/fuzz/fuzz-journald.h +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++#include "alloc-util.h" ++#include "journald-server.h" ++#include "sd-event.h" ++ ++static void fuzz_journald_processing_function( ++ const uint8_t *data, ++ size_t size, ++ void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len) ++ ) { ++ Server s = {}; ++ char *label = NULL; ++ size_t label_len = 0; ++ struct ucred *ucred = NULL; ++ struct timeval *tv = NULL; ++ ++ if (size == 0) ++ return; ++ ++ assert_se(sd_event_default(&s.event) >= 0); ++ s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; ++ s.buffer = memdup_suffix0(data, size); ++ assert_se(s.buffer); ++ s.buffer_size = size + 1; ++ s.storage = STORAGE_NONE; ++ (*f)(&s, s.buffer, size, ucred, tv, label, label_len); ++ server_done(&s); ++} diff --git a/SOURCES/0144-journald-make-server_process_native_message-compatib.patch b/SOURCES/0144-journald-make-server_process_native_message-compatib.patch new file mode 100644 index 0000000..cd7d314 --- /dev/null +++ b/SOURCES/0144-journald-make-server_process_native_message-compatib.patch @@ -0,0 +1,40 @@ +From eb711891df269ea784e3c9adc3483d9ec86c25e9 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 3 Sep 2018 07:03:10 +0000 +Subject: [PATCH] journald: make server_process_native_message compatible with + fuzz_journald_processing_function + +(cherry picked from commit 21acb27b71f6284a57e4e9f3ac5f0d38721ef4eb) + +Resolves: #1696224 +--- + src/journal/journald-native.c | 2 +- + src/journal/journald-native.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c +index da62448ca6..466b6f7213 100644 +--- a/src/journal/journald-native.c ++++ b/src/journal/journald-native.c +@@ -293,7 +293,7 @@ finish: + + void server_process_native_message( + Server *s, +- const void *buffer, size_t buffer_size, ++ const char *buffer, size_t buffer_size, + const struct ucred *ucred, + const struct timeval *tv, + const char *label, size_t label_len) { +diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h +index 7211d4fab4..2a33ef74c5 100644 +--- a/src/journal/journald-native.h ++++ b/src/journal/journald-native.h +@@ -5,7 +5,7 @@ + + void server_process_native_message( + Server *s, +- const void *buffer, ++ const char *buffer, + size_t buffer_size, + const struct ucred *ucred, + const struct timeval *tv, diff --git a/SOURCES/0145-tests-add-a-fuzzer-for-server_process_native_message.patch b/SOURCES/0145-tests-add-a-fuzzer-for-server_process_native_message.patch new file mode 100644 index 0000000..01faecd --- /dev/null +++ b/SOURCES/0145-tests-add-a-fuzzer-for-server_process_native_message.patch @@ -0,0 +1,46 @@ +From f9a28e4e070ed86a0c5138dbfb98a60f00beb8d4 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 3 Sep 2018 07:05:48 +0000 +Subject: [PATCH] tests: add a fuzzer for server_process_native_message + +(cherry picked from commit 9cdea02db57a36442ad9e9afcd67760ca319173a) + +Resolves: #1696224 +--- + src/fuzz/fuzz-journald-native.c | 10 ++++++++++ + src/fuzz/meson.build | 5 +++++ + 2 files changed, 15 insertions(+) + create mode 100644 src/fuzz/fuzz-journald-native.c + +diff --git a/src/fuzz/fuzz-journald-native.c b/src/fuzz/fuzz-journald-native.c +new file mode 100644 +index 0000000000..f4de5fd8eb +--- /dev/null ++++ b/src/fuzz/fuzz-journald-native.c +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "fuzz.h" ++#include "fuzz-journald.h" ++#include "journald-native.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ fuzz_journald_processing_function(data, size, server_process_native_message); ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 28770b68b8..5a97ef5091 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -19,6 +19,11 @@ fuzzers += [ + libshared], + [libmount]], + ++ [['src/fuzz/fuzz-journald-native.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journald-syslog.c'], + [libjournal_core, + libshared], diff --git a/SOURCES/0146-tests-add-a-fuzzer-for-sd-ndisc.patch b/SOURCES/0146-tests-add-a-fuzzer-for-sd-ndisc.patch new file mode 100644 index 0000000..c1b2ccf --- /dev/null +++ b/SOURCES/0146-tests-add-a-fuzzer-for-sd-ndisc.patch @@ -0,0 +1,98 @@ +From aec984020cd22ac8a199bcd067047fba50850889 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Wed, 26 Sep 2018 15:04:26 +0000 +Subject: [PATCH] tests: add a fuzzer for sd-ndisc + +(cherry picked from commit 0f0a1dad7d69802a7e6c7fc9aba350f0e87c1952) + +Resolves: #1696224 +--- + src/fuzz/fuzz-ndisc-rs.c | 57 ++++++++++++++++++++++++++++++++++++++++ + src/fuzz/meson.build | 10 +++++++ + 2 files changed, 67 insertions(+) + create mode 100644 src/fuzz/fuzz-ndisc-rs.c + +diff --git a/src/fuzz/fuzz-ndisc-rs.c b/src/fuzz/fuzz-ndisc-rs.c +new file mode 100644 +index 0000000000..7f2d8f8649 +--- /dev/null ++++ b/src/fuzz/fuzz-ndisc-rs.c +@@ -0,0 +1,57 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++#include ++ ++#include "alloc-util.h" ++#include "icmp6-util.h" ++#include "fuzz.h" ++#include "sd-ndisc.h" ++#include "socket-util.h" ++#include "ndisc-internal.h" ++ ++static int test_fd[2]; ++ ++int icmp6_bind_router_solicitation(int index) { ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) >= 0); ++ return test_fd[0]; ++} ++ ++int icmp6_bind_router_advertisement(int index) { ++ return -ENOSYS; ++} ++ ++int icmp6_receive(int fd, void *iov_base, size_t iov_len, ++ struct in6_addr *dst, triple_timestamp *timestamp) { ++ assert_se(read(fd, iov_base, iov_len) == (ssize_t) iov_len); ++ ++ if (timestamp) ++ triple_timestamp_get(timestamp); ++ ++ return 0; ++} ++ ++int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { ++ return 0; ++} ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ struct ether_addr mac_addr = { ++ .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} ++ }; ++ _cleanup_(sd_event_unrefp) sd_event *e = NULL; ++ _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL; ++ ++ assert_se(sd_event_new(&e) >= 0); ++ assert_se(sd_ndisc_new(&nd) >= 0); ++ assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); ++ assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0); ++ assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); ++ assert_se(sd_ndisc_start(nd) >= 0); ++ assert_se(write(test_fd[1], data, size) == (ssize_t) size); ++ (void) sd_event_run(e, (uint64_t) -1); ++ assert_se(sd_ndisc_stop(nd) >= 0); ++ close(test_fd[1]); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 5a97ef5091..5c81ac0c5b 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -14,6 +14,16 @@ fuzzers += [ + libshared], + []], + ++ [['src/fuzz/fuzz-ndisc-rs.c', ++ 'src/libsystemd-network/dhcp-identifier.h', ++ 'src/libsystemd-network/dhcp-identifier.c', ++ 'src/libsystemd-network/icmp6-util.h', ++ 'src/systemd/sd-dhcp6-client.h', ++ 'src/systemd/sd-ndisc.h'], ++ [libshared, ++ libsystemd_network], ++ []], ++ + [['src/fuzz/fuzz-unit-file.c'], + [libcore, + libshared], diff --git a/SOURCES/0147-ndisc-fix-two-infinite-loops.patch b/SOURCES/0147-ndisc-fix-two-infinite-loops.patch new file mode 100644 index 0000000..34ff112 --- /dev/null +++ b/SOURCES/0147-ndisc-fix-two-infinite-loops.patch @@ -0,0 +1,34 @@ +From 0318890ed2325b916ccfa5a59ede98e6a4b5fe60 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 28 Sep 2018 19:28:05 +0900 +Subject: [PATCH] ndisc: fix two infinite loops + +(cherry picked from commit f3241c61f12dbd8f0ed37419ae272e291d09461d) + +Resolves: #1696224 +--- + src/libsystemd-network/ndisc-router.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c +index 25b693a458..3806804435 100644 +--- a/src/libsystemd-network/ndisc-router.c ++++ b/src/libsystemd-network/ndisc-router.c +@@ -189,7 +189,7 @@ int ndisc_router_parse(sd_ndisc_router *rt) { + + if (has_mtu) { + log_ndisc("MTU option specified twice, ignoring."); +- continue; ++ break; + } + + if (length != 8) { +@@ -230,7 +230,7 @@ int ndisc_router_parse(sd_ndisc_router *rt) { + + if (has_flag_extension) { + log_ndisc("Flags extension option specified twice, ignoring."); +- continue; ++ break; + } + + if (length < 1*8) { diff --git a/SOURCES/0148-tests-add-reproducers-for-several-issues-uncovered-w.patch b/SOURCES/0148-tests-add-reproducers-for-several-issues-uncovered-w.patch new file mode 100644 index 0000000..723fbfa --- /dev/null +++ b/SOURCES/0148-tests-add-reproducers-for-several-issues-uncovered-w.patch @@ -0,0 +1,70 @@ +From 8918fcc041a7f58e55d6d2b40e8dc3c396819b67 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Sun, 2 Sep 2018 18:13:31 +0000 +Subject: [PATCH] tests: add reproducers for several issues uncovered with + fuzz-journald-syslog + +This is a follow-up to a70f343cacf03ac51cdefb0d2e. + +(cherry picked from commit 3311c74d0560e4aa6a223f5e288a5fbf2404d3fa) + +Resolves: #1696224 +--- + test/fuzz-regressions/fuzz-journald-syslog/github-9795 | 1 + + test/fuzz-regressions/fuzz-journald-syslog/github-9820 | 1 + + test/fuzz-regressions/fuzz-journald-syslog/github-9827 | 1 + + test/fuzz-regressions/fuzz-journald-syslog/github-9829 | 1 + + test/fuzz-regressions/meson.build | 4 ++++ + 5 files changed, 8 insertions(+) + create mode 100644 test/fuzz-regressions/fuzz-journald-syslog/github-9795 + create mode 100644 test/fuzz-regressions/fuzz-journald-syslog/github-9820 + create mode 100644 test/fuzz-regressions/fuzz-journald-syslog/github-9827 + create mode 100644 test/fuzz-regressions/fuzz-journald-syslog/github-9829 + +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9795 b/test/fuzz-regressions/fuzz-journald-syslog/github-9795 +new file mode 100644 +index 0000000000..0519ecba6e +--- /dev/null ++++ b/test/fuzz-regressions/fuzz-journald-syslog/github-9795 +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9820 b/test/fuzz-regressions/fuzz-journald-syslog/github-9820 +new file mode 100644 +index 0000000000..55e1bb5967 +--- /dev/null ++++ b/test/fuzz-regressions/fuzz-journald-syslog/github-9820 +@@ -0,0 +1 @@ ++<13>Aug 4 04:08:03 something-is-about-to-go-wrong: +\ No newline at end of file +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9827 b/test/fuzz-regressions/fuzz-journald-syslog/github-9827 +new file mode 100644 +index 0000000000..6787e487a4 +--- /dev/null ++++ b/test/fuzz-regressions/fuzz-journald-syslog/github-9827 +@@ -0,0 +1 @@ ++<> +\ No newline at end of file +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9829 b/test/fuzz-regressions/fuzz-journald-syslog/github-9829 +new file mode 100644 +index 0000000000..22ded55aa2 +--- /dev/null ++++ b/test/fuzz-regressions/fuzz-journald-syslog/github-9829 +@@ -0,0 +1 @@ ++: +\ No newline at end of file +diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build +index 3a2c306492..74fd88cfcd 100644 +--- a/test/fuzz-regressions/meson.build ++++ b/test/fuzz-regressions/meson.build +@@ -18,6 +18,10 @@ fuzz_regression_tests = ''' + fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 + fuzz-journal-remote/oss-fuzz-8659 + fuzz-journal-remote/oss-fuzz-8686 ++ fuzz-journald-syslog/github-9795 ++ fuzz-journald-syslog/github-9820 ++ fuzz-journald-syslog/github-9827 ++ fuzz-journald-syslog/github-9829 + fuzz-unit-file/oss-fuzz-6884 + fuzz-unit-file/oss-fuzz-6885 + fuzz-unit-file/oss-fuzz-6886 diff --git a/SOURCES/0149-tests-add-a-reproducer-for-an-infinite-loop-in-ndisc.patch b/SOURCES/0149-tests-add-a-reproducer-for-an-infinite-loop-in-ndisc.patch new file mode 100644 index 0000000..438dee1 --- /dev/null +++ b/SOURCES/0149-tests-add-a-reproducer-for-an-infinite-loop-in-ndisc.patch @@ -0,0 +1,46 @@ +From 514d782be9af0bd3e37a4e224816d3ba70b51ec0 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Wed, 26 Sep 2018 15:10:21 +0000 +Subject: [PATCH] tests: add a reproducer for an infinite loop in + ndisc_handle_datagram + +=0 ndisc_router_parse (rt=0x60d000000110) at ../src/libsystemd-network/ndisc-router.c:126 +=1 0x000055555558dc67 in ndisc_handle_datagram (nd=0x608000000020, rt=0x60d000000110) at ../src/libsystemd-network/sd-ndisc.c:170 +=2 0x000055555558e65d in ndisc_recv (s=0x611000000040, fd=4, revents=1, userdata=0x608000000020) at ../src/libsystemd-network/sd-ndisc.c:233 +=3 0x00007ffff63913a8 in source_dispatch (s=0x611000000040) at ../src/libsystemd/sd-event/sd-event.c:3042 +=4 0x00007ffff6395eab in sd_event_dispatch (e=0x617000000080) at ../src/libsystemd/sd-event/sd-event.c:3455 +=5 0x00007ffff6396b12 in sd_event_run (e=0x617000000080, timeout=18446744073709551615) at ../src/libsystemd/sd-event/sd-event.c:3512 +=6 0x0000555555583f5c in LLVMFuzzerTestOneInput (data=0x6060000000e0 "\206", size=53) at ../src/fuzz/fuzz-ndisc-rs.c:422 +=7 0x0000555555586356 in main (argc=2, argv=0x7fffffffe3d8) at ../src/fuzz/fuzz-main.c:33 + +(cherry picked from commit df30e78e02f653c9e6ee6677b7ccaea21d3dcd7d) + +Resolves: #1696224 +--- + ...imeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 | Bin 0 -> 53 bytes + test/fuzz-regressions/meson.build | 1 + + 2 files changed, 1 insertion(+) + create mode 100644 test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 + +diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 b/test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 +new file mode 100644 +index 0000000000000000000000000000000000000000..410cf38c1ec2156680e80160825b883fb4f12aa9 +GIT binary patch +literal 53 +ucmZo;U|{$U0h55t23AHOm-#;v2(&S9GpRCgaeXR_WB`f-fhq$7NEHAcu@3A2 + +literal 0 +HcmV?d00001 + +diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build +index 74fd88cfcd..7aa2cbce11 100644 +--- a/test/fuzz-regressions/meson.build ++++ b/test/fuzz-regressions/meson.build +@@ -22,6 +22,7 @@ fuzz_regression_tests = ''' + fuzz-journald-syslog/github-9820 + fuzz-journald-syslog/github-9827 + fuzz-journald-syslog/github-9829 ++ fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 + fuzz-unit-file/oss-fuzz-6884 + fuzz-unit-file/oss-fuzz-6885 + fuzz-unit-file/oss-fuzz-6886 diff --git a/SOURCES/0150-tests-add-a-reproducer-for-another-infinite-loop-in-.patch b/SOURCES/0150-tests-add-a-reproducer-for-another-infinite-loop-in-.patch new file mode 100644 index 0000000..8ad518f --- /dev/null +++ b/SOURCES/0150-tests-add-a-reproducer-for-another-infinite-loop-in-.patch @@ -0,0 +1,37 @@ +From 1d33acf3ae230456db55fb7d153047cbd6b76623 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Wed, 26 Sep 2018 18:09:09 +0000 +Subject: [PATCH] tests: add a reproducer for another infinite loop in + ndisc_handle_datagram + +(cherry picked from commit bbb393877b2cfcbe2f205c902ca7d9f7ce91f1a1) + +Resolves: #1696224 +--- + ...imeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b | Bin 0 -> 71 bytes + test/fuzz-regressions/meson.build | 1 + + 2 files changed, 1 insertion(+) + create mode 100644 test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b + +diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b b/test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b +new file mode 100644 +index 0000000000000000000000000000000000000000..04e871fbcbddfe0642bd6855228bf8da163ad6e3 +GIT binary patch +literal 71 +ucmZo;U}$4tu#$oUW@d)Jzy1TkUp6M@U)f7q +Date: Sat, 7 Jul 2018 17:43:40 +0200 +Subject: [PATCH] fuzz: rename "fuzz-corpus" directory to just "fuzz" + +Also, all corpus subdirectories are named exactly the same as the fuzzer they +are for. This makes the paths a bit longer, but easier. + +(cherry picked from commit 93b575b26605c347a717b2aa24ddf9cad08b8080) + +Resolves: #1696224 +--- + test/{fuzz-corpus => fuzz}/.gitattributes | 0 + .../fuzz-dhcp-server}/discover-existing | Bin + .../fuzz-dhcp-server}/discover-new | Bin + .../dhcp-server => fuzz/fuzz-dhcp-server}/release | Bin + .../fuzz-dhcp-server}/request-existing | Bin + .../fuzz-dhcp-server}/request-new | Bin + .../fuzz-dhcp-server}/request-reboot | Bin + .../fuzz-dhcp-server}/request-renew | Bin + .../fuzz-journal-remote}/invalid-ts.txt | Bin + .../fuzz-journal-remote}/sample.txt | 0 + .../dev-mapper-fedora_krowka\\x2dswap.swap" | 0 + .../fuzz-unit-file}/directives.service | 0 + .../unit-file => fuzz/fuzz-unit-file}/empty.scope | 0 + .../unit-file => fuzz/fuzz-unit-file}/machine.slice | 0 + .../proc-sys-fs-binfmt_misc.automount | 0 + .../unit-file => fuzz/fuzz-unit-file}/syslog.socket | 0 + .../systemd-ask-password-console.path | 0 + .../fuzz-unit-file}/systemd-machined.service | 0 + .../fuzz-unit-file}/systemd-resolved.service | 0 + .../fuzz-unit-file}/systemd-tmpfiles-clean.timer | 0 + .../unit-file => fuzz/fuzz-unit-file}/timers.target | 0 + .../fuzz-unit-file}/var-lib-machines.mount | 0 + tools/oss-fuzz.sh | 6 ++++-- + 23 files changed, 4 insertions(+), 2 deletions(-) + rename test/{fuzz-corpus => fuzz}/.gitattributes (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/discover-existing (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/discover-new (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/release (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/request-existing (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/request-new (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/request-reboot (100%) + rename test/{fuzz-corpus/dhcp-server => fuzz/fuzz-dhcp-server}/request-renew (100%) + rename test/{fuzz-corpus/journal-remote => fuzz/fuzz-journal-remote}/invalid-ts.txt (100%) + rename test/{fuzz-corpus/journal-remote => fuzz/fuzz-journal-remote}/sample.txt (100%) + rename "test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" => "test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/directives.service (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/empty.scope (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/machine.slice (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/proc-sys-fs-binfmt_misc.automount (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/syslog.socket (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/systemd-ask-password-console.path (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/systemd-machined.service (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/systemd-resolved.service (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/systemd-tmpfiles-clean.timer (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/timers.target (100%) + rename test/{fuzz-corpus/unit-file => fuzz/fuzz-unit-file}/var-lib-machines.mount (100%) + +diff --git a/test/fuzz-corpus/.gitattributes b/test/fuzz/.gitattributes +similarity index 100% +rename from test/fuzz-corpus/.gitattributes +rename to test/fuzz/.gitattributes +diff --git a/test/fuzz-corpus/dhcp-server/discover-existing b/test/fuzz/fuzz-dhcp-server/discover-existing +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/discover-existing +rename to test/fuzz/fuzz-dhcp-server/discover-existing +diff --git a/test/fuzz-corpus/dhcp-server/discover-new b/test/fuzz/fuzz-dhcp-server/discover-new +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/discover-new +rename to test/fuzz/fuzz-dhcp-server/discover-new +diff --git a/test/fuzz-corpus/dhcp-server/release b/test/fuzz/fuzz-dhcp-server/release +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/release +rename to test/fuzz/fuzz-dhcp-server/release +diff --git a/test/fuzz-corpus/dhcp-server/request-existing b/test/fuzz/fuzz-dhcp-server/request-existing +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/request-existing +rename to test/fuzz/fuzz-dhcp-server/request-existing +diff --git a/test/fuzz-corpus/dhcp-server/request-new b/test/fuzz/fuzz-dhcp-server/request-new +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/request-new +rename to test/fuzz/fuzz-dhcp-server/request-new +diff --git a/test/fuzz-corpus/dhcp-server/request-reboot b/test/fuzz/fuzz-dhcp-server/request-reboot +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/request-reboot +rename to test/fuzz/fuzz-dhcp-server/request-reboot +diff --git a/test/fuzz-corpus/dhcp-server/request-renew b/test/fuzz/fuzz-dhcp-server/request-renew +similarity index 100% +rename from test/fuzz-corpus/dhcp-server/request-renew +rename to test/fuzz/fuzz-dhcp-server/request-renew +diff --git a/test/fuzz-corpus/journal-remote/invalid-ts.txt b/test/fuzz/fuzz-journal-remote/invalid-ts.txt +similarity index 100% +rename from test/fuzz-corpus/journal-remote/invalid-ts.txt +rename to test/fuzz/fuzz-journal-remote/invalid-ts.txt +diff --git a/test/fuzz-corpus/journal-remote/sample.txt b/test/fuzz/fuzz-journal-remote/sample.txt +similarity index 100% +rename from test/fuzz-corpus/journal-remote/sample.txt +rename to test/fuzz/fuzz-journal-remote/sample.txt +diff --git "a/test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" "b/test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" +similarity index 100% +rename from "test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" +rename to "test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\\x2dswap.swap" +diff --git a/test/fuzz-corpus/unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +similarity index 100% +rename from test/fuzz-corpus/unit-file/directives.service +rename to test/fuzz/fuzz-unit-file/directives.service +diff --git a/test/fuzz-corpus/unit-file/empty.scope b/test/fuzz/fuzz-unit-file/empty.scope +similarity index 100% +rename from test/fuzz-corpus/unit-file/empty.scope +rename to test/fuzz/fuzz-unit-file/empty.scope +diff --git a/test/fuzz-corpus/unit-file/machine.slice b/test/fuzz/fuzz-unit-file/machine.slice +similarity index 100% +rename from test/fuzz-corpus/unit-file/machine.slice +rename to test/fuzz/fuzz-unit-file/machine.slice +diff --git a/test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount b/test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount +similarity index 100% +rename from test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount +rename to test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount +diff --git a/test/fuzz-corpus/unit-file/syslog.socket b/test/fuzz/fuzz-unit-file/syslog.socket +similarity index 100% +rename from test/fuzz-corpus/unit-file/syslog.socket +rename to test/fuzz/fuzz-unit-file/syslog.socket +diff --git a/test/fuzz-corpus/unit-file/systemd-ask-password-console.path b/test/fuzz/fuzz-unit-file/systemd-ask-password-console.path +similarity index 100% +rename from test/fuzz-corpus/unit-file/systemd-ask-password-console.path +rename to test/fuzz/fuzz-unit-file/systemd-ask-password-console.path +diff --git a/test/fuzz-corpus/unit-file/systemd-machined.service b/test/fuzz/fuzz-unit-file/systemd-machined.service +similarity index 100% +rename from test/fuzz-corpus/unit-file/systemd-machined.service +rename to test/fuzz/fuzz-unit-file/systemd-machined.service +diff --git a/test/fuzz-corpus/unit-file/systemd-resolved.service b/test/fuzz/fuzz-unit-file/systemd-resolved.service +similarity index 100% +rename from test/fuzz-corpus/unit-file/systemd-resolved.service +rename to test/fuzz/fuzz-unit-file/systemd-resolved.service +diff --git a/test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer b/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer +similarity index 100% +rename from test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer +rename to test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer +diff --git a/test/fuzz-corpus/unit-file/timers.target b/test/fuzz/fuzz-unit-file/timers.target +similarity index 100% +rename from test/fuzz-corpus/unit-file/timers.target +rename to test/fuzz/fuzz-unit-file/timers.target +diff --git a/test/fuzz-corpus/unit-file/var-lib-machines.mount b/test/fuzz/fuzz-unit-file/var-lib-machines.mount +similarity index 100% +rename from test/fuzz-corpus/unit-file/var-lib-machines.mount +rename to test/fuzz/fuzz-unit-file/var-lib-machines.mount +diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh +index 200407fcca..451cc665ce 100755 +--- a/tools/oss-fuzz.sh ++++ b/tools/oss-fuzz.sh +@@ -35,8 +35,10 @@ fi + meson $build -D$fuzzflag -Db_lundef=false + ninja -C $build fuzzers + +-for d in "$(dirname "$0")/../test/fuzz-corpus/"*; do +- zip -jqr $OUT/fuzz-$(basename "$d")_seed_corpus.zip "$d" ++# The seed corpus is a separate flat archive for each fuzzer, ++# with a fixed name ${fuzzer}_seed_corpus.zip. ++for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do ++ zip -jqr $OUT/$(basename "$d")_seed_corpus.zip "$d" + done + + # get fuzz-dns-packet corpus diff --git a/SOURCES/0152-test-add-testcase-for-issue-10007-by-oss-fuzz.patch b/SOURCES/0152-test-add-testcase-for-issue-10007-by-oss-fuzz.patch new file mode 100644 index 0000000..23efc15 --- /dev/null +++ b/SOURCES/0152-test-add-testcase-for-issue-10007-by-oss-fuzz.patch @@ -0,0 +1,37 @@ +From 684f05b8d7d491c7323302f35f4e28418732e558 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 22 Aug 2018 12:39:40 +0900 +Subject: [PATCH] test: add testcase for issue 10007 by oss-fuzz + +(cherry picked from commit a1a605f144e5635fdae57125a92032b3e5ebeca9) + +Resolves: #1696224 +--- + test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 | 6 ++++++ + test/fuzz-regressions/meson.build | 1 + + 2 files changed, 7 insertions(+) + create mode 100644 test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 + +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 b/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 +new file mode 100644 +index 0000000000..893630c83f +--- /dev/null ++++ b/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 +@@ -0,0 +1,6 @@ ++socket ++ # ++[Socket] ++ListenStream=vsock u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H5%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%HHs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%HHs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fus-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0s-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%u%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%s-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H23372036708:255 ++ListenStream=vsock:34843013755:210 ++Bis0%Hs-fu%H%H0%Hs-fu%H%H0%Hs-fu%H%H0%s-fu/H%H0%Hs-fu%H%H32767%Hs-fu%H%H0%Hs-fu%H%H0%Hs-f +\ No newline at end of file +diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build +index 776ee07f67..b98436a4af 100644 +--- a/test/fuzz-regressions/meson.build ++++ b/test/fuzz-regressions/meson.build +@@ -37,4 +37,5 @@ fuzz_regression_tests = ''' + fuzz-unit-file/oss-fuzz-7004 + fuzz-unit-file/oss-fuzz-8064 + fuzz-unit-file/oss-fuzz-8827 ++ fuzz-unit-file/oss-fuzz-10007 + '''.split() diff --git a/SOURCES/0153-fuzz-unify-the-fuzz-regressions-directory-with-the-m.patch b/SOURCES/0153-fuzz-unify-the-fuzz-regressions-directory-with-the-m.patch new file mode 100644 index 0000000..a95a8bb --- /dev/null +++ b/SOURCES/0153-fuzz-unify-the-fuzz-regressions-directory-with-the-m.patch @@ -0,0 +1,240 @@ +From 338519bd5d676d3f7bb5d58f4dac9fb6814afa78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 7 Jul 2018 18:09:21 +0200 +Subject: [PATCH] fuzz: unify the "fuzz-regressions" directory with the main + corpus + +There isn't really much need to keep them separate. Anything which is a good +corpus entry can be used as a smoke test, and anything which which is a +regression test can just as well be inserted into the corpus. + +The only functional difference from this patch (apart from different paths in +output) is that the regression tests are now zipped together with the rest of +the corpus. + +$ meson configure build -Dslow-tests=true && ninja -C build test +... +307/325 fuzz-dns-packet:issue-7888:address OK 0.06 s +308/325 fuzz-dns-packet:oss-fuzz-5465:address OK 0.04 s +309/325 fuzz-journal-remote:crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76:address OK 0.07 s +310/325 fuzz-journal-remote:crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45:address OK 0.05 s +311/325 fuzz-journal-remote:oss-fuzz-8659:address OK 0.05 s +312/325 fuzz-journal-remote:oss-fuzz-8686:address OK 0.07 s +313/325 fuzz-unit-file:oss-fuzz-6884:address OK 0.06 s +314/325 fuzz-unit-file:oss-fuzz-6885:address OK 0.05 s +315/325 fuzz-unit-file:oss-fuzz-6886:address OK 0.05 s +316/325 fuzz-unit-file:oss-fuzz-6892:address OK 0.05 s +317/325 fuzz-unit-file:oss-fuzz-6897:address OK 0.05 s +318/325 fuzz-unit-file:oss-fuzz-6897-evverx:address OK 0.06 s +319/325 fuzz-unit-file:oss-fuzz-6908:address OK 0.07 s +320/325 fuzz-unit-file:oss-fuzz-6917:address OK 0.07 s +321/325 fuzz-unit-file:oss-fuzz-6977:address OK 0.13 s +322/325 fuzz-unit-file:oss-fuzz-6977-unminimized:address OK 0.12 s +323/325 fuzz-unit-file:oss-fuzz-7004:address OK 0.05 s +324/325 fuzz-unit-file:oss-fuzz-8064:address OK 0.05 s +325/325 fuzz-unit-file:oss-fuzz-8827:address OK 0.52 s + +(cherry picked from commit c74a3f973e3e0bac13d66a28728a47f10046b71f) + +Resolves: #1696224 +--- + meson.build | 4 +--- + test/fuzz-regressions/.gitattributes | 1 - + .../fuzz-dns-packet/issue-7888 | Bin + .../fuzz-dns-packet/oss-fuzz-5465 | Bin + .../crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 | Bin + .../crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 | Bin + .../fuzz-journal-remote/oss-fuzz-8659 | 0 + .../fuzz-journal-remote/oss-fuzz-8686 | 0 + .../fuzz-journald-syslog/github-9795 | 0 + .../fuzz-journald-syslog/github-9820 | 0 + .../fuzz-journald-syslog/github-9827 | 0 + .../fuzz-journald-syslog/github-9829 | 0 + ...timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 | Bin + ...timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b | Bin + .../fuzz-unit-file/oss-fuzz-10007 | 0 + .../fuzz-unit-file/oss-fuzz-6884 | 0 + .../fuzz-unit-file/oss-fuzz-6885 | 0 + .../fuzz-unit-file/oss-fuzz-6886 | 0 + .../fuzz-unit-file/oss-fuzz-6892 | 0 + .../fuzz-unit-file/oss-fuzz-6897 | 0 + .../fuzz-unit-file/oss-fuzz-6897-evverx | 0 + .../fuzz-unit-file/oss-fuzz-6908 | 0 + .../fuzz-unit-file/oss-fuzz-6917 | 0 + .../fuzz-unit-file/oss-fuzz-6977 | 0 + .../fuzz-unit-file/oss-fuzz-6977-unminimized | 0 + .../fuzz-unit-file/oss-fuzz-7004 | 0 + .../fuzz-unit-file/oss-fuzz-8064 | 0 + .../fuzz-unit-file/oss-fuzz-8827 | 0 + test/{fuzz-regressions => fuzz}/meson.build | 0 + test/meson.build | 2 +- + 30 files changed, 2 insertions(+), 5 deletions(-) + delete mode 100644 test/fuzz-regressions/.gitattributes + rename test/{fuzz-regressions => fuzz}/fuzz-dns-packet/issue-7888 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-dns-packet/oss-fuzz-5465 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journal-remote/oss-fuzz-8659 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journal-remote/oss-fuzz-8686 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journald-syslog/github-9795 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journald-syslog/github-9820 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journald-syslog/github-9827 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-journald-syslog/github-9829 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-10007 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6884 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6885 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6886 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6892 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6897 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6897-evverx (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6908 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6917 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6977 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-6977-unminimized (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-7004 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-8064 (100%) + rename test/{fuzz-regressions => fuzz}/fuzz-unit-file/oss-fuzz-8827 (100%) + rename test/{fuzz-regressions => fuzz}/meson.build (100%) + +diff --git a/meson.build b/meson.build +index f2d67b7e02..709597e5c4 100644 +--- a/meson.build ++++ b/meson.build +@@ -2777,9 +2777,7 @@ foreach tuple : sanitizers + test('@0@:@1@:@2@'.format(b, c, sanitizer), + env, + args : [exe.full_path(), +- join_paths(meson.source_root(), +- 'test/fuzz-regressions', +- p)]) ++ join_paths(meson.source_root(), 'test/fuzz', p)]) + endif + endforeach + endif +diff --git a/test/fuzz-regressions/.gitattributes b/test/fuzz-regressions/.gitattributes +deleted file mode 100644 +index 7b1b3e1835..0000000000 +--- a/test/fuzz-regressions/.gitattributes ++++ /dev/null +@@ -1 +0,0 @@ +-/*/* -whitespace +diff --git a/test/fuzz-regressions/fuzz-dns-packet/issue-7888 b/test/fuzz/fuzz-dns-packet/issue-7888 +similarity index 100% +rename from test/fuzz-regressions/fuzz-dns-packet/issue-7888 +rename to test/fuzz/fuzz-dns-packet/issue-7888 +diff --git a/test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465 b/test/fuzz/fuzz-dns-packet/oss-fuzz-5465 +similarity index 100% +rename from test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465 +rename to test/fuzz/fuzz-dns-packet/oss-fuzz-5465 +diff --git a/test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 b/test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 +rename to test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 +diff --git a/test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 b/test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 +rename to test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 +diff --git a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659 b/test/fuzz/fuzz-journal-remote/oss-fuzz-8659 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659 +rename to test/fuzz/fuzz-journal-remote/oss-fuzz-8659 +diff --git a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686 b/test/fuzz/fuzz-journal-remote/oss-fuzz-8686 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686 +rename to test/fuzz/fuzz-journal-remote/oss-fuzz-8686 +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9795 b/test/fuzz/fuzz-journald-syslog/github-9795 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journald-syslog/github-9795 +rename to test/fuzz/fuzz-journald-syslog/github-9795 +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9820 b/test/fuzz/fuzz-journald-syslog/github-9820 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journald-syslog/github-9820 +rename to test/fuzz/fuzz-journald-syslog/github-9820 +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9827 b/test/fuzz/fuzz-journald-syslog/github-9827 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journald-syslog/github-9827 +rename to test/fuzz/fuzz-journald-syslog/github-9827 +diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9829 b/test/fuzz/fuzz-journald-syslog/github-9829 +similarity index 100% +rename from test/fuzz-regressions/fuzz-journald-syslog/github-9829 +rename to test/fuzz/fuzz-journald-syslog/github-9829 +diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 b/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 +similarity index 100% +rename from test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 +rename to test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 +diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b b/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b +similarity index 100% +rename from test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b +rename to test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 b/test/fuzz/fuzz-unit-file/oss-fuzz-10007 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-10007 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884 b/test/fuzz/fuzz-unit-file/oss-fuzz-6884 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6884 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885 b/test/fuzz/fuzz-unit-file/oss-fuzz-6885 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6885 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886 b/test/fuzz/fuzz-unit-file/oss-fuzz-6886 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6886 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892 b/test/fuzz/fuzz-unit-file/oss-fuzz-6892 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6892 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897 b/test/fuzz/fuzz-unit-file/oss-fuzz-6897 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6897 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx b/test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908 b/test/fuzz/fuzz-unit-file/oss-fuzz-6908 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6908 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917 b/test/fuzz/fuzz-unit-file/oss-fuzz-6917 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6917 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977 b/test/fuzz/fuzz-unit-file/oss-fuzz-6977 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6977 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized b/test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized +rename to test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004 b/test/fuzz/fuzz-unit-file/oss-fuzz-7004 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-7004 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064 b/test/fuzz/fuzz-unit-file/oss-fuzz-8064 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-8064 +diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827 b/test/fuzz/fuzz-unit-file/oss-fuzz-8827 +similarity index 100% +rename from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827 +rename to test/fuzz/fuzz-unit-file/oss-fuzz-8827 +diff --git a/test/fuzz-regressions/meson.build b/test/fuzz/meson.build +similarity index 100% +rename from test/fuzz-regressions/meson.build +rename to test/fuzz/meson.build +diff --git a/test/meson.build b/test/meson.build +index 826e684e59..fb9f2cdb9b 100644 +--- a/test/meson.build ++++ b/test/meson.build +@@ -244,4 +244,4 @@ if conf.get('ENABLE_HWDB') == 1 + timeout : 90) + endif + +-subdir('fuzz-regressions') ++subdir('fuzz') diff --git a/SOURCES/0154-test-bus-marshal-use-cescaping-instead-of-hexmem.patch b/SOURCES/0154-test-bus-marshal-use-cescaping-instead-of-hexmem.patch new file mode 100644 index 0000000..6509a94 --- /dev/null +++ b/SOURCES/0154-test-bus-marshal-use-cescaping-instead-of-hexmem.patch @@ -0,0 +1,50 @@ +From 4c6c21669483a38cf2a387784a3881b3a47139a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 7 Jul 2018 19:08:52 +0200 +Subject: [PATCH] test-bus-marshal: use cescaping instead of hexmem + +It is easier to see the contents this way by eye. + +(cherry picked from commit 3ddf3d439463ab2c76391a4d22b54166be2dbe94) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/test-bus-marshal.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c +index c647f0ff12..f007168ca6 100644 +--- a/src/libsystemd/sd-bus/test-bus-marshal.c ++++ b/src/libsystemd/sd-bus/test-bus-marshal.c +@@ -20,8 +20,8 @@ + #include "bus-label.h" + #include "bus-message.h" + #include "bus-util.h" ++#include "escape.h" + #include "fd-util.h" +-#include "hexdecoct.h" + #include "log.h" + #include "util.h" + +@@ -112,7 +112,7 @@ int main(int argc, char *argv[]) { + uint8_t u, v; + void *buffer = NULL; + size_t sz; +- char *h; ++ _cleanup_free_ char *h = NULL; + const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; + char *s; + _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL; +@@ -194,11 +194,9 @@ int main(int argc, char *argv[]) { + r = bus_message_get_blob(m, &buffer, &sz); + assert_se(r >= 0); + +- h = hexmem(buffer, sz); ++ h = cescape_length(buffer, sz); + assert_se(h); +- + log_info("message size = %zu, contents =\n%s", sz, h); +- free(h); + + #if HAVE_GLIB + #ifndef __SANITIZE_ADDRESS__ diff --git a/SOURCES/0155-meson-add-Dlog-trace-to-set-LOG_TRACE.patch b/SOURCES/0155-meson-add-Dlog-trace-to-set-LOG_TRACE.patch new file mode 100644 index 0000000..baca5af --- /dev/null +++ b/SOURCES/0155-meson-add-Dlog-trace-to-set-LOG_TRACE.patch @@ -0,0 +1,50 @@ +From c405c3035b595970e65ac9586909618525372c45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 7 Aug 2018 17:34:47 +0200 +Subject: [PATCH] meson: add -Dlog-trace to set LOG_TRACE + +The justification is the same as for -Dvalgrind: setting config in +meson in this way is easier, because when the value is changed stuff +that should be rebuilt is rebuilt. + +(cherry picked from commit fd5dec9adf76591d713f163d43d04e3beb76893e) + +Resolves: #1696224 +--- + meson.build | 2 ++ + meson_options.txt | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/meson.build b/meson.build +index 709597e5c4..c1013d525b 100644 +--- a/meson.build ++++ b/meson.build +@@ -782,6 +782,7 @@ conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap) + conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache) + + conf.set10('VALGRIND', get_option('valgrind')) ++conf.set10('LOG_TRACE', get_option('log-trace')) + + ##################################################################### + +@@ -2993,6 +2994,7 @@ foreach tuple : [ + ['debug hashmap'], + ['debug mmap cache'], + ['valgrind', conf.get('VALGRIND') == 1], ++ ['trace logging', conf.get('LOG_TRACE') == 1], + ] + + if tuple.length() >= 2 +diff --git a/meson_options.txt b/meson_options.txt +index 5716f45ccf..f06a130582 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -52,6 +52,8 @@ option('memory-accounting-default', type : 'boolean', + description : 'enable MemoryAccounting= by default') + option('valgrind', type : 'boolean', value : false, + description : 'do extra operations to avoid valgrind warnings') ++option('log-trace', type : 'boolean', value : false, ++ description : 'enable low level debug logging') + + option('utmp', type : 'boolean', + description : 'support for utmp/wtmp log handling') diff --git a/SOURCES/0156-meson-allow-building-resolved-and-machined-without-n.patch b/SOURCES/0156-meson-allow-building-resolved-and-machined-without-n.patch new file mode 100644 index 0000000..6efe520 --- /dev/null +++ b/SOURCES/0156-meson-allow-building-resolved-and-machined-without-n.patch @@ -0,0 +1,235 @@ +From 1a368abf7a3d72ecda504a69602b33b6869a485c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 18 Jul 2018 09:25:57 +0900 +Subject: [PATCH] meson: allow building resolved and machined without nss + modules + +This adds -Dnss-resolve= and -Dnss-mymachines= meson options. +By using this option, e.g., resolved can be built without nss-resolve. +When no nss modules are built, then test-nss is neither built. + +Also, This changes the option name -Dmyhostname= to -Dnss-myhostname= +for consistency to other nss related options. + +Closes #9596. + +(cherry picked from commit 08540a9591efe105439be81fc43d6dc65b715978) + +Resolves: #1696224 +--- + man/nss-myhostname.xml | 2 +- + man/nss-mymachines.xml | 2 +- + man/nss-resolve.xml | 2 +- + man/rules/meson.build | 6 +++--- + meson.build | 40 ++++++++++++++++++++++++++++++++++------ + meson_options.txt | 12 ++++++++---- + src/test/meson.build | 2 +- + src/test/test-nss.c | 6 +++--- + 8 files changed, 52 insertions(+), 20 deletions(-) + +diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml +index e1aabacad2..18a6f5f665 100644 +--- a/man/nss-myhostname.xml ++++ b/man/nss-myhostname.xml +@@ -6,7 +6,7 @@ + SPDX-License-Identifier: LGPL-2.1+ + --> + +- ++ + + + nss-myhostname +diff --git a/man/nss-mymachines.xml b/man/nss-mymachines.xml +index 394a905665..d9811b24cc 100644 +--- a/man/nss-mymachines.xml ++++ b/man/nss-mymachines.xml +@@ -6,7 +6,7 @@ + SPDX-License-Identifier: LGPL-2.1+ + --> + +- ++ + + + nss-mymachines +diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml +index 588bc04976..56c8099e70 100644 +--- a/man/nss-resolve.xml ++++ b/man/nss-resolve.xml +@@ -6,7 +6,7 @@ + SPDX-License-Identifier: LGPL-2.1+ + --> + +- ++ + + + nss-resolve +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 9458a4012d..989d11c9b9 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -37,9 +37,9 @@ manpages = [ + ['modules-load.d', '5', [], 'HAVE_KMOD'], + ['networkctl', '1', [], 'ENABLE_NETWORKD'], + ['networkd.conf', '5', ['networkd.conf.d'], 'ENABLE_NETWORKD'], +- ['nss-myhostname', '8', ['libnss_myhostname.so.2'], 'ENABLE_MYHOSTNAME'], +- ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_MACHINED'], +- ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_RESOLVE'], ++ ['nss-myhostname', '8', ['libnss_myhostname.so.2'], 'ENABLE_NSS_MYHOSTNAME'], ++ ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_NSS_MYMACHINES'], ++ ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'], + ['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'], + ['os-release', '5', [], ''], + ['pam_systemd', '8', [], 'HAVE_PAM'], +diff --git a/meson.build b/meson.build +index c1013d525b..863e8eb399 100644 +--- a/meson.build ++++ b/meson.build +@@ -1216,7 +1216,6 @@ foreach term : ['utmp', + 'networkd', + 'timedated', + 'timesyncd', +- 'myhostname', + 'firstboot', + 'randomseed', + 'backlight', +@@ -1233,12 +1232,39 @@ foreach term : ['utmp', + 'smack', + 'gshadow', + 'idn', ++ 'nss-myhostname', + 'nss-systemd'] + have = get_option(term) + name = 'ENABLE_' + term.underscorify().to_upper() + conf.set10(name, have) + endforeach + ++foreach tuple : [['nss-mymachines', 'machined'], ++ ['nss-resolve', 'resolve']] ++ want = get_option(tuple[0]) ++ if want != 'false' ++ have = get_option(tuple[1]) ++ if want == 'true' and not have ++ error('@0@ is requested but @1@ is disabled'.format(tuple[0], tuple[1])) ++ endif ++ else ++ have = false ++ endif ++ name = 'ENABLE_' + tuple[0].underscorify().to_upper() ++ conf.set10(name, have) ++endforeach ++ ++enable_nss = false ++foreach term : ['ENABLE_NSS_MYHOSTNAME', ++ 'ENABLE_NSS_MYMACHINES', ++ 'ENABLE_NSS_RESOLVE', ++ 'ENABLE_NSS_SYSTEMD'] ++ if conf.get(term) == 1 ++ enable_nss = true ++ endif ++endforeach ++conf.set10('ENABLE_NSS', enable_nss) ++ + conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesyncd')) + + want_tests = get_option('tests') +@@ -1417,10 +1443,10 @@ test_dlopen = executable( + link_with : [libbasic], + dependencies : [libdl]) + +-foreach tuple : [['myhostname', 'ENABLE_MYHOSTNAME'], ++foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'], + ['systemd', 'ENABLE_NSS_SYSTEMD'], +- ['mymachines', 'ENABLE_MACHINED'], +- ['resolve', 'ENABLE_RESOLVE']] ++ ['mymachines', 'ENABLE_NSS_MYMACHINES'], ++ ['resolve', 'ENABLE_NSS_RESOLVE']] + + condition = tuple[1] == '' or conf.get(tuple[1]) == 1 + if condition +@@ -2943,7 +2969,6 @@ foreach tuple : [ + ['idn'], + ['libidn2'], + ['libidn'], +- ['nss-systemd'], + ['libiptc'], + ['elfutils'], + ['binfmt'], +@@ -2978,7 +3003,10 @@ foreach tuple : [ + ['blkid'], + ['dbus'], + ['glib'], +- ['nss-myhostname', conf.get('ENABLE_MYHOSTNAME') == 1], ++ ['nss-myhostname', conf.get('ENABLE_NSS_MYHOSTNAME') == 1], ++ ['nss-mymachines', conf.get('ENABLE_NSS_MYMACHINES') == 1], ++ ['nss-resolve', conf.get('ENABLE_NSS_RESOLVE') == 1], ++ ['nss-systemd', conf.get('ENABLE_NSS_SYSTEMD') == 1], + ['hwdb'], + ['tpm'], + ['man pages', want_man], +diff --git a/meson_options.txt b/meson_options.txt +index f06a130582..563b11f0a2 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -91,8 +91,14 @@ option('timesyncd', type : 'boolean', + description : 'install the systemd-timesyncd daemon') + option('remote', type : 'combo', choices : ['auto', 'true', 'false'], + description : 'support for "journal over the network"') +-option('myhostname', type : 'boolean', +- description : 'nss-myhostname support') ++option('nss-myhostname', type : 'boolean', ++ description : 'install nss-myhostname module') ++option('nss-mymachines', type : 'combo', choices : ['auto', 'true', 'false'], ++ description : 'install nss-mymachines module') ++option('nss-resolve', type : 'combo', choices : ['auto', 'true', 'false'], ++ description : 'install nss-resolve module') ++option('nss-systemd', type : 'boolean', ++ description : 'install nss-systemd module') + option('firstboot', type : 'boolean', + description : 'support for firstboot mechanism') + option('randomseed', type : 'boolean', +@@ -249,8 +255,6 @@ option('libidn2', type : 'combo', choices : ['auto', 'true', 'false'], + description : 'libidn2 support') + option('libidn', type : 'combo', choices : ['auto', 'true', 'false'], + description : 'libidn support') +-option('nss-systemd', type : 'boolean', +- description : 'enable nss-systemd') + option('libiptc', type : 'combo', choices : ['auto', 'true', 'false'], + description : 'libiptc support') + option('qrencode', type : 'combo', choices : ['auto', 'true', 'false'], +diff --git a/src/test/meson.build b/src/test/meson.build +index b982251b1f..0998f59897 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -650,7 +650,7 @@ tests += [ + [['src/test/test-nss.c'], + [], + [libdl], +- '', 'manual'], ++ 'ENABLE_NSS', 'manual'], + + [['src/test/test-umount.c', + 'src/core/mount-setup.c', +diff --git a/src/test/test-nss.c b/src/test/test-nss.c +index 9e543e7557..e0e7bb300d 100644 +--- a/src/test/test-nss.c ++++ b/src/test/test-nss.c +@@ -431,13 +431,13 @@ static int parse_argv(int argc, char **argv, + modules = strv_new(argv[1], NULL); + else + modules = strv_new( +-#if ENABLE_MYHOSTNAME ++#if ENABLE_NSS_MYHOSTNAME + "myhostname", + #endif +-#if ENABLE_RESOLVE ++#if ENABLE_NSS_RESOLVE + "resolve", + #endif +-#if ENABLE_MACHINED ++#if ENABLE_NSS_MYMACHINES + "mymachines", + #endif + "dns", diff --git a/SOURCES/0157-meson-drop-duplicated-condition.patch b/SOURCES/0157-meson-drop-duplicated-condition.patch new file mode 100644 index 0000000..51b5c7e --- /dev/null +++ b/SOURCES/0157-meson-drop-duplicated-condition.patch @@ -0,0 +1,33 @@ +From fff862ce6f33acb6ce8dc422e0f53ec681ebed6d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 7 Aug 2018 18:10:53 +0200 +Subject: [PATCH] meson: drop duplicated condition + +The generic check suffices for those four. + +(cherry picked from commit 6bd2bc8e16a6d515f8a21c47fd6b833d7fcfdd1c) + +Resolves: #1696224 +--- + meson.build | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/meson.build b/meson.build +index 863e8eb399..f623bcf37d 100644 +--- a/meson.build ++++ b/meson.build +@@ -3003,10 +3003,10 @@ foreach tuple : [ + ['blkid'], + ['dbus'], + ['glib'], +- ['nss-myhostname', conf.get('ENABLE_NSS_MYHOSTNAME') == 1], +- ['nss-mymachines', conf.get('ENABLE_NSS_MYMACHINES') == 1], +- ['nss-resolve', conf.get('ENABLE_NSS_RESOLVE') == 1], +- ['nss-systemd', conf.get('ENABLE_NSS_SYSTEMD') == 1], ++ ['nss-myhostname'], ++ ['nss-mymachines'], ++ ['nss-resolve'], ++ ['nss-systemd'], + ['hwdb'], + ['tpm'], + ['man pages', want_man], diff --git a/SOURCES/0158-meson-use-.source_root-in-more-places.patch b/SOURCES/0158-meson-use-.source_root-in-more-places.patch new file mode 100644 index 0000000..0cc4b24 --- /dev/null +++ b/SOURCES/0158-meson-use-.source_root-in-more-places.patch @@ -0,0 +1,81 @@ +From 2eca34cfa911fa7c1aafef5d60b7a2e752ae5b3b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 10 Aug 2018 16:50:07 +0200 +Subject: [PATCH] meson: use .source_root() in more places + +In the main meson.build file, .source_root() and .current_source_dir() are +equivalent, but it seems more appropriate to use .source_root() when we are appending +a path which is by design relative to repo root. + +(cherry picked from commit 243e5cecc3a211519544ccba01c44edc827ac517) + +Resolves: #1696224 +--- + meson.build | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/meson.build b/meson.build +index f623bcf37d..fe161e5ec5 100644 +--- a/meson.build ++++ b/meson.build +@@ -1453,7 +1453,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'], + module = tuple[0] + + sym = 'src/nss-@0@/nss-@0@.sym'.format(module) +- version_script_arg = join_paths(meson.current_source_dir(), sym) ++ version_script_arg = join_paths(meson.source_root(), sym) + + nss = shared_library( + 'nss_' + module, +@@ -1704,7 +1704,7 @@ if conf.get('ENABLE_LOGIND') == 1 + public_programs += [exe] + + if conf.get('HAVE_PAM') == 1 +- version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym) ++ version_script_arg = join_paths(meson.source_root(), pam_systemd_sym) + pam_systemd = shared_library( + 'pam_systemd', + pam_systemd_c, +@@ -2816,7 +2816,7 @@ endforeach + if git.found() + all_files = run_command( + git, +- ['--git-dir=@0@/.git'.format(meson.current_source_dir()), ++ ['--git-dir=@0@/.git'.format(meson.source_root()), + 'ls-files', + ':/*.[ch]']) + all_files = files(all_files.stdout().split()) +@@ -2824,10 +2824,10 @@ if git.found() + custom_target( + 'tags', + output : 'tags', +- command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files) ++ command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files) + run_target( + 'ctags', +- command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files) ++ command : [env, 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files) + endif + + if git.found() +@@ -2840,17 +2840,17 @@ endif + if git.found() + git_head = run_command( + git, +- ['--git-dir=@0@/.git'.format(meson.current_source_dir()), ++ ['--git-dir=@0@/.git'.format(meson.source_root()), + 'rev-parse', 'HEAD']).stdout().strip() + git_head_short = run_command( + git, +- ['--git-dir=@0@/.git'.format(meson.current_source_dir()), ++ ['--git-dir=@0@/.git'.format(meson.source_root()), + 'rev-parse', '--short=7', 'HEAD']).stdout().strip() + + run_target( + 'git-snapshot', + command : ['git', 'archive', +- '-o', '@0@/systemd-@1@.tar.gz'.format(meson.current_source_dir(), ++ '-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(), + git_head_short), + '--prefix', 'systemd-@0@/'.format(git_head), + 'HEAD']) diff --git a/SOURCES/0159-meson-treat-all-fuzz-cases-as-unit-tests.patch b/SOURCES/0159-meson-treat-all-fuzz-cases-as-unit-tests.patch new file mode 100644 index 0000000..7751f3d --- /dev/null +++ b/SOURCES/0159-meson-treat-all-fuzz-cases-as-unit-tests.patch @@ -0,0 +1,141 @@ +From 6a8c286e1a45dfa64c48cd4d5a911d4f71de9a16 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 10 Aug 2018 17:15:05 +0200 +Subject: [PATCH] meson: treat all fuzz cases as unit tests + +318/365 fuzz-bus-message:crash-26bba7182dedc8848939931d9fcefcb7922f2e56:address OK 0.03 s +319/365 fuzz-bus-message:crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e:address OK 0.03 s +320/365 fuzz-bus-message:crash-b88ad9ecf4aacf4a0caca5b5543953265367f084:address OK 0.03 s +321/365 fuzz-bus-message:crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e:address OK 0.03 s +322/365 fuzz-bus-message:crash-d8f3941c74219b4c03532c9b244d5ea539c61af5:address OK 0.03 s +323/365 fuzz-bus-message:crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5:address OK 0.03 s +324/365 fuzz-bus-message:leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20:address OK 0.04 s +325/365 fuzz-bus-message:message1:address OK 0.03 s +326/365 fuzz-bus-message:timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b:address OK 0.03 s +327/365 fuzz-dhcp-server:discover-existing:address OK 0.04 s +328/365 fuzz-dhcp-server:discover-new:address OK 0.03 s +329/365 fuzz-dhcp-server:release:address OK 0.04 s +330/365 fuzz-dhcp-server:request-existing:address OK 0.03 s +331/365 fuzz-dhcp-server:request-new:address OK 0.03 s +332/365 fuzz-dhcp-server:request-reboot:address OK 0.03 s +333/365 fuzz-dhcp-server:request-renew:address OK 0.03 s +334/365 fuzz-dns-packet:issue-7888:address OK 0.03 s +335/365 fuzz-dns-packet:oss-fuzz-5465:address OK 0.03 s +336/365 fuzz-journal-remote:crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76:address OK 0.06 s +337/365 fuzz-journal-remote:crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45:address OK 0.04 s +338/365 fuzz-journal-remote:invalid-ts.txt:address OK 0.04 s +339/365 fuzz-journal-remote:oss-fuzz-8659:address OK 0.06 s +340/365 fuzz-journal-remote:oss-fuzz-8686:address OK 0.04 s +341/365 fuzz-journal-remote:sample.txt:address OK 0.07 s +342/365 fuzz-unit-file:directives.service:address OK 0.03 s +343/365 fuzz-unit-file:empty.scope:address OK 0.04 s +344/365 fuzz-unit-file:machine.slice:address OK 0.03 s +345/365 fuzz-unit-file:oss-fuzz-6884:address OK 0.05 s +346/365 fuzz-unit-file:oss-fuzz-6885:address OK 0.03 s +347/365 fuzz-unit-file:oss-fuzz-6886:address OK 0.04 s +348/365 fuzz-unit-file:oss-fuzz-6892:address OK 0.03 s +349/365 fuzz-unit-file:oss-fuzz-6897:address OK 0.05 s +350/365 fuzz-unit-file:oss-fuzz-6897-evverx:address OK 0.04 s +351/365 fuzz-unit-file:oss-fuzz-6908:address OK 0.05 s +352/365 fuzz-unit-file:oss-fuzz-6917:address OK 0.06 s +353/365 fuzz-unit-file:oss-fuzz-6977:address OK 0.08 s +354/365 fuzz-unit-file:oss-fuzz-6977-unminimized:address OK 0.10 s +355/365 fuzz-unit-file:oss-fuzz-7004:address OK 0.03 s +356/365 fuzz-unit-file:oss-fuzz-8064:address OK 0.03 s +357/365 fuzz-unit-file:oss-fuzz-8827:address OK 0.50 s +358/365 fuzz-unit-file:proc-sys-fs-binfmt_misc.automount:address OK 0.03 s +359/365 fuzz-unit-file:syslog.socket:address OK 0.03 s +360/365 fuzz-unit-file:systemd-ask-password-console.path:address OK 0.03 s +361/365 fuzz-unit-file:systemd-machined.service:address OK 0.03 s +362/365 fuzz-unit-file:systemd-resolved.service:address OK 0.03 s +363/365 fuzz-unit-file:systemd-tmpfiles-clean.timer:address OK 0.03 s +364/365 fuzz-unit-file:timers.target:address OK 0.03 s +365/365 fuzz-unit-file:var-lib-machines.mount:address OK 0.04 s + +This gives us slightly nicer coverage in the normal test run. + +When in a git repo, git ls-files is used to get a list of files known to git. +This mirrors what update-man-rules does for man files. Only looking at files +known to git makes it easier to not forget to commit the test file to git, +and also makes bisecting easier if some files are left in repo. + +When outside of a git repo, we expect to be unpacked from a tarball, so just +using all files reported by ls is OK. + +(cherry picked from commit e6bad6746151c79a5f408e95714ffa5cea290ab0) + +Resolves: #1696224 +--- + meson.build | 2 +- + test/fuzz/meson.build | 48 ++++++++++++++++++------------------------- + 2 files changed, 21 insertions(+), 29 deletions(-) + +diff --git a/meson.build b/meson.build +index fe161e5ec5..04b461dcd4 100644 +--- a/meson.build ++++ b/meson.build +@@ -2804,7 +2804,7 @@ foreach tuple : sanitizers + test('@0@:@1@:@2@'.format(b, c, sanitizer), + env, + args : [exe.full_path(), +- join_paths(meson.source_root(), 'test/fuzz', p)]) ++ join_paths(meson.source_root(), p)]) + endif + endforeach + endif +diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build +index b98436a4af..56d0f69660 100644 +--- a/test/fuzz/meson.build ++++ b/test/fuzz/meson.build +@@ -11,31 +11,23 @@ sanitize_address = custom_target( + + sanitizers = [['address', sanitize_address]] + +-fuzz_regression_tests = ''' +- fuzz-dns-packet/issue-7888 +- fuzz-dns-packet/oss-fuzz-5465 +- fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 +- fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 +- fuzz-journal-remote/oss-fuzz-8659 +- fuzz-journal-remote/oss-fuzz-8686 +- fuzz-journald-syslog/github-9795 +- fuzz-journald-syslog/github-9820 +- fuzz-journald-syslog/github-9827 +- fuzz-journald-syslog/github-9829 +- fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 +- fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b +- fuzz-unit-file/oss-fuzz-6884 +- fuzz-unit-file/oss-fuzz-6885 +- fuzz-unit-file/oss-fuzz-6886 +- fuzz-unit-file/oss-fuzz-6892 +- fuzz-unit-file/oss-fuzz-6897 +- fuzz-unit-file/oss-fuzz-6897-evverx +- fuzz-unit-file/oss-fuzz-6908 +- fuzz-unit-file/oss-fuzz-6917 +- fuzz-unit-file/oss-fuzz-6977 +- fuzz-unit-file/oss-fuzz-6977-unminimized +- fuzz-unit-file/oss-fuzz-7004 +- fuzz-unit-file/oss-fuzz-8064 +- fuzz-unit-file/oss-fuzz-8827 +- fuzz-unit-file/oss-fuzz-10007 +-'''.split() ++if git.found() ++ out = run_command( ++ git, ++ '--git-dir=@0@/.git'.format(meson.source_root()), ++ 'ls-files', ':/test/fuzz/*/*') ++else ++ out = run_command( ++ 'sh', '-c', 'ls @0@/*/*'.format(meson.current_source_dir())) ++endif ++ ++fuzz_regression_tests = [] ++foreach p : out.stdout().split() ++ # Remove the last entry which is ''. ++ # ++ # Also, backslashes get mangled, so skip test. See ++ # https://github.com/mesonbuild/meson/issues/1564. ++ if not p.contains('\\') ++ fuzz_regression_tests += p ++ endif ++endforeach diff --git a/SOURCES/0160-fuzz-bus-message-add-fuzzer-for-message-parsing.patch b/SOURCES/0160-fuzz-bus-message-add-fuzzer-for-message-parsing.patch new file mode 100644 index 0000000..57678f6 --- /dev/null +++ b/SOURCES/0160-fuzz-bus-message-add-fuzzer-for-message-parsing.patch @@ -0,0 +1,102 @@ +From 9a6a36b44ad131036fef5c91edc86c842c9821ba Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 7 Jul 2018 19:30:25 +0200 +Subject: [PATCH] fuzz-bus-message: add fuzzer for message parsing + +As with other fuzzers, SYSTEMD_FUZZ_OUTPUT=1 and SYSTEMD_LOG_LEVEL=debug can be +used for debugging. + +(cherry picked from commit 56b560c26339c4b282c06038316a91509eae75fd) + +Resolves: #1696224 +--- + src/fuzz/fuzz-bus-message.c | 47 ++++++++++++++++++++++++++++ + src/fuzz/meson.build | 4 +++ + test/fuzz/fuzz-bus-message/message1 | Bin 0 -> 534 bytes + 3 files changed, 51 insertions(+) + create mode 100644 src/fuzz/fuzz-bus-message.c + create mode 100644 test/fuzz/fuzz-bus-message/message1 + +diff --git a/src/fuzz/fuzz-bus-message.c b/src/fuzz/fuzz-bus-message.c +new file mode 100644 +index 0000000000..9842c62a6f +--- /dev/null ++++ b/src/fuzz/fuzz-bus-message.c +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++#include ++ ++#include "alloc-util.h" ++#include "bus-dump.h" ++#include "bus-message.h" ++#include "env-util.h" ++#include "fd-util.h" ++#include "fuzz.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ _cleanup_free_ char *out = NULL; /* out should be freed after g */ ++ size_t out_size; ++ _cleanup_fclose_ FILE *g = NULL; ++ _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; ++ _cleanup_free_ void *buffer = NULL; ++ int r; ++ ++ /* We don't want to fill the logs with messages about parse errors. ++ * Disable most logging if not running standalone */ ++ if (!getenv("SYSTEMD_LOG_LEVEL")) ++ log_set_max_level(LOG_CRIT); ++ ++ r = sd_bus_new(&bus); ++ assert_se(r >= 0); ++ ++ assert_se(buffer = memdup(data, size)); ++ ++ r = bus_message_from_malloc(bus, buffer, size, NULL, 0, NULL, &m); ++ if (r == -EBADMSG) ++ return 0; ++ assert_se(r >= 0); ++ TAKE_PTR(buffer); ++ ++ if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) ++ assert_se(g = open_memstream(&out, &out_size)); ++ ++ bus_message_dump(m, g ?: stdout, BUS_MESSAGE_DUMP_WITH_HEADER); ++ ++ r = sd_bus_message_rewind(m, true); ++ assert_se(r >= 0); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 5c81ac0c5b..1dbe28e57e 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -1,6 +1,10 @@ + # SPDX-License-Identifier: LGPL-2.1+ + + fuzzers += [ ++ [['src/fuzz/fuzz-bus-message.c'], ++ [libshared], ++ []], ++ + [['src/fuzz/fuzz-dns-packet.c', + dns_type_headers], + [libsystemd_resolve_core, +diff --git a/test/fuzz/fuzz-bus-message/message1 b/test/fuzz/fuzz-bus-message/message1 +new file mode 100644 +index 0000000000000000000000000000000000000000..2df70fd7cb6f0e632c4d5c2358091309a5cd3edc +GIT binary patch +literal 534 +zcmZ{h!A`?442GSJjTUi2h$EV`OM6*iyZ|>&NW6m6ZC#~`RCNGV2*icg27V{4hLEuI +z*Z%6nv6IG-c{fDW8PO*Z8RG~@1*A4LLPziq^|n=>fKTCf&ROnOFWhXL{-6KzKQR>* +zA}kdo{MtXi^_lPUKI=U`x#dhG*Hq0w(L%415E=fPT+(I2*knx96tO2RVnnVP6o! +Yuz#WfEX)Cqd!b_JHzYppZsXhk08nC8%>V!Z + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0161-bus-message-use-structured-initialization-to-avoid-u.patch b/SOURCES/0161-bus-message-use-structured-initialization-to-avoid-u.patch new file mode 100644 index 0000000..80b4a78 --- /dev/null +++ b/SOURCES/0161-bus-message-use-structured-initialization-to-avoid-u.patch @@ -0,0 +1,115 @@ +From a82cf4abc81722706b4466e65c1a05f997cf9fdc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 9 Jul 2018 07:38:10 +0200 +Subject: [PATCH] bus-message: use structured initialization to avoid use of + unitialized memory + +As far as I can see, we would either reuse some values from a previously exited +container or just random bytes from the heap. + +Should fix #10127. + +(cherry picked from commit cf81c68e96aa29d0c28b5d3a26d1de9aa1b53b85) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 59 +++++++++++++---------------- + 1 file changed, 27 insertions(+), 32 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 780c8c6185..7f87d018fb 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -1956,7 +1956,7 @@ _public_ int sd_bus_message_open_container( + char type, + const char *contents) { + +- struct bus_container *c, *w; ++ struct bus_container *c; + uint32_t *array_size = NULL; + _cleanup_free_ char *signature = NULL; + size_t before, begin = 0; +@@ -2001,17 +2001,14 @@ _public_ int sd_bus_message_open_container( + return r; + + /* OK, let's fill it in */ +- w = m->containers + m->n_containers++; +- w->enclosing = type; +- w->signature = TAKE_PTR(signature); +- w->peeked_signature = NULL; +- w->index = 0; +- w->array_size = array_size; +- w->before = before; +- w->begin = begin; +- w->n_offsets = w->offsets_allocated = 0; +- w->offsets = NULL; +- w->need_offsets = need_offsets; ++ m->containers[m->n_containers++] = (struct bus_container) { ++ .enclosing = type, ++ .signature = TAKE_PTR(signature), ++ .array_size = array_size, ++ .before = before, ++ .begin = begin, ++ .need_offsets = need_offsets, ++ }; + + return 0; + } +@@ -3980,10 +3977,10 @@ static int bus_message_enter_dict_entry( + _public_ int sd_bus_message_enter_container(sd_bus_message *m, + char type, + const char *contents) { +- struct bus_container *c, *w; ++ struct bus_container *c; + uint32_t *array_size = NULL; + _cleanup_free_ char *signature = NULL; +- size_t before; ++ size_t before, end; + _cleanup_free_ size_t *offsets = NULL; + size_t n_offsets = 0, item_size = 0; + int r; +@@ -4062,28 +4059,26 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, + return r; + + /* OK, let's fill it in */ +- w = m->containers + m->n_containers++; +- w->enclosing = type; +- w->signature = TAKE_PTR(signature); +- w->peeked_signature = NULL; +- w->index = 0; +- +- w->before = before; +- w->begin = m->rindex; +- +- /* Unary type has fixed size of 1, but virtual size of 0 */ + if (BUS_MESSAGE_IS_GVARIANT(m) && + type == SD_BUS_TYPE_STRUCT && + isempty(signature)) +- w->end = m->rindex + 0; ++ end = m->rindex + 0; + else +- w->end = m->rindex + c->item_size; +- +- w->array_size = array_size; +- w->item_size = item_size; +- w->offsets = TAKE_PTR(offsets); +- w->n_offsets = n_offsets; +- w->offset_index = 0; ++ end = m->rindex + c->item_size; ++ ++ m->containers[m->n_containers++] = (struct bus_container) { ++ .enclosing = type, ++ .signature = TAKE_PTR(signature), ++ ++ .before = before, ++ .begin = m->rindex, ++ /* Unary type has fixed size of 1, but virtual size of 0 */ ++ .end = end, ++ .array_size = array_size, ++ .item_size = item_size, ++ .offsets = TAKE_PTR(offsets), ++ .n_offsets = n_offsets, ++ }; + + return 1; + } diff --git a/SOURCES/0162-bus-message-avoid-an-infinite-loop-on-empty-structur.patch b/SOURCES/0162-bus-message-avoid-an-infinite-loop-on-empty-structur.patch new file mode 100644 index 0000000..e821357 --- /dev/null +++ b/SOURCES/0162-bus-message-avoid-an-infinite-loop-on-empty-structur.patch @@ -0,0 +1,176 @@ +From a2da2b45ac05ef91074e90097115e8c734ca0f64 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 9 Jul 2018 10:52:51 +0200 +Subject: [PATCH] bus-message: avoid an infinite loop on empty structures + +The alternative would be to treat gvariant and !gvariant messages differently. +But this is a problem because we check signatures is variuos places before we +have an actual message, for example in sd_bus_add_object_vtable(). It seems +better to treat things consistent (i.e. follow the lowest common denominator) +and disallow empty structures everywhere. + +(cherry picked from commit ec6bda56cbca9509b1abde1122645630caca877c) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 3 ++- + src/libsystemd/sd-bus/bus-signature.c | 6 ++++++ + src/libsystemd/sd-bus/test-bus-gvariant.c | 6 +++--- + src/libsystemd/sd-bus/test-bus-marshal.c | 6 +++--- + src/libsystemd/sd-bus/test-bus-signature.c | 8 ++++---- + ...crash-26bba7182dedc8848939931d9fcefcb7922f2e56 | Bin 0 -> 157 bytes + ...meout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b | Bin 0 -> 534 bytes + 7 files changed, 18 insertions(+), 11 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 + create mode 100644 test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 7f87d018fb..1d06fcb80e 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -4178,6 +4178,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + + /* signature_element_length does verification internally */ + ++ /* The array element must not be empty */ + assert(l >= 1); + if (free_and_strndup(&c->peeked_signature, + c->signature + c->index + 1, l) < 0) +@@ -4201,7 +4202,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + if (r < 0) + return r; + +- assert(l >= 2); ++ assert(l >= 3); + if (free_and_strndup(&c->peeked_signature, + c->signature + c->index + 1, l - 2) < 0) + return -ENOMEM; +diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c +index 18c91e8707..1ca37cbb5a 100644 +--- a/src/libsystemd/sd-bus/bus-signature.c ++++ b/src/libsystemd/sd-bus/bus-signature.c +@@ -58,6 +58,12 @@ static int signature_element_length_internal( + p += t; + } + ++ if (p - s < 2) ++ /* D-Bus spec: Empty structures are not allowed; there ++ * must be at least one type code between the parentheses. ++ */ ++ return -EINVAL; ++ + *l = p - s + 1; + return 0; + } +diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c +index 75804f3458..e606970a3a 100644 +--- a/src/libsystemd/sd-bus/test-bus-gvariant.c ++++ b/src/libsystemd/sd-bus/test-bus-gvariant.c +@@ -19,7 +19,7 @@ + + static void test_bus_gvariant_is_fixed_size(void) { + assert_se(bus_gvariant_is_fixed_size("") > 0); +- assert_se(bus_gvariant_is_fixed_size("()") > 0); ++ assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL); + assert_se(bus_gvariant_is_fixed_size("y") > 0); + assert_se(bus_gvariant_is_fixed_size("u") > 0); + assert_se(bus_gvariant_is_fixed_size("b") > 0); +@@ -44,7 +44,7 @@ static void test_bus_gvariant_is_fixed_size(void) { + + static void test_bus_gvariant_get_size(void) { + assert_se(bus_gvariant_get_size("") == 0); +- assert_se(bus_gvariant_get_size("()") == 1); ++ assert_se(bus_gvariant_get_size("()") == -EINVAL); + assert_se(bus_gvariant_get_size("y") == 1); + assert_se(bus_gvariant_get_size("u") == 4); + assert_se(bus_gvariant_get_size("b") == 1); +@@ -76,7 +76,7 @@ static void test_bus_gvariant_get_size(void) { + + static void test_bus_gvariant_get_alignment(void) { + assert_se(bus_gvariant_get_alignment("") == 1); +- assert_se(bus_gvariant_get_alignment("()") == 1); ++ assert_se(bus_gvariant_get_alignment("()") == -EINVAL); + assert_se(bus_gvariant_get_alignment("y") == 1); + assert_se(bus_gvariant_get_alignment("b") == 1); + assert_se(bus_gvariant_get_alignment("u") == 4); +diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c +index f007168ca6..1743b1b491 100644 +--- a/src/libsystemd/sd-bus/test-bus-marshal.c ++++ b/src/libsystemd/sd-bus/test-bus-marshal.c +@@ -151,7 +151,7 @@ int main(int argc, char *argv[]) { + assert_se(r >= 0); + + r = sd_bus_message_append(m, "()"); +- assert_se(r >= 0); ++ assert_se(r == -EINVAL); + + r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3"); + assert_se(r >= 0); +@@ -293,7 +293,7 @@ int main(int argc, char *argv[]) { + assert_se(v == 10); + + r = sd_bus_message_read(m, "()"); +- assert_se(r > 0); ++ assert_se(r < 0); + + r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d); + assert_se(r > 0); +@@ -374,7 +374,7 @@ int main(int argc, char *argv[]) { + + assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0); + +- r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()"); ++ r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y"); + assert_se(r >= 0); + + assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0); +diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c +index 1ba1909198..a716cd1b35 100644 +--- a/src/libsystemd/sd-bus/test-bus-signature.c ++++ b/src/libsystemd/sd-bus/test-bus-signature.c +@@ -16,9 +16,9 @@ int main(int argc, char *argv[]) { + assert_se(signature_is_single("v", false)); + assert_se(signature_is_single("as", false)); + assert_se(signature_is_single("(ss)", false)); +- assert_se(signature_is_single("()", false)); +- assert_se(signature_is_single("(()()()()())", false)); +- assert_se(signature_is_single("(((())))", false)); ++ assert_se(!signature_is_single("()", false)); ++ assert_se(!signature_is_single("(()()()()())", false)); ++ assert_se(!signature_is_single("(((())))", false)); + assert_se(signature_is_single("((((s))))", false)); + assert_se(signature_is_single("{ss}", true)); + assert_se(signature_is_single("a{ss}", false)); +@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) { + assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false)); + assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false)); + +- assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false)); ++ assert_se(signature_is_valid("((((((((((((((((((((((((((((((((s))))))))))))))))))))))))))))))))", false)); + assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false)); + + assert_se(namespace_complex_pattern("", "")); +diff --git a/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 +new file mode 100644 +index 0000000000000000000000000000000000000000..f1bf3229effc982c8b129182fe60739efe3c5013 +GIT binary patch +literal 157 +mcmd1#|DTC5gMmSS0SHWtK_neOii>$FgGM4Akdcw0DF6TjSP;el + +literal 0 +HcmV?d00001 + +diff --git a/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b +new file mode 100644 +index 0000000000000000000000000000000000000000..c975f906eef521a3cfac5627c8b371ee55aa0e6c +GIT binary patch +literal 534 +zcmcJL!Ab-%42J(Y?m8o$d;nSS(q4Ae_Yi!A47)oFEOwaGU5e<<_x8`!K@h}~fslMn +zn)c7Z!M!`6y9Pc0I2S?0hHh3l#W~|szZ;Ct$XAT}7+V?FCpm1RoiBemuU&_Ys%S@7 +zdCkYS>{AZe=OjL~Ie67zrCwgdYud(O^J==RG>!dpXFS^tlZIX@tK0h@{D4MV@hJsW +zyR)R1zXEs6tHM*H04&I}2-7)y>9oEVCxw(Vn{LBxXmJ)=frMcRdZlJ-~v +b#4gh=OPF@NW^U~wGO=l?@b9nvy +Date: Mon, 9 Jul 2018 11:12:33 +0200 +Subject: [PATCH] bus-message: let's always use -EBADMSG when the message is + bad + +-EINVAL means the arguments were somehow wrong, so translate the code we get +internally into -EBADMSG when returning. + +(cherry picked from commit 69bd42ca072dfb2f7603b1f82053063293ab54b5) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 2 ++ + .../crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e | Bin 0 -> 93 bytes + 2 files changed, 2 insertions(+) + create mode 100644 test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 1d06fcb80e..83f17436a1 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5414,6 +5414,8 @@ int bus_message_parse_fields(sd_bus_message *m) { + &m->root_container.item_size, + &m->root_container.offsets, + &m->root_container.n_offsets); ++ if (r == -EINVAL) ++ return -EBADMSG; + if (r < 0) + return r; + } +diff --git a/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e b/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e +new file mode 100644 +index 0000000000000000000000000000000000000000..2ae1a8715a12c65fba27d8e60216112a99b0ace7 +GIT binary patch +literal 93 +wcmd1FDP>|PH8L_f3B<@i03SeB2xg~!`?q0o*WZ8t85 +Date: Tue, 24 Jul 2018 20:14:39 +0200 +Subject: [PATCH] bus-message: rename function for clarity + +There's already message_free_last_container(), so rename to match. + +(cherry picked from commit 9c65778d614588d21645163dea97a5fe2c1c4ca5) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 44 ++++++++++++++--------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 83f17436a1..7392a43a19 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -77,7 +77,7 @@ static void message_reset_parts(sd_bus_message *m) { + m->cached_rindex_part_begin = 0; + } + +-static struct bus_container *message_get_container(sd_bus_message *m) { ++static struct bus_container *message_get_last_container(sd_bus_message *m) { + assert(m); + + if (m->n_containers == 0) +@@ -90,7 +90,7 @@ static struct bus_container *message_get_container(sd_bus_message *m) { + static void message_free_last_container(sd_bus_message *m) { + struct bus_container *c; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + free(c->signature); + free(c->peeked_signature); +@@ -1220,7 +1220,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) { + /* Add offset to current container, unless this is the first + * item in it, which will have the 0 offset, which we can + * ignore. */ +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (!c->need_offsets) + return 0; +@@ -1392,7 +1392,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void + assert_return(bus_type_is_basic(type), -EINVAL); + assert_return(!m->poisoned, -ESTALE); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (c->signature && c->signature[c->index]) { + /* Container signature is already set */ +@@ -1585,7 +1585,7 @@ _public_ int sd_bus_message_append_string_space( + assert_return(!m->sealed, -EPERM); + assert_return(!m->poisoned, -ESTALE); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (c->signature && c->signature[c->index]) { + /* Container signature is already set */ +@@ -1974,7 +1974,7 @@ _public_ int sd_bus_message_open_container( + return -ENOMEM; + } + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + signature = strdup(contents); + if (!signature) { +@@ -2199,7 +2199,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) { + assert_return(m->n_containers > 0, -EINVAL); + assert_return(!m->poisoned, -ESTALE); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (c->enclosing != SD_BUS_TYPE_ARRAY) + if (c->signature && c->signature[c->index] != 0) +@@ -2703,7 +2703,7 @@ _public_ int sd_bus_message_append_string_memfd( + if (size > (uint64_t) (uint32_t) -1) + return -EINVAL; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + if (c->signature && c->signature[c->index]) { + /* Container signature is already set */ + +@@ -3036,7 +3036,7 @@ static bool message_end_of_signature(sd_bus_message *m) { + + assert(m); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + return !c->signature || c->signature[c->index] == 0; + } + +@@ -3045,7 +3045,7 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) { + + assert(m); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + if (c->enclosing != SD_BUS_TYPE_ARRAY) + return false; + +@@ -3306,7 +3306,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) { + if (message_end_of_array(m, m->rindex)) + return 0; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + if (c->signature[c->index] != type) + return -ENXIO; + +@@ -4036,7 +4036,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m, + if (message_end_of_array(m, m->rindex)) + return 0; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + signature = strdup(contents); + if (!signature) +@@ -4092,7 +4092,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) { + assert_return(m->sealed, -EPERM); + assert_return(m->n_containers > 0, -ENXIO); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (c->enclosing != SD_BUS_TYPE_ARRAY) { + if (c->signature && c->signature[c->index] != 0) +@@ -4113,7 +4113,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) { + + message_free_last_container(m); + +- c = message_get_container(m); ++ c = message_get_last_container(m); + saved = c->index; + c->index = c->saved_index; + r = container_next_item(m, c, &m->rindex); +@@ -4132,7 +4132,7 @@ static void message_quit_container(sd_bus_message *m) { + assert(m->n_containers > 0); + + /* Undo seeks */ +- c = message_get_container(m); ++ c = message_get_last_container(m); + assert(m->rindex >= c->before); + m->rindex = c->before; + +@@ -4140,7 +4140,7 @@ static void message_quit_container(sd_bus_message *m) { + message_free_last_container(m); + + /* Correct index of new top-level container */ +- c = message_get_container(m); ++ c = message_get_last_container(m); + c->index = c->saved_index; + } + +@@ -4157,7 +4157,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + if (message_end_of_array(m, m->rindex)) + goto eof; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (bus_type_is_basic(c->signature[c->index])) { + if (contents) +@@ -4301,9 +4301,9 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) { + message_reset_containers(m); + m->rindex = 0; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + } else { +- c = message_get_container(m); ++ c = message_get_last_container(m); + + c->offset_index = 0; + c->index = 0; +@@ -4546,7 +4546,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) { + if (message_end_of_array(m, m->rindex)) + return 0; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + r = signature_element_length(c->signature + c->index, &l); + if (r < 0) +@@ -4712,7 +4712,7 @@ _public_ int sd_bus_message_read_array( + if (r <= 0) + return r; + +- c = message_get_container(m); ++ c = message_get_last_container(m); + + if (BUS_MESSAGE_IS_GVARIANT(m)) { + align = bus_gvariant_get_alignment(CHAR_TO_STR(type)); +@@ -5609,7 +5609,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet + + assert_return(m, NULL); + +- c = complete ? &m->root_container : message_get_container(m); ++ c = complete ? &m->root_container : message_get_last_container(m); + return strempty(c->signature); + } + diff --git a/SOURCES/0165-bus-message-use-define.patch b/SOURCES/0165-bus-message-use-define.patch new file mode 100644 index 0000000..0700407 --- /dev/null +++ b/SOURCES/0165-bus-message-use-define.patch @@ -0,0 +1,25 @@ +From 5d6a8b1b9728cfa54c89441a089ffbb156b59648 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 24 Jul 2018 21:24:53 +0200 +Subject: [PATCH] bus-message: use define + +(cherry picked from commit f22c308aff556bf5c6599ffcb61e637e366ab232) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 7392a43a19..81aaa7f59f 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -227,7 +227,7 @@ static int message_append_field_string( + /* dbus1 doesn't allow strings over 32bit, let's enforce this + * globally, to not risk convertability */ + l = strlen(s); +- if (l > (size_t) (uint32_t) -1) ++ if (l > UINT32_MAX) + return -EINVAL; + + /* Signature "(yv)" where the variant contains "s" */ diff --git a/SOURCES/0166-bus-do-not-print-null-if-the-message-has-unknown-typ.patch b/SOURCES/0166-bus-do-not-print-null-if-the-message-has-unknown-typ.patch new file mode 100644 index 0000000..1196d52 --- /dev/null +++ b/SOURCES/0166-bus-do-not-print-null-if-the-message-has-unknown-typ.patch @@ -0,0 +1,33 @@ +From 625795e6214ae7c7f0f7f35b2c1f53e1e173b1ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 2 Aug 2018 00:46:20 +0200 +Subject: [PATCH] bus: do not print (null) if the message has unknown type + +(cherry picked from commit e8fd7e4b5b5269377efc641a7da43850822c1250) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-dump.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c +index 3a28c7c6e3..2bd06053a6 100644 +--- a/src/libsystemd/sd-bus/bus-dump.c ++++ b/src/libsystemd/sd-bus/bus-dump.c +@@ -59,8 +59,14 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { + "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64, + m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() : + m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() : +- m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(), +- ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(), ++ m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", ++ special_glyph(TRIANGULAR_BULLET), ++ ansi_normal(), ++ ++ ansi_highlight(), ++ bus_message_type_to_string(m->header->type) ?: "(unknown)", ++ ansi_normal(), ++ + m->header->endian, + m->header->flags, + m->header->version, diff --git a/SOURCES/0167-bus-message-fix-calculation-of-offsets-table.patch b/SOURCES/0167-bus-message-fix-calculation-of-offsets-table.patch new file mode 100644 index 0000000..bb77b2b --- /dev/null +++ b/SOURCES/0167-bus-message-fix-calculation-of-offsets-table.patch @@ -0,0 +1,126 @@ +From 38a5ae776dc62b42ef5ced8f9812771181af528b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 2 Aug 2018 14:25:11 +0200 +Subject: [PATCH] bus-message: fix calculation of offsets table + +The offsets specify the ends of variable length data. We would trust the +incoming data, putting the offsets specified in our message +into the offsets tables after doing some superficial verification. +But when actually reading the data we apply alignment, so we would take +the previous offset, align it, making it bigger then current offset, and +then we'd try to read data of negative length. + +In the attached example, the message specifies the following offsets: +[1, 4] +but the alignment of those items is +[1, 8] +so we'd calculate the second item as starting at 8 and ending at 4. + +(cherry picked from commit 12603b84d2fb07603e2ea94b240c6b78ad17510e) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 36 +++++++++--------- + ...h-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 | Bin 0 -> 28 bytes + 2 files changed, 18 insertions(+), 18 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 81aaa7f59f..d0af34f632 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -3140,6 +3140,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_ + assert(alignment > 0); + + *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment); ++ assert(c->offsets[c->offset_index+1] >= *rindex); + c->item_size = c->offsets[c->offset_index+1] - *rindex; + } else { + +@@ -3179,6 +3180,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_ + assert(alignment > 0); + + *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment); ++ assert(c->offsets[c->offset_index+1] >= *rindex); + c->item_size = c->offsets[c->offset_index+1] - *rindex; + + c->offset_index++; +@@ -3725,7 +3727,7 @@ static int build_struct_offsets( + size_t *n_offsets) { + + unsigned n_variable = 0, n_total = 0, v; +- size_t previous = 0, where; ++ size_t previous, where; + const char *p; + size_t sz; + void *q; +@@ -3804,6 +3806,7 @@ static int build_struct_offsets( + + /* Second, loop again and build an offset table */ + p = signature; ++ previous = m->rindex; + while (*p != 0) { + size_t n, offset; + int k; +@@ -3817,37 +3820,34 @@ static int build_struct_offsets( + memcpy(t, p, n); + t[n] = 0; + ++ size_t align = bus_gvariant_get_alignment(t); ++ assert(align > 0); ++ ++ /* The possible start of this member after including alignment */ ++ size_t start = ALIGN_TO(previous, align); ++ + k = bus_gvariant_get_size(t); + if (k < 0) { + size_t x; + +- /* variable size */ ++ /* Variable size */ + if (v > 0) { + v--; + + x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz); + if (x >= size) + return -EBADMSG; +- if (m->rindex + x < previous) +- return -EBADMSG; + } else +- /* The last item's end +- * is determined from +- * the start of the +- * offset array */ ++ /* The last item's end is determined ++ * from the start of the offset array */ + x = size - (n_variable * sz); + + offset = m->rindex + x; +- +- } else { +- size_t align; +- +- /* fixed size */ +- align = bus_gvariant_get_alignment(t); +- assert(align > 0); +- +- offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k; +- } ++ if (offset < start) ++ return -EBADMSG; ++ } else ++ /* Fixed size */ ++ offset = start + k; + } + + previous = (*offsets)[(*n_offsets)++] = offset; +diff --git a/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 b/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 +new file mode 100644 +index 0000000000000000000000000000000000000000..9d3fa0035fd360a37833e8b58cc4aea90df9de83 +GIT binary patch +literal 28 +fcmd1#|DTDG0Z1?a!8`>PAeqj{pplqVrYQgbfcytC + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0168-bus-message-remove-duplicate-assignment.patch b/SOURCES/0168-bus-message-remove-duplicate-assignment.patch new file mode 100644 index 0000000..000327d --- /dev/null +++ b/SOURCES/0168-bus-message-remove-duplicate-assignment.patch @@ -0,0 +1,24 @@ +From fcaaf6f3640c6cac73ba2b3807cde9fd94e0789b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 2 Aug 2018 14:25:31 +0200 +Subject: [PATCH] bus-message: remove duplicate assignment + +(cherry picked from commit 4d82a8d5052fce8c1ea51f8bdec3476fb8cc4747) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index d0af34f632..c8f7937102 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -4305,7 +4305,6 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) { + } else { + c = message_get_last_container(m); + +- c->offset_index = 0; + c->index = 0; + m->rindex = c->begin; + } diff --git a/SOURCES/0169-bus-message-fix-calculation-of-offsets-table-for-arr.patch b/SOURCES/0169-bus-message-fix-calculation-of-offsets-table-for-arr.patch new file mode 100644 index 0000000..c3ccf71 --- /dev/null +++ b/SOURCES/0169-bus-message-fix-calculation-of-offsets-table-for-arr.patch @@ -0,0 +1,87 @@ +From 871bb5457c5951870d447f53c976a1a1f2dac85d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 3 Aug 2018 14:46:57 +0200 +Subject: [PATCH] bus-message: fix calculation of offsets table for arrays + +This is similar to the grandparent commit 'fix calculation of offsets table', +except that now the change is for array elements. Same story as before: we need +to make sure that the offsets increase enough taking alignment into account. + +While at it, rename 'p' to 'previous' to match similar code in other places. + +(cherry picked from commit f88214cf9d66c93f4d22c4c8980de9ee3ff45bab) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 17 ++++++++++++----- + ...sh-d8f3941c74219b4c03532c9b244d5ea539c61af5 | Bin 0 -> 41 bytes + 2 files changed, 12 insertions(+), 5 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index c8f7937102..ac823aaf58 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -3532,7 +3532,7 @@ static int bus_message_enter_array( + + size_t rindex; + void *q; +- int r, alignment; ++ int r; + + assert(m); + assert(c); +@@ -3558,6 +3558,7 @@ static int bus_message_enter_array( + + if (!BUS_MESSAGE_IS_GVARIANT(m)) { + /* dbus1 */ ++ int alignment; + + r = message_peek_body(m, &rindex, 4, 4, &q); + if (r < 0) +@@ -3591,7 +3592,8 @@ static int bus_message_enter_array( + *n_offsets = 0; + + } else { +- size_t where, p = 0, framing, sz; ++ size_t where, previous = 0, framing, sz; ++ int alignment; + unsigned i; + + /* gvariant: variable length array */ +@@ -3619,17 +3621,22 @@ static int bus_message_enter_array( + if (!*offsets) + return -ENOMEM; + ++ alignment = bus_gvariant_get_alignment(c->signature); ++ assert(alignment > 0); ++ + for (i = 0; i < *n_offsets; i++) { +- size_t x; ++ size_t x, start; ++ ++ start = ALIGN_TO(previous, alignment); + + x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz); + if (x > c->item_size - sz) + return -EBADMSG; +- if (x < p) ++ if (x < start) + return -EBADMSG; + + (*offsets)[i] = rindex + x; +- p = x; ++ previous = x; + } + + *item_size = (*offsets)[0] - rindex; +diff --git a/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 +new file mode 100644 +index 0000000000000000000000000000000000000000..26262e1149825a114a89bf9cee5aeca0be463984 +GIT binary patch +literal 41 +rcmd1#|DTC5gMmSS0SHWtIT#p03 +Date: Fri, 3 Aug 2018 16:36:51 +0200 +Subject: [PATCH] bus-message: drop asserts in functions which are wrappers for + varargs version + +The function does no processing on it's own, and just forwards arguments +to the other function. Let's just use the asserts there. + +(cherry picked from commit 8792bdf8a3311f9e629daa0ec592c97c1cfb2a7c) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index ac823aaf58..153cdf933b 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -2469,11 +2469,6 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) { + va_list ap; + int r; + +- assert_return(m, -EINVAL); +- assert_return(types, -EINVAL); +- assert_return(!m->sealed, -EPERM); +- assert_return(!m->poisoned, -ESTALE); +- + va_start(ap, types); + r = sd_bus_message_appendv(m, types, ap); + va_end(ap); +@@ -4524,10 +4519,6 @@ _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) { + va_list ap; + int r; + +- assert_return(m, -EINVAL); +- assert_return(m->sealed, -EPERM); +- assert_return(types, -EINVAL); +- + va_start(ap, types); + r = message_read_ap(m, types, ap); + va_end(ap); diff --git a/SOURCES/0171-bus-message-output-debug-information-about-offset-tr.patch b/SOURCES/0171-bus-message-output-debug-information-about-offset-tr.patch new file mode 100644 index 0000000..615a7f0 --- /dev/null +++ b/SOURCES/0171-bus-message-output-debug-information-about-offset-tr.patch @@ -0,0 +1,29 @@ +From f6af2bfe4b353b25a61c362c3ada9be06c8f15c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 3 Aug 2018 18:05:27 +0200 +Subject: [PATCH] bus-message: output debug information about offset troubles + +(cherry picked from commit 0b4775b52747bebf7ecb62062798475629767044) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 153cdf933b..09e72d89dd 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -3845,8 +3845,11 @@ static int build_struct_offsets( + x = size - (n_variable * sz); + + offset = m->rindex + x; +- if (offset < start) ++ if (offset < start) { ++ log_debug("For type %s with alignment %zu, message specifies offset %zu which is smaller than previous end %zu + alignment = %zu", ++ t, align, offset, previous, start); + return -EBADMSG; ++ } + } else + /* Fixed size */ + offset = start + k; diff --git a/SOURCES/0172-bus-message-fix-skipping-of-array-fields-in-gvariant.patch b/SOURCES/0172-bus-message-fix-skipping-of-array-fields-in-gvariant.patch new file mode 100644 index 0000000..5f7774b --- /dev/null +++ b/SOURCES/0172-bus-message-fix-skipping-of-array-fields-in-gvariant.patch @@ -0,0 +1,59 @@ +From d212765dc94ba25c04e0e9a278586f0e86851e35 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 11 Aug 2018 08:32:20 +0200 +Subject: [PATCH] bus-message: fix skipping of array fields in !gvariant + messages + +We copied part of the string into a buffer that was off by two. +If the element signature had length one, we'd copy 0 bytes and crash when +looking at the "first" byte. Otherwise, we would crash because strncpy would +not terminate the string. + +(cherry picked from commit 73777ddba5100fe6c0791cd37a91f24a515f3202) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 8 ++++---- + ...crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 | Bin 0 -> 534 bytes + 2 files changed, 4 insertions(+), 4 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 09e72d89dd..202f1aab30 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -4981,18 +4981,18 @@ static int message_skip_fields( + + } else if (t == SD_BUS_TYPE_ARRAY) { + +- r = signature_element_length(*signature+1, &l); ++ r = signature_element_length(*signature + 1, &l); + if (r < 0) + return r; + + assert(l >= 1); + { +- char sig[l-1], *s; ++ char sig[l + 1], *s = sig; + uint32_t nas; + int alignment; + +- strncpy(sig, *signature + 1, l-1); +- s = sig; ++ strncpy(sig, *signature + 1, l); ++ sig[l] = '\0'; + + alignment = bus_type_get_alignment(sig[0]); + if (alignment < 0) +diff --git a/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 b/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 +new file mode 100644 +index 0000000000000000000000000000000000000000..6a20265a39e1b4a318b50aee2b13727ddc4113bf +GIT binary patch +literal 534 +zcmc~{WMHggWMD`aVqj=xU|>*W&P&W-;Q0Fg|9>Elfq|V9OfmRED27Bi2!jjC2Wn-| +z17hYPAOVtNW-Ml42GVKy`9P9^ffdMS1=8h-IVt%J91NTwNgyEFV4&K>#6$*=MMgl( +r%#fH?l1eMv=;=K=_yi-CK!KUB2_%6r0c0u^mlS2@rGxk|0FGY(dwVLU + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0173-bus-message-also-properly-copy-struct-signature-when.patch b/SOURCES/0173-bus-message-also-properly-copy-struct-signature-when.patch new file mode 100644 index 0000000..89e0100 --- /dev/null +++ b/SOURCES/0173-bus-message-also-properly-copy-struct-signature-when.patch @@ -0,0 +1,33 @@ +From 13993b51c5cab806d81a7305c895bafd4cd48876 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 11 Aug 2018 09:02:48 +0200 +Subject: [PATCH] bus-message: also properly copy struct signature when + skipping + +The change is similar to that in the previous commit, but I don't have +a reproducer / test case case for this one, so I'm keeping it seperate. + +(cherry picked from commit 3d338a302f56c0ef0445660d9856794abe1af8b5) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 202f1aab30..e71d29f91d 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5036,9 +5036,9 @@ static int message_skip_fields( + + assert(l >= 2); + { +- char sig[l-1], *s; +- strncpy(sig, *signature + 1, l-1); +- s = sig; ++ char sig[l + 1], *s = sig; ++ strncpy(sig, *signature + 1, l); ++ sig[l] = '\0'; + + r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s); + if (r < 0) diff --git a/SOURCES/0174-fuzz-bus-message-add-two-test-cases-that-pass-now.patch b/SOURCES/0174-fuzz-bus-message-add-two-test-cases-that-pass-now.patch new file mode 100644 index 0000000..cd69663 --- /dev/null +++ b/SOURCES/0174-fuzz-bus-message-add-two-test-cases-that-pass-now.patch @@ -0,0 +1,39 @@ +From 5ae60bf0848d38b101f8c79ffa82efcb27d6767c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 11 Aug 2018 11:31:45 +0200 +Subject: [PATCH] fuzz-bus-message: add two test cases that pass now + +It seems that they got fixed by one of the patches. Let's add them +just in case. + +(cherry picked from commit edde66ffc2404de58e8b19810951f376efb344da) + +Resolves: #1696224 +--- + ...crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 | Bin 0 -> 89 bytes + ...crash-4f0211eb269e28db941961061494bfdbf3345e54 | Bin 0 -> 143 bytes + 2 files changed, 0 insertions(+), 0 deletions(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 + create mode 100644 test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54 + +diff --git a/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 b/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 +new file mode 100644 +index 0000000000000000000000000000000000000000..aa0c6ff7f7b6d2e3fa4358716ee1d05ba74cefc0 +GIT binary patch +literal 89 +scmc~q)(CT7OTMiz#q2KEMtDT&4= +liD{N8W@+Y0hK!61V4zWvq@j_NlvJFQnL&wm%}Py80RUy_C0PIf + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0175-bus-message-return-EBADMSG-not-EINVAL-on-invalid-gva.patch b/SOURCES/0175-bus-message-return-EBADMSG-not-EINVAL-on-invalid-gva.patch new file mode 100644 index 0000000..0cd8d72 --- /dev/null +++ b/SOURCES/0175-bus-message-return-EBADMSG-not-EINVAL-on-invalid-gva.patch @@ -0,0 +1,41 @@ +From b63440ad69581bad39a2eda7ab449f8a3f901c4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 11 Aug 2018 11:43:09 +0200 +Subject: [PATCH] bus-message: return -EBADMSG not -EINVAL on invalid !gvariant + messages + +(cherry picked from commit d831fb6f2bde829f9309aea242f502587662d1cc) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 2 +- + ...crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 | Bin 0 -> 534 bytes + 2 files changed, 1 insertion(+), 1 deletion(-) + create mode 100644 test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index e71d29f91d..613722a1a0 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5047,7 +5047,7 @@ static int message_skip_fields( + + *signature += l; + } else +- return -EINVAL; ++ return -EBADMSG; + } + } + +diff --git a/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 b/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 +new file mode 100644 +index 0000000000000000000000000000000000000000..5faf3308e7ac9c14d66422169e74ba8c05ad7319 +GIT binary patch +literal 534 +zcmd5(y$ZrW3{L#Rf|Cy*1sA)t;uE+zxcCZJw53qIqj#v2xH$UGez{(yI63-3NWO$5 +zU+!uqzB5rdCwdYQvnEi=V1glA8o?i`lMy}upTQSe=c-Assy=GTr+lHv=4$0!Vy$EX +z_LzYX&1*Ob(W(=vPGKsxuBpzYaDn6&un5*x;uk`Xz?Yk^O%qgGJ(zd +Date: Thu, 23 Aug 2018 14:48:40 +0200 +Subject: [PATCH] bus-message: avoid wrap-around when using length read from + message + +We would read (-1), and then add 1 to it, call message_peek_body(..., 0, ...), +and when trying to make use of the data. + +The fuzzer test case is just for one site, but they all look similar. + +v2: fix two UINT8_MAX/UINT32_MAX mismatches founds by LGTM +(cherry picked from commit 902000c19830f5e5a96e8948d691b42e91ecb1e7) + +Resolves: #1696224 +--- + src/libsystemd/sd-bus/bus-message.c | 24 ++++++++++++++++++ + ...h-603dfd98252375ac7dbced53c2ec312671939a36 | Bin 0 -> 40 bytes + 2 files changed, 24 insertions(+) + create mode 100644 test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 613722a1a0..53cbd675b7 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -3414,6 +3414,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) { + return r; + + l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q); ++ if (l == UINT32_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_body(m, &rindex, 1, l+1, &q); + if (r < 0) + return r; +@@ -3436,6 +3440,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) { + return r; + + l = *(uint8_t*) q; ++ if (l == UINT8_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_body(m, &rindex, 1, l+1, &q); + if (r < 0) + return r; +@@ -3701,6 +3709,10 @@ static int bus_message_enter_variant( + return r; + + l = *(uint8_t*) q; ++ if (l == UINT8_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_body(m, &rindex, 1, l+1, &q); + if (r < 0) + return r; +@@ -4269,6 +4281,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char + return r; + + l = *(uint8_t*) q; ++ if (l == UINT8_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_body(m, &rindex, 1, l+1, &q); + if (r < 0) + return r; +@@ -4849,6 +4865,10 @@ static int message_peek_field_string( + if (r < 0) + return r; + ++ if (l == UINT32_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_fields(m, ri, 1, l+1, &q); + if (r < 0) + return r; +@@ -4900,6 +4920,10 @@ static int message_peek_field_signature( + return r; + + l = *(uint8_t*) q; ++ if (l == UINT8_MAX) ++ /* avoid overflow right below */ ++ return -EBADMSG; ++ + r = message_peek_fields(m, ri, 1, l+1, &q); + if (r < 0) + return r; +diff --git a/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 +new file mode 100644 +index 0000000000000000000000000000000000000000..b3fee9e07af4f925697a549bbc8ffc03a277fac0 +GIT binary patch +literal 40 +mcmc~{Vqjzdg7laF|BC@>cE)0c{}2$`*K@IKT2AZ~5ElR}@e}O; + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0177-util-do-not-use-stack-frame-for-parsing-arbitrary-in.patch b/SOURCES/0177-util-do-not-use-stack-frame-for-parsing-arbitrary-in.patch new file mode 100644 index 0000000..296afc3 --- /dev/null +++ b/SOURCES/0177-util-do-not-use-stack-frame-for-parsing-arbitrary-in.patch @@ -0,0 +1,66 @@ +From a652268ae11633cf64c87586bed1fd3c7141707a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 22 Aug 2018 12:33:27 +0900 +Subject: [PATCH] util: do not use stack frame for parsing arbitrary inputs + +This replaces strndupa() by strndup() in socket_address_parse(), +as input string may be too long. + +Fixes issue 10007 by ClusterFuzz-External: +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10007 + +(cherry picked from commit 8d30fcb9b51b1d102a589171b6e28f5f370236f6) + +Resolves: #1696224 +--- + src/basic/socket-util.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index a913102e13..3f90a81d35 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -50,7 +50,8 @@ static const char* const socket_address_type_table[] = { + DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int); + + int socket_address_parse(SocketAddress *a, const char *s) { +- char *e, *n; ++ _cleanup_free_ char *n = NULL; ++ char *e; + int r; + + assert(a); +@@ -68,7 +69,9 @@ int socket_address_parse(SocketAddress *a, const char *s) { + if (!e) + return -EINVAL; + +- n = strndupa(s+1, e-s-1); ++ n = strndup(s+1, e-s-1); ++ if (!n) ++ return -ENOMEM; + + errno = 0; + if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) +@@ -125,7 +128,10 @@ int socket_address_parse(SocketAddress *a, const char *s) { + if (r < 0) + return r; + +- n = strndupa(cid_start, e - cid_start); ++ n = strndup(cid_start, e - cid_start); ++ if (!n) ++ return -ENOMEM; ++ + if (!isempty(n)) { + r = safe_atou(n, &a->sockaddr.vm.svm_cid); + if (r < 0) +@@ -146,7 +152,9 @@ int socket_address_parse(SocketAddress *a, const char *s) { + if (r < 0) + return r; + +- n = strndupa(s, e-s); ++ n = strndup(s, e-s); ++ if (!n) ++ return -ENOMEM; + + /* IPv4 in w.x.y.z:p notation? */ + r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr); diff --git a/SOURCES/0178-travis-enable-ASan-and-UBSan-on-RHEL8.patch b/SOURCES/0178-travis-enable-ASan-and-UBSan-on-RHEL8.patch new file mode 100644 index 0000000..633d215 --- /dev/null +++ b/SOURCES/0178-travis-enable-ASan-and-UBSan-on-RHEL8.patch @@ -0,0 +1,213 @@ +From d84b1c62b9739e9c043a717aecec2da181eb9df7 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 23 Feb 2019 17:10:55 +0100 +Subject: [PATCH] travis: enable ASan and UBSan on RHEL8 + +Resolves: #1683319 +rhel-only +--- + .travis.yml | 23 ++++++- + ci/travis-centos-rhel8.sh | 138 +++++++++++++++++++++++--------------- + 2 files changed, 105 insertions(+), 56 deletions(-) + +diff --git a/.travis.yml b/.travis.yml +index c5c9c345a9..67677bdf06 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -8,8 +8,7 @@ env: + + jobs: + include: +- - stage: Build & test +- name: CentOS 7 ++ - name: CentOS 7 + language: bash + env: + - CENTOS_RELEASE="centos7" +@@ -28,3 +27,23 @@ jobs: + - set +e + after_script: + - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP ++ ++ - name: CentOS 7 (ASan+UBSan) ++ language: bash ++ env: ++ - CENTOS_RELEASE="centos7" ++ - CONT_NAME="systemd-centos-$CENTOS_RELEASE" ++ - DOCKER_EXEC="docker exec -ti $CONT_NAME" ++ before_install: ++ - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce ++ - docker --version ++ install: ++ - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP ++ script: ++ - set -e ++ # Build systemd ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN_ASAN ++ - set +e ++ after_script: ++ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index 1f72d984e0..c3d1018682 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -19,6 +19,60 @@ ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja + # Repo with additional depencencies to compile newer systemd on CentOS 7 + COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo" + COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}" ++# RHEL8 options ++CONFIGURE_OPTS=( ++ -Dsysvinit-path=/etc/rc.d/init.d ++ -Drc-local=/etc/rc.d/rc.local ++ -Ddns-servers='' ++ -Ddev-kvm-mode=0666 ++ -Dkmod=true ++ -Dxkbcommon=true ++ -Dblkid=true ++ -Dseccomp=true ++ -Dima=true ++ -Dselinux=true ++ -Dapparmor=false ++ -Dpolkit=true ++ -Dxz=true ++ -Dzlib=true ++ -Dbzip2=true ++ -Dlz4=true ++ -Dpam=true ++ -Dacl=true ++ -Dsmack=true ++ -Dgcrypt=true ++ -Daudit=true ++ -Delfutils=true ++ -Dlibcryptsetup=true ++ -Delfutils=true ++ -Dqrencode=false ++ -Dgnutls=true ++ -Dmicrohttpd=true ++ -Dlibidn2=true ++ -Dlibiptc=true ++ -Dlibcurl=true ++ -Defi=true ++ -Dtpm=true ++ -Dhwdb=true ++ -Dsysusers=true ++ -Ddefault-kill-user-processes=false ++ -Dtests=unsafe ++ -Dinstall-tests=true ++ -Dtty-gid=5 ++ -Dusers-gid=100 ++ -Dnobody-user=nobody ++ -Dnobody-group=nobody ++ -Dsplit-usr=false ++ -Dsplit-bin=true ++ -Db_lto=false ++ -Dnetworkd=false ++ -Dtimesyncd=false ++ -Ddefault-hierarchy=legacy ++ # Custom options ++ -Dslow-tests=true ++ -Dtests=unsafe ++ -Dinstall-tests=true ++) + + function info() { + echo -e "\033[33;1m$1\033[0m" +@@ -57,60 +111,6 @@ for phase in "${PHASES[@]}"; do + RUN) + info "Run phase" + # Build systemd +- CONFIGURE_OPTS=( +- # RHEL8 options +- -Dsysvinit-path=/etc/rc.d/init.d +- -Drc-local=/etc/rc.d/rc.local +- -Ddns-servers='' +- -Ddev-kvm-mode=0666 +- -Dkmod=true +- -Dxkbcommon=true +- -Dblkid=true +- -Dseccomp=true +- -Dima=true +- -Dselinux=true +- -Dapparmor=false +- -Dpolkit=true +- -Dxz=true +- -Dzlib=true +- -Dbzip2=true +- -Dlz4=true +- -Dpam=true +- -Dacl=true +- -Dsmack=true +- -Dgcrypt=true +- -Daudit=true +- -Delfutils=true +- -Dlibcryptsetup=true +- -Delfutils=true +- -Dqrencode=false +- -Dgnutls=true +- -Dmicrohttpd=true +- -Dlibidn2=true +- -Dlibiptc=true +- -Dlibcurl=true +- -Defi=true +- -Dtpm=true +- -Dhwdb=true +- -Dsysusers=true +- -Ddefault-kill-user-processes=false +- -Dtests=unsafe +- -Dinstall-tests=true +- -Dtty-gid=5 +- -Dusers-gid=100 +- -Dnobody-user=nobody +- -Dnobody-group=nobody +- -Dsplit-usr=false +- -Dsplit-bin=true +- -Db_lto=false +- -Dnetworkd=false +- -Dtimesyncd=false +- -Ddefault-hierarchy=legacy +- # Custom options +- -Dslow-tests=true +- -Dtests=unsafe +- -Dinstall-tests=true +- ) + docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}" + $DOCKER_EXEC ninja -v -C build + # Let's install the new systemd and "reboot" the container to avoid +@@ -122,6 +122,36 @@ for phase in "${PHASES[@]}"; do + echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl" + $DOCKER_EXEC ninja -C build test + ;; ++ RUN_ASAN|RUN_CLANG_ASAN) ++ # Let's install newer gcc for proper ASan/UBSan support ++ $DOCKER_EXEC yum -y install centos-release-scl ++ $DOCKER_EXEC yum -y install devtoolset-8 devtoolset-8-libasan-devel libasan5 devtoolset-8-libubsan-devel libubsan1 ++ $DOCKER_EXEC bash -c "echo 'source scl_source enable devtoolset-8' >> /root/.bashrc" ++ # Note to my future frustrated self: docker exec runs the given command ++ # as sh -c 'command' - which means both .bash_profile and .bashrc will ++ # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e. ++ # sh -l), whereas .bashrc is sourced for NON-LOGIN INTERACTIVE shells ++ # (i.e. sh -i). ++ # As the default docker exec command lacks either of those options, ++ # we need to use a wrapper command which runs the wanted command ++ # under an explicit bash -i, so the SCL source above works properly. ++ docker exec -it $CONT_NAME bash -ic 'gcc --version' ++ ++ if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then ++ ENV_VARS="-e CC=clang -e CXX=clang++" ++ MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 ++ fi ++ docker exec $ENV_VARS -it $CONT_NAME bash -ic "meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}" ++ docker exec -it $CONT_NAME bash -ic 'ninja -v -C build' ++ ++ # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. ++ travis_wait docker exec --interactive=false \ ++ -e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \ ++ -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \ ++ -e "TRAVIS=$TRAVIS" \ ++ -t $CONT_NAME \ ++ bash -ic 'meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs' ++ ;; + CLEANUP) + info "Cleanup phase" + docker stop $CONT_NAME diff --git a/SOURCES/0179-tests-keep-SYS_PTRACE-when-running-under-ASan.patch b/SOURCES/0179-tests-keep-SYS_PTRACE-when-running-under-ASan.patch new file mode 100644 index 0000000..2a509c5 --- /dev/null +++ b/SOURCES/0179-tests-keep-SYS_PTRACE-when-running-under-ASan.patch @@ -0,0 +1,31 @@ +From ee93272cf9915710251704c7bf7c1f1a0b02cb7f Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 9 Nov 2018 12:47:30 +0100 +Subject: [PATCH] tests: keep SYS_PTRACE when running under ASan + +(cherry picked from commit 7a3025658836c536f81fdd742fa338545294f5bf) + +Resolves: #1683319 +--- + src/test/test-capability.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-capability.c b/src/test/test-capability.c +index 72975cef94..20eb877a3c 100644 +--- a/src/test/test-capability.c ++++ b/src/test/test-capability.c +@@ -19,8 +19,13 @@ + static uid_t test_uid = -1; + static gid_t test_gid = -1; + ++#ifdef __SANITIZE_ADDRESS__ ++/* Keep CAP_SYS_PTRACE when running under Address Sanitizer */ ++static const uint64_t test_flags = UINT64_C(1) << CAP_SYS_PTRACE; ++#else + /* We keep CAP_DAC_OVERRIDE to avoid errors with gcov when doing test coverage */ +-static uint64_t test_flags = 1ULL << CAP_DAC_OVERRIDE; ++static const uint64_t test_flags = UINT64_C(1) << CAP_DAC_OVERRIDE; ++#endif + + /* verify cap_last_cap() against /proc/sys/kernel/cap_last_cap */ + static void test_last_cap_file(void) { diff --git a/SOURCES/0180-tree-wide-various-ubsan-zero-size-memory-fixes.patch b/SOURCES/0180-tree-wide-various-ubsan-zero-size-memory-fixes.patch new file mode 100644 index 0000000..05617f9 --- /dev/null +++ b/SOURCES/0180-tree-wide-various-ubsan-zero-size-memory-fixes.patch @@ -0,0 +1,60 @@ +From 6bb1d52f0554f687ef27de46c0b9daac9d256d60 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Oct 2018 11:34:30 +0200 +Subject: [PATCH] tree-wide: various ubsan zero size memory fixes + +Fixes: #10346 +(cherry picked from commit 65f95765d05ddcd9e5849b68c379afa7e87d1248) + +Resolves: #1683319 +--- + src/basic/bitmap.c | 2 +- + src/basic/util.h | 8 +++++++- + src/test/test-hexdecoct.c | 2 +- + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/basic/bitmap.c b/src/basic/bitmap.c +index c17c6a7a02..a4cd6451b0 100644 +--- a/src/basic/bitmap.c ++++ b/src/basic/bitmap.c +@@ -206,7 +206,7 @@ bool bitmap_equal(Bitmap *a, Bitmap *b) { + return true; + + common_n_bitmaps = MIN(a->n_bitmaps, b->n_bitmaps); +- if (memcmp(a->bitmaps, b->bitmaps, sizeof(uint64_t) * common_n_bitmaps) != 0) ++ if (memcmp_safe(a->bitmaps, b->bitmaps, sizeof(uint64_t) * common_n_bitmaps) != 0) + return false; + + c = a->n_bitmaps > b->n_bitmaps ? a : b; +diff --git a/src/basic/util.h b/src/basic/util.h +index b68ef25ed8..4659a21b06 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -134,7 +134,13 @@ static inline int memcmp_safe(const void *s1, const void *s2, size_t n) { + + int on_ac_power(void); + +-#define memzero(x,l) (memset((x), 0, (l))) ++#define memzero(x,l) \ ++ ({ \ ++ size_t _l_ = (l); \ ++ void *_x_ = (x); \ ++ _l_ == 0 ? _x_ : memset(_x_, 0, _l_); \ ++ }) ++ + #define zero(x) (memzero(&(x), sizeof(x))) + + static inline void *mempset(void *s, int c, size_t n) { +diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c +index da9f3008bb..a972ddcef7 100644 +--- a/src/test/test-hexdecoct.c ++++ b/src/test/test-hexdecoct.c +@@ -84,7 +84,7 @@ static void test_unhexmem_one(const char *s, size_t l, int retval) { + l = strlen(s); + + assert_se(hex = hexmem(mem, len)); +- answer = strndupa(s, l); ++ answer = strndupa(s ?: "", l); + assert_se(streq(delete_chars(answer, WHITESPACE), hex)); + } + } diff --git a/SOURCES/0181-util-introduce-memcmp_safe.patch b/SOURCES/0181-util-introduce-memcmp_safe.patch new file mode 100644 index 0000000..c56f5ff --- /dev/null +++ b/SOURCES/0181-util-introduce-memcmp_safe.patch @@ -0,0 +1,27 @@ +From 465534a9417b7d7cf74f686da674b3f74d77ac58 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 8 Aug 2018 16:22:55 +0900 +Subject: [PATCH] util: introduce memcmp_safe() + +(cherry picked from commit f30faf854b9bf01da294547a1bc3660506d750db) + +Resolves: #1683319 +--- + src/basic/util.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 4659a21b06..c70467f98c 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -113,9 +113,7 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*com + qsort_r(base, nmemb, size, compar, userdata); + } + +-/** +- * Normal memcpy requires src to be nonnull. We do nothing if n is 0. +- */ ++/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */ + static inline void memcpy_safe(void *dst, const void *src, size_t n) { + if (n == 0) + return; diff --git a/SOURCES/0182-test-socket-util-avoid-memleak-reported-by-valgrind.patch b/SOURCES/0182-test-socket-util-avoid-memleak-reported-by-valgrind.patch new file mode 100644 index 0000000..085b163 --- /dev/null +++ b/SOURCES/0182-test-socket-util-avoid-memleak-reported-by-valgrind.patch @@ -0,0 +1,49 @@ +From fe6895fb6a5f8c61f0c47aa95e1c86bb88b7cf4f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 21 Aug 2018 19:44:48 +0200 +Subject: [PATCH] test-socket-util: avoid "memleak" reported by valgrind + +valgrind reports the allocation done in the short-lived child as a leak. +Let's restructure the code to avoid this. + +(cherry picked from commit 181c4ba750770b54a54b5abbe8ae8ff4f6db59b5) + +Resolves: #1683319 +--- + src/test/test-socket-util.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c +index ac2ea52a5c..588485d881 100644 +--- a/src/test/test-socket-util.c ++++ b/src/test/test-socket-util.c +@@ -431,7 +431,6 @@ static void test_getpeercred_getpeergroups(void) { + if (r == 0) { + static const gid_t gids[] = { 3, 4, 5, 6, 7 }; + gid_t *test_gids; +- _cleanup_free_ gid_t *peer_groups = NULL; + size_t n_test_gids; + uid_t test_uid; + gid_t test_gid; +@@ -472,12 +471,16 @@ static void test_getpeercred_getpeergroups(void) { + assert_se(ucred.gid == test_gid); + assert_se(ucred.pid == getpid_cached()); + +- r = getpeergroups(pair[0], &peer_groups); +- assert_se(r >= 0 || IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)); ++ { ++ _cleanup_free_ gid_t *peer_groups = NULL; + +- if (r >= 0) { +- assert_se((size_t) r == n_test_gids); +- assert_se(memcmp(peer_groups, test_gids, sizeof(gid_t) * n_test_gids) == 0); ++ r = getpeergroups(pair[0], &peer_groups); ++ assert_se(r >= 0 || IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)); ++ ++ if (r >= 0) { ++ assert_se((size_t) r == n_test_gids); ++ assert_se(memcmp(peer_groups, test_gids, sizeof(gid_t) * n_test_gids) == 0); ++ } + } + + safe_close_pair(pair); diff --git a/SOURCES/0183-sd-journal-escape-binary-data-in-match_make_string.patch b/SOURCES/0183-sd-journal-escape-binary-data-in-match_make_string.patch new file mode 100644 index 0000000..a4fd0f9 --- /dev/null +++ b/SOURCES/0183-sd-journal-escape-binary-data-in-match_make_string.patch @@ -0,0 +1,57 @@ +From b234013c618e3a346fd831d65e08662844fc9f81 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 12 Oct 2018 12:17:04 +0000 +Subject: [PATCH] sd-journal: escape binary data in match_make_string() + +Fixes: #10383 +(cherry picked from commit 9e8b1ec08e8eb0b4611b7caf6adb8828feb32312) + +Resolves: #1683319 +--- + src/journal/sd-journal.c | 3 ++- + src/journal/test-journal-match.c | 4 +++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 83abd82d1c..323300baec 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -16,6 +16,7 @@ + #include "catalog.h" + #include "compress.h" + #include "dirent-util.h" ++#include "escape.h" + #include "fd-util.h" + #include "fileio.h" + #include "format-util.h" +@@ -381,7 +382,7 @@ static char *match_make_string(Match *m) { + return strdup("none"); + + if (m->type == MATCH_DISCRETE) +- return strndup(m->data, m->size); ++ return cescape_length(m->data, m->size); + + LIST_FOREACH(matches, i, m->matches) { + char *t, *k; +diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c +index 4e5ad1791a..d2a52b9145 100644 +--- a/src/journal/test-journal-match.c ++++ b/src/journal/test-journal-match.c +@@ -23,6 +23,8 @@ int main(int argc, char *argv[]) { + assert_se(sd_journal_add_match(j, "", 0) < 0); + assert_se(sd_journal_add_match(j, "=", 0) < 0); + assert_se(sd_journal_add_match(j, "=xxxxx", 0) < 0); ++ assert_se(sd_journal_add_match(j, (uint8_t[4]){'A', '=', '\1', '\2'}, 4) >= 0); ++ assert_se(sd_journal_add_match(j, (uint8_t[5]){'B', '=', 'C', '\0', 'D'}, 5) >= 0); + assert_se(sd_journal_add_match(j, "HALLO=WALDO", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=mmmm", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0); +@@ -53,7 +55,7 @@ int main(int argc, char *argv[]) { + + printf("resulting match expression is: %s\n", t); + +- assert_se(streq(t, "(((L3=ok OR L3=yes) OR ((L4_2=ok OR L4_2=yes) AND (L4_1=ok OR L4_1=yes))) AND ((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO))))")); ++ assert_se(streq(t, "(((L3=ok OR L3=yes) OR ((L4_2=ok OR L4_2=yes) AND (L4_1=ok OR L4_1=yes))) AND ((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO) AND B=C\\000D AND A=\\001\\002)))")); + + return 0; + } diff --git a/SOURCES/0184-capability-introduce-CAP_TO_MASK_CORRECTED-macro-rep.patch b/SOURCES/0184-capability-introduce-CAP_TO_MASK_CORRECTED-macro-rep.patch new file mode 100644 index 0000000..2141b6a --- /dev/null +++ b/SOURCES/0184-capability-introduce-CAP_TO_MASK_CORRECTED-macro-rep.patch @@ -0,0 +1,46 @@ +From 401f1fdc309175d3920c0fe168e52c601474c000 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Oct 2018 11:07:54 +0200 +Subject: [PATCH] capability: introduce CAP_TO_MASK_CORRECTED() macro replacing + CAP_TO_MASK() + +linux/capability.h's CAP_TO_MASK potentially shifts a signed int "1" +(i.e. 32bit wide) left by 31 which means it becomes negative. That's +just weird, and ubsan complains about it. Let's introduce our own macro +CAP_TO_MASK_CORRECTED which doesn't fall into this trap, and make use of +it. + +Fixes: #10347 +(cherry picked from commit 5f00c5684f96c93a22840f7241ee444b9a632b1e) + +Resolves: #1683319 +--- + src/basic/capability-util.h | 4 ++++ + src/libsystemd/sd-bus/bus-creds.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h +index 4a4a86093a..59591d4b52 100644 +--- a/src/basic/capability-util.h ++++ b/src/basic/capability-util.h +@@ -39,3 +39,7 @@ static inline bool cap_test_all(uint64_t caps) { + } + + bool ambient_capabilities_supported(void); ++ ++/* Identical to linux/capability.h's CAP_TO_MASK(), but uses an unsigned 1U instead of a signed 1 for shifting left, in ++ * order to avoid complaints about shifting a signed int left by 31 bits, which would make it negative. */ ++#define CAP_TO_MASK_CORRECTED(x) (1U << ((x) & 31U)) +diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c +index aae9fcd58b..b180a033b8 100644 +--- a/src/libsystemd/sd-bus/bus-creds.c ++++ b/src/libsystemd/sd-bus/bus-creds.c +@@ -663,7 +663,7 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { + + sz = DIV_ROUND_UP(cap_last_cap(), 32U); + +- return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability)); ++ return !!(c->capability[offset * sz + CAP_TO_INDEX((uint32_t) capability)] & CAP_TO_MASK_CORRECTED((uint32_t) capability)); + } + + _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { diff --git a/SOURCES/0185-sd-bus-use-size_t-when-dealing-with-memory-offsets.patch b/SOURCES/0185-sd-bus-use-size_t-when-dealing-with-memory-offsets.patch new file mode 100644 index 0000000..5c9c680 --- /dev/null +++ b/SOURCES/0185-sd-bus-use-size_t-when-dealing-with-memory-offsets.patch @@ -0,0 +1,25 @@ +From 51747496a38894d76d3e5b4295c54b1654b7eb69 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Oct 2018 11:12:22 +0200 +Subject: [PATCH] sd-bus: use size_t when dealing with memory offsets + +(cherry picked from commit 3cae6c21e732fd46ff024d6625243d88ef6377ed) + +Resolves: #1683319 +--- + src/libsystemd/sd-bus/bus-creds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c +index b180a033b8..6896bcf246 100644 +--- a/src/libsystemd/sd-bus/bus-creds.c ++++ b/src/libsystemd/sd-bus/bus-creds.c +@@ -651,7 +651,7 @@ _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) { + return 0; + } + +-static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { ++static int has_cap(sd_bus_creds *c, size_t offset, int capability) { + size_t sz; + + assert(c); diff --git a/SOURCES/0186-sd-bus-call-cap_last_cap-only-once-in-has_cap.patch b/SOURCES/0186-sd-bus-call-cap_last_cap-only-once-in-has_cap.patch new file mode 100644 index 0000000..8cb9689 --- /dev/null +++ b/SOURCES/0186-sd-bus-call-cap_last_cap-only-once-in-has_cap.patch @@ -0,0 +1,40 @@ +From 770b16b22dd0eec04fd1493dae644206c32f8e04 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Oct 2018 11:12:54 +0200 +Subject: [PATCH] sd-bus: call cap_last_cap() only once in has_cap() + +Also, use the same type everywhere for dealing with it. + +(cherry picked from commit 92a40e20bf970c3ded8a50fbeeae882a7b970c9a) + +Resolves: #1683319 +--- + src/libsystemd/sd-bus/bus-creds.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c +index 6896bcf246..2a47c68ffc 100644 +--- a/src/libsystemd/sd-bus/bus-creds.c ++++ b/src/libsystemd/sd-bus/bus-creds.c +@@ -652,16 +652,19 @@ _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) { + } + + static int has_cap(sd_bus_creds *c, size_t offset, int capability) { ++ unsigned long lc; + size_t sz; + + assert(c); + assert(capability >= 0); + assert(c->capability); + +- if ((unsigned) capability > cap_last_cap()) ++ lc = cap_last_cap(); ++ ++ if ((unsigned long) capability > lc) + return 0; + +- sz = DIV_ROUND_UP(cap_last_cap(), 32U); ++ sz = DIV_ROUND_UP(lc, 32LU); + + return !!(c->capability[offset * sz + CAP_TO_INDEX((uint32_t) capability)] & CAP_TO_MASK_CORRECTED((uint32_t) capability)); + } diff --git a/SOURCES/0187-mount-point-honour-AT_SYMLINK_FOLLOW-correctly.patch b/SOURCES/0187-mount-point-honour-AT_SYMLINK_FOLLOW-correctly.patch new file mode 100644 index 0000000..e6aff06 --- /dev/null +++ b/SOURCES/0187-mount-point-honour-AT_SYMLINK_FOLLOW-correctly.patch @@ -0,0 +1,26 @@ +From 24e6a5d1deac8aae11a6a3a22fb9b71cb77fdb33 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 8 Dec 2018 20:21:43 +0100 +Subject: [PATCH] mount-point: honour AT_SYMLINK_FOLLOW correctly + +Fixes: #11092 +(cherry picked from commit be24321f3dae91a166166b239954032727439942) + +Resolves: #1683319 +--- + src/basic/mount-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index ebe41a4c6c..3670b7f591 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -109,7 +109,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id + if ((flags & AT_EMPTY_PATH) && isempty(filename)) + xsprintf(path, "/proc/self/fdinfo/%i", fd); + else { +- subfd = openat(fd, filename, O_CLOEXEC|O_PATH); ++ subfd = openat(fd, filename, O_CLOEXEC|O_PATH|(flags & AT_SYMLINK_FOLLOW ? 0 : O_NOFOLLOW)); + if (subfd < 0) + return -errno; + diff --git a/SOURCES/0188-travis-switch-from-trusty-to-xenial.patch b/SOURCES/0188-travis-switch-from-trusty-to-xenial.patch new file mode 100644 index 0000000..d60795c --- /dev/null +++ b/SOURCES/0188-travis-switch-from-trusty-to-xenial.patch @@ -0,0 +1,24 @@ +From 814bb6a8bc39e0f9900d84e564759a3a8698fb04 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 23 Feb 2019 22:28:05 +0100 +Subject: [PATCH] travis: switch from trusty to xenial + +This should fix the timeout in test-event + +Taken from: b635e4ef6b2f35f07111bb66a68fe850a2ccab72 + +Resolves: #1683319 +--- + .travis.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.travis.yml b/.travis.yml +index 67677bdf06..0010da5784 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -1,4 +1,5 @@ + sudo: required ++dist: xenial + services: + - docker + diff --git a/SOURCES/0189-test-socket-util-Add-tests-for-receive_fd_iov-and-fr.patch b/SOURCES/0189-test-socket-util-Add-tests-for-receive_fd_iov-and-fr.patch new file mode 100644 index 0000000..1414f34 --- /dev/null +++ b/SOURCES/0189-test-socket-util-Add-tests-for-receive_fd_iov-and-fr.patch @@ -0,0 +1,262 @@ +From 8798fcef9052d2946637fa2d4376844fad6b5f8c Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 24 Jul 2018 20:15:55 -0700 +Subject: [PATCH] test-socket-util: Add tests for receive_fd_iov() and friends. + +Test it when sending an FD without any contents, or an FD and some contents, +or only contents and no FD (using a bare send().) + +Also fix the previous test which forked but was missing an _exit() at the +end of the child execution code. + +(cherry picked from commit 8a3386ab4fea9c4efa9c72e7c149cf510a46f03e) + +Resolves: #1683319 +--- + src/test/test-socket-util.c | 215 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 215 insertions(+) + +diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c +index 588485d881..19c5395b92 100644 +--- a/src/test/test-socket-util.c ++++ b/src/test/test-socket-util.c +@@ -6,8 +6,11 @@ + + #include "alloc-util.h" + #include "async.h" ++#include "exit-status.h" + #include "fd-util.h" ++#include "fileio.h" + #include "in-addr-util.h" ++#include "io-util.h" + #include "log.h" + #include "macro.h" + #include "process-util.h" +@@ -484,9 +487,215 @@ static void test_getpeercred_getpeergroups(void) { + } + + safe_close_pair(pair); ++ _exit(EXIT_SUCCESS); + } + } + ++static void test_passfd_read(void) { ++ static const char file_contents[] = "test contents for passfd"; ++ _cleanup_close_pair_ int pair[2] = { -1, -1 }; ++ int r; ++ ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); ++ ++ r = safe_fork("(passfd_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); ++ assert_se(r >= 0); ++ ++ if (r == 0) { ++ /* Child */ ++ char tmpfile[] = "/tmp/test-socket-util-passfd-read-XXXXXX"; ++ _cleanup_close_ int tmpfd = -1; ++ ++ pair[0] = safe_close(pair[0]); ++ ++ tmpfd = mkostemp_safe(tmpfile); ++ assert_se(tmpfd >= 0); ++ assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents)); ++ tmpfd = safe_close(tmpfd); ++ ++ tmpfd = open(tmpfile, O_RDONLY); ++ assert_se(tmpfd >= 0); ++ assert_se(unlink(tmpfile) == 0); ++ ++ assert_se(send_one_fd(pair[1], tmpfd, MSG_DONTWAIT) == 0); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ /* Parent */ ++ char buf[64]; ++ struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1); ++ _cleanup_close_ int fd = -1; ++ ++ pair[1] = safe_close(pair[1]); ++ ++ assert_se(receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd) == 0); ++ ++ assert_se(fd >= 0); ++ r = read(fd, buf, sizeof(buf)-1); ++ assert_se(r >= 0); ++ buf[r] = 0; ++ assert_se(streq(buf, file_contents)); ++} ++ ++static void test_passfd_contents_read(void) { ++ _cleanup_close_pair_ int pair[2] = { -1, -1 }; ++ static const char file_contents[] = "test contents in the file"; ++ static const char wire_contents[] = "test contents on the wire"; ++ int r; ++ ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); ++ ++ r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); ++ assert_se(r >= 0); ++ ++ if (r == 0) { ++ /* Child */ ++ struct iovec iov = IOVEC_INIT_STRING(wire_contents); ++ char tmpfile[] = "/tmp/test-socket-util-passfd-contents-read-XXXXXX"; ++ _cleanup_close_ int tmpfd = -1; ++ ++ pair[0] = safe_close(pair[0]); ++ ++ tmpfd = mkostemp_safe(tmpfile); ++ assert_se(tmpfd >= 0); ++ assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents)); ++ tmpfd = safe_close(tmpfd); ++ ++ tmpfd = open(tmpfile, O_RDONLY); ++ assert_se(tmpfd >= 0); ++ assert_se(unlink(tmpfile) == 0); ++ ++ assert_se(send_one_fd_iov(pair[1], tmpfd, &iov, 1, MSG_DONTWAIT) > 0); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ /* Parent */ ++ char buf[64]; ++ struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1); ++ _cleanup_close_ int fd = -1; ++ ssize_t k; ++ ++ pair[1] = safe_close(pair[1]); ++ ++ k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd); ++ assert_se(k > 0); ++ buf[k] = 0; ++ assert_se(streq(buf, wire_contents)); ++ ++ assert_se(fd >= 0); ++ r = read(fd, buf, sizeof(buf)-1); ++ assert_se(r >= 0); ++ buf[r] = 0; ++ assert_se(streq(buf, file_contents)); ++} ++ ++static void test_receive_nopassfd(void) { ++ _cleanup_close_pair_ int pair[2] = { -1, -1 }; ++ static const char wire_contents[] = "no fd passed here"; ++ int r; ++ ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); ++ ++ r = safe_fork("(receive_nopassfd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); ++ assert_se(r >= 0); ++ ++ if (r == 0) { ++ /* Child */ ++ struct iovec iov = IOVEC_INIT_STRING(wire_contents); ++ ++ pair[0] = safe_close(pair[0]); ++ ++ assert_se(send_one_fd_iov(pair[1], -1, &iov, 1, MSG_DONTWAIT) > 0); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ /* Parent */ ++ char buf[64]; ++ struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1); ++ int fd = -999; ++ ssize_t k; ++ ++ pair[1] = safe_close(pair[1]); ++ ++ k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd); ++ assert_se(k > 0); ++ buf[k] = 0; ++ assert_se(streq(buf, wire_contents)); ++ ++ /* no fd passed here, confirm it was reset */ ++ assert_se(fd == -1); ++} ++ ++static void test_send_nodata_nofd(void) { ++ _cleanup_close_pair_ int pair[2] = { -1, -1 }; ++ int r; ++ ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); ++ ++ r = safe_fork("(send_nodata_nofd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); ++ assert_se(r >= 0); ++ ++ if (r == 0) { ++ /* Child */ ++ pair[0] = safe_close(pair[0]); ++ ++ assert_se(send_one_fd_iov(pair[1], -1, NULL, 0, MSG_DONTWAIT) == -EINVAL); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ /* Parent */ ++ char buf[64]; ++ struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1); ++ int fd = -999; ++ ssize_t k; ++ ++ pair[1] = safe_close(pair[1]); ++ ++ k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd); ++ /* recvmsg() will return errno EAGAIN if nothing was sent */ ++ assert_se(k == -EAGAIN); ++ ++ /* receive_one_fd_iov returned error, so confirm &fd wasn't touched */ ++ assert_se(fd == -999); ++} ++ ++static void test_send_emptydata(void) { ++ _cleanup_close_pair_ int pair[2] = { -1, -1 }; ++ int r; ++ ++ assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); ++ ++ r = safe_fork("(send_emptydata)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL); ++ assert_se(r >= 0); ++ ++ if (r == 0) { ++ /* Child */ ++ struct iovec iov = IOVEC_INIT_STRING(""); /* zero-length iov */ ++ assert_se(iov.iov_len == 0); ++ ++ pair[0] = safe_close(pair[0]); ++ ++ /* This will succeed, since iov is set. */ ++ assert_se(send_one_fd_iov(pair[1], -1, &iov, 1, MSG_DONTWAIT) == 0); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ /* Parent */ ++ char buf[64]; ++ struct iovec iov = IOVEC_INIT(buf, sizeof(buf)-1); ++ int fd = -999; ++ ssize_t k; ++ ++ pair[1] = safe_close(pair[1]); ++ ++ k = receive_one_fd_iov(pair[0], &iov, 1, MSG_DONTWAIT, &fd); ++ /* receive_one_fd_iov() returns -EIO if an fd is not found and no data was returned. */ ++ assert_se(k == -EIO); ++ ++ /* receive_one_fd_iov returned error, so confirm &fd wasn't touched */ ++ assert_se(fd == -999); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -515,5 +724,11 @@ int main(int argc, char *argv[]) { + + test_getpeercred_getpeergroups(); + ++ test_passfd_read(); ++ test_passfd_contents_read(); ++ test_receive_nopassfd(); ++ test_send_nodata_nofd(); ++ test_send_emptydata(); ++ + return 0; + } diff --git a/SOURCES/0190-socket-util-Introduce-send_one_fd_iov-and-receive_on.patch b/SOURCES/0190-socket-util-Introduce-send_one_fd_iov-and-receive_on.patch new file mode 100644 index 0000000..5225b97 --- /dev/null +++ b/SOURCES/0190-socket-util-Introduce-send_one_fd_iov-and-receive_on.patch @@ -0,0 +1,289 @@ +From bc7c550c444210aa8decf98ac0c1dcd051fcc532 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 24 Jul 2018 18:46:01 -0700 +Subject: [PATCH] socket-util: Introduce send_one_fd_iov() and + receive_one_fd_iov() + +These take a struct iovec to send data together with the passed FD. + +The receive function returns the FD through an output argument. In case data is +received, but no FD is passed, the receive function will set the output +argument to -1 explicitly. + +Update code in dynamic-user to use the new helpers. + +(cherry picked from commit d34673ecb825aa9ecf6958b0caab792f5061c56a) + +Resolves: #1683319 +--- + src/basic/socket-util.c | 97 ++++++++++++++++++++++++++++++++--------- + src/basic/socket-util.h | 10 ++++- + src/core/dynamic-user.c | 57 ++---------------------- + 3 files changed, 90 insertions(+), 74 deletions(-) + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index 3f90a81d35..986bc6e67f 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -1011,9 +1011,10 @@ int getpeergroups(int fd, gid_t **ret) { + return (int) n; + } + +-int send_one_fd_sa( ++ssize_t send_one_fd_iov_sa( + int transport_fd, + int fd, ++ struct iovec *iov, size_t iovlen, + const struct sockaddr *sa, socklen_t len, + int flags) { + +@@ -1024,28 +1025,58 @@ int send_one_fd_sa( + struct msghdr mh = { + .msg_name = (struct sockaddr*) sa, + .msg_namelen = len, +- .msg_control = &control, +- .msg_controllen = sizeof(control), ++ .msg_iov = iov, ++ .msg_iovlen = iovlen, + }; +- struct cmsghdr *cmsg; ++ ssize_t k; + + assert(transport_fd >= 0); +- assert(fd >= 0); + +- cmsg = CMSG_FIRSTHDR(&mh); +- cmsg->cmsg_level = SOL_SOCKET; +- cmsg->cmsg_type = SCM_RIGHTS; +- cmsg->cmsg_len = CMSG_LEN(sizeof(int)); +- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); ++ /* ++ * We need either an FD or data to send. ++ * If there's nothing, return an error. ++ */ ++ if (fd < 0 && !iov) ++ return -EINVAL; + +- mh.msg_controllen = CMSG_SPACE(sizeof(int)); +- if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0) +- return -errno; ++ if (fd >= 0) { ++ struct cmsghdr *cmsg; + +- return 0; ++ mh.msg_control = &control; ++ mh.msg_controllen = sizeof(control); ++ ++ cmsg = CMSG_FIRSTHDR(&mh); ++ cmsg->cmsg_level = SOL_SOCKET; ++ cmsg->cmsg_type = SCM_RIGHTS; ++ cmsg->cmsg_len = CMSG_LEN(sizeof(int)); ++ memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); ++ ++ mh.msg_controllen = CMSG_SPACE(sizeof(int)); ++ } ++ k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags); ++ if (k < 0) ++ return (ssize_t) -errno; ++ ++ return k; + } + +-int receive_one_fd(int transport_fd, int flags) { ++int send_one_fd_sa( ++ int transport_fd, ++ int fd, ++ const struct sockaddr *sa, socklen_t len, ++ int flags) { ++ ++ assert(fd >= 0); ++ ++ return (int) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, sa, len, flags); ++} ++ ++ssize_t receive_one_fd_iov( ++ int transport_fd, ++ struct iovec *iov, size_t iovlen, ++ int flags, ++ int *ret_fd) { ++ + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; +@@ -1053,10 +1084,14 @@ int receive_one_fd(int transport_fd, int flags) { + struct msghdr mh = { + .msg_control = &control, + .msg_controllen = sizeof(control), ++ .msg_iov = iov, ++ .msg_iovlen = iovlen, + }; + struct cmsghdr *cmsg, *found = NULL; ++ ssize_t k; + + assert(transport_fd >= 0); ++ assert(ret_fd); + + /* + * Receive a single FD via @transport_fd. We don't care for +@@ -1066,8 +1101,9 @@ int receive_one_fd(int transport_fd, int flags) { + * combination with send_one_fd(). + */ + +- if (recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags) < 0) +- return -errno; ++ k = recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags); ++ if (k < 0) ++ return (ssize_t) -errno; + + CMSG_FOREACH(cmsg, &mh) { + if (cmsg->cmsg_level == SOL_SOCKET && +@@ -1079,12 +1115,33 @@ int receive_one_fd(int transport_fd, int flags) { + } + } + +- if (!found) { ++ if (!found) + cmsg_close_all(&mh); ++ ++ /* If didn't receive an FD or any data, return an error. */ ++ if (k == 0 && !found) + return -EIO; +- } + +- return *(int*) CMSG_DATA(found); ++ if (found) ++ *ret_fd = *(int*) CMSG_DATA(found); ++ else ++ *ret_fd = -1; ++ ++ return k; ++} ++ ++int receive_one_fd(int transport_fd, int flags) { ++ int fd; ++ ssize_t k; ++ ++ k = receive_one_fd_iov(transport_fd, NULL, 0, flags, &fd); ++ if (k == 0) ++ return fd; ++ ++ /* k must be negative, since receive_one_fd_iov() only returns ++ * a positive value if data was received through the iov. */ ++ assert(k < 0); ++ return (int) k; + } + + ssize_t next_datagram_size_fd(int fd) { +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 8e23cf2dbd..82781a0de1 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -130,11 +130,19 @@ int getpeercred(int fd, struct ucred *ucred); + int getpeersec(int fd, char **ret); + int getpeergroups(int fd, gid_t **ret); + ++ssize_t send_one_fd_iov_sa( ++ int transport_fd, ++ int fd, ++ struct iovec *iov, size_t iovlen, ++ const struct sockaddr *sa, socklen_t len, ++ int flags); + int send_one_fd_sa(int transport_fd, + int fd, + const struct sockaddr *sa, socklen_t len, + int flags); +-#define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags) ++#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags) ++#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags) ++ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd); + int receive_one_fd(int transport_fd, int flags); + + ssize_t next_datagram_size_fd(int fd); +diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c +index 7c5111ddf6..021fd93a76 100644 +--- a/src/core/dynamic-user.c ++++ b/src/core/dynamic-user.c +@@ -312,20 +312,8 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) { + static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) { + uid_t uid = UID_INVALID; + struct iovec iov = IOVEC_INIT(&uid, sizeof(uid)); +- union { +- struct cmsghdr cmsghdr; +- uint8_t buf[CMSG_SPACE(sizeof(int))]; +- } control = {}; +- struct msghdr mh = { +- .msg_control = &control, +- .msg_controllen = sizeof(control), +- .msg_iov = &iov, +- .msg_iovlen = 1, +- }; +- struct cmsghdr *cmsg; +- ++ int lock_fd; + ssize_t k; +- int lock_fd = -1; + + assert(d); + assert(ret_uid); +@@ -334,15 +322,9 @@ static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) { + /* Read the UID and lock fd that is stored in the storage AF_UNIX socket. This should be called with the lock + * on the socket taken. */ + +- k = recvmsg(d->storage_socket[0], &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); ++ k = receive_one_fd_iov(d->storage_socket[0], &iov, 1, MSG_DONTWAIT, &lock_fd); + if (k < 0) +- return -errno; +- +- cmsg = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int))); +- if (cmsg) +- lock_fd = *(int*) CMSG_DATA(cmsg); +- else +- cmsg_close_all(&mh); /* just in case... */ ++ return (int) k; + + *ret_uid = uid; + *ret_lock_fd = lock_fd; +@@ -352,42 +334,11 @@ static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) { + + static int dynamic_user_push(DynamicUser *d, uid_t uid, int lock_fd) { + struct iovec iov = IOVEC_INIT(&uid, sizeof(uid)); +- union { +- struct cmsghdr cmsghdr; +- uint8_t buf[CMSG_SPACE(sizeof(int))]; +- } control = {}; +- struct msghdr mh = { +- .msg_control = &control, +- .msg_controllen = sizeof(control), +- .msg_iov = &iov, +- .msg_iovlen = 1, +- }; +- ssize_t k; + + assert(d); + + /* Store the UID and lock_fd in the storage socket. This should be called with the socket pair lock taken. */ +- +- if (lock_fd >= 0) { +- struct cmsghdr *cmsg; +- +- cmsg = CMSG_FIRSTHDR(&mh); +- cmsg->cmsg_level = SOL_SOCKET; +- cmsg->cmsg_type = SCM_RIGHTS; +- cmsg->cmsg_len = CMSG_LEN(sizeof(int)); +- memcpy(CMSG_DATA(cmsg), &lock_fd, sizeof(int)); +- +- mh.msg_controllen = CMSG_SPACE(sizeof(int)); +- } else { +- mh.msg_control = NULL; +- mh.msg_controllen = 0; +- } +- +- k = sendmsg(d->storage_socket[1], &mh, MSG_DONTWAIT|MSG_NOSIGNAL); +- if (k < 0) +- return -errno; +- +- return 0; ++ return send_one_fd_iov(d->storage_socket[1], lock_fd, &iov, 1, MSG_DONTWAIT); + } + + static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) { diff --git a/SOURCES/0191-core-swap-order-of-n_storage_fds-and-n_socket_fds-pa.patch b/SOURCES/0191-core-swap-order-of-n_storage_fds-and-n_socket_fds-pa.patch new file mode 100644 index 0000000..bd21f12 --- /dev/null +++ b/SOURCES/0191-core-swap-order-of-n_storage_fds-and-n_socket_fds-pa.patch @@ -0,0 +1,184 @@ +From 5e75fbf0ccc427fbe5151ab2096f75dcad5b00e7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jul 2018 09:56:54 +0200 +Subject: [PATCH] core: swap order of "n_storage_fds" and "n_socket_fds" + parameters + +When process fd lists to pass to activated programs we always place the +socket activation fds first, and the storage fds last. Irritatingly in +almost all calls the "n_storage_fds" parameter (i.e. the number of +storage fds to pass) came first so far, and the "n_socket_fds" parameter +second. Let's clean this up, and specify the number of fds in the order +the fds themselves are passed. + +(Also, let's fix one more case where "unsigned" was used to size an +array, while we should use "size_t" instead.) + +(cherry picked from commit 25b583d7ffd699384435eba8e49f6ce927a83af0) + +Resolves: #1683334 +--- + src/core/execute.c | 14 +++++++------- + src/core/execute.h | 2 +- + src/core/service.c | 25 ++++++++++++++----------- + 3 files changed, 22 insertions(+), 19 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index ffb92ddfc7..7476ac51da 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -147,11 +147,11 @@ static int shift_fds(int fds[], size_t n_fds) { + return 0; + } + +-static int flags_fds(const int fds[], size_t n_storage_fds, size_t n_socket_fds, bool nonblock) { ++static int flags_fds(const int fds[], size_t n_socket_fds, size_t n_storage_fds, bool nonblock) { + size_t i, n_fds; + int r; + +- n_fds = n_storage_fds + n_socket_fds; ++ n_fds = n_socket_fds + n_storage_fds; + if (n_fds <= 0) + return 0; + +@@ -2718,8 +2718,8 @@ static int exec_child( + int socket_fd, + int named_iofds[3], + int *fds, +- size_t n_storage_fds, + size_t n_socket_fds, ++ size_t n_storage_fds, + char **files_env, + int user_lookup_fd, + int *exit_status) { +@@ -3171,7 +3171,7 @@ static int exec_child( + if (r >= 0) + r = shift_fds(fds, n_fds); + if (r >= 0) +- r = flags_fds(fds, n_storage_fds, n_socket_fds, context->non_blocking); ++ r = flags_fds(fds, n_socket_fds, n_storage_fds, context->non_blocking); + if (r < 0) { + *exit_status = EXIT_FDS; + return log_unit_error_errno(unit, r, "Failed to adjust passed file descriptors: %m"); +@@ -3449,7 +3449,7 @@ int exec_spawn(Unit *unit, + assert(context); + assert(ret); + assert(params); +- assert(params->fds || (params->n_storage_fds + params->n_socket_fds <= 0)); ++ assert(params->fds || (params->n_socket_fds + params->n_storage_fds <= 0)); + + if (context->std_input == EXEC_INPUT_SOCKET || + context->std_output == EXEC_OUTPUT_SOCKET || +@@ -3469,8 +3469,8 @@ int exec_spawn(Unit *unit, + } else { + socket_fd = -1; + fds = params->fds; +- n_storage_fds = params->n_storage_fds; + n_socket_fds = params->n_socket_fds; ++ n_storage_fds = params->n_storage_fds; + } + + r = exec_context_named_iofds(context, params, named_iofds); +@@ -3509,8 +3509,8 @@ int exec_spawn(Unit *unit, + socket_fd, + named_iofds, + fds, +- n_storage_fds, + n_socket_fds, ++ n_storage_fds, + files_env, + unit->manager->user_lookup_fds[1], + &exit_status); +diff --git a/src/core/execute.h b/src/core/execute.h +index 77ffe82323..49705e0d3a 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -296,8 +296,8 @@ struct ExecParameters { + + int *fds; + char **fd_names; +- size_t n_storage_fds; + size_t n_socket_fds; ++ size_t n_storage_fds; + + ExecFlags flags; + bool selinux_context_net:1; +diff --git a/src/core/service.c b/src/core/service.c +index db17221888..7f8ce1b998 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1178,21 +1178,23 @@ static int service_coldplug(Unit *u) { + return 0; + } + +-static int service_collect_fds(Service *s, +- int **fds, +- char ***fd_names, +- unsigned *n_storage_fds, +- unsigned *n_socket_fds) { ++static int service_collect_fds( ++ Service *s, ++ int **fds, ++ char ***fd_names, ++ size_t *n_socket_fds, ++ size_t *n_storage_fds) { + + _cleanup_strv_free_ char **rfd_names = NULL; + _cleanup_free_ int *rfds = NULL; +- unsigned rn_socket_fds = 0, rn_storage_fds = 0; ++ size_t rn_socket_fds = 0, rn_storage_fds = 0; + int r; + + assert(s); + assert(fds); + assert(fd_names); + assert(n_socket_fds); ++ assert(n_storage_fds); + + if (s->socket_fd >= 0) { + +@@ -1256,7 +1258,7 @@ static int service_collect_fds(Service *s, + + if (s->n_fd_store > 0) { + ServiceFDStore *fs; +- unsigned n_fds; ++ size_t n_fds; + char **nl; + int *t; + +@@ -1325,9 +1327,10 @@ static int service_spawn( + .stdin_fd = -1, + .stdout_fd = -1, + .stderr_fd = -1, ++ .exec_fd = -1, + }; + _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL; +- unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0; ++ size_t n_socket_fds = 0, n_storage_fds = 0, n_env = 0; + _cleanup_free_ int *fds = NULL; + pid_t pid; + int r; +@@ -1353,11 +1356,11 @@ static int service_spawn( + s->exec_context.std_output == EXEC_OUTPUT_SOCKET || + s->exec_context.std_error == EXEC_OUTPUT_SOCKET) { + +- r = service_collect_fds(s, &fds, &fd_names, &n_storage_fds, &n_socket_fds); ++ r = service_collect_fds(s, &fds, &fd_names, &n_socket_fds, &n_storage_fds); + if (r < 0) + return r; + +- log_unit_debug(UNIT(s), "Passing %i fds to service", n_storage_fds + n_socket_fds); ++ log_unit_debug(UNIT(s), "Passing %zu fds to service", n_socket_fds + n_storage_fds); + } + + r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), timeout)); +@@ -1450,8 +1453,8 @@ static int service_spawn( + exec_params.environment = final_env; + exec_params.fds = fds; + exec_params.fd_names = fd_names; +- exec_params.n_storage_fds = n_storage_fds; + exec_params.n_socket_fds = n_socket_fds; ++ exec_params.n_storage_fds = n_storage_fds; + exec_params.watchdog_usec = s->watchdog_usec; + exec_params.selinux_context_net = s->socket_fd_selinux_context_net; + if (s->type == SERVICE_IDLE) diff --git a/SOURCES/0192-execute-use-our-usual-syntax-for-defining-bit-masks.patch b/SOURCES/0192-execute-use-our-usual-syntax-for-defining-bit-masks.patch new file mode 100644 index 0000000..325203d --- /dev/null +++ b/SOURCES/0192-execute-use-our-usual-syntax-for-defining-bit-masks.patch @@ -0,0 +1,31 @@ +From 8c937623864721345a5789d664775416723b6614 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 5 Jul 2018 10:00:52 +0200 +Subject: [PATCH] execute: use our usual syntax for defining bit masks + +(cherry picked from commit ce0d60a7c4e07c5bdfed9f076bd48752287f0777) + +Resolves: #1683334 +--- + src/core/execute.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/core/execute.h b/src/core/execute.h +index 49705e0d3a..f24dbf581a 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -85,10 +85,10 @@ struct ExecStatus { + }; + + typedef enum ExecCommandFlags { +- EXEC_COMMAND_IGNORE_FAILURE = 1, +- EXEC_COMMAND_FULLY_PRIVILEGED = 2, +- EXEC_COMMAND_NO_SETUID = 4, +- EXEC_COMMAND_AMBIENT_MAGIC = 8, ++ EXEC_COMMAND_IGNORE_FAILURE = 1 << 0, ++ EXEC_COMMAND_FULLY_PRIVILEGED = 1 << 1, ++ EXEC_COMMAND_NO_SETUID = 1 << 2, ++ EXEC_COMMAND_AMBIENT_MAGIC = 1 << 3, + } ExecCommandFlags; + + struct ExecCommand { diff --git a/SOURCES/0193-core-introduce-new-Type-exec-service-type.patch b/SOURCES/0193-core-introduce-new-Type-exec-service-type.patch new file mode 100644 index 0000000..866af38 --- /dev/null +++ b/SOURCES/0193-core-introduce-new-Type-exec-service-type.patch @@ -0,0 +1,572 @@ +From c7861c541e49e0bf3678d9f3c9093ee819ed436a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jul 2018 11:47:14 +0200 +Subject: [PATCH] core: introduce new Type=exec service type + +Users are often surprised that "systemd-run" command lines like +"systemd-run -p User=idontexist /bin/true" will return successfully, +even though the logs show that the process couldn't be invoked, as the +user "idontexist" doesn't exist. This is because Type=simple will only +wait until fork() succeeded before returning start-up success. + +This patch adds a new service type Type=exec, which is very similar to +Type=simple, but waits until the child process completed the execve() +before returning success. It uses a pipe that has O_CLOEXEC set for this +logic, so that the kernel automatically sends POLLHUP on it when the +execve() succeeded but leaves the pipe open if not. This means PID 1 +waits exactly until the execve() succeeded in the child, and not longer +and not shorter, which is the desired functionality. + +Making use of this new functionality, the command line +"systemd-run -p User=idontexist -p Type=exec /bin/true" will now fail, +as expected. + +(cherry picked from commit 5686391b006ee82d8a4559067ad9818e3e631247) + +Resolves: #1683334 +--- + src/core/execute.c | 89 +++++++++++++++++++++--- + src/core/execute.h | 3 + + src/core/mount.c | 9 +-- + src/core/service.c | 167 ++++++++++++++++++++++++++++++++++++++++++--- + src/core/service.h | 4 ++ + src/core/socket.c | 9 +-- + src/core/swap.c | 1 + + 7 files changed, 254 insertions(+), 28 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 7476ac51da..c62f3cf849 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2566,6 +2566,7 @@ static int close_remaining_fds( + const DynamicCreds *dcreds, + int user_lookup_fd, + int socket_fd, ++ int exec_fd, + int *fds, size_t n_fds) { + + size_t n_dont_close = 0; +@@ -2582,6 +2583,8 @@ static int close_remaining_fds( + + if (socket_fd >= 0) + dont_close[n_dont_close++] = socket_fd; ++ if (exec_fd >= 0) ++ dont_close[n_dont_close++] = exec_fd; + if (n_fds > 0) { + memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds); + n_dont_close += n_fds; +@@ -2725,9 +2728,10 @@ static int exec_child( + int *exit_status) { + + _cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL; +- _cleanup_free_ char *home_buffer = NULL; ++ int *fds_with_exec_fd, n_fds_with_exec_fd, r, ngids = 0, exec_fd = -1; + _cleanup_free_ gid_t *supplementary_gids = NULL; + const char *username = NULL, *groupname = NULL; ++ _cleanup_free_ char *home_buffer = NULL; + const char *home = NULL, *shell = NULL; + dev_t journal_stream_dev = 0; + ino_t journal_stream_ino = 0; +@@ -2747,7 +2751,6 @@ static int exec_child( + #endif + uid_t uid = UID_INVALID; + gid_t gid = GID_INVALID; +- int r, ngids = 0; + size_t n_fds; + ExecDirectoryType dt; + int secure_bits; +@@ -2791,8 +2794,8 @@ static int exec_child( + /* In case anything used libc syslog(), close this here, too */ + closelog(); + +- n_fds = n_storage_fds + n_socket_fds; +- r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, fds, n_fds); ++ n_fds = n_socket_fds + n_storage_fds; ++ r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, params->exec_fd, fds, n_fds); + if (r < 0) { + *exit_status = EXIT_FDS; + return log_unit_error_errno(unit, r, "Failed to close unwanted file descriptors: %m"); +@@ -3165,9 +3168,45 @@ static int exec_child( + } + + /* We repeat the fd closing here, to make sure that nothing is leaked from the PAM modules. Note that we are +- * more aggressive this time since socket_fd and the netns fds we don't need anymore. The custom endpoint fd +- * was needed to upload the policy and can now be closed as well. */ +- r = close_all_fds(fds, n_fds); ++ * more aggressive this time since socket_fd and the netns fds we don't need anymore. We do keep the exec_fd ++ * however if we have it as we want to keep it open until the final execve(). */ ++ ++ if (params->exec_fd >= 0) { ++ exec_fd = params->exec_fd; ++ ++ if (exec_fd < 3 + (int) n_fds) { ++ int moved_fd; ++ ++ /* Let's move the exec fd far up, so that it's outside of the fd range we want to pass to the ++ * process we are about to execute. */ ++ ++ moved_fd = fcntl(exec_fd, F_DUPFD_CLOEXEC, 3 + (int) n_fds); ++ if (moved_fd < 0) { ++ *exit_status = EXIT_FDS; ++ return log_unit_error_errno(unit, errno, "Couldn't move exec fd up: %m"); ++ } ++ ++ safe_close(exec_fd); ++ exec_fd = moved_fd; ++ } else { ++ /* This fd should be FD_CLOEXEC already, but let's make sure. */ ++ r = fd_cloexec(exec_fd, true); ++ if (r < 0) { ++ *exit_status = EXIT_FDS; ++ return log_unit_error_errno(unit, r, "Failed to make exec fd FD_CLOEXEC: %m"); ++ } ++ } ++ ++ fds_with_exec_fd = newa(int, n_fds + 1); ++ memcpy(fds_with_exec_fd, fds, n_fds * sizeof(int)); ++ fds_with_exec_fd[n_fds] = exec_fd; ++ n_fds_with_exec_fd = n_fds + 1; ++ } else { ++ fds_with_exec_fd = fds; ++ n_fds_with_exec_fd = n_fds; ++ } ++ ++ r = close_all_fds(fds_with_exec_fd, n_fds_with_exec_fd); + if (r >= 0) + r = shift_fds(fds, n_fds); + if (r >= 0) +@@ -3177,6 +3216,11 @@ static int exec_child( + return log_unit_error_errno(unit, r, "Failed to adjust passed file descriptors: %m"); + } + ++ /* At this point, the fds we want to pass to the program are all ready and set up, with O_CLOEXEC turned off ++ * and at the right fd numbers. The are no other fds open, with one exception: the exec_fd if it is defined, ++ * and it has O_CLOEXEC set, after all we want it to be closed by the execve(), so that our parent knows we ++ * came this far. */ ++ + secure_bits = context->secure_bits; + + if (needs_sandboxing) { +@@ -3407,10 +3451,35 @@ static int exec_child( + LOG_UNIT_INVOCATION_ID(unit)); + } + ++ if (exec_fd >= 0) { ++ uint8_t hot = 1; ++ ++ /* We have finished with all our initializations. Let's now let the manager know that. From this point ++ * on, if the manager sees POLLHUP on the exec_fd, then execve() was successful. */ ++ ++ if (write(exec_fd, &hot, sizeof(hot)) < 0) { ++ *exit_status = EXIT_EXEC; ++ return log_unit_error_errno(unit, errno, "Failed to enable exec_fd: %m"); ++ } ++ } ++ + execve(command->path, final_argv, accum_env); ++ r = -errno; ++ ++ if (exec_fd >= 0) { ++ uint8_t hot = 0; ++ ++ /* The execve() failed. This means the exec_fd is still open. Which means we need to tell the manager ++ * that POLLHUP on it no longer means execve() succeeded. */ ++ ++ if (write(exec_fd, &hot, sizeof(hot)) < 0) { ++ *exit_status = EXIT_EXEC; ++ return log_unit_error_errno(unit, errno, "Failed to disable exec_fd: %m"); ++ } ++ } + +- if (errno == ENOENT && (command->flags & EXEC_COMMAND_IGNORE_FAILURE)) { +- log_struct_errno(LOG_INFO, errno, ++ if (r == -ENOENT && (command->flags & EXEC_COMMAND_IGNORE_FAILURE)) { ++ log_struct_errno(LOG_INFO, r, + "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR, + LOG_UNIT_ID(unit), + LOG_UNIT_INVOCATION_ID(unit), +@@ -3421,7 +3490,7 @@ static int exec_child( + } + + *exit_status = EXIT_EXEC; +- return log_unit_error_errno(unit, errno, "Failed to execute command: %m"); ++ return log_unit_error_errno(unit, r, "Failed to execute command: %m"); + } + + static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***l); +diff --git a/src/core/execute.h b/src/core/execute.h +index f24dbf581a..bff1634b88 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -316,6 +316,9 @@ struct ExecParameters { + int stdin_fd; + int stdout_fd; + int stderr_fd; ++ ++ /* An fd that is closed by the execve(), and thus will result in EOF when the execve() is done */ ++ int exec_fd; + }; + + #include "unit.h" +diff --git a/src/core/mount.c b/src/core/mount.c +index 21437dad08..16229d4af1 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -747,10 +747,11 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) { + static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + + ExecParameters exec_params = { +- .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, +- .stdin_fd = -1, +- .stdout_fd = -1, +- .stderr_fd = -1, ++ .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, ++ .stdin_fd = -1, ++ .stdout_fd = -1, ++ .stderr_fd = -1, ++ .exec_fd = -1, + }; + pid_t pid; + int r; +diff --git a/src/core/service.c b/src/core/service.c +index 7f8ce1b998..3eab749362 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -79,9 +79,10 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = + [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING + }; + +-static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events, void *userdata); ++static int service_dispatch_inotify_io(sd_event_source *source, int fd, uint32_t events, void *userdata); + static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); + static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata); ++static int service_dispatch_exec_io(sd_event_source *source, int fd, uint32_t events, void *userdata); + + static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); + static void service_enter_reload_by_notify(Service *s); +@@ -389,6 +390,7 @@ static void service_done(Unit *u) { + service_stop_watchdog(s); + + s->timer_event_source = sd_event_source_unref(s->timer_event_source); ++ s->exec_fd_event_source = sd_event_source_unref(s->exec_fd_event_source); + + service_release_resources(u); + } +@@ -1066,6 +1068,9 @@ static void service_set_state(Service *s, ServiceState state) { + !(state == SERVICE_DEAD && UNIT(s)->job)) + service_close_socket_fd(s); + ++ if (state != SERVICE_START) ++ s->exec_fd_event_source = sd_event_source_unref(s->exec_fd_event_source); ++ + if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) + service_stop_watchdog(s); + +@@ -1296,6 +1301,63 @@ static int service_collect_fds( + return 0; + } + ++static int service_allocate_exec_fd_event_source( ++ Service *s, ++ int fd, ++ sd_event_source **ret_event_source) { ++ ++ _cleanup_(sd_event_source_unrefp) sd_event_source *source = NULL; ++ int r; ++ ++ assert(s); ++ assert(fd >= 0); ++ assert(ret_event_source); ++ ++ r = sd_event_add_io(UNIT(s)->manager->event, &source, fd, 0, service_dispatch_exec_io, s); ++ if (r < 0) ++ return log_unit_error_errno(UNIT(s), r, "Failed to allocate exec_fd event source: %m"); ++ ++ /* This is a bit lower priority than SIGCHLD, as that carries a lot more interesting failure information */ ++ ++ r = sd_event_source_set_priority(source, SD_EVENT_PRIORITY_NORMAL-3); ++ if (r < 0) ++ return log_unit_error_errno(UNIT(s), r, "Failed to adjust priority of exec_fd event source: %m"); ++ ++ (void) sd_event_source_set_description(source, "service event_fd"); ++ ++ r = sd_event_source_set_io_fd_own(source, true); ++ if (r < 0) ++ return log_unit_error_errno(UNIT(s), r, "Failed to pass ownership of fd to event source: %m"); ++ ++ *ret_event_source = TAKE_PTR(source); ++ return 0; ++} ++ ++static int service_allocate_exec_fd( ++ Service *s, ++ sd_event_source **ret_event_source, ++ int* ret_exec_fd) { ++ ++ _cleanup_close_pair_ int p[2] = { -1, -1 }; ++ int r; ++ ++ assert(s); ++ assert(ret_event_source); ++ assert(ret_exec_fd); ++ ++ if (pipe2(p, O_CLOEXEC|O_NONBLOCK) < 0) ++ return log_unit_error_errno(UNIT(s), errno, "Failed to allocate exec_fd pipe: %m"); ++ ++ r = service_allocate_exec_fd_event_source(s, p[0], ret_event_source); ++ if (r < 0) ++ return r; ++ ++ p[0] = -1; ++ *ret_exec_fd = TAKE_FD(p[1]); ++ ++ return 0; ++} ++ + static bool service_exec_needs_notify_socket(Service *s, ExecFlags flags) { + assert(s); + +@@ -1330,7 +1392,9 @@ static int service_spawn( + .exec_fd = -1, + }; + _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL; ++ _cleanup_(sd_event_source_unrefp) sd_event_source *exec_fd_source = NULL; + size_t n_socket_fds = 0, n_storage_fds = 0, n_env = 0; ++ _cleanup_close_ int exec_fd = -1; + _cleanup_free_ int *fds = NULL; + pid_t pid; + int r; +@@ -1363,6 +1427,14 @@ static int service_spawn( + log_unit_debug(UNIT(s), "Passing %zu fds to service", n_socket_fds + n_storage_fds); + } + ++ if (!FLAGS_SET(flags, EXEC_IS_CONTROL) && s->type == SERVICE_EXEC) { ++ assert(!s->exec_fd_event_source); ++ ++ r = service_allocate_exec_fd(s, &exec_fd_source, &exec_fd); ++ if (r < 0) ++ return r; ++ } ++ + r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), timeout)); + if (r < 0) + return r; +@@ -1462,6 +1534,7 @@ static int service_spawn( + exec_params.stdin_fd = s->stdin_fd; + exec_params.stdout_fd = s->stdout_fd; + exec_params.stderr_fd = s->stderr_fd; ++ exec_params.exec_fd = exec_fd; + + r = exec_spawn(UNIT(s), + c, +@@ -1473,6 +1546,9 @@ static int service_spawn( + if (r < 0) + return r; + ++ s->exec_fd_event_source = TAKE_PTR(exec_fd_source); ++ s->exec_fd_hot = false; ++ + r = unit_watch_pid(UNIT(s), pid); + if (r < 0) /* FIXME: we need to do something here */ + return r; +@@ -1984,14 +2060,12 @@ static void service_enter_start(Service *s) { + s->control_pid = pid; + service_set_state(s, SERVICE_START); + +- } else if (IN_SET(s->type, SERVICE_ONESHOT, SERVICE_DBUS, SERVICE_NOTIFY)) { ++ } else if (IN_SET(s->type, SERVICE_ONESHOT, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_EXEC)) { + +- /* For oneshot services we wait until the start +- * process exited, too, but it is our main process. */ ++ /* For oneshot services we wait until the start process exited, too, but it is our main process. */ + +- /* For D-Bus services we know the main pid right away, +- * but wait for the bus name to appear on the +- * bus. Notify services are similar. */ ++ /* For D-Bus services we know the main pid right away, but wait for the bus name to appear on the ++ * bus. 'notify' and 'exec' services are similar. */ + + service_set_main_pid(s, pid); + service_set_state(s, SERVICE_START); +@@ -2444,6 +2518,13 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { + if (r < 0) + return r; + ++ if (s->exec_fd_event_source) { ++ r = unit_serialize_item_fd(u, f, fds, "exec-fd", sd_event_source_get_io_fd(s->exec_fd_event_source)); ++ if (r < 0) ++ return r; ++ unit_serialize_item(u, f, "exec-fd-hot", yes_no(s->exec_fd_hot)); ++ } ++ + if (UNIT_ISSET(s->accept_socket)) { + r = unit_serialize_item(u, f, "accept-socket", UNIT_DEREF(s->accept_socket)->id); + if (r < 0) +@@ -2777,6 +2858,18 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, + s->stderr_fd = fdset_remove(fds, fd); + s->exec_context.stdio_as_fds = true; + } ++ } else if (streq(key, "exec-fd")) { ++ int fd; ++ ++ if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) ++ log_unit_debug(u, "Failed to parse exec-fd value: %s", value); ++ else { ++ s->exec_fd_event_source = sd_event_source_unref(s->exec_fd_event_source); ++ ++ fd = fdset_remove(fds, fd); ++ if (service_allocate_exec_fd_event_source(s, fd, &s->exec_fd_event_source) < 0) ++ safe_close(fd); ++ } + } else if (streq(key, "watchdog-override-usec")) { + usec_t watchdog_override_usec; + if (timestamp_deserialize(value, &watchdog_override_usec) < 0) +@@ -2860,7 +2953,7 @@ static int service_watch_pid_file(Service *s) { + + log_unit_debug(UNIT(s), "Setting watch for PID file %s", s->pid_file_pathspec->path); + +- r = path_spec_watch(s->pid_file_pathspec, service_dispatch_io); ++ r = path_spec_watch(s->pid_file_pathspec, service_dispatch_inotify_io); + if (r < 0) + goto fail; + +@@ -2904,7 +2997,7 @@ static int service_demand_pid_file(Service *s) { + return service_watch_pid_file(s); + } + +-static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events, void *userdata) { ++static int service_dispatch_inotify_io(sd_event_source *source, int fd, uint32_t events, void *userdata) { + PathSpec *p = userdata; + Service *s; + +@@ -2937,6 +3030,59 @@ fail: + return 0; + } + ++static int service_dispatch_exec_io(sd_event_source *source, int fd, uint32_t events, void *userdata) { ++ Service *s = SERVICE(userdata); ++ ++ assert(s); ++ ++ log_unit_debug(UNIT(s), "got exec-fd event"); ++ ++ /* If Type=exec is set, we'll consider a service started successfully the instant we invoked execve() ++ * successfully for it. We implement this through a pipe() towards the child, which the kernel automatically ++ * closes for us due to O_CLOEXEC on execve() in the child, which then triggers EOF on the pipe in the ++ * parent. We need to be careful however, as there are other reasons that we might cause the child's side of ++ * the pipe to be closed (for example, a simple exit()). To deal with that we'll ignore EOFs on the pipe unless ++ * the child signalled us first that it is about to call the execve(). It does so by sending us a simple ++ * non-zero byte via the pipe. We also provide the child with a way to inform us in case execve() failed: if it ++ * sends a zero byte we'll ignore POLLHUP on the fd again. */ ++ ++ for (;;) { ++ uint8_t x; ++ ssize_t n; ++ ++ n = read(fd, &x, sizeof(x)); ++ if (n < 0) { ++ if (errno == EAGAIN) /* O_NONBLOCK in effect → everything queued has now been processed. */ ++ return 0; ++ ++ return log_unit_error_errno(UNIT(s), errno, "Failed to read from exec_fd: %m"); ++ } ++ if (n == 0) { /* EOF → the event we are waiting for */ ++ ++ s->exec_fd_event_source = sd_event_source_unref(s->exec_fd_event_source); ++ ++ if (s->exec_fd_hot) { /* Did the child tell us to expect EOF now? */ ++ log_unit_debug(UNIT(s), "Got EOF on exec-fd"); ++ ++ s->exec_fd_hot = false; ++ ++ /* Nice! This is what we have been waiting for. Transition to next state. */ ++ if (s->type == SERVICE_EXEC && s->state == SERVICE_START) ++ service_enter_start_post(s); ++ } else ++ log_unit_debug(UNIT(s), "Got EOF on exec-fd while it was disabled, ignoring."); ++ ++ return 0; ++ } ++ ++ /* A byte was read → this turns on/off the exec fd logic */ ++ assert(n == sizeof(x)); ++ s->exec_fd_hot = x; ++ } ++ ++ return 0; ++} ++ + static void service_notify_cgroup_empty_event(Unit *u) { + Service *s = SERVICE(u); + +@@ -3850,7 +3996,8 @@ static const char* const service_type_table[_SERVICE_TYPE_MAX] = { + [SERVICE_ONESHOT] = "oneshot", + [SERVICE_DBUS] = "dbus", + [SERVICE_NOTIFY] = "notify", +- [SERVICE_IDLE] = "idle" ++ [SERVICE_IDLE] = "idle", ++ [SERVICE_EXEC] = "exec", + }; + + DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType); +diff --git a/src/core/service.h b/src/core/service.h +index a142b09f0d..1206e3cdda 100644 +--- a/src/core/service.h ++++ b/src/core/service.h +@@ -30,6 +30,7 @@ typedef enum ServiceType { + SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */ + SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */ + SERVICE_IDLE, /* much like simple, but delay exec() until all jobs are dispatched. */ ++ SERVICE_EXEC, /* we fork and wait until we execute exec() (this means our own setup is waited for) */ + _SERVICE_TYPE_MAX, + _SERVICE_TYPE_INVALID = -1 + } ServiceType; +@@ -165,6 +166,8 @@ struct Service { + NotifyAccess notify_access; + NotifyState notify_state; + ++ sd_event_source *exec_fd_event_source; ++ + ServiceFDStore *fd_store; + size_t n_fd_store; + unsigned n_fd_store_max; +@@ -179,6 +182,7 @@ struct Service { + + unsigned n_restarts; + bool flush_n_restarts; ++ bool exec_fd_hot; + }; + + extern const UnitVTable service_vtable; +diff --git a/src/core/socket.c b/src/core/socket.c +index 56d32225c4..d488c64e91 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1867,10 +1867,11 @@ static int socket_coldplug(Unit *u) { + static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + + ExecParameters exec_params = { +- .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, +- .stdin_fd = -1, +- .stdout_fd = -1, +- .stderr_fd = -1, ++ .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, ++ .stdin_fd = -1, ++ .stdout_fd = -1, ++ .stderr_fd = -1, ++ .exec_fd = -1, + }; + pid_t pid; + int r; +diff --git a/src/core/swap.c b/src/core/swap.c +index b78b1aa266..e01e61e56d 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -606,6 +606,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + .stdin_fd = -1, + .stdout_fd = -1, + .stderr_fd = -1, ++ .exec_fd = -1, + }; + pid_t pid; + int r; diff --git a/SOURCES/0194-man-document-the-new-Type-exec-type.patch b/SOURCES/0194-man-document-the-new-Type-exec-type.patch new file mode 100644 index 0000000..671277f --- /dev/null +++ b/SOURCES/0194-man-document-the-new-Type-exec-type.patch @@ -0,0 +1,207 @@ +From d77d5a9399e393734fe8c8a5ad085036775854a7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jul 2018 12:01:26 +0200 +Subject: [PATCH] man: document the new Type=exec type + +And while we are at it, let's rearrange and extend the Type= +documentation a bit. Let's make it an itemized list, and let's add a +paragraph explaining which type best to use. + +(cherry picked from commit 79905a246d645d21633f09f564b3672d5085a85c) + +Resolves: #1683334 +--- + man/systemd-run.xml | 10 +++ + man/systemd.service.xml | 158 ++++++++++++++++++++++------------------ + 2 files changed, 97 insertions(+), 71 deletions(-) + +diff --git a/man/systemd-run.xml b/man/systemd-run.xml +index 1c254afae3..a134b2c0dc 100644 +--- a/man/systemd-run.xml ++++ b/man/systemd-run.xml +@@ -83,6 +83,16 @@ + COMMAND may be omitted. In this case, systemd-run creates only a + .path, .socket, or .timer unit that triggers the + specified unit. ++ ++ By default, services created with systemd-run default to the type, ++ see the description of Type= in ++ systemd.service5 for ++ details. Note that when this type is used the service manager (and thus the systemd-run command) ++ considers service start-up successful as soon as the fork() for the main service process ++ succeeded, i.e. before the execve() is invoked, and thus even if the specified command cannot ++ be started. Consider using the service type (i.e. ) to ++ ensure that systemd-run returns successfully only if the specified command line has been ++ successfully started. + + + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index add54524ce..315b80e704 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -153,77 +153,93 @@ + + Type= + +- Configures the process start-up type for this +- service unit. One of +- , +- , +- , +- , +- or +- . +- +- If set to (the default if +- neither Type= nor +- BusName=, but ExecStart= +- are specified), it is expected that the process configured +- with ExecStart= is the main process of the +- service. In this mode, if the process offers functionality to +- other processes on the system, its communication channels +- should be installed before the daemon is started up (e.g. +- sockets set up by systemd, via socket activation), as systemd +- will immediately proceed starting follow-up units. +- +- If set to , it is expected that +- the process configured with ExecStart= will +- call fork() as part of its start-up. The +- parent process is expected to exit when start-up is complete +- and all communication channels are set up. The child continues +- to run as the main daemon process. This is the behavior of +- traditional UNIX daemons. If this setting is used, it is +- recommended to also use the PIDFile= +- option, so that systemd can identify the main process of the +- daemon. systemd will proceed with starting follow-up units as +- soon as the parent process exits. +- +- Behavior of is similar to +- ; however, it is expected that the +- process has to exit before systemd starts follow-up units. +- RemainAfterExit= is particularly useful for +- this type of service. This is the implied default if neither +- Type= nor ExecStart= are +- specified. +- +- Behavior of is similar to +- ; however, it is expected that the +- daemon acquires a name on the D-Bus bus, as configured by +- BusName=. systemd will proceed with +- starting follow-up units after the D-Bus bus name has been +- acquired. Service units with this option configured implicitly +- gain dependencies on the dbus.socket +- unit. This type is the default if BusName= +- is specified. +- +- Behavior of is similar to +- ; however, it is expected that the +- daemon sends a notification message via +- sd_notify3 +- or an equivalent call when it has finished starting up. +- systemd will proceed with starting follow-up units after this +- notification message has been sent. If this option is used, +- NotifyAccess= (see below) should be set to +- open access to the notification socket provided by systemd. If +- NotifyAccess= is missing or set to +- , it will be forcibly set to +- . Note that currently +- Type= will not work +- if used in combination with +- PrivateNetwork=. +- +- Behavior of is very similar to ; however, actual execution +- of the service program is delayed until all active jobs are dispatched. This may be used to avoid interleaving +- of output of shell services with the status output on the console. Note that this type is useful only to +- improve console output, it is not useful as a general unit ordering tool, and the effect of this service type +- is subject to a 5s time-out, after which the service program is invoked anyway. ++ ++ Configures the process start-up type for this service unit. One of , ++ , , , , ++ or : ++ ++ ++ If set to (the default if ExecStart= is ++ specified but neither Type= nor BusName= are), the service manager ++ will consider the unit started immediately after the main service process has been forked off. It is ++ expected that the process configured with ExecStart= is the main process of the ++ service. In this mode, if the process offers functionality to other processes on the system, its ++ communication channels should be installed before the service is started up (e.g. sockets set up by ++ systemd, via socket activation), as the service manager will immediately proceed starting follow-up units, ++ right after creating the main service process, and before executing the service's binary. Note that this ++ means systemctl start command lines for services will report ++ success even if the service's binary cannot be invoked successfully (for example because the selected ++ User= doesn't exist, or the service binary is missing). ++ ++ The type is similar to , but the service ++ manager will consider the unit started immediately after the main service binary has been executed. The service ++ manager will delay starting of follow-up units until that point. (Or in other words: ++ proceeds with further jobs right after fork() returns, while ++ will not proceed before both fork() and ++ execve() in the service process succeeded.) Note that this means systemctl ++ start command lines for services will report failure when the service's ++ binary cannot be invoked successfully (for example because the selected User= doesn't ++ exist, or the service binary is missing). ++ ++ If set to , it is expected that the process configured with ++ ExecStart= will call fork() as part of its start-up. The parent ++ process is expected to exit when start-up is complete and all communication channels are set up. The child ++ continues to run as the main service process, and the service manager will consider the unit started when ++ the parent process exits. This is the behavior of traditional UNIX services. If this setting is used, it is ++ recommended to also use the PIDFile= option, so that systemd can reliably identify the ++ main process of the service. systemd will proceed with starting follow-up units as soon as the parent ++ process exits. ++ ++ Behavior of is similar to ; however, the ++ service manager will consider the unit started after the main process exits. It will then start follow-up ++ units. RemainAfterExit= is particularly useful for this type of ++ service. Type= is the implied default if neither ++ Type= nor ExecStart= are specified. ++ ++ Behavior of is similar to ; however, it is ++ expected that the service acquires a name on the D-Bus bus, as configured by ++ BusName=. systemd will proceed with starting follow-up units after the D-Bus bus name ++ has been acquired. Service units with this option configured implicitly gain dependencies on the ++ dbus.socket unit. This type is the default if BusName= is ++ specified. ++ ++ Behavior of is similar to ; however, it is ++ expected that the service sends a notification message via ++ sd_notify3 or an ++ equivalent call when it has finished starting up. systemd will proceed with starting follow-up units after ++ this notification message has been sent. If this option is used, NotifyAccess= (see ++ below) should be set to open access to the notification socket provided by systemd. If ++ NotifyAccess= is missing or set to , it will be forcibly set to ++ . Note that currently Type= will not work if ++ used in combination with PrivateNetwork=. ++ ++ Behavior of is very similar to ; however, ++ actual execution of the service program is delayed until all active jobs are dispatched. This may be used ++ to avoid interleaving of output of shell services with the status output on the console. Note that this ++ type is useful only to improve console output, it is not useful as a general unit ordering tool, and the ++ effect of this service type is subject to a 5s time-out, after which the service program is invoked ++ anyway. ++ ++ ++ It is generally recommended to use Type= for long-running ++ services whenever possible, as it is the simplest and fastest option. However, as this service type won't ++ propagate service start-up failures and doesn't allow ordering of other units against completion of ++ initialization of the service (which for example is useful if clients need to connect to the service through ++ some form of IPC, and the IPC channel is only established by the service itself — in contrast to doing this ++ ahead of time through socket or bus activation or similar), it might not be sufficient for many cases. If so, ++ or (the latter only in case the service provides a D-Bus ++ interface) are the preferred options as they allow service program code to precisely schedule when to ++ consider the service started up successfully and when to proceed with follow-up units. The ++ service type requires explicit support in the service codebase (as ++ sd_notify() or an equivalent API needs to be invoked by the service at the appropriate ++ time) — if it's not supported, then is an alternative: it supports the traditional ++ UNIX service start-up protocol. Finally, might be an option for cases where it is ++ enough to ensure the service binary is invoked, and where the service binary itself executes no or little ++ initialization on its own (and its initialization is unlikely to fail). Note that using any type other than ++ possibly delays the boot process, as the service manager needs to wait for service ++ initialization to complete. It is hence recommended not to needlessly use any types other than ++ . (Also note it is generally not recommended to use or ++ for long-running services.) + + + diff --git a/SOURCES/0195-sd-bus-allow-connecting-to-the-pseudo-container-.hos.patch b/SOURCES/0195-sd-bus-allow-connecting-to-the-pseudo-container-.hos.patch new file mode 100644 index 0000000..2bad492 --- /dev/null +++ b/SOURCES/0195-sd-bus-allow-connecting-to-the-pseudo-container-.hos.patch @@ -0,0 +1,57 @@ +From 6bf178a9a6e3fd6544d8e37a0082febf81c0ad2d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jul 2018 12:23:26 +0200 +Subject: [PATCH] sd-bus: allow connecting to the pseudo-container ".host" + +machined exposes the pseudo-container ".host" as a reference to the host +system, and this means "machinectl login .host" and "machinectl shell +.host" get your a login/shell on the host. systemd-run currently doesn't +allow that. Let's fix that, and make sd-bus understand ".host" as an +alias for connecting to the host system. + +(cherry picked from commit 1e5057b904473696ae0d591d7555233adcb51fa4) + +Resolves: #1683334 +--- + src/basic/util.c | 5 +++++ + src/libsystemd/sd-bus/sd-bus.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/basic/util.c b/src/basic/util.c +index 8f2d6061da..82cb937314 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -255,6 +255,11 @@ int container_get_leader(const char *machine, pid_t *pid) { + assert(machine); + assert(pid); + ++ if (streq(machine, ".host")) { ++ *pid = 1; ++ return 0; ++ } ++ + if (!machine_name_is_valid(machine)) + return -EINVAL; + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 7f03528b89..f53a98d6bf 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -952,7 +952,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) + return -EINVAL; + + if (machine) { +- if (!machine_name_is_valid(machine)) ++ if (!streq(machine, ".host") && !machine_name_is_valid(machine)) + return -EINVAL; + + free_and_replace(b->machine, machine); +@@ -1450,7 +1450,7 @@ _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) { + + assert_return(machine, -EINVAL); + assert_return(ret, -EINVAL); +- assert_return(machine_name_is_valid(machine), -EINVAL); ++ assert_return(streq(machine, ".host") || machine_name_is_valid(machine), -EINVAL); + + r = sd_bus_new(&b); + if (r < 0) diff --git a/SOURCES/0196-sd-login-let-s-also-make-sd-login-understand-.host.patch b/SOURCES/0196-sd-login-let-s-also-make-sd-login-understand-.host.patch new file mode 100644 index 0000000..08b90d7 --- /dev/null +++ b/SOURCES/0196-sd-login-let-s-also-make-sd-login-understand-.host.patch @@ -0,0 +1,56 @@ +From 1fd670e06332423a3e0b19ca717145c14e8418a1 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jul 2018 12:24:50 +0200 +Subject: [PATCH] sd-login: let's also make sd-login understand ".host" + +if sd-bus and machined grok it, then sd-login should grok it too. + +(cherry picked from commit a8c9b7a0fc0aa02666042543ff9a652aae3c9499) + +Resolves: #1683334 +--- + src/libsystemd/sd-login/sd-login.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c +index c2f7133e42..aeae6d78a9 100644 +--- a/src/libsystemd/sd-login/sd-login.c ++++ b/src/libsystemd/sd-login/sd-login.c +@@ -892,20 +892,27 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { + const char *p; + int r; + +- assert_return(machine_name_is_valid(machine), -EINVAL); + assert_return(class, -EINVAL); + +- p = strjoina("/run/systemd/machines/", machine); +- r = parse_env_file(NULL, p, NEWLINE, "CLASS", &c, NULL); +- if (r == -ENOENT) +- return -ENXIO; +- if (r < 0) +- return r; +- if (!c) +- return -EIO; ++ if (streq(machine, ".host")) { ++ c = strdup("host"); ++ if (!c) ++ return -ENOMEM; ++ } else { ++ if (!machine_name_is_valid(machine)) ++ return -EINVAL; + +- *class = TAKE_PTR(c); ++ p = strjoina("/run/systemd/machines/", machine); ++ r = parse_env_file(NULL, p, NEWLINE, "CLASS", &c, NULL); ++ if (r == -ENOENT) ++ return -ENXIO; ++ if (r < 0) ++ return r; ++ if (!c) ++ return -EIO; ++ } + ++ *class = TAKE_PTR(c); + return 0; + } + diff --git a/SOURCES/0197-test-add-test-for-Type-exec.patch b/SOURCES/0197-test-add-test-for-Type-exec.patch new file mode 100644 index 0000000..f1a2c90 --- /dev/null +++ b/SOURCES/0197-test-add-test-for-Type-exec.patch @@ -0,0 +1,109 @@ +From afb82e108fe45d8481f2be50c74c4c6f307f8d60 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 17 Jul 2018 12:35:12 +0200 +Subject: [PATCH] test: add test for Type=exec + +(cherry picked from commit 0e1f17561f5f6061ec5503de044298372ed7ca37) + +Resolves: #1683334 +--- + test/TEST-23-TYPE-EXEC/Makefile | 4 +++ + test/TEST-23-TYPE-EXEC/test.sh | 42 +++++++++++++++++++++++++++++ + test/TEST-23-TYPE-EXEC/testsuite.sh | 28 +++++++++++++++++++ + 3 files changed, 74 insertions(+) + create mode 100644 test/TEST-23-TYPE-EXEC/Makefile + create mode 100755 test/TEST-23-TYPE-EXEC/test.sh + create mode 100755 test/TEST-23-TYPE-EXEC/testsuite.sh + +diff --git a/test/TEST-23-TYPE-EXEC/Makefile b/test/TEST-23-TYPE-EXEC/Makefile +new file mode 100644 +index 0000000000..34d7cc6cdf +--- /dev/null ++++ b/test/TEST-23-TYPE-EXEC/Makefile +@@ -0,0 +1,4 @@ ++BUILD_DIR=$(shell ../../tools/find-build-dir.sh) ++ ++all setup clean run: ++ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-23-TYPE-EXEC/test.sh b/test/TEST-23-TYPE-EXEC/test.sh +new file mode 100755 +index 0000000000..bdcea239a7 +--- /dev/null ++++ b/test/TEST-23-TYPE-EXEC/test.sh +@@ -0,0 +1,42 @@ ++#!/bin/bash ++# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- ++# ex: ts=8 sw=4 sts=4 et filetype=sh ++set -e ++TEST_DESCRIPTION="test Type=exec" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < /testok ++ ++exit 0 diff --git a/SOURCES/0198-journal-gateway-explicitly-declare-local-variables.patch b/SOURCES/0198-journal-gateway-explicitly-declare-local-variables.patch new file mode 100644 index 0000000..c6ebb61 --- /dev/null +++ b/SOURCES/0198-journal-gateway-explicitly-declare-local-variables.patch @@ -0,0 +1,75 @@ +From e020d3e72755fc8c25d33efad1b7322e42d8610b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 27 Jun 2018 14:22:24 +0900 +Subject: [PATCH] journal-gateway: explicitly declare local variables + +Suggested by LGTM. + +(cherry picked from commit c497e449f41774a36e01ae2cc2abade6133dffe1) + +Resolves: #1705971 +--- + src/journal-remote/browse.html | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/journal-remote/browse.html b/src/journal-remote/browse.html +index 32848c7673..9f519adbd6 100644 +--- a/src/journal-remote/browse.html ++++ b/src/journal-remote/browse.html +@@ -304,7 +304,6 @@ + var buf = ''; + + for (i in l) { +- + if (l[i] == '') + continue; + +@@ -322,6 +321,7 @@ + else + priority = 6; + ++ var clazz; + if (priority <= 3) + clazz = "message-error"; + else if (priority <= 5) +@@ -388,7 +388,7 @@ + var d = JSON.parse(event.currentTarget.responseText); + + document.getElementById("diventry").style.display = "block"; +- entry = document.getElementById("tableentry"); ++ var entry = document.getElementById("tableentry"); + + var buf = ""; + for (var key in d) { +@@ -455,7 +455,7 @@ + (event.currentTarget.status != 200 && event.currentTarget.status != 0)) + return; + +- f = document.getElementById("filter"); ++ var f = document.getElementById("filter"); + + var l = event.currentTarget.responseText.split('\n'); + var buf = ''; +@@ -511,11 +511,12 @@ + } + + function initFilter() { +- f = document.getElementById("filter"); ++ var f = document.getElementById("filter"); + + var buf = ''; + + var filter = localStorage["filter"]; ++ var j; + if (filter != null && filter != "") { + buf += ''; + j = 1; +@@ -529,7 +530,7 @@ + function installHandlers() { + document.onkeyup = onKeyUp; + +- logs = document.getElementById("divlogs"); ++ var logs = document.getElementById("divlogs"); + logs.addEventListener("mousewheel", onMouseWheel, false); + logs.addEventListener("DOMMouseScroll", onMouseWheel, false); + } diff --git a/SOURCES/0199-tools-drop-unused-variable.patch b/SOURCES/0199-tools-drop-unused-variable.patch new file mode 100644 index 0000000..457a2a2 --- /dev/null +++ b/SOURCES/0199-tools-drop-unused-variable.patch @@ -0,0 +1,24 @@ +From b7786387a6cdc447b874f36a8d9831b1acd2eb13 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sat, 8 Dec 2018 19:33:37 +0900 +Subject: [PATCH] tools: drop unused variable + +(cherry picked from commit 2f6c9b6f3fb0128cee7f74985c143b4850feff6d) + +Resolves: #1705971 +--- + tools/gdb-sd_dump_hashmaps.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py +index ea15160107..0701d139e2 100644 +--- a/tools/gdb-sd_dump_hashmaps.py ++++ b/tools/gdb-sd_dump_hashmaps.py +@@ -16,7 +16,6 @@ class sd_dump_hashmaps(gdb.Command): + d = gdb.parse_and_eval("hashmap_debug_list") + all_entry_sizes = gdb.parse_and_eval("all_entry_sizes") + all_direct_buckets = gdb.parse_and_eval("all_direct_buckets") +- hashmap_base_t = gdb.lookup_type("HashmapBase") + uchar_t = gdb.lookup_type("unsigned char") + ulong_t = gdb.lookup_type("unsigned long") + debug_offset = gdb.parse_and_eval("(unsigned long)&((HashmapBase*)0)->debug") diff --git a/SOURCES/0200-journal-gateway-use-localStorage-cursor-only-when-it.patch b/SOURCES/0200-journal-gateway-use-localStorage-cursor-only-when-it.patch new file mode 100644 index 0000000..7dbc0c3 --- /dev/null +++ b/SOURCES/0200-journal-gateway-use-localStorage-cursor-only-when-it.patch @@ -0,0 +1,36 @@ +From 8ae19bfcfe0a52b55171f4f60772afe418831230 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 27 Jun 2018 14:50:19 +0900 +Subject: [PATCH] journal-gateway: use localStorage["cursor"] only when it has + valid value + +Discovered by LGTM. + +(cherry picked from commit 944072feddb73333023d0a98bf87fd2a17f894d3) + +Resolves: #1705971 +--- + src/journal-remote/browse.html | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/journal-remote/browse.html b/src/journal-remote/browse.html +index 9f519adbd6..e5162d1088 100644 +--- a/src/journal-remote/browse.html ++++ b/src/journal-remote/browse.html +@@ -236,10 +236,12 @@ + + function entriesLoad(range) { + +- if (range == null) +- range = localStorage["cursor"] + ":0"; +- if (range == null) +- range = ""; ++ if (range == null) { ++ if (localStorage["cursor"] != null && localStorage["cursor"] != "") ++ range = localStorage["cursor"] + ":0"; ++ else ++ range = ""; ++ } + + var url = "/entries"; + diff --git a/SOURCES/0201-sd-bus-deal-with-cookie-overruns.patch b/SOURCES/0201-sd-bus-deal-with-cookie-overruns.patch new file mode 100644 index 0000000..bf61bb4 --- /dev/null +++ b/SOURCES/0201-sd-bus-deal-with-cookie-overruns.patch @@ -0,0 +1,87 @@ +From 980418c331293aeb8595fcc95cbc4a9e1a485eda Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 Feb 2019 11:02:46 +0100 +Subject: [PATCH] sd-bus: deal with cookie overruns + +Apparently this happens IRL. Let's carefully deal with issues like this: +when we overrun, let's not go back to zero but instead leave the highest +cookie bit set. We use that as indication that we are in "overrun +territory", and then are particularly careful with checking cookies, +i.e. that they haven't been used for still outstanding replies yet. This +should retain the quick cookie generation behaviour we used to have, but +permits dealing with overruns. + +Replaces: #11804 +Fixes: #11809 +(cherry picked from commit 1f82f5bb4237ed5f015daf93f818e9db95e764b8) + +Resolves: #1694999 +--- + src/libsystemd/sd-bus/sd-bus.c | 47 +++++++++++++++++++++++++++++++++- + 1 file changed, 46 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index f53a98d6bf..3583e24e64 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -1597,6 +1597,47 @@ _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) { + return 0; + } + ++#define COOKIE_CYCLED (UINT32_C(1) << 31) ++ ++static uint64_t cookie_inc(uint64_t cookie) { ++ ++ /* Stay within the 32bit range, since classic D-Bus can't deal with more */ ++ if (cookie >= UINT32_MAX) ++ return COOKIE_CYCLED; /* Don't go back to zero, but use the highest bit for checking ++ * whether we are looping. */ ++ ++ return cookie + 1; ++} ++ ++static int next_cookie(sd_bus *b) { ++ uint64_t new_cookie; ++ ++ assert(b); ++ ++ new_cookie = cookie_inc(b->cookie); ++ ++ /* Small optimization: don't bother with checking for cookie reuse until we overran cookiespace at ++ * least once, but then do it thorougly. */ ++ if (FLAGS_SET(new_cookie, COOKIE_CYCLED)) { ++ uint32_t i; ++ ++ /* Check if the cookie is currently in use. If so, pick the next one */ ++ for (i = 0; i < COOKIE_CYCLED; i++) { ++ if (!ordered_hashmap_contains(b->reply_callbacks, &new_cookie)) ++ goto good; ++ ++ new_cookie = cookie_inc(new_cookie); ++ } ++ ++ /* Can't fulfill request */ ++ return -EBUSY; ++ } ++ ++good: ++ b->cookie = new_cookie; ++ return 0; ++} ++ + static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { + int r; + +@@ -1620,7 +1661,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { + return r; + } + +- return sd_bus_message_seal(m, ++b->cookie, timeout); ++ r = next_cookie(b); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_message_seal(m, b->cookie, timeout); + } + + static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) { diff --git a/SOURCES/0202-journal-remote-do-not-request-Content-Length-if-Tran.patch b/SOURCES/0202-journal-remote-do-not-request-Content-Length-if-Tran.patch new file mode 100644 index 0000000..431cdff --- /dev/null +++ b/SOURCES/0202-journal-remote-do-not-request-Content-Length-if-Tran.patch @@ -0,0 +1,77 @@ +From f551c05e4799386508e10f0f007251e426493a67 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 11 Mar 2019 12:27:18 +0900 +Subject: [PATCH] journal-remote: do not request Content-Length if + Transfer-Encoding is chunked + +This fixes a bug introduced by 7fdb237f5473cb8fc2129e57e8a0039526dcb4fd. + +Closes #11571. + +(cherry picked from commit a289dfd69b3ff4bccdde93e84b67c947bafa27e1) + +Resolves: #1708849 +--- + src/journal-remote/journal-remote-main.c | 41 ++++++++++++++++-------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c +index 5b0bbba310..47fe9d7433 100644 +--- a/src/journal-remote/journal-remote-main.c ++++ b/src/journal-remote/journal-remote-main.c +@@ -254,6 +254,7 @@ static int request_handler( + const char *header; + int r, code, fd; + _cleanup_free_ char *hostname = NULL; ++ bool chunked = false; + size_t len; + + assert(connection); +@@ -279,21 +280,33 @@ static int request_handler( + return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE, + "Content-Type: application/vnd.fdo.journal is required."); + ++ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Transfer-Encoding"); ++ if (header) { ++ if (!strcaseeq(header, "chunked")) ++ return mhd_respondf(connection, 0, MHD_HTTP_BAD_REQUEST, ++ "Unsupported Transfer-Encoding type: %s", header); ++ ++ chunked = true; ++ } ++ + header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length"); +- if (!header) +- return mhd_respond(connection, MHD_HTTP_LENGTH_REQUIRED, +- "Content-Length header is required."); +- r = safe_atozu(header, &len); +- if (r < 0) +- return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED, +- "Content-Length: %s cannot be parsed: %m", header); +- +- if (len > ENTRY_SIZE_MAX) +- /* When serialized, an entry of maximum size might be slightly larger, +- * so this does not correspond exactly to the limit in journald. Oh well. +- */ +- return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE, +- "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX); ++ if (header) { ++ if (chunked) ++ return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, ++ "Content-Length must not specified when Transfer-Encoding type is 'chuncked'"); ++ ++ r = safe_atozu(header, &len); ++ if (r < 0) ++ return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED, ++ "Content-Length: %s cannot be parsed: %m", header); ++ ++ if (len > ENTRY_SIZE_MAX) ++ /* When serialized, an entry of maximum size might be slightly larger, ++ * so this does not correspond exactly to the limit in journald. Oh well. ++ */ ++ return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE, ++ "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX); ++ } + + { + const union MHD_ConnectionInfo *ci; diff --git a/SOURCES/0203-journal-do-not-remove-multiple-spaces-after-identifi.patch b/SOURCES/0203-journal-do-not-remove-multiple-spaces-after-identifi.patch new file mode 100644 index 0000000..3c7d150 --- /dev/null +++ b/SOURCES/0203-journal-do-not-remove-multiple-spaces-after-identifi.patch @@ -0,0 +1,79 @@ +From fffbf1f90be5236b310bc0b10034815b1051f0ac Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 10 Aug 2018 11:07:54 +0900 +Subject: [PATCH] journal: do not remove multiple spaces after identifier in + syslog message + +Single space is used as separator. +C.f. discussions in #156. + +Fixes #9839 introduced by a6aadf4ae0bae185dc4c414d492a4a781c80ffe5. + +(cherry picked from commit 8595102d3ddde6d25c282f965573a6de34ab4421) + +Resolves: #1691817 +--- + src/journal/journald-syslog.c | 4 +++- + src/journal/test-journal-syslog.c | 24 ++++++++++++++---------- + 2 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c +index 97711ac7a3..e0b55cc566 100644 +--- a/src/journal/journald-syslog.c ++++ b/src/journal/journald-syslog.c +@@ -219,7 +219,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) + if (t) + *identifier = t; + +- e += strspn(p + e, WHITESPACE); ++ /* Single space is used as separator */ ++ if (p[e] != '\0' && strchr(WHITESPACE, p[e])) ++ e++; + + *buf = p + e; + return e; +diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c +index 05f759817e..7294cde032 100644 +--- a/src/journal/test-journal-syslog.c ++++ b/src/journal/test-journal-syslog.c +@@ -6,7 +6,7 @@ + #include "string-util.h" + + static void test_syslog_parse_identifier(const char *str, +- const char *ident, const char *pid, int ret) { ++ const char *ident, const char *pid, const char *rest, int ret) { + const char *buf = str; + _cleanup_free_ char *ident2 = NULL, *pid2 = NULL; + int ret2; +@@ -16,18 +16,22 @@ static void test_syslog_parse_identifier(const char *str, + assert_se(ret == ret2); + assert_se(ident == ident2 || streq_ptr(ident, ident2)); + assert_se(pid == pid2 || streq_ptr(pid, pid2)); ++ assert_se(streq(buf, rest)); + } + + int main(void) { +- test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11); +- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6); +- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7); +- test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0); +- test_syslog_parse_identifier(":", "", NULL, 1); +- test_syslog_parse_identifier(": ", "", NULL, 3); +- test_syslog_parse_identifier("pidu:", "pidu", NULL, 5); +- test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6); +- test_syslog_parse_identifier("pidu : ", NULL, NULL, 0); ++ test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11); ++ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6); ++ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, " xxx", 6); ++ test_syslog_parse_identifier("pidu xxx", NULL, NULL, "pidu xxx", 0); ++ test_syslog_parse_identifier(" pidu xxx", NULL, NULL, " pidu xxx", 0); ++ test_syslog_parse_identifier("", NULL, NULL, "", 0); ++ test_syslog_parse_identifier(" ", NULL, NULL, " ", 0); ++ test_syslog_parse_identifier(":", "", NULL, "", 1); ++ test_syslog_parse_identifier(": ", "", NULL, " ", 2); ++ test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5); ++ test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6); ++ test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0); + + return 0; + } diff --git a/SOURCES/0204-cryptsetup-Do-not-fallback-to-PLAIN-mapping-if-LUKS-.patch b/SOURCES/0204-cryptsetup-Do-not-fallback-to-PLAIN-mapping-if-LUKS-.patch new file mode 100644 index 0000000..eab6715 --- /dev/null +++ b/SOURCES/0204-cryptsetup-Do-not-fallback-to-PLAIN-mapping-if-LUKS-.patch @@ -0,0 +1,62 @@ +From 4f9d00380ea41f5a4eb1610ae5c354a8f749cc98 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 27 May 2019 09:27:54 +0200 +Subject: [PATCH] cryptsetup: Do not fallback to PLAIN mapping if LUKS data + device set fails. + +If crypt_load() for LUKS succeeds, we know that it is a LUKS device. +Failure of data device setting should fail in this case; remapping +as a PLAIN device late could mean data corruption. + +(If a user wants to map PLAIN device over a device with LUKS header, +it should be said explicitly with "plain" argument type.) + +Also, if there is no explicit PLAIN type requested and crypt device +is already initialized (crypt_data_type() is set), do not run +the initialization again. + +(cherry picked from commit 2e4beb875bcb24e7d7d4339cc202b0b3f2953f71) + +Related: #1719153 +--- + src/cryptsetup/cryptsetup.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index abeba44ee8..5be1469d69 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -492,11 +492,14 @@ static int attach_luks_or_plain(struct crypt_device *cd, + return r; + } + +- if (data_device) ++ if (data_device) { + r = crypt_set_data_device(cd, data_device); ++ if (r < 0) ++ return log_error_errno(r, "Failed to set LUKS data device %s: %m", data_device); ++ } + } + +- if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) { ++ if ((!arg_type && !crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) { + struct crypt_params_plain params = { + .offset = arg_offset, + .skip = arg_skip, +@@ -543,14 +546,13 @@ static int attach_luks_or_plain(struct crypt_device *cd, + * parameters when used for plain + * mode. */ + r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, ¶ms); ++ if (r < 0) ++ return log_error_errno(r, "Loading of cryptographic parameters failed: %m"); + + /* hash == NULL implies the user passed "plain" */ + pass_volume_key = (params.hash == NULL); + } + +- if (r < 0) +- return log_error_errno(r, "Loading of cryptographic parameters failed: %m"); +- + log_info("Set cipher %s, mode %s, key size %i bits for device %s.", + crypt_get_cipher(cd), + crypt_get_cipher_mode(cd), diff --git a/SOURCES/0205-cryptsetup-call-crypt_load-for-LUKS-only-once.patch b/SOURCES/0205-cryptsetup-call-crypt_load-for-LUKS-only-once.patch new file mode 100644 index 0000000..543efeb --- /dev/null +++ b/SOURCES/0205-cryptsetup-call-crypt_load-for-LUKS-only-once.patch @@ -0,0 +1,79 @@ +From 788fb775f7deb8c456868362454e2a5f50c6068f Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 27 May 2019 09:43:03 +0200 +Subject: [PATCH] cryptsetup: call crypt_load() for LUKS only once + +The crypt_load() for LUKS2 can read a quite big area of disk +(metadata area size is configurable and can increase up to megabytes). + +This initialization is not needed to be repeated, just use the existing context. + +(This patch is also required for the following change.) + +(cherry picked from commit ea9a9d49e4af31c49e5c216e7e5e2f533e727579) + +Related: #1719153 +--- + src/cryptsetup/cryptsetup.c | 28 ++++++++++++---------------- + 1 file changed, 12 insertions(+), 16 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 5be1469d69..a0bd80ea65 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -475,7 +475,6 @@ static int attach_tcrypt( + static int attach_luks_or_plain(struct crypt_device *cd, + const char *name, + const char *key_file, +- const char *data_device, + char **passwords, + uint32_t flags) { + int r = 0; +@@ -485,20 +484,6 @@ static int attach_luks_or_plain(struct crypt_device *cd, + assert(name); + assert(key_file || passwords); + +- if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) { +- r = crypt_load(cd, CRYPT_LUKS, NULL); +- if (r < 0) { +- log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd)); +- return r; +- } +- +- if (data_device) { +- r = crypt_set_data_device(cd, data_device); +- if (r < 0) +- return log_error_errno(r, "Failed to set LUKS data device %s: %m", data_device); +- } +- } +- + if ((!arg_type && !crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) { + struct crypt_params_plain params = { + .offset = arg_offset, +@@ -687,6 +672,18 @@ int main(int argc, char *argv[]) { + log_warning("Key file %s is world-readable. This is not a good idea!", key_file); + } + ++ if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) { ++ r = crypt_load(cd, CRYPT_LUKS, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd)); ++ ++ if (arg_header) { ++ r = crypt_set_data_device(cd, argv[3]); ++ if (r < 0) ++ return log_error_errno(r, "Failed to set LUKS data device %s: %m", argv[3]); ++ } ++ } ++ + for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) { + _cleanup_strv_free_erase_ char **passwords = NULL; + +@@ -704,7 +701,6 @@ int main(int argc, char *argv[]) { + r = attach_luks_or_plain(cd, + argv[2], + key_file, +- arg_header ? argv[3] : NULL, + passwords, + flags); + if (r >= 0) diff --git a/SOURCES/0206-cryptsetup-Add-LUKS2-token-support.patch b/SOURCES/0206-cryptsetup-Add-LUKS2-token-support.patch new file mode 100644 index 0000000..f818181 --- /dev/null +++ b/SOURCES/0206-cryptsetup-Add-LUKS2-token-support.patch @@ -0,0 +1,45 @@ +From 7a597a091de83a861d81166b0e863bf2977c829c Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 27 May 2019 09:44:14 +0200 +Subject: [PATCH] cryptsetup: Add LUKS2 token support. + +LUKS2 supports so-called tokens. The libcryptsetup internally +support keyring token (it tries to open device using specified +keyring entry). +Only if all token fails (or are not available), it uses a passphrase. + +This patch aligns the functionality with the cryptsetup utility +(cryptsetup luksOpen tries tokens first) but does not replace +the systemd native ask-password function (can be used the same in +combination with this patch). + +(cherry picked from commit 894bb3ca4c730cc9e9d46ef5004ba4ca5e201d8d) + +Resolves: #1719153 +--- + src/cryptsetup/cryptsetup.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index a0bd80ea65..4e1b3eff19 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -682,6 +682,18 @@ int main(int argc, char *argv[]) { + if (r < 0) + return log_error_errno(r, "Failed to set LUKS data device %s: %m", argv[3]); + } ++#ifdef CRYPT_ANY_TOKEN ++ /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */ ++ if (!key_file) { ++ r = crypt_activate_by_token(cd, argv[2], CRYPT_ANY_TOKEN, NULL, flags); ++ if (r >= 0) { ++ log_debug("Volume %s activated with LUKS token id %i.", argv[2], r); ++ return 0; ++ } ++ ++ log_debug_errno(r, "Token activation unsuccessful for device %s: %m", crypt_get_device_name(cd)); ++ } ++#endif + } + + for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) { diff --git a/SOURCES/0207-udev-scsi_id-fix-incorrect-page-length-when-get-devi.patch b/SOURCES/0207-udev-scsi_id-fix-incorrect-page-length-when-get-devi.patch new file mode 100644 index 0000000..a884b4f --- /dev/null +++ b/SOURCES/0207-udev-scsi_id-fix-incorrect-page-length-when-get-devi.patch @@ -0,0 +1,30 @@ +From 7b3ef169e3142fb471c48f265881b371380d77e0 Mon Sep 17 00:00:00 2001 +From: Zhang Xianwei +Date: Mon, 13 May 2019 18:41:55 +0800 +Subject: [PATCH] udev/scsi_id: fix incorrect page length when get device + identification VPD page + +The length of device identification VPD page is filled with two bytes, +but scsi_id only gets the low byte. Fix it. + +Signed-off-by: Zhang Xianwei +(cherry picked from commit 1f7b6872dbe8ccae1f3bda9aa6aeb87c9b42e01e) + +Resolves: #1713227 +--- + src/udev/scsi_id/scsi_serial.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c +index fd91657a32..fb6055395d 100644 +--- a/src/udev/scsi_id/scsi_serial.c ++++ b/src/udev/scsi_id/scsi_serial.c +@@ -661,7 +661,7 @@ static int do_scsi_page83_inquiry(struct udev *udev, + * Examine each descriptor returned. There is normally only + * one or a small number of descriptors. + */ +- for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) { ++ for (j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) { + retval = check_fill_0x83_id(udev, + dev_scsi, &page_83[j], + &id_search_list[id_ind], diff --git a/SOURCES/0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch b/SOURCES/0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch new file mode 100644 index 0000000..c40fd1c --- /dev/null +++ b/SOURCES/0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch @@ -0,0 +1,55 @@ +From d70e1c2eb596b8144197192e2324abbb45f547a6 Mon Sep 17 00:00:00 2001 +From: Jonathon Kowalski +Date: Thu, 17 Jan 2019 17:08:00 +0000 +Subject: [PATCH] Change job mode of manager triggered restarts to JOB_REPLACE + +Fixes: #11305 +Fixes: #3260 +Related: #11456 + +So, here's what happens in the described scenario in #11305. A unit goes +down, and that triggeres stop jobs for the other two units as they were +bound to it. Now, the timer for manager triggered restarts kicks in and +schedules a restart job with the JOB_FAIL job mode. This means there is +a stop job installed on those units, and now due to them being bound to +us they also get a restart job enqueued. This however is a conflicts, as +neither stop can merge into restart, nor restart into stop. However, +restart should be able to replace stop in any case. If the stop +procedure is ongoing, it can cancel the stop job, install itself, and +then after reaching dead finish and convert itself to a start job. +However, if we increase the timer, then it can always take those units +from inactive -> auto-restart. + +We change the job mode to JOB_REPLACE so the restart job cancels the +stop job and installs itself. + +Also, the original bug could be worked around by bumping RestartSec= to +avoid the conflicting. + +This doesn't seem to be something that is going to break uses. That is +because for those who already had it working, there must have never been +conflicting jobs, as that would result in a desctructive transaction by +virtue of the job mode used. + +After this change, the test case is able to work nicely without issues. + +(cherry picked from commit 03ff2dc71ecb09272d728d458498b44f7f132f51) + +Resolves: #1712524 +--- + src/core/service.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 3eab749362..8342c131c8 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2133,7 +2133,7 @@ static void service_enter_restart(Service *s) { + * restarted. We use JOB_RESTART (instead of the more obvious + * JOB_START) here so that those dependency jobs will be added + * as well. */ +- r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_FAIL, &error, NULL); ++ r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_REPLACE, &error, NULL); + if (r < 0) + goto fail; + diff --git a/SOURCES/0209-bash-completion-analyze-support-security.patch b/SOURCES/0209-bash-completion-analyze-support-security.patch new file mode 100644 index 0000000..aec8a8d --- /dev/null +++ b/SOURCES/0209-bash-completion-analyze-support-security.patch @@ -0,0 +1,58 @@ +From 8d1a8f099dbf79d0e18e055721228192a637a759 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 6 Dec 2018 18:51:56 +0100 +Subject: [PATCH] bash-completion: analyze: support 'security' + +(cherry picked from commit 83da42c3bf86e8787cfec2c7fb6ca379dfec3632) + +Resolves: #1733395 +--- + shell-completion/bash/systemd-analyze | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze +index 21d0fcf1b8..b4fcfc6492 100644 +--- a/shell-completion/bash/systemd-analyze ++++ b/shell-completion/bash/systemd-analyze +@@ -31,8 +31,13 @@ __get_machines() { + machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; }; + } + ++__get_services() { ++ systemctl list-units --no-legend --no-pager -t service --all $1 | \ ++ { while read -r a b c; do [[ $b == "loaded" ]]; echo " $a"; done } ++} ++ + _systemd_analyze() { +- local i verb comps ++ local i verb comps mode + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + + local -A OPTS=( +@@ -51,6 +56,7 @@ _systemd_analyze() { + [SECCOMP_FILTER]='syscall-filter' + [SERVICE_WATCHDOGS]='service-watchdogs' + [CAT_CONFIG]='cat-config' ++ [SECURITY]='security' + ) + + local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf +@@ -149,6 +155,18 @@ _systemd_analyze() { + comps="$CONFIGS $( compgen -A file -- "$cur" )" + compopt -o filenames + fi ++ ++ elif __contains_word "$verb" ${VERBS[SECURITY]}; then ++ if [[ $cur = -* ]]; then ++ comps='--help --version --no-pager --system --user -H --host -M --machine' ++ else ++ if __contains_word "--user" ${COMP_WORDS[*]}; then ++ mode=--user ++ else ++ mode=--system ++ fi ++ comps=$( __get_services $mode ) ++ fi + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) diff --git a/SOURCES/0210-man-note-that-journal-does-not-validate-syslog-field.patch b/SOURCES/0210-man-note-that-journal-does-not-validate-syslog-field.patch new file mode 100644 index 0000000..3e9de97 --- /dev/null +++ b/SOURCES/0210-man-note-that-journal-does-not-validate-syslog-field.patch @@ -0,0 +1,28 @@ +From 705a67a53a8a1b836ef17f048366bbf33357afc1 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 14 May 2019 10:45:08 +0200 +Subject: [PATCH] man: note that journal does not validate syslog fields + +(cherry picked from commit 63ea8032f28052f7cda860e5324c0a83dee7ed23) + +Resolves: #1707175 +--- + man/systemd.journal-fields.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml +index c079274c32..0c95c4cd95 100644 +--- a/man/systemd.journal-fields.xml ++++ b/man/systemd.journal-fields.xml +@@ -111,6 +111,11 @@ + program_invocation_short_name variable, + see + program_invocation_short_name3.) ++ Note that the journal service does not validate the values of any structured ++ journal fields whose name is not prefixed with an underscore, and this includes any ++ syslog related fields such as these. Hence, applications that supply a facility, PID, ++ or log level are expected to do so properly formatted, i.e. as numeric integers formatted ++ as decimal strings. + + + diff --git a/SOURCES/0211-rules-skip-memory-hotplug-on-ppc64.patch b/SOURCES/0211-rules-skip-memory-hotplug-on-ppc64.patch new file mode 100644 index 0000000..3e311ee --- /dev/null +++ b/SOURCES/0211-rules-skip-memory-hotplug-on-ppc64.patch @@ -0,0 +1,22 @@ +From 72dd8d8cd1a7417805009050f859d502b1c6cf3e Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 6 Jun 2019 09:35:27 +0200 +Subject: [PATCH] rules: skip memory hotplug on ppc64 + +Resolves (#1713159) +--- + rules/40-redhat.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index 17b33682bd..fadc6e59f1 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -7,6 +7,7 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online} + SUBSYSTEM!="memory", GOTO="memory_hotplug_end" + ACTION!="add", GOTO="memory_hotplug_end" + PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end" ++PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end" + + ENV{.state}="online" + PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable" diff --git a/SOURCES/0212-mount-simplify-proc-self-mountinfo-handler.patch b/SOURCES/0212-mount-simplify-proc-self-mountinfo-handler.patch new file mode 100644 index 0000000..316dda2 --- /dev/null +++ b/SOURCES/0212-mount-simplify-proc-self-mountinfo-handler.patch @@ -0,0 +1,86 @@ +From daf63a3c6c6cd241017bdf9a26c7b1caf744e69b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Jul 2019 14:53:07 +0200 +Subject: [PATCH] mount: simplify /proc/self/mountinfo handler + +Our IO handler is only installed for one fd, hence there's no reason to +conditionalize on it again. + +Also, split out the draining into a helper function of its own. + +(cherry picked from commit fcd8e119c28be19ffbc5227089cf4d3b8ba60238) + +Conflicts: + src/core/mount.c + +Related: #1696178 +--- + src/core/mount.c | 48 ++++++++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 22 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 16229d4af1..85b07375e2 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1758,6 +1758,29 @@ fail: + mount_shutdown(m); + } + ++static int drain_libmount(Manager *m) { ++ bool rescan = false; ++ int r; ++ ++ assert(m); ++ ++ /* Drain all events and verify that the event is valid. ++ * ++ * Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir ++ * may generate event which is irrelevant for us. ++ * ++ * error: r < 0; valid: r == 0, false positive: r == 1 */ ++ do { ++ r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to drain libmount events: %m"); ++ if (r == 0) ++ rescan = true; ++ } while (r == 0); ++ ++ return rescan; ++} ++ + static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { + _cleanup_set_free_ Set *around = NULL, *gone = NULL; + Manager *m = userdata; +@@ -1769,28 +1792,9 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, + assert(m); + assert(revents & EPOLLIN); + +- if (fd == mnt_monitor_get_fd(m->mount_monitor)) { +- bool rescan = false; +- +- /* Drain all events and verify that the event is valid. +- * +- * Note that libmount also monitors /run/mount mkdir if the +- * directory does not exist yet. The mkdir may generate event +- * which is irrelevant for us. +- * +- * error: r < 0; valid: r == 0, false positive: rc == 1 */ +- do { +- r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL); +- if (r == 0) +- rescan = true; +- else if (r < 0) +- return log_error_errno(r, "Failed to drain libmount events"); +- } while (r == 0); +- +- log_debug("libmount event [rescan: %s]", yes_no(rescan)); +- if (!rescan) +- return 0; +- } ++ r = drain_libmount(m); ++ if (r <= 0) ++ return r; + + r = mount_load_proc_self_mountinfo(m, true); + if (r < 0) { diff --git a/SOURCES/0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch b/SOURCES/0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch new file mode 100644 index 0000000..032ea39 --- /dev/null +++ b/SOURCES/0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch @@ -0,0 +1,90 @@ +From 4bc21bbc61acd1ce114da381a9742f6bcd4ffde8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Jul 2019 18:57:13 +0200 +Subject: [PATCH] mount: rescan /proc/self/mountinfo before processing waitid() + results + +(The interesting bits about the what and why are in a comment in the +patch, please have a look there instead of looking here in the commit +msg). + +Fixes: #10872 +(cherry picked from commit 350804867dbcc9b7ccabae1187d730d37e2d8a21) + +Conflicts: + src/core/mount.c + +Resolves: #1696178 +--- + src/core/mount.c | 30 +++++++++++++++++++++++++++--- + 1 file changed, 27 insertions(+), 3 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 85b07375e2..2ac04e3874 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -53,6 +53,7 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { + + static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); + static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); ++static int mount_process_proc_self_mountinfo(Manager *m); + + static bool MOUNT_STATE_WITH_PROCESS(MountState state) { + return IN_SET(state, +@@ -1241,6 +1242,22 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { + if (pid != m->control_pid) + return; + ++ /* So here's the thing, we really want to know before /usr/bin/mount or /usr/bin/umount exit whether ++ * they established/remove a mount. This is important when mounting, but even more so when unmounting ++ * since we need to deal with nested mounts and otherwise cannot safely determine whether to repeat ++ * the unmounts. In theory, the kernel fires /proc/self/mountinfo changes off before returning from ++ * the mount() or umount() syscalls, and thus we should see the changes to the proc file before we ++ * process the waitid() for the /usr/bin/(u)mount processes. However, this is unfortunately racy: we ++ * have to waitid() for processes using P_ALL (since we need to reap unexpected children that got ++ * reparented to PID 1), but when using P_ALL we might end up reaping processes that terminated just ++ * instants ago, i.e. already after our last event loop iteration (i.e. after the last point we might ++ * have noticed /proc/self/mountinfo events via epoll). This means event loop priorities for ++ * processing SIGCHLD vs. /proc/self/mountinfo IO events are not as relevant as we want. To fix that ++ * race, let's explicitly scan /proc/self/mountinfo before we start processing /usr/bin/(u)mount ++ * dying. It's ugly, but it makes our ordering systematic again, and makes sure we always see ++ * /proc/self/mountinfo changes before our mount/umount exits. */ ++ (void) mount_process_proc_self_mountinfo(u->manager); ++ + m->control_pid = 0; + + if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL)) +@@ -1781,16 +1798,14 @@ static int drain_libmount(Manager *m) { + return rescan; + } + +-static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { ++static int mount_process_proc_self_mountinfo(Manager *m) { + _cleanup_set_free_ Set *around = NULL, *gone = NULL; +- Manager *m = userdata; + const char *what; + Iterator i; + Unit *u; + int r; + + assert(m); +- assert(revents & EPOLLIN); + + r = drain_libmount(m); + if (r <= 0) +@@ -1898,6 +1913,15 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, + return 0; + } + ++static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { ++ Manager *m = userdata; ++ ++ assert(m); ++ assert(revents & EPOLLIN); ++ ++ return mount_process_proc_self_mountinfo(m); ++} ++ + static void mount_reset_failed(Unit *u) { + Mount *m = MOUNT(u); + diff --git a/SOURCES/0214-swap-scan-proc-swaps-before-processing-waitid-result.patch b/SOURCES/0214-swap-scan-proc-swaps-before-processing-waitid-result.patch new file mode 100644 index 0000000..e872790 --- /dev/null +++ b/SOURCES/0214-swap-scan-proc-swaps-before-processing-waitid-result.patch @@ -0,0 +1,69 @@ +From a0c135f7771dbe3a6cd3da2aaa106900be0f4470 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Jul 2019 18:58:44 +0200 +Subject: [PATCH] swap: scan /proc/swaps before processing waitid() results + +Similar to the previous commit, but for /proc/swaps, where the same +logic and rationale applies. + +(cherry picked from commit bcce581d65de68cca01c73e1c890e261e72d20af) + +Related: #1696178 +--- + src/core/swap.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/src/core/swap.c b/src/core/swap.c +index e01e61e56d..b644753a1c 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -40,6 +40,7 @@ static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { + + static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); + static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); ++static int swap_process_proc_swaps(Manager *m); + + static bool SWAP_STATE_WITH_PROCESS(SwapState state) { + return IN_SET(state, +@@ -990,6 +991,10 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { + if (pid != s->control_pid) + return; + ++ /* Let's scan /proc/swaps before we process SIGCHLD. For the reasoning see the similar code in ++ * mount.c */ ++ (void) swap_process_proc_swaps(u->manager); ++ + s->control_pid = 0; + + if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL)) +@@ -1125,13 +1130,11 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) { + return r; + } + +-static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { +- Manager *m = userdata; ++static int swap_process_proc_swaps(Manager *m) { + Unit *u; + int r; + + assert(m); +- assert(revents & EPOLLPRI); + + r = swap_load_proc_swaps(m, true); + if (r < 0) { +@@ -1205,6 +1208,15 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v + return 1; + } + ++static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { ++ Manager *m = userdata; ++ ++ assert(m); ++ assert(revents & EPOLLPRI); ++ ++ return swap_process_proc_swaps(m); ++} ++ + static Unit *swap_following(Unit *u) { + Swap *s = SWAP(u); + Swap *other, *first = NULL; diff --git a/SOURCES/0215-analyze-security-fix-potential-division-by-zero.patch b/SOURCES/0215-analyze-security-fix-potential-division-by-zero.patch new file mode 100644 index 0000000..3e150b0 --- /dev/null +++ b/SOURCES/0215-analyze-security-fix-potential-division-by-zero.patch @@ -0,0 +1,25 @@ +From ebe93460ef5ae3744c4b627361f4dc5815cffc13 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 31 Jul 2019 09:13:41 +0200 +Subject: [PATCH] analyze-security: fix potential division by zero + +Upstream PR: https://github.com/systemd/systemd/pull/13238 + +Resolves: #1734400 +--- + src/analyze/analyze-security.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +index 541fc0d97a..eec040d5c3 100644 +--- a/src/analyze/analyze-security.c ++++ b/src/analyze/analyze-security.c +@@ -1494,6 +1494,8 @@ static int assess(const struct security_info *info, Table *overview_table, Analy + } + } + ++ assert(weight_sum > 0); ++ + if (details_table) { + size_t row; + diff --git a/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch b/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch new file mode 100644 index 0000000..2d967cf --- /dev/null +++ b/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch @@ -0,0 +1,26 @@ +From cffe5d0e781f6fa7f2275b94d2dcc26e00859a78 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 17 Jul 2019 19:16:33 +0200 +Subject: [PATCH] core: never propagate reload failure to service result + +Fixes: #11238 +(cherry picked from commit d611cfa748aaf600832160132774074e808c82c7) + +Resolves: #1735787 +--- + src/core/service.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 8342c131c8..24f167572a 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3310,7 +3310,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + "Control process exited, code=%s status=%i", + sigchld_code_to_string(code), status); + +- if (s->result == SERVICE_SUCCESS) ++ if (s->state != SERVICE_RELOAD && s->result == SERVICE_SUCCESS) + s->result = f; + + if (s->control_command && diff --git a/SOURCES/0217-man-document-systemd-analyze-security.patch b/SOURCES/0217-man-document-systemd-analyze-security.patch new file mode 100644 index 0000000..07ec674 --- /dev/null +++ b/SOURCES/0217-man-document-systemd-analyze-security.patch @@ -0,0 +1,59 @@ +From d11fdacaf3c804b60dfe8371062f34ac2b624ac9 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Fri, 13 Sep 2019 09:23:32 +0200 +Subject: [PATCH] man: document systemd-analyze security + +(cherry-picked from commit ee93c1e664a7bbc59f1578e285c871999507b14d) + +Resolves: #1750343 +--- + man/systemd-analyze.xml | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml +index 7aa10fc68e..f3b595880f 100644 +--- a/man/systemd-analyze.xml ++++ b/man/systemd-analyze.xml +@@ -106,6 +106,12 @@ + service-watchdogs + BOOL + ++ ++ systemd-analyze ++ OPTIONS ++ security ++ UNIT ++ + + + +@@ -253,6 +259,29 @@ NAutoVTs=8 + systemd.service5. + The hardware watchdog is not affected by this setting. + ++ systemd-analyze security analyzes the security and sandboxing settings of one or more ++ specified service units. If at least one unit name is specified the security settings of the specified service ++ units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded, ++ long-running service units are inspected and a terse table with results shown. The command checks for various ++ security-related service settings, assigning each a numeric "exposure level" value, depending on how important a ++ setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range ++ 0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied ++ sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only ++ analyzes the per-service security features systemd itself implements. This means that any additional security ++ mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should ++ not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the ++ service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels ++ do indicate however that most likely the service might benefit from additional settings applied to them. Please ++ note that many of the security and sandboxing settings individually can be circumvented — unless combined with ++ others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing ++ options can be undone by the service code itself. Due to that is essential that each service uses the most ++ comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these ++ combinations and relationships between the settings, but not all. Also note that the security and sandboxing ++ settings analyzed here only apply to the operations executed by the service code itself. If a service has access to ++ an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same ++ restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is ++ not validated too. ++ + If no command is passed, systemd-analyze + time is implied. + diff --git a/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch b/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch new file mode 100644 index 0000000..4cfc715 --- /dev/null +++ b/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch @@ -0,0 +1,772 @@ +From a2e00522971897909db2a81b4daf10e5700f453e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 15 Mar 2019 10:13:55 +0100 +Subject: [PATCH] man: reorder and add examples to systemd-analyze(1) + +The number of verbs supported by systemd-analyze has grown quite a bit, and the +man page has become an unreadable wall of text. Let's put each verb in a +separate subsection, grouping similar verbs together, and add a lot of examples +to guide the user. + +(cherry picked from commit d323a99001c1f7625e8ac902e18deb514a4ca18d) + +Related: #1750343 +--- + man/systemd-analyze.xml | 678 +++++++++++++++++++++++++--------------- + 1 file changed, 429 insertions(+), 249 deletions(-) + +diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml +index f3b595880f..7c873cbdd1 100644 +--- a/man/systemd-analyze.xml ++++ b/man/systemd-analyze.xml +@@ -41,46 +41,50 @@ + critical-chain + UNIT + ++ + + systemd-analyze + OPTIONS +- plot +- > file.svg ++ log-level ++ LEVEL + + + systemd-analyze + OPTIONS +- dot +- PATTERN +- > file.dot ++ log-target ++ TARGET + + + systemd-analyze + OPTIONS +- dump ++ service-watchdogs ++ BOOL + ++ + + systemd-analyze + OPTIONS +- cat-config +- NAME|PATH ++ dump + ++ + + systemd-analyze + OPTIONS +- unit-paths ++ plot ++ >file.svg + + + systemd-analyze + OPTIONS +- log-level +- LEVEL ++ dot ++ PATTERN ++ >file.dot + ++ + + systemd-analyze + OPTIONS +- log-target +- TARGET ++ unit-paths + + + systemd-analyze +@@ -91,20 +95,20 @@ + + systemd-analyze + OPTIONS +- verify +- FILES ++ calendar ++ SPECS + + + systemd-analyze + OPTIONS +- calendar +- SPECS ++ timespan ++ SPAN + + + systemd-analyze + OPTIONS +- service-watchdogs +- BOOL ++ cat-config ++ NAME|PATH + + + systemd-analyze +@@ -123,73 +127,299 @@ + verify the correctness of unit files. It is also used to access + special functions useful for advanced system manager debugging. + +- systemd-analyze time prints the time +- spent in the kernel before userspace has been reached, the time +- spent in the initial RAM disk (initrd) before normal system +- userspace has been reached, and the time normal system userspace +- took to initialize. Note that these measurements simply measure +- the time passed up to the point where all system services have +- been spawned, but not necessarily until they fully finished +- initialization or the disk is idle. +- +- systemd-analyze blame prints a list of +- all running units, ordered by the time they took to initialize. +- This information may be used to optimize boot-up times. Note that +- the output might be misleading as the initialization of one +- service might be slow simply because it waits for the +- initialization of another service to complete. +- Also note: systemd-analyze blame doesn't display +- results for services with Type=simple, +- because systemd considers such services to be started immediately, +- hence no measurement of the initialization delays can be done. +- +- systemd-analyze critical-chain +- [UNIT…] prints a tree of +- the time-critical chain of units (for each of the specified +- UNITs or for the default target +- otherwise). The time after the unit is active or started is +- printed after the "@" character. The time the unit takes to start +- is printed after the "+" character. Note that the output might be +- misleading as the initialization of one service might depend on +- socket activation and because of the parallel execution of +- units. +- +- systemd-analyze plot prints an SVG +- graphic detailing which system services have been started at what +- time, highlighting the time they spent on initialization. +- +- systemd-analyze dot generates textual +- dependency graph description in dot format for further processing +- with the GraphViz +- dot1 +- tool. Use a command line like systemd-analyze dot | dot +- -Tsvg > systemd.svg to generate a graphical dependency +- tree. Unless or +- is passed, the generated graph will +- show both ordering and requirement dependencies. Optional pattern +- globbing style specifications (e.g. *.target) +- may be given at the end. A unit dependency is included in the +- graph if any of these patterns match either the origin or +- destination node. +- +- systemd-analyze dump outputs a (usually +- very long) human-readable serialization of the complete server +- state. Its format is subject to change without notice and should +- not be parsed by applications. +- +- systemd-analyze cat-config is similar +- to systemctl cat, but operates on config files. +- It will copy the contents of a config file and any drop-ins to standard +- output, using the usual systemd set of directories and rules for +- precedence. Each argument must be either an absolute path including +- the prefix (such as /etc/systemd/logind.conf or +- /usr/lib/systemd/logind.conf), or a name +- relative to the prefix (such as systemd/logind.conf). +- ++ If no command is passed, systemd-analyze ++ time is implied. ++ ++ ++ <command>systemd-analyze time</command> ++ ++ This command prints the time spent in the kernel before userspace has been reached, the time ++ spent in the initial RAM disk (initrd) before normal system userspace has been reached, and the time ++ normal system userspace took to initialize. Note that these measurements simply measure the time passed ++ up to the point where all system services have been spawned, but not necessarily until they fully ++ finished initialization or the disk is idle. ++ ++ ++ <command>Show how long the boot took</command> ++ ++ # in a container ++$ systemd-analyze time ++Startup finished in 296ms (userspace) ++multi-user.target reached after 275ms in userspace ++ ++# on a real machine ++$ systemd-analyze time ++Startup finished in 2.584s (kernel) + 19.176s (initrd) + 47.847s (userspace) = 1min 9.608s ++multi-user.target reached after 47.820s in userspace ++ ++ ++ ++ ++ ++ <command>systemd-analyze blame</command> ++ ++ This command prints a list of all running units, ordered by the time they took to initialize. ++ This information may be used to optimize boot-up times. Note that the output might be misleading as the ++ initialization of one service might be slow simply because it waits for the initialization of another ++ service to complete. Also note: systemd-analyze blame doesn't display results for ++ services with Type=simple, because systemd considers such services to be started ++ immediately, hence no measurement of the initialization delays can be done. ++ ++ ++ <command>Show which units took the most time during boot</command> ++ ++ $ systemd-analyze blame ++ 32.875s pmlogger.service ++ 20.905s systemd-networkd-wait-online.service ++ 13.299s dev-vda1.device ++ ... ++ 23ms sysroot.mount ++ 11ms initrd-udevadm-cleanup-db.service ++ 3ms sys-kernel-config.mount ++ ++ ++ ++ ++ ++ <command>systemd-analyze critical-chain <optional><replaceable>UNIT</replaceable>...</optional></command> ++ ++ This command prints a tree of the time-critical chain of units (for each of the specified ++ UNITs or for the default target otherwise). The time after the unit is ++ active or started is printed after the "@" character. The time the unit takes to start is printed after ++ the "+" character. Note that the output might be misleading as the initialization of services might ++ depend on socket activation and because of the parallel execution of units. ++ ++ ++ <command>systemd-analyze time</command> ++ ++ $ systemd-analyze critical-chain ++multi-user.target @47.820s ++└─pmie.service @35.968s +548ms ++ └─pmcd.service @33.715s +2.247s ++ └─network-online.target @33.712s ++ └─systemd-networkd-wait-online.service @12.804s +20.905s ++ └─systemd-networkd.service @11.109s +1.690s ++ └─systemd-udevd.service @9.201s +1.904s ++ └─systemd-tmpfiles-setup-dev.service @7.306s +1.776s ++ └─kmod-static-nodes.service @6.976s +177ms ++ └─systemd-journald.socket ++ └─system.slice ++ └─-.slice ++ ++ ++ ++ ++ ++ <command>systemd-analyze log-level [<replaceable>LEVEL</replaceable>]</command> ++ ++ systemd-analyze log-level prints the current log level of the ++ systemd daemon. If an optional argument LEVEL is ++ provided, then the command changes the current log level of the systemd daemon to ++ LEVEL (accepts the same values as described in ++ systemd1). ++ ++ ++ ++ <command>systemd-analyze log-target [<replaceable>TARGET</replaceable>]</command> ++ ++ systemd-analyze log-target prints the current log target of the ++ systemd daemon. If an optional argument TARGET is ++ provided, then the command changes the current log target of the systemd daemon to ++ TARGET (accepts the same values as , described ++ in systemd1). ++ ++ ++ ++ <command>systemd-analyze service-watchdogs [yes|no]</command> ++ ++ systemd-analyze service-watchdogs prints the current state of service runtime ++ watchdogs of the systemd daemon. If an optional boolean argument is provided, then ++ globally enables or disables the service runtime watchdogs () and ++ emergency actions (e.g. or ); see ++ systemd.service5. ++ The hardware watchdog is not affected by this setting. ++ ++ ++ ++ <command>systemd-analyze dump</command> ++ ++ This command outputs a (usually very long) human-readable serialization of the complete server ++ state. Its format is subject to change without notice and should not be parsed by applications. ++ ++ ++ Show the internal state of user manager ++ ++ $ systemd-analyze --user dump ++Timestamp userspace: Thu 2019-03-14 23:28:07 CET ++Timestamp finish: Thu 2019-03-14 23:28:07 CET ++Timestamp generators-start: Thu 2019-03-14 23:28:07 CET ++Timestamp generators-finish: Thu 2019-03-14 23:28:07 CET ++Timestamp units-load-start: Thu 2019-03-14 23:28:07 CET ++Timestamp units-load-finish: Thu 2019-03-14 23:28:07 CET ++-> Unit proc-timer_list.mount: ++ Description: /proc/timer_list ++ ... ++-> Unit default.target: ++ Description: Main user target ++... ++ ++ ++ ++ ++ ++ <command>systemd-analyze plot</command> ++ ++ This command prints an SVG graphic detailing which system services have been started at what ++ time, highlighting the time they spent on initialization. ++ ++ ++ <command>Plot a bootchart</command> ++ ++ $ systemd-analyze plot >bootup.svg ++$ eog bootup.svg& ++ ++ ++ ++ ++ ++ <command>systemd-analyze dot [<replaceable>pattern</replaceable>...]</command> ++ ++ This command generates textual dependency graph description in dot format for further processing ++ with the GraphViz ++ dot1 ++ tool. Use a command line like systemd-analyze dot | dot -Tsvg >systemd.svg to ++ generate a graphical dependency tree. Unless or is ++ passed, the generated graph will show both ordering and requirement dependencies. Optional pattern ++ globbing style specifications (e.g. *.target) may be given at the end. A unit ++ dependency is included in the graph if any of these patterns match either the origin or destination ++ node. ++ ++ ++ Plot all dependencies of any unit whose name starts with <literal>avahi-daemon</literal> ++ ++ ++ $ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg >avahi.svg ++$ eog avahi.svg ++ ++ ++ ++ Plot the dependencies between all known target units + +- +- Showing logind configuration +- $ systemd-analyze cat-config systemd/logind.conf ++ $ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' \ ++ | dot -Tsvg >targets.svg ++$ eog targets.svg ++ ++ ++ ++ ++ <command>systemd-analyze unit-paths</command> ++ ++ This command outputs a list of all directories from which unit files, .d ++ overrides, and .wants, .requires symlinks may be ++ loaded. Combine with to retrieve the list for the user manager instance, and ++ for the global configuration of user manager instances. ++ ++ ++ <command>Show all paths for generated units</command> ++ ++ $ systemd-analyze unit-paths | grep '^/run' ++/run/systemd/system.control ++/run/systemd/transient ++/run/systemd/generator.early ++/run/systemd/system ++/run/systemd/system.attached ++/run/systemd/generator ++/run/systemd/generator.late ++ ++ ++ ++ Note that this verb prints the list that is compiled into systemd-analyze ++ itself, and does not comunicate with the running manager. Use ++ systemctl [--user] [--global] show -p UnitPath --value ++ to retrieve the actual list that the manager uses, with any empty directories omitted. ++ ++ ++ ++ <command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>...</optional></command> ++ ++ This command will list system calls contained in the specified system call set ++ SET, or all known sets if no sets are specified. Argument ++ SET must include the @ prefix. ++ ++ ++ ++ <command>systemd-analyze calendar <replaceable>EXPRESSION</replaceable>...</command> ++ ++ This command will parse and normalize repetitive calendar time events, and will calculate when ++ they elapse next. This takes the same input as the OnCalendar= setting in ++ systemd.timer5, ++ following the syntax described in ++ systemd.time7. By ++ default, only the next time the calendar expression will elapse is shown; use ++ to show the specified number of next times the expression ++ elapses. ++ ++ ++ Show leap days in the near future ++ ++ $ systemd-analyze calendar --iterations=5 '*-2-29 0:0:0' ++ Original form: *-2-29 0:0:0 ++Normalized form: *-02-29 00:00:00 ++ Next elapse: Sat 2020-02-29 00:00:00 UTC ++ From now: 11 months 15 days left ++ Iter. #2: Thu 2024-02-29 00:00:00 UTC ++ From now: 4 years 11 months left ++ Iter. #3: Tue 2028-02-29 00:00:00 UTC ++ From now: 8 years 11 months left ++ Iter. #4: Sun 2032-02-29 00:00:00 UTC ++ From now: 12 years 11 months left ++ Iter. #5: Fri 2036-02-29 00:00:00 UTC ++ From now: 16 years 11 months left ++ ++ ++ ++ ++ ++ <command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command> ++ ++ This command parses a time span and outputs the normalized form and the equivalent value in ++ microseconds. The time span should adhere to the same syntax documented in ++ systemd.time7. ++ Values without associated magnitudes are parsed as seconds. ++ ++ ++ Show parsing of timespans ++ ++ $ systemd-analyze timespan 1s 300s '1year 0.000001s' ++Original: 1s ++ μs: 1000000 ++ Human: 1s ++ ++Original: 300s ++ μs: 300000000 ++ Human: 5min ++ ++Original: 1year 0.000001s ++ μs: 31557600000001 ++ Human: 1y 1us ++ ++ ++ ++ ++ ++ <command>systemd-analyze cat-config</command> ++ <replaceable>NAME</replaceable>|<replaceable>PATH</replaceable>... ++ ++ This command is similar to systemctl cat, but operates on config files. It ++ will copy the contents of a config file and any drop-ins to standard output, using the usual systemd ++ set of directories and rules for precedence. Each argument must be either an absolute path including ++ the prefix (such as /etc/systemd/logind.conf or ++ /usr/lib/systemd/logind.conf), or a name relative to the prefix (such as ++ systemd/logind.conf). ++ ++ ++ Showing logind configuration ++ $ systemd-analyze cat-config systemd/logind.conf + # /etc/systemd/logind.conf + ... + [Login] +@@ -201,90 +431,122 @@ NAutoVTs=8 + + # /etc/systemd/logind.conf.d/50-override.conf + ... some administrator override +- +- +- +- systemd-analyze unit-paths outputs a list of all +- directories from which unit files, .d overrides, and +- .wants, .requires symlinks may be +- loaded. Combine with to retrieve the list for the user +- manager instance, and for the global configuration of +- user manager instances. Note that this verb prints the list that is compiled into +- systemd-analyze itself, and does not comunicate with the +- running manager. Use +- systemctl [--user] [--global] show -p UnitPath --value +- to retrieve the actual list that the manager uses, with any empty directories +- omitted. +- +- systemd-analyze log-level +- prints the current log level of the systemd daemon. +- If an optional argument LEVEL is provided, then the command changes the current log +- level of the systemd daemon to LEVEL (accepts the same values as +- described in +- systemd1). +- +- systemd-analyze log-target +- prints the current log target of the systemd daemon. +- If an optional argument TARGET is provided, then the command changes the current log +- target of the systemd daemon to TARGET (accepts the same values as +- , described in +- systemd1). +- +- systemd-analyze syscall-filter SET +- will list system calls contained in the specified system call set SET, +- or all known sets if no sets are specified. Argument SET must include +- the @ prefix. +- +- systemd-analyze verify will load unit files and print +- warnings if any errors are detected. Files specified on the command line will be +- loaded, but also any other units referenced by them. The full unit search path is +- formed by combining the directories for all command line arguments, and the usual unit +- load paths (variable $SYSTEMD_UNIT_PATH is supported, and may be +- used to replace or augment the compiled in set of unit load paths; see +- systemd.unit5). +- All units files present in the directories containing the command line arguments will +- be used in preference to the other paths. +- +- systemd-analyze calendar will parse and normalize repetitive calendar time events, and +- will calculate when they will elapse next. This takes the same input as the OnCalendar= setting +- in systemd.timer5, following the +- syntax described in +- systemd.time7. +- +- systemd-analyze service-watchdogs +- prints the current state of service runtime watchdogs of the systemd daemon. +- If an optional boolean argument is provided, then globally enables or disables the service +- runtime watchdogs () and emergency actions (e.g. +- or ); see +- systemd.service5. +- The hardware watchdog is not affected by this setting. +- +- systemd-analyze security analyzes the security and sandboxing settings of one or more +- specified service units. If at least one unit name is specified the security settings of the specified service +- units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded, +- long-running service units are inspected and a terse table with results shown. The command checks for various +- security-related service settings, assigning each a numeric "exposure level" value, depending on how important a +- setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range +- 0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied +- sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only +- analyzes the per-service security features systemd itself implements. This means that any additional security +- mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should +- not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the +- service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels +- do indicate however that most likely the service might benefit from additional settings applied to them. Please +- note that many of the security and sandboxing settings individually can be circumvented — unless combined with +- others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing +- options can be undone by the service code itself. Due to that is essential that each service uses the most +- comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these +- combinations and relationships between the settings, but not all. Also note that the security and sandboxing +- settings analyzed here only apply to the operations executed by the service code itself. If a service has access to +- an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same +- restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is +- not validated too. ++ ++ ++ + +- If no command is passed, systemd-analyze +- time is implied. ++ ++ <command>systemd-analyze verify <replaceable>FILE</replaceable>...</command> ++ ++ This command will load unit files and print warnings if any errors are detected. Files specified ++ on the command line will be loaded, but also any other units referenced by them. The full unit search ++ path is formed by combining the directories for all command line arguments, and the usual unit load ++ paths (variable $SYSTEMD_UNIT_PATH is supported, and may be used to replace or ++ augment the compiled in set of unit load paths; see ++ systemd.unit5). All ++ units files present in the directories containing the command line arguments will be used in preference ++ to the other paths. ++ ++ The following errors are currently detected: ++ ++ unknown sections and directives, ++ ++ missing dependencies which are required to start the given unit, ++ ++ man pages listed in Documentation= which are not found in the ++ system, ++ ++ commands listed in ExecStart= and similar which are not found in ++ the system or not executable. ++ + ++ ++ Misspelt directives ++ ++ $ cat ./user.slice ++[Unit] ++WhatIsThis=11 ++Documentation=man:nosuchfile(1) ++Requires=different.service ++ ++[Service] ++Description=x ++ ++$ systemd-analyze verify ./user.slice ++[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit' ++[./user.slice:13] Unknown section 'Service'. Ignoring. ++Error: org.freedesktop.systemd1.LoadFailed: ++ Unit different.service failed to load: ++ No such file or directory. ++Failed to create user.slice/start: Invalid argument ++user.slice: man nosuchfile(1) command failed with code 16 ++ ++ ++ ++ ++ Missing service units ++ ++ $ tail ./a.socket ./b.socket ++==> ./a.socket <== ++[Socket] ++ListenStream=100 ++ ++==> ./b.socket <== ++[Socket] ++ListenStream=100 ++Accept=yes ++ ++$ systemd-analyze verify ./a.socket ./b.socket ++Service a.service not loaded, a.socket cannot be started. ++Service b@0.service not loaded, b.socket cannot be started. ++ ++ ++ ++ ++ ++ <command>systemd-analyze security <optional><replaceable>UNIT</replaceable>...</optional></command> ++ ++ This command analyzes the security and sandboxing settings of one or more specified service ++ units. If at least one unit name is specified the security settings of the specified service units are ++ inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded, ++ long-running service units are inspected and a terse table with results shown. The command checks for ++ various security-related service settings, assigning each a numeric "exposure level" value, depending ++ on how important a setting is. It then calculates an overall exposure level for the whole unit, which ++ is an estimation in the range 0.0…10.0 indicating how exposed a service is security-wise. High exposure ++ levels indicate very little applied sandboxing. Low exposure levels indicate tight sandboxing and ++ strongest security restrictions. Note that this only analyzes the per-service security features systemd ++ itself implements. This means that any additional security mechanisms applied by the service code ++ itself are not accounted for. The exposure level determined this way should not be misunderstood: a ++ high exposure level neither means that there is no effective sandboxing applied by the service code ++ itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels do ++ indicate however that most likely the service might benefit from additional settings applied to ++ them. ++ ++ Please note that many of the security and sandboxing settings individually can be circumvented — ++ unless combined with others. For example, if a service retains the privilege to establish or undo mount ++ points many of the sandboxing options can be undone by the service code itself. Due to that is ++ essential that each service uses the most comprehensive and strict sandboxing and security settings ++ possible. The tool will take into account some of these combinations and relationships between the ++ settings, but not all. Also note that the security and sandboxing settings analyzed here only apply to ++ the operations executed by the service code itself. If a service has access to an IPC system (such as ++ D-Bus) it might request operations from other services that are not subject to the same ++ restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access ++ policy is not validated too. ++ ++ ++ Analyze <filename noindex="true">systemd-logind.service</filename> ++ ++ $ systemd-analyze security --no-pager systemd-logind.service ++ NAME DESCRIPTION EXPOSURE ++✗ PrivateNetwork= Service has access to the host's network 0.5 ++✗ User=/DynamicUser= Service runs as root user 0.4 ++✗ DeviceAllow= Service has no device ACL 0.2 ++✓ IPAddressDeny= Service blocks all IP address ranges ++... ++→ Overall exposure level for systemd-logind.service: 4.1 OK 🙂 ++ ++ ++ + + + +@@ -408,88 +670,6 @@ NAutoVTs=8 + otherwise. + + +- +- Examples for <command>dot</command> +- +- +- Plots all dependencies of any unit whose name starts with +- <literal>avahi-daemon</literal> +- +- $ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg +-$ eog avahi.svg +- +- +- +- Plots the dependencies between all known target units +- +- $ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg +-$ eog targets.svg +- +- +- +- +- Examples for <command>verify</command> +- +- The following errors are currently detected: +- +- unknown sections and directives, +- +- +- missing dependencies which are required to start +- the given unit, +- +- man pages listed in +- Documentation= which are not found in the +- system, +- +- commands listed in ExecStart= +- and similar which are not found in the system or not +- executable. +- +- +- +- Misspelt directives +- +- $ cat ./user.slice +-[Unit] +-WhatIsThis=11 +-Documentation=man:nosuchfile(1) +-Requires=different.service +- +-[Service] +-Description=x +- +-$ systemd-analyze verify ./user.slice +-[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit' +-[./user.slice:13] Unknown section 'Service'. Ignoring. +-Error: org.freedesktop.systemd1.LoadFailed: +- Unit different.service failed to load: +- No such file or directory. +-Failed to create user.slice/start: Invalid argument +-user.slice: man nosuchfile(1) command failed with code 16 +- +- +- +- +- Missing service units +- +- $ tail ./a.socket ./b.socket +-==> ./a.socket <== +-[Socket] +-ListenStream=100 +- +-==> ./b.socket <== +-[Socket] +-ListenStream=100 +-Accept=yes +- +-$ systemd-analyze verify ./a.socket ./b.socket +-Service a.service not loaded, a.socket cannot be started. +-Service b@0.service not loaded, b.socket cannot be started. +- +- +- +- + + + diff --git a/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch b/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch new file mode 100644 index 0000000..f5ba536 --- /dev/null +++ b/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch @@ -0,0 +1,132 @@ +From ac7db0c5b48f1090f77dbcfa0a1e0dc08d5c471e Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 14 Oct 2019 15:26:48 +0200 +Subject: [PATCH] travis: move to CentOS 8 docker images + +As the CentOS 8 Docker images is finally out, we can use it and drop the +plethora of workarounds we had to implement to compile RHEL8 systemd on +CentOS 7. + +Resolves: #1761519 +--- + .travis.yml | 22 ++++++++++------------ + ci/travis-centos-rhel8.sh | 32 +++++++++----------------------- + 2 files changed, 19 insertions(+), 35 deletions(-) + +diff --git a/.travis.yml b/.travis.yml +index 0010da5784..70c60cf24e 100644 +--- a/.travis.yml ++++ b/.travis.yml +@@ -9,42 +9,40 @@ env: + + jobs: + include: +- - name: CentOS 7 ++ - name: CentOS 8 + language: bash + env: +- - CENTOS_RELEASE="centos7" ++ - CENTOS_RELEASE="centos8" + - CONT_NAME="systemd-centos-$CENTOS_RELEASE" + - DOCKER_EXEC="docker exec -ti $CONT_NAME" + before_install: + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version + install: +- - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP ++ - $CI_ROOT/travis-centos-rhel8.sh SETUP + script: + - set -e + # Build systemd +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN ++ - $CI_ROOT/travis-centos-rhel8.sh RUN + - set +e + after_script: +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP ++ - $CI_ROOT/travis-centos-rhel8.sh CLEANUP + +- - name: CentOS 7 (ASan+UBSan) ++ - name: CentOS 8 (ASan+UBSan) + language: bash + env: +- - CENTOS_RELEASE="centos7" ++ - CENTOS_RELEASE="centos8" + - CONT_NAME="systemd-centos-$CENTOS_RELEASE" + - DOCKER_EXEC="docker exec -ti $CONT_NAME" + before_install: + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker --version + install: +- - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP ++ - $CI_ROOT/travis-centos-rhel8.sh SETUP + script: + - set -e + # Build systemd +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN_ASAN ++ - $CI_ROOT/travis-centos-rhel8.sh RUN_ASAN + - set +e + after_script: +- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP ++ - $CI_ROOT/travis-centos-rhel8.sh CLEANUP +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index c3d1018682..ade44a0413 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -15,10 +15,7 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" + DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" + DOCKER_RUN="${DOCKER_RUN:-docker run}" + REPO_ROOT="${REPO_ROOT:-$PWD}" +-ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja-build libasan net-tools strace nc busybox e2fsprogs quota dnsmasq) +-# Repo with additional depencencies to compile newer systemd on CentOS 7 +-COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo" +-COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}" ++ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq) + # RHEL8 options + CONFIGURE_OPTS=( + -Dsysvinit-path=/etc/rc.d/init.d +@@ -95,18 +92,14 @@ for phase in "${PHASES[@]}"; do + -dit --net=host centos:$CENTOS_RELEASE /sbin/init + # Beautiful workaround for Fedora's version of Docker + sleep 1 +- $DOCKER_EXEC yum makecache +- $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH" +- $DOCKER_EXEC yum -q -y install epel-release yum-utils +- $DOCKER_EXEC yum-config-manager -q --enable epel +- $DOCKER_EXEC yum -y upgrade +- # Install necessary build/test requirements +- $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" +- $DOCKER_EXEC python3.6 -m ensurepip +- $DOCKER_EXEC python3.6 -m pip install meson +- # Create necessary symlinks +- $DOCKER_EXEC ln --force -s /usr/bin/python3.6 /usr/bin/python3 +- $DOCKER_EXEC ln --force -s /usr/bin/ninja-build /usr/bin/ninja ++ $DOCKER_EXEC dnf makecache ++ # Install and enable EPEL ++ $DOCKER_EXEC dnf -q -y install epel-release dnf-utils "${ADDITIONAL_DEPS[@]}" ++ $DOCKER_EXEC dnf config-manager -q --enable epel ++ # Upgrade the container to get the most recent environment ++ $DOCKER_EXEC dnf -y upgrade ++ # Install systemd's build dependencies ++ $DOCKER_EXEC dnf -q -y --enablerepo "PowerTools" builddep systemd + ;; + RUN) + info "Run phase" +@@ -117,16 +110,9 @@ for phase in "${PHASES[@]}"; do + # unexpected fails due to incompatibilities with older systemd + $DOCKER_EXEC ninja -C build install + docker restart $CONT_NAME +- # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt +- # and it's pointless to run it on a VM in a Docker container... +- echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl" + $DOCKER_EXEC ninja -C build test + ;; + RUN_ASAN|RUN_CLANG_ASAN) +- # Let's install newer gcc for proper ASan/UBSan support +- $DOCKER_EXEC yum -y install centos-release-scl +- $DOCKER_EXEC yum -y install devtoolset-8 devtoolset-8-libasan-devel libasan5 devtoolset-8-libubsan-devel libubsan1 +- $DOCKER_EXEC bash -c "echo 'source scl_source enable devtoolset-8' >> /root/.bashrc" + # Note to my future frustrated self: docker exec runs the given command + # as sh -c 'command' - which means both .bash_profile and .bashrc will + # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e. diff --git a/SOURCES/0220-travis-drop-SCL-remains.patch b/SOURCES/0220-travis-drop-SCL-remains.patch new file mode 100644 index 0000000..30d5378 --- /dev/null +++ b/SOURCES/0220-travis-drop-SCL-remains.patch @@ -0,0 +1,50 @@ +From 5b14988845b591f6fa2fc1e032618fe882827f4a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 14 Oct 2019 16:22:51 +0200 +Subject: [PATCH] travis: drop SCL remains + +The `bash -ic` wrapper existed solely to make SCL work as expected + +Resolves: #1761519 +--- + ci/travis-centos-rhel8.sh | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index ade44a0413..da131c726b 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -113,22 +113,12 @@ for phase in "${PHASES[@]}"; do + $DOCKER_EXEC ninja -C build test + ;; + RUN_ASAN|RUN_CLANG_ASAN) +- # Note to my future frustrated self: docker exec runs the given command +- # as sh -c 'command' - which means both .bash_profile and .bashrc will +- # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e. +- # sh -l), whereas .bashrc is sourced for NON-LOGIN INTERACTIVE shells +- # (i.e. sh -i). +- # As the default docker exec command lacks either of those options, +- # we need to use a wrapper command which runs the wanted command +- # under an explicit bash -i, so the SCL source above works properly. +- docker exec -it $CONT_NAME bash -ic 'gcc --version' +- + if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then + ENV_VARS="-e CC=clang -e CXX=clang++" + MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 + fi +- docker exec $ENV_VARS -it $CONT_NAME bash -ic "meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}" +- docker exec -it $CONT_NAME bash -ic 'ninja -v -C build' ++ docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]} ++ docker exec -it $CONT_NAME ninja -v -C build + + # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. + travis_wait docker exec --interactive=false \ +@@ -136,7 +126,7 @@ for phase in "${PHASES[@]}"; do + -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \ + -e "TRAVIS=$TRAVIS" \ + -t $CONT_NAME \ +- bash -ic 'meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs' ++ meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs + ;; + CLEANUP) + info "Cleanup phase" diff --git a/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch b/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch new file mode 100644 index 0000000..97f64e0 --- /dev/null +++ b/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch @@ -0,0 +1,110 @@ +From 8bd791fb3a8e85063e297204bdef8004aacd22b1 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 8 Aug 2018 18:27:15 +0900 +Subject: [PATCH] syslog: fix segfault in syslog_parse_priority() + +(cherry picked from commit a5ee33b951cfa22db53d0274c9c6c0d9d4dae39d) + +Resolves: #1761519 +--- + src/basic/syslog-util.c | 20 +++++++++++--------- + src/journal/test-journal-syslog.c | 20 ++++++++++++++++++++ + 2 files changed, 31 insertions(+), 9 deletions(-) + +diff --git a/src/basic/syslog-util.c b/src/basic/syslog-util.c +index 21461fa581..fe129482f3 100644 +--- a/src/basic/syslog-util.c ++++ b/src/basic/syslog-util.c +@@ -10,7 +10,8 @@ + + int syslog_parse_priority(const char **p, int *priority, bool with_facility) { + int a = 0, b = 0, c = 0; +- int k; ++ const char *end; ++ size_t k; + + assert(p); + assert(*p); +@@ -19,21 +20,22 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) { + if ((*p)[0] != '<') + return 0; + +- if (!strchr(*p, '>')) ++ end = strchr(*p, '>'); ++ if (!end) + return 0; + +- if ((*p)[2] == '>') { ++ k = end - *p; ++ assert(k > 0); ++ ++ if (k == 2) + c = undecchar((*p)[1]); +- k = 3; +- } else if ((*p)[3] == '>') { ++ else if (k == 3) { + b = undecchar((*p)[1]); + c = undecchar((*p)[2]); +- k = 4; +- } else if ((*p)[4] == '>') { ++ } else if (k == 4) { + a = undecchar((*p)[1]); + b = undecchar((*p)[2]); + c = undecchar((*p)[3]); +- k = 5; + } else + return 0; + +@@ -46,7 +48,7 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) { + else + *priority = (*priority & LOG_FACMASK) | c; + +- *p += k; ++ *p += k + 1; + return 1; + } + +diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c +index 7294cde032..120477cc9f 100644 +--- a/src/journal/test-journal-syslog.c ++++ b/src/journal/test-journal-syslog.c +@@ -4,6 +4,7 @@ + #include "journald-syslog.h" + #include "macro.h" + #include "string-util.h" ++#include "syslog-util.h" + + static void test_syslog_parse_identifier(const char *str, + const char *ident, const char *pid, const char *rest, int ret) { +@@ -19,6 +20,17 @@ static void test_syslog_parse_identifier(const char *str, + assert_se(streq(buf, rest)); + } + ++static void test_syslog_parse_priority(const char *str, int priority, int ret) { ++ const char *buf = str; ++ int priority2, ret2; ++ ++ ret2 = syslog_parse_priority(&buf, &priority2, false); ++ ++ assert_se(ret == ret2); ++ if (ret2 == 1) ++ assert_se(priority == priority2); ++} ++ + int main(void) { + test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11); + test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6); +@@ -33,5 +45,13 @@ int main(void) { + test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6); + test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0); + ++ test_syslog_parse_priority("<>", 0, 0); ++ test_syslog_parse_priority("<>aaa", 0, 0); ++ test_syslog_parse_priority("", 0, 0); ++ test_syslog_parse_priority("aaa", 0, 0); ++ test_syslog_parse_priority(" ", 0, 0); ++ test_syslog_parse_priority(" aaa", 0, 0); ++ /* TODO: add test cases of valid priorities */ ++ + return 0; + } diff --git a/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch b/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch new file mode 100644 index 0000000..bfe310a --- /dev/null +++ b/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch @@ -0,0 +1,45 @@ +From fbe5fa22f5b99d4e444db54aadb661e9c932eb6c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 13:00:40 +0100 +Subject: [PATCH] sd-bus: make strict asan shut up + +asan doesn't like it if we use strndup() (i.e. a string function) on a +non-NULL terminated buffer (i.e. something that isn't really a string). + +Let's hence use memdup_suffix0() instead of strndup(), which is more +appropriate for binary data that is to become a string. + +Fixes: #10385 +(cherry picked from commit ac0a94f7438b49a0890d9806db1fa211a5bca10a) + +Resolves: #1761519 +--- + src/libsystemd/sd-bus/bus-message.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 53cbd675b7..19cb2b9a97 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5101,6 +5101,7 @@ int bus_message_parse_fields(sd_bus_message *m) { + return -EBADMSG; + + if (*p == 0) { ++ char *k; + size_t l; + + /* We found the beginning of the signature +@@ -5114,9 +5115,11 @@ int bus_message_parse_fields(sd_bus_message *m) { + p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END) + return -EBADMSG; + +- if (free_and_strndup(&m->root_container.signature, +- p + 1 + 1, l - 2) < 0) ++ k = memdup_suffix0(p + 1 + 1, l - 2); ++ if (!k) + return -ENOMEM; ++ ++ free_and_replace(m->root_container.signature, k); + break; + } + diff --git a/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch b/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch new file mode 100644 index 0000000..d5df9f1 --- /dev/null +++ b/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch @@ -0,0 +1,43 @@ +From 2f44943836b69455792a5422673f8a69bc9705ba Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 14 Oct 2019 17:14:35 +0200 +Subject: [PATCH] travis: don't run slow tests under ASan/UBSan + +Resolves: #1761519 +--- + ci/travis-centos-rhel8.sh | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index da131c726b..a1502e15ee 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -65,10 +65,6 @@ CONFIGURE_OPTS=( + -Dnetworkd=false + -Dtimesyncd=false + -Ddefault-hierarchy=legacy +- # Custom options +- -Dslow-tests=true +- -Dtests=unsafe +- -Dinstall-tests=true + ) + + function info() { +@@ -104,7 +100,7 @@ for phase in "${PHASES[@]}"; do + RUN) + info "Run phase" + # Build systemd +- docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}" ++ docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}" + $DOCKER_EXEC ninja -v -C build + # Let's install the new systemd and "reboot" the container to avoid + # unexpected fails due to incompatibilities with older systemd +@@ -117,7 +113,7 @@ for phase in "${PHASES[@]}"; do + ENV_VARS="-e CC=clang -e CXX=clang++" + MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 + fi +- docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]} ++ docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}" + docker exec -it $CONT_NAME ninja -v -C build + + # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. diff --git a/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch b/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch new file mode 100644 index 0000000..b79434e --- /dev/null +++ b/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch @@ -0,0 +1,67 @@ +From 6240d78097c6f828aa2ca3b50ac322b41dc41fd1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 23 Aug 2019 11:34:45 +0200 +Subject: [PATCH] kernel-install: do not require non-empty kernel cmdline + +When booting with Fedora-Server-dvd-x86_64-30-20190411.n.0.iso, +/proc/cmdline is empty (libvirt, qemu host with bios, not sure if that +matters), after installation to disk, anaconda would "crash" in kernel-core +%posttrans, after calling kernel-install, because dracut would fail +with + +> Could not determine the kernel command line parameters. +> Please specify the kernel command line in /etc/kernel/cmdline! + +I guess it's legitimate, even if unusual, to have no cmdline parameters. +Two changes are done in this patch: + +1. do not fail if the cmdline is empty. +2. if /usr/lib/kernel/cmdline or /etc/kernel/cmdline are present, but + empty, ignore /proc/cmdline. If there's explicit configuration to + have empty cmdline, don't ignore it. + +The same change was done in dracut: +https://github.com/dracutdevs/dracut/pull/561. + +(cherry picked from commit 88e1306af6380794842fb31108ba67895799fab4) + +Resolves: #1701454 +--- + src/kernel-install/90-loaderentry.install | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install +index a271cdb8a0..1619301536 100644 +--- a/src/kernel-install/90-loaderentry.install ++++ b/src/kernel-install/90-loaderentry.install +@@ -43,13 +43,13 @@ if ! [[ $PRETTY_NAME ]]; then + PRETTY_NAME="Linux $KERNEL_VERSION" + fi + +-declare -a BOOT_OPTIONS +- + if [[ -f /etc/kernel/cmdline ]]; then + read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline +-fi ++elif [[ -f /usr/lib/kernel/cmdline ]]; then ++ read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline ++else ++ declare -a BOOT_OPTIONS + +-if ! [[ ${BOOT_OPTIONS[*]} ]]; then + read -r -d '' -a line < /proc/cmdline + for i in "${line[@]}"; do + [[ "${i#initrd=*}" != "$i" ]] && continue +@@ -57,12 +57,6 @@ if ! [[ ${BOOT_OPTIONS[*]} ]]; then + done + fi + +-if ! [[ ${BOOT_OPTIONS[*]} ]]; then +- echo "Could not determine the kernel command line parameters." >&2 +- echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 +- exit 1 +-fi +- + cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" && + chown root:root "$BOOT_DIR_ABS/linux" && + chmod 0644 "$BOOT_DIR_ABS/linux" || { diff --git a/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch b/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch new file mode 100644 index 0000000..1a3af20 --- /dev/null +++ b/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch @@ -0,0 +1,36 @@ +From c6c8e0d097d6ba12471c6112c3fd339ea40329d5 Mon Sep 17 00:00:00 2001 +From: Thadeu Lima de Souza Cascardo +Date: Mon, 13 May 2019 16:58:01 -0300 +Subject: [PATCH] ask-password: prevent buffer overrow when reading from + keyring + +When we read from keyring, a temporary buffer is allocated in order to +determine the size needed for the entire data. However, when zeroing that area, +we use the data size returned by the read instead of the lesser size allocate +for the buffer. + +That will cause memory corruption that causes systemd-cryptsetup to crash +either when a single large password is used or when multiple passwords have +already been pushed to the keyring. + +Signed-off-by: Thadeu Lima de Souza Cascardo +(cherry picked from commit 59c55e73eaee345e1ee67c23eace8895ed499693) + +Resolves: #1752050 +--- + src/shared/ask-password-api.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c +index 682dc754fc..764ebd08e1 100644 +--- a/src/shared/ask-password-api.c ++++ b/src/shared/ask-password-api.c +@@ -79,7 +79,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) { + if (n < m) + break; + +- explicit_bzero(p, n); ++ explicit_bzero(p, m); + free(p); + m *= 2; + } diff --git a/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch b/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch new file mode 100644 index 0000000..d568e76 --- /dev/null +++ b/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch @@ -0,0 +1,37 @@ +From 985837dab9c892858a92ae50043843307f5e0714 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 19 Jul 2019 18:29:11 +0200 +Subject: [PATCH] core: try to reopen /dev/kmsg again right after mounting /dev + +I was debugging stuff during early boot, and was confused that I never +found the logs for it in kmsg. The reason for that was that /proc is +generally not mounted the first time we do log_open() and hence +log_set_target(LOG_TARGET_KMSG) we do when running as PID 1 had not +effect. A lot later during start-up we call log_open() again where this +is fixed (after the point where we close all remaining fds still open), +but in the meantime no logs every got written to kmsg. This patch fixes +that. + +(cherry picked from commit 0a2eef1ee1fef74be9d12f7dc4d0006b645b579c) + +Resolves: #1749212 +--- + src/core/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index 44dd8348be..af7b26d6f1 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2215,6 +2215,11 @@ int main(int argc, char *argv[]) { + goto finish; + } + ++ /* Let's open the log backend a second time, in case the first time didn't ++ * work. Quite possibly we have mounted /dev just now, so /dev/kmsg became ++ * available, and it previously wasn't. */ ++ log_open(); ++ + r = initialize_security( + &loaded_policy, + &security_start_timestamp, diff --git a/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch b/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch new file mode 100644 index 0000000..d305484 --- /dev/null +++ b/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch @@ -0,0 +1,29 @@ +From 9f259b46b760b2aa08ac1fe76fe61df514e2768f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 3 Sep 2019 10:05:42 +0200 +Subject: [PATCH] buildsys: don't garbage collect sections while linking + +gc-sections is actually very aggressive and garbage collects ELF +sections used by annobin gcc plugin and annocheck then reports gaps in +coverage. Let's drop that linker flag. + +RHEL-only + +Resolves: #1748258 +--- + meson.build | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/meson.build b/meson.build +index 04b461dcd4..613a5133b6 100644 +--- a/meson.build ++++ b/meson.build +@@ -357,8 +357,6 @@ if get_option('buildtype') != 'debug' + '-ffunction-sections', + '-fdata-sections', + ] +- +- possible_link_flags += '-Wl,--gc-sections' + endif + + add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c') diff --git a/SOURCES/0228-udev-introduce-CONST-key-name.patch b/SOURCES/0228-udev-introduce-CONST-key-name.patch new file mode 100644 index 0000000..127eea3 --- /dev/null +++ b/SOURCES/0228-udev-introduce-CONST-key-name.patch @@ -0,0 +1,186 @@ +From d6210c3d053d70175d72ed1d1719497eed76000b Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 17 Oct 2019 09:37:35 +0200 +Subject: [PATCH] udev: introduce CONST key name + +Currently, there is no way to match against system-wide constants, such +as architecture or virtualization type, without forking helper binaries. +That potentially results in a huge number of spawned processes which +output always the same answer. + +This patch introduces a special CONST keyword which takes a hard-coded +string as its key and returns a value assigned to that key. Currently +implemented are CONST{arch} and CONST{virt}, which can be used to match +against the system's architecture and virtualization type. + +(based on commit 4801d8afe2ff1c1c075c9f0bc5631612172e0bb7) + +Resolves: #1762679 +--- + man/udev.xml | 26 ++++++++++++++++++++++++++ + rules/40-redhat.rules | 6 +++--- + src/udev/udev-rules.c | 32 ++++++++++++++++++++++++++++++++ + test/rule-syntax-check.py | 2 +- + 4 files changed, 62 insertions(+), 4 deletions(-) + +diff --git a/man/udev.xml b/man/udev.xml +index bdf901a8f0..8c1eb41787 100644 +--- a/man/udev.xml ++++ b/man/udev.xml +@@ -236,6 +236,32 @@ + + + ++ ++ CONST{key} ++ ++ Match against a system-wide constant. Supported keys are: ++ ++ ++ arch ++ ++ System's architecture. See in ++ systemd.unit5 ++ for possible values. ++ ++ ++ ++ virt ++ ++ System's virtualization environment. See ++ systemd-detect-virt1 ++ for possible values. ++ ++ ++ ++ Unknown keys will never match. ++ ++ ++ + + TAG + +diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules +index fadc6e59f1..3c95cd2df0 100644 +--- a/rules/40-redhat.rules ++++ b/rules/40-redhat.rules +@@ -6,11 +6,11 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online} + # Memory hotadd request + SUBSYSTEM!="memory", GOTO="memory_hotplug_end" + ACTION!="add", GOTO="memory_hotplug_end" +-PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end" +-PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end" ++CONST{arch}=="s390*", GOTO="memory_hotplug_end" ++CONST{arch}=="ppc64*", GOTO="memory_hotplug_end" + + ENV{.state}="online" +-PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable" ++CONST{virt}=="none", ENV{.state}="online_movable" + ATTR{state}=="offline", ATTR{state}="$env{.state}" + + LABEL="memory_hotplug_end" +diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c +index 58af863f3d..a246cbe67e 100644 +--- a/src/udev/udev-rules.c ++++ b/src/udev/udev-rules.c +@@ -17,6 +17,7 @@ + #include + + #include "alloc-util.h" ++#include "architecture.h" + #include "conf-files.h" + #include "dirent-util.h" + #include "escape.h" +@@ -34,6 +35,7 @@ + #include "udev.h" + #include "user-util.h" + #include "util.h" ++#include "virt.h" + + #define PREALLOC_TOKEN 2048 + +@@ -123,6 +125,7 @@ enum token_type { + TK_M_DEVLINK, /* val */ + TK_M_NAME, /* val */ + TK_M_ENV, /* val, attr */ ++ TK_M_CONST, /* val, attr */ + TK_M_TAG, /* val */ + TK_M_SUBSYSTEM, /* val */ + TK_M_DRIVER, /* val */ +@@ -259,6 +262,7 @@ static const char *token_str(enum token_type type) { + [TK_M_DEVLINK] = "M DEVLINK", + [TK_M_NAME] = "M NAME", + [TK_M_ENV] = "M ENV", ++ [TK_M_CONST] = "M CONST", + [TK_M_TAG] = "M TAG", + [TK_M_SUBSYSTEM] = "M SUBSYSTEM", + [TK_M_DRIVER] = "M DRIVER", +@@ -370,6 +374,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) { + case TK_M_SYSCTL: + case TK_M_ATTRS: + case TK_M_ENV: ++ case TK_M_CONST: + case TK_A_ATTR: + case TK_A_SYSCTL: + case TK_A_ENV: +@@ -903,6 +908,7 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, + token->key.builtin_cmd = *(enum udev_builtin_cmd *)data; + break; + case TK_M_ENV: ++ case TK_M_CONST: + case TK_M_ATTR: + case TK_M_SYSCTL: + case TK_M_ATTRS: +@@ -1226,6 +1232,17 @@ static void add_rule(struct udev_rules *rules, char *line, + rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr); + } + ++ } else if (startswith(key, "CONST{")) { ++ attr = get_key_attribute(rules->udev, key + STRLEN("CONST")); ++ if (attr == NULL || !STR_IN_SET(attr, "arch", "virt")) ++ LOG_AND_RETURN("error parsing %s attribute", "CONST"); ++ ++ if (op == OP_REMOVE) ++ LOG_AND_RETURN("invalid %s operation", "CONST"); ++ ++ if (op < OP_MATCH_MAX) ++ rule_add_key(&rule_tmp, TK_M_CONST, op, value, attr); ++ + } else if (streq(key, "TAG")) { + if (op < OP_MATCH_MAX) + rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL); +@@ -1855,6 +1872,21 @@ void udev_rules_apply_to_event(struct udev_rules *rules, + goto nomatch; + break; + } ++ case TK_M_CONST: { ++ const char *key_name = rules_str(rules, cur->key.attr_off); ++ const char *value = NULL; ++ ++ if (streq(key_name, "arch")) { ++ value = architecture_to_string(uname_architecture()); ++ } else if (streq(key_name, "virt")) { ++ value = virtualization_to_string(detect_virtualization()); ++ } else ++ assert_not_reached("Invalid CONST key"); ++ ++ if (match_key(rules, cur, value)) ++ goto nomatch; ++ break; ++ } + case TK_M_TAG: { + struct udev_list_entry *list_entry; + bool match = false; +diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py +index c7c0a1a656..6e59f421f5 100755 +--- a/test/rule-syntax-check.py ++++ b/test/rule-syntax-check.py +@@ -19,7 +19,7 @@ quoted_string_re = r'"(?:[^\\"]|\\.)*"' + no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$') + # PROGRAM can also be specified as an assignment. + program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$') +-args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$') ++args_tests = re.compile(r'(ATTRS?|ENV|CONST|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$') + no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$') + args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$') + # Find comma-separated groups, but allow commas that are inside quoted strings. diff --git a/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch b/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch new file mode 100644 index 0000000..655f32a --- /dev/null +++ b/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch @@ -0,0 +1,50 @@ +From e1bd03e75860fb349a6de589bbb1274acc454aef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Fri, 13 Sep 2019 11:18:18 +0200 +Subject: [PATCH] Call getgroups() to know size of supplementary groups array + to allocate + +Resolves RHBZ #1743230 - journalctl dumps core when stack limit is reduced to 256 KB + +(cherry picked from commit f5e0b942af1e86993c21f4e5c84342bb10403dac) + +Resolves: #1743235 +--- + src/basic/user-util.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index a562a397c7..c533f67025 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -358,9 +358,8 @@ char* gid_to_name(gid_t gid) { + } + + int in_gid(gid_t gid) { +- long ngroups_max; + gid_t *gids; +- int r, i; ++ int ngroups, r, i; + + if (getgid() == gid) + return 1; +@@ -371,12 +370,15 @@ int in_gid(gid_t gid) { + if (!gid_is_valid(gid)) + return -EINVAL; + +- ngroups_max = sysconf(_SC_NGROUPS_MAX); +- assert(ngroups_max > 0); ++ ngroups = getgroups(0, NULL); ++ if (ngroups < 0) ++ return -errno; ++ if (ngroups == 0) ++ return 0; + +- gids = newa(gid_t, ngroups_max); ++ gids = newa(gid_t, ngroups); + +- r = getgroups(ngroups_max, gids); ++ r = getgroups(ngroups, gids); + if (r < 0) + return -errno; + diff --git a/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch b/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch new file mode 100644 index 0000000..691f180 --- /dev/null +++ b/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch @@ -0,0 +1,30 @@ +From 1bf923686a6842f222b1ef5f5174511340c75685 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 1 Oct 2019 08:45:08 +0200 +Subject: [PATCH] Consider smb3 as remote filesystem + +Currently systemd will treat smb3 as local filesystem and cause +can't boot failures. Add smb3 to the list of remote filesystems +to fix this issue. + +Signed-off-by: Kenneth D'souza + +(cherry picked from commit ff7d6a740b0c6fa3be63d3908a0858730a0837c5) + +Resolves: #1757257 +--- + src/basic/mount-util.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 3670b7f591..5b04e21f34 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -603,6 +603,7 @@ bool fstype_is_network(const char *fstype) { + return STR_IN_SET(fstype, + "afs", + "cifs", ++ "smb3", + "smbfs", + "sshfs", + "ncpfs", diff --git a/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch b/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch new file mode 100644 index 0000000..5d740cf --- /dev/null +++ b/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch @@ -0,0 +1,114 @@ +From f057aa6bb604845fa10ad569bca306e5e1e8fe0d Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 18 Mar 2019 11:48:34 +0100 +Subject: [PATCH] process-util: introduce pid_is_my_child() helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +No functional changes. + +Thanks Renaud Métrich for backporting this to RHEL. +Resolves: #1744972 +--- + src/basic/process-util.c | 14 ++++++++++++++ + src/basic/process-util.h | 1 + + src/core/cgroup.c | 7 ++----- + src/core/service.c | 8 ++------ + 4 files changed, 19 insertions(+), 11 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index aa3eff779a..6dbeee9dda 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -903,6 +903,20 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) { + return 0; + } + ++int pid_is_my_child(pid_t pid) { ++ pid_t ppid; ++ int r; ++ ++ if (pid <= 1) ++ return false; ++ ++ r = get_process_ppid(pid, &ppid); ++ if (r < 0) ++ return r; ++ ++ return ppid == getpid_cached(); ++} ++ + bool pid_is_unwaited(pid_t pid) { + /* Checks whether a PID is still valid at all, including a zombie */ + +diff --git a/src/basic/process-util.h b/src/basic/process-util.h +index a5bb072b25..a3bd2851b4 100644 +--- a/src/basic/process-util.h ++++ b/src/basic/process-util.h +@@ -68,6 +68,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value); + + bool pid_is_alive(pid_t pid); + bool pid_is_unwaited(pid_t pid); ++int pid_is_my_child(pid_t pid); + int pid_from_same_root_fs(pid_t pid); + + bool is_main_thread(void); +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 62ab41a288..b7ed07e65b 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1876,7 +1876,7 @@ void unit_prune_cgroup(Unit *u) { + + int unit_search_main_pid(Unit *u, pid_t *ret) { + _cleanup_fclose_ FILE *f = NULL; +- pid_t pid = 0, npid, mypid; ++ pid_t pid = 0, npid; + int r; + + assert(u); +@@ -1889,15 +1889,12 @@ int unit_search_main_pid(Unit *u, pid_t *ret) { + if (r < 0) + return r; + +- mypid = getpid_cached(); + while (cg_read_pid(f, &npid) > 0) { +- pid_t ppid; + + if (npid == pid) + continue; + +- /* Ignore processes that aren't our kids */ +- if (get_process_ppid(npid, &ppid) >= 0 && ppid != mypid) ++ if (pid_is_my_child(npid) == 0) + continue; + + if (pid != 0) +diff --git a/src/core/service.c b/src/core/service.c +index 24f167572a..614ba05d89 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -139,8 +139,6 @@ static void service_unwatch_pid_file(Service *s) { + } + + static int service_set_main_pid(Service *s, pid_t pid) { +- pid_t ppid; +- + assert(s); + + if (pid <= 1) +@@ -159,12 +157,10 @@ static int service_set_main_pid(Service *s, pid_t pid) { + + s->main_pid = pid; + s->main_pid_known = true; ++ s->main_pid_alien = pid_is_my_child(pid) == 0; + +- if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid_cached()) { ++ if (s->main_pid_alien) + log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", pid); +- s->main_pid_alien = true; +- } else +- s->main_pid_alien = false; + + return 0; + } diff --git a/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch b/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch new file mode 100644 index 0000000..46cf59e --- /dev/null +++ b/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch @@ -0,0 +1,323 @@ +From 79e9566ec0a61d887ab63f17192dbd71aae36ee0 Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 18 Mar 2019 20:59:36 +0100 +Subject: [PATCH] core: reduce the number of stalled PIDs from the watched + processes list when possible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some PIDs can remain in the watched list even though their processes have +exited since a long time. It can easily happen if the main process of a forking +service manages to spawn a child before the control process exits for example. + +However when a pid is about to be mapped to a unit by calling unit_watch_pid(), +the caller usually knows if the pid should belong to this unit exclusively: if +we just forked() off a child, then we can be sure that its PID is otherwise +unused. In this case we take this opportunity to remove any stalled PIDs from +the watched process list. + +If we learnt about a PID in any other form (for example via PID file, via +searching, MAINPID= and so on), then we can't assume anything. + +Thanks Renaud Métrich for backporting this to RHEL. +Resolves: #1744972 +--- + src/core/cgroup.c | 2 +- + src/core/dbus-scope.c | 2 +- + src/core/manager.c | 10 ++++++++++ + src/core/manager.h | 2 ++ + src/core/mount.c | 5 ++--- + src/core/service.c | 16 ++++++++-------- + src/core/socket.c | 7 +++---- + src/core/swap.c | 5 ++--- + src/core/unit.c | 8 +++++++- + src/core/unit.h | 2 +- + src/test/test-watch-pid.c | 12 ++++++------ + 11 files changed, 43 insertions(+), 28 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index b7ed07e65b..76eafdc082 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1926,7 +1926,7 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) { + pid_t pid; + + while ((r = cg_read_pid(f, &pid)) > 0) { +- r = unit_watch_pid(u, pid); ++ r = unit_watch_pid(u, pid, false); + if (r < 0 && ret >= 0) + ret = r; + } +diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c +index 6725f62794..0bbf64fff1 100644 +--- a/src/core/dbus-scope.c ++++ b/src/core/dbus-scope.c +@@ -106,7 +106,7 @@ static int bus_scope_set_transient_property( + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, false); + if (r < 0 && r != -EEXIST) + return r; + } +diff --git a/src/core/manager.c b/src/core/manager.c +index c83e296cf3..0eae7d46fb 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2044,6 +2044,16 @@ void manager_clear_jobs(Manager *m) { + job_finish_and_invalidate(j, JOB_CANCELED, false, false); + } + ++void manager_unwatch_pid(Manager *m, pid_t pid) { ++ assert(m); ++ ++ /* First let's drop the unit keyed as "pid". */ ++ (void) hashmap_remove(m->watch_pids, PID_TO_PTR(pid)); ++ ++ /* Then, let's also drop the array keyed by -pid. */ ++ free(hashmap_remove(m->watch_pids, PID_TO_PTR(-pid))); ++} ++ + static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) { + Manager *m = userdata; + Job *j; +diff --git a/src/core/manager.h b/src/core/manager.h +index c7f4d66ecd..fa47952d24 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -406,6 +406,8 @@ int manager_get_dump_string(Manager *m, char **ret); + + void manager_clear_jobs(Manager *m); + ++void manager_unwatch_pid(Manager *m, pid_t pid); ++ + unsigned manager_dispatch_load_queue(Manager *m); + + int manager_environment_add(Manager *m, char **minus, char **plus); +diff --git a/src/core/mount.c b/src/core/mount.c +index 2ac04e3874..5878814b1b 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -677,7 +677,7 @@ static int mount_coldplug(Unit *u) { + pid_is_unwaited(m->control_pid) && + MOUNT_STATE_WITH_PROCESS(new_state)) { + +- r = unit_watch_pid(UNIT(m), m->control_pid); ++ r = unit_watch_pid(UNIT(m), m->control_pid, false); + if (r < 0) + return r; + +@@ -781,9 +781,8 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + if (r < 0) + return r; + +- r = unit_watch_pid(UNIT(m), pid); ++ r = unit_watch_pid(UNIT(m), pid, true); + if (r < 0) +- /* FIXME: we need to do something here */ + return r; + + *_pid = pid; +diff --git a/src/core/service.c b/src/core/service.c +index 614ba05d89..310838a5f6 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -974,7 +974,7 @@ static int service_load_pid_file(Service *s, bool may_warn) { + if (r < 0) + return r; + +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, false); + if (r < 0) /* FIXME: we need to do something here */ + return log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid); + +@@ -1004,7 +1004,7 @@ static void service_search_main_pid(Service *s) { + if (service_set_main_pid(s, pid) < 0) + return; + +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, false); + if (r < 0) + /* FIXME: we need to do something here */ + log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" from: %m", pid); +@@ -1135,7 +1135,7 @@ static int service_coldplug(Unit *u) { + SERVICE_RUNNING, SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) { +- r = unit_watch_pid(UNIT(s), s->main_pid); ++ r = unit_watch_pid(UNIT(s), s->main_pid, false); + if (r < 0) + return r; + } +@@ -1147,7 +1147,7 @@ static int service_coldplug(Unit *u) { + SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { +- r = unit_watch_pid(UNIT(s), s->control_pid); ++ r = unit_watch_pid(UNIT(s), s->control_pid, false); + if (r < 0) + return r; + } +@@ -1545,8 +1545,8 @@ static int service_spawn( + s->exec_fd_event_source = TAKE_PTR(exec_fd_source); + s->exec_fd_hot = false; + +- r = unit_watch_pid(UNIT(s), pid); +- if (r < 0) /* FIXME: we need to do something here */ ++ r = unit_watch_pid(UNIT(s), pid, true); ++ if (r < 0) + return r; + + *_pid = pid; +@@ -3643,7 +3643,7 @@ static void service_notify_message( + } + if (r > 0) { + service_set_main_pid(s, new_main_pid); +- unit_watch_pid(UNIT(s), new_main_pid); ++ unit_watch_pid(UNIT(s), new_main_pid, false); + notify_dbus = true; + } + } +@@ -3858,7 +3858,7 @@ static void service_bus_name_owner_change( + log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, name, pid); + + service_set_main_pid(s, pid); +- unit_watch_pid(UNIT(s), pid); ++ unit_watch_pid(UNIT(s), pid, false); + } + } + } +diff --git a/src/core/socket.c b/src/core/socket.c +index d488c64e91..b034549634 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1816,7 +1816,7 @@ static int socket_coldplug(Unit *u) { + SOCKET_FINAL_SIGTERM, + SOCKET_FINAL_SIGKILL)) { + +- r = unit_watch_pid(UNIT(s), s->control_pid); ++ r = unit_watch_pid(UNIT(s), s->control_pid, false); + if (r < 0) + return r; + +@@ -1902,9 +1902,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + if (r < 0) + return r; + +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, true); + if (r < 0) +- /* FIXME: we need to do something here */ + return r; + + *_pid = pid; +@@ -1973,7 +1972,7 @@ static int socket_chown(Socket *s, pid_t *_pid) { + _exit(EXIT_SUCCESS); + } + +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, true); + if (r < 0) + goto fail; + +diff --git a/src/core/swap.c b/src/core/swap.c +index b644753a1c..e717dbb54a 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -531,7 +531,7 @@ static int swap_coldplug(Unit *u) { + pid_is_unwaited(s->control_pid) && + SWAP_STATE_WITH_PROCESS(new_state)) { + +- r = unit_watch_pid(UNIT(s), s->control_pid); ++ r = unit_watch_pid(UNIT(s), s->control_pid, false); + if (r < 0) + return r; + +@@ -636,9 +636,8 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + if (r < 0) + goto fail; + +- r = unit_watch_pid(UNIT(s), pid); ++ r = unit_watch_pid(UNIT(s), pid, true); + if (r < 0) +- /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; +diff --git a/src/core/unit.c b/src/core/unit.c +index d298afb0d4..b0b1c77ef7 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2500,7 +2500,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + unit_add_to_gc_queue(u); + } + +-int unit_watch_pid(Unit *u, pid_t pid) { ++int unit_watch_pid(Unit *u, pid_t pid, bool exclusive) { + int r; + + assert(u); +@@ -2508,6 +2508,12 @@ int unit_watch_pid(Unit *u, pid_t pid) { + + /* Watch a specific PID */ + ++ /* Caller might be sure that this PID belongs to this unit only. Let's take this ++ * opportunity to remove any stalled references to this PID as they can be created ++ * easily (when watching a process which is not our direct child). */ ++ if (exclusive) ++ manager_unwatch_pid(u->manager, pid); ++ + r = set_ensure_allocated(&u->pids, NULL); + if (r < 0) + return r; +diff --git a/src/core/unit.h b/src/core/unit.h +index e1a60da244..68cc1869e4 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -655,7 +655,7 @@ typedef enum UnitNotifyFlags { + + void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags); + +-int unit_watch_pid(Unit *u, pid_t pid); ++int unit_watch_pid(Unit *u, pid_t pid, bool exclusive); + void unit_unwatch_pid(Unit *u, pid_t pid); + void unit_unwatch_all_pids(Unit *u); + +diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c +index cb43b35bc5..8c70175aed 100644 +--- a/src/test/test-watch-pid.c ++++ b/src/test/test-watch-pid.c +@@ -49,25 +49,25 @@ int main(int argc, char *argv[]) { + assert_se(hashmap_isempty(m->watch_pids)); + assert_se(manager_get_unit_by_pid(m, 4711) == NULL); + +- assert_se(unit_watch_pid(a, 4711) >= 0); ++ assert_se(unit_watch_pid(a, 4711, false) >= 0); + assert_se(manager_get_unit_by_pid(m, 4711) == a); + +- assert_se(unit_watch_pid(a, 4711) >= 0); ++ assert_se(unit_watch_pid(a, 4711, false) >= 0); + assert_se(manager_get_unit_by_pid(m, 4711) == a); + +- assert_se(unit_watch_pid(b, 4711) >= 0); ++ assert_se(unit_watch_pid(b, 4711, false) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b); + +- assert_se(unit_watch_pid(b, 4711) >= 0); ++ assert_se(unit_watch_pid(b, 4711, false) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b); + +- assert_se(unit_watch_pid(c, 4711) >= 0); ++ assert_se(unit_watch_pid(c, 4711, false) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b || u == c); + +- assert_se(unit_watch_pid(c, 4711) >= 0); ++ assert_se(unit_watch_pid(c, 4711, false) >= 0); + u = manager_get_unit_by_pid(m, 4711); + assert_se(u == a || u == b || u == c); + diff --git a/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch b/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch new file mode 100644 index 0000000..058ff69 --- /dev/null +++ b/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch @@ -0,0 +1,55 @@ +From 25b93538eba0275d35ef4b0792c2cd63d63d5e8d Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Tue, 19 Mar 2019 10:59:26 +0100 +Subject: [PATCH] core: only watch processes when it's really necessary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we know that main pid is our child then it's unnecessary to watch all +other processes of a unit since in this case we will get SIGCHLD when the main +process will exit and will act upon accordingly. + +So let's watch all processes only if the main process is not our child since in +this case we need to detect when the cgroup will become empty in order to +figure out when the service becomes dead. This is only needed by cgroupv1. + +Thanks Renaud Métrich for backporting this to RHEL. +Resolves: #1744972 +--- + src/core/service.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 310838a5f6..b1ec52d220 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3410,8 +3410,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + if (main_pid_good(s) <= 0) + service_enter_stop_post(s, f); + +- /* If there is still a service +- * process around, wait until ++ /* If there is still a service process around, wait until + * that one quit, too */ + break; + +@@ -3433,10 +3432,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + if (notify_dbus) + unit_add_to_dbus_queue(u); + +- /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to watch, +- * under the assumption that we'll sooner or later get a SIGCHLD for them, as the original process we watched +- * was probably the parent of them, and they are hence now our children. */ +- (void) unit_enqueue_rewatch_pids(u); ++ /* We watch the main/control process otherwise we can't retrieve the unit they ++ * belong to with cgroupv1. But if they are not our direct child, we won't get a ++ * SIGCHLD for them. Therefore we need to look for others to watch so we can ++ * detect when the cgroup becomes empty. Note that the control process is always ++ * our child so it's pointless to watch all other processes. */ ++ if (!control_pid_good(s)) ++ if (!s->main_pid_known || s->main_pid_alien) ++ (void) unit_enqueue_rewatch_pids(u); + } + + static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) { diff --git a/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch b/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch new file mode 100644 index 0000000..a503b82 --- /dev/null +++ b/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch @@ -0,0 +1,641 @@ +From a26f2b2732733aa361fec0a3a8f0ba377f48e75c Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Sun, 7 Oct 2018 20:28:36 -0700 +Subject: [PATCH] core: implement per unit journal rate limiting + +Add LogRateLimitIntervalSec= and LogRateLimitBurst= options for +services. If provided, these values get passed to the journald +client context, and those values are used in the rate limiting +function in the journal over the the journald.conf values. + +Part of #10230 + +(cherry picked from commit 90fc172e191f44979005a524521112f2bd1ff21b) + +Resolves: #1719577 +--- + catalog/systemd.catalog.in | 3 +- + doc/TRANSIENT-SETTINGS.md | 2 + + man/journald.conf.xml | 8 +- + man/systemd.exec.xml | 16 ++++ + src/core/dbus-execute.c | 8 ++ + src/core/execute.c | 14 ++++ + src/core/execute.h | 3 + + src/core/load-fragment-gperf.gperf.m4 | 2 + + src/core/unit.c | 92 +++++++++++++++++++++ + src/core/unit.h | 2 + + src/journal/journald-context.c | 50 ++++++++++- + src/journal/journald-context.h | 3 + + src/journal/journald-rate-limit.c | 38 ++++----- + src/journal/journald-rate-limit.h | 4 +- + src/journal/journald-server.c | 4 +- + src/shared/bus-unit-util.c | 8 ++ + test/fuzz/fuzz-unit-file/directives.service | 2 + + 17 files changed, 231 insertions(+), 28 deletions(-) + +diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in +index f1bddc6f7d..8234e387cf 100644 +--- a/catalog/systemd.catalog.in ++++ b/catalog/systemd.catalog.in +@@ -52,7 +52,8 @@ dropped, other services' messages are unaffected. + + The limits controlling when messages are dropped may be configured + with RateLimitIntervalSec= and RateLimitBurst= in +-/etc/systemd/journald.conf. See journald.conf(5) for details. ++/etc/systemd/journald.conf or LogRateLimitIntervalSec= and LogRateLimitBurst= ++in the unit file. See journald.conf(5) and systemd.exec(5) for details. + + -- e9bf28e6e834481bb6f48f548ad13606 + Subject: Journal messages have been missed +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index ca9e8387b7..0ea444b133 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -135,6 +135,8 @@ All execution-related settings are available for transient units. + ✓ SyslogLevelPrefix= + ✓ LogLevelMax= + ✓ LogExtraFields= ++✓ LogRateLimitIntervalSec= ++✓ LogRateLimitBurst= + ✓ SecureBits= + ✓ CapabilityBoundingSet= + ✓ AmbientCapabilities= +diff --git a/man/journald.conf.xml b/man/journald.conf.xml +index ee8e8b7faf..b57a244b22 100644 +--- a/man/journald.conf.xml ++++ b/man/journald.conf.xml +@@ -140,7 +140,13 @@ + following units: s, min, + h, ms, + us. To turn off any kind of rate limiting, +- set either value to 0. ++ set either value to 0. ++ ++ If a service provides rate limits for itself through ++ LogRateLimitIntervalSec= and/or LogRateLimitBurst= ++ in systemd.exec5, ++ those values will override the settings specified here. ++ + + + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 3bd790b485..737c52bcc4 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -1905,6 +1905,22 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy + matching. Assign an empty string to reset the list. + + ++ ++ LogRateLimitIntervalSec= ++ LogRateLimitBurst= ++ ++ Configures the rate limiting that is applied to messages generated by this unit. If, in the ++ time interval defined by LogRateLimitIntervalSec=, more messages than specified in ++ LogRateLimitBurst= are logged by a service, all further messages within the interval are ++ dropped until the interval is over. A message about the number of dropped messages is generated. The time ++ specification for LogRateLimitIntervalSec= may be specified in the following units: "s", ++ "min", "h", "ms", "us" (see ++ systemd.time7 for details). ++ The default settings are set by RateLimitIntervalSec= and RateLimitBurst= ++ configured in journald.conf5. ++ ++ ++ + + SyslogIdentifier= + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index c44970c10c..33a91c012e 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -718,6 +718,8 @@ const sd_bus_vtable bus_exec_vtable[] = { + SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -1073,6 +1075,12 @@ int bus_exec_context_set_transient_property( + if (streq(name, "CPUSchedulingPriority")) + return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error); + ++ if (streq(name, "LogRateLimitIntervalUSec")) ++ return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error); ++ ++ if (streq(name, "LogRateLimitBurst")) ++ return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error); ++ + if (streq(name, "Personality")) + return bus_set_transient_personality(u, name, &c->personality, message, flags, error); + +diff --git a/src/core/execute.c b/src/core/execute.c +index c62f3cf849..8293c522bc 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -3693,6 +3693,9 @@ void exec_context_done(ExecContext *c) { + + exec_context_free_log_extra_fields(c); + ++ c->log_rate_limit_interval_usec = 0; ++ c->log_rate_limit_burst = 0; ++ + c->stdin_data = mfree(c->stdin_data); + c->stdin_data_size = 0; + } +@@ -4153,6 +4156,17 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t)); + } + ++ if (c->log_rate_limit_interval_usec > 0) { ++ char buf_timespan[FORMAT_TIMESPAN_MAX]; ++ ++ fprintf(f, ++ "%sLogRateLimitIntervalSec: %s\n", ++ prefix, format_timespan(buf_timespan, sizeof(buf_timespan), c->log_rate_limit_interval_usec, USEC_PER_SEC)); ++ } ++ ++ if (c->log_rate_limit_burst > 0) ++ fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_rate_limit_burst); ++ + if (c->n_log_extra_fields > 0) { + size_t j; + +diff --git a/src/core/execute.h b/src/core/execute.h +index bff1634b88..8c91636adc 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -216,6 +216,9 @@ struct ExecContext { + struct iovec* log_extra_fields; + size_t n_log_extra_fields; + ++ usec_t log_rate_limit_interval_usec; ++ unsigned log_rate_limit_burst; ++ + bool cpu_sched_reset_on_fork; + bool non_blocking; + bool private_tmp; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 15fb47838c..1066bcfb8f 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -57,6 +57,8 @@ $1.SyslogFacility, config_parse_log_facility, 0, + $1.SyslogLevel, config_parse_log_level, 0, offsetof($1, exec_context.syslog_priority) + $1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix) + $1.LogLevelMax, config_parse_log_level, 0, offsetof($1, exec_context.log_level_max) ++$1.LogRateLimitIntervalSec, config_parse_sec, 0, offsetof($1, exec_context.log_rate_limit_interval_usec) ++$1.LogRateLimitBurst, config_parse_unsigned, 0, offsetof($1, exec_context.log_rate_limit_burst) + $1.LogExtraFields, config_parse_log_extra_fields, 0, offsetof($1, exec_context) + $1.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof($1, exec_context) + $1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context.secure_bits) +diff --git a/src/core/unit.c b/src/core/unit.c +index b0b1c77ef7..115739f4c6 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3245,6 +3245,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { + unit_serialize_item(u, f, "exported-invocation-id", yes_no(u->exported_invocation_id)); + unit_serialize_item(u, f, "exported-log-level-max", yes_no(u->exported_log_level_max)); + unit_serialize_item(u, f, "exported-log-extra-fields", yes_no(u->exported_log_extra_fields)); ++ unit_serialize_item(u, f, "exported-log-rate-limit-interval", yes_no(u->exported_log_rate_limit_interval)); ++ unit_serialize_item(u, f, "exported-log-rate-limit-burst", yes_no(u->exported_log_rate_limit_burst)); + + unit_serialize_item_format(u, f, "cpu-usage-base", "%" PRIu64, u->cpu_usage_base); + if (u->cpu_usage_last != NSEC_INFINITY) +@@ -3508,6 +3510,26 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + + continue; + ++ } else if (streq(l, "exported-log-rate-limit-interval")) { ++ ++ r = parse_boolean(v); ++ if (r < 0) ++ log_unit_debug(u, "Failed to parse exported log rate limit interval %s, ignoring.", v); ++ else ++ u->exported_log_rate_limit_interval = r; ++ ++ continue; ++ ++ } else if (streq(l, "exported-log-rate-limit-burst")) { ++ ++ r = parse_boolean(v); ++ if (r < 0) ++ log_unit_debug(u, "Failed to parse exported log rate limit burst %s, ignoring.", v); ++ else ++ u->exported_log_rate_limit_burst = r; ++ ++ continue; ++ + } else if (STR_IN_SET(l, "cpu-usage-base", "cpuacct-usage-base")) { + + r = safe_atou64(v, &u->cpu_usage_base); +@@ -5241,6 +5263,60 @@ fail: + return r; + } + ++static int unit_export_log_rate_limit_interval(Unit *u, const ExecContext *c) { ++ _cleanup_free_ char *buf = NULL; ++ const char *p; ++ int r; ++ ++ assert(u); ++ assert(c); ++ ++ if (u->exported_log_rate_limit_interval) ++ return 0; ++ ++ if (c->log_rate_limit_interval_usec == 0) ++ return 0; ++ ++ p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id); ++ ++ if (asprintf(&buf, "%" PRIu64, c->log_rate_limit_interval_usec) < 0) ++ return log_oom(); ++ ++ r = symlink_atomic(buf, p); ++ if (r < 0) ++ return log_unit_debug_errno(u, r, "Failed to create log rate limit interval symlink %s: %m", p); ++ ++ u->exported_log_rate_limit_interval = true; ++ return 0; ++} ++ ++static int unit_export_log_rate_limit_burst(Unit *u, const ExecContext *c) { ++ _cleanup_free_ char *buf = NULL; ++ const char *p; ++ int r; ++ ++ assert(u); ++ assert(c); ++ ++ if (u->exported_log_rate_limit_burst) ++ return 0; ++ ++ if (c->log_rate_limit_burst == 0) ++ return 0; ++ ++ p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id); ++ ++ if (asprintf(&buf, "%u", c->log_rate_limit_burst) < 0) ++ return log_oom(); ++ ++ r = symlink_atomic(buf, p); ++ if (r < 0) ++ return log_unit_debug_errno(u, r, "Failed to create log rate limit burst symlink %s: %m", p); ++ ++ u->exported_log_rate_limit_burst = true; ++ return 0; ++} ++ + void unit_export_state_files(Unit *u) { + const ExecContext *c; + +@@ -5274,6 +5350,8 @@ void unit_export_state_files(Unit *u) { + if (c) { + (void) unit_export_log_level_max(u, c); + (void) unit_export_log_extra_fields(u, c); ++ (void) unit_export_log_rate_limit_interval(u, c); ++ (void) unit_export_log_rate_limit_burst(u, c); + } + } + +@@ -5310,6 +5388,20 @@ void unit_unlink_state_files(Unit *u) { + + u->exported_log_extra_fields = false; + } ++ ++ if (u->exported_log_rate_limit_interval) { ++ p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id); ++ (void) unlink(p); ++ ++ u->exported_log_rate_limit_interval = false; ++ } ++ ++ if (u->exported_log_rate_limit_burst) { ++ p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id); ++ (void) unlink(p); ++ ++ u->exported_log_rate_limit_burst = false; ++ } + } + + int unit_prepare_exec(Unit *u) { +diff --git a/src/core/unit.h b/src/core/unit.h +index 68cc1869e4..99755823eb 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -349,6 +349,8 @@ typedef struct Unit { + bool exported_invocation_id:1; + bool exported_log_level_max:1; + bool exported_log_extra_fields:1; ++ bool exported_log_rate_limit_interval:1; ++ bool exported_log_rate_limit_burst:1; + + /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If + * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */ +diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c +index dba3525ed8..c8e97e16de 100644 +--- a/src/journal/journald-context.c ++++ b/src/journal/journald-context.c +@@ -140,6 +140,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) { + c->timestamp = USEC_INFINITY; + c->extra_fields_mtime = NSEC_INFINITY; + c->log_level_max = -1; ++ c->log_rate_limit_interval = s->rate_limit_interval; ++ c->log_rate_limit_burst = s->rate_limit_burst; + + r = hashmap_put(s->client_contexts, PID_TO_PTR(pid), c); + if (r < 0) { +@@ -151,7 +153,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) { + return 0; + } + +-static void client_context_reset(ClientContext *c) { ++static void client_context_reset(Server *s, ClientContext *c) { ++ assert(s); + assert(c); + + c->timestamp = USEC_INFINITY; +@@ -186,6 +189,9 @@ static void client_context_reset(ClientContext *c) { + c->extra_fields_mtime = NSEC_INFINITY; + + c->log_level_max = -1; ++ ++ c->log_rate_limit_interval = s->rate_limit_interval; ++ c->log_rate_limit_burst = s->rate_limit_burst; + } + + static ClientContext* client_context_free(Server *s, ClientContext *c) { +@@ -199,7 +205,7 @@ static ClientContext* client_context_free(Server *s, ClientContext *c) { + if (c->in_lru) + assert_se(prioq_remove(s->client_contexts_lru, c, &c->lru_index) >= 0); + +- client_context_reset(c); ++ client_context_reset(s, c); + + return mfree(c); + } +@@ -464,6 +470,42 @@ static int client_context_read_extra_fields( + return 0; + } + ++static int client_context_read_log_rate_limit_interval(ClientContext *c) { ++ _cleanup_free_ char *value = NULL; ++ const char *p; ++ int r; ++ ++ assert(c); ++ ++ if (!c->unit) ++ return 0; ++ ++ p = strjoina("/run/systemd/units/log-rate-limit-interval:", c->unit); ++ r = readlink_malloc(p, &value); ++ if (r < 0) ++ return r; ++ ++ return safe_atou64(value, &c->log_rate_limit_interval); ++} ++ ++static int client_context_read_log_rate_limit_burst(ClientContext *c) { ++ _cleanup_free_ char *value = NULL; ++ const char *p; ++ int r; ++ ++ assert(c); ++ ++ if (!c->unit) ++ return 0; ++ ++ p = strjoina("/run/systemd/units/log-rate-limit-burst:", c->unit); ++ r = readlink_malloc(p, &value); ++ if (r < 0) ++ return r; ++ ++ return safe_atou(value, &c->log_rate_limit_burst); ++} ++ + static void client_context_really_refresh( + Server *s, + ClientContext *c, +@@ -490,6 +532,8 @@ static void client_context_really_refresh( + (void) client_context_read_invocation_id(s, c); + (void) client_context_read_log_level_max(s, c); + (void) client_context_read_extra_fields(s, c); ++ (void) client_context_read_log_rate_limit_interval(c); ++ (void) client_context_read_log_rate_limit_burst(c); + + c->timestamp = timestamp; + +@@ -520,7 +564,7 @@ void client_context_maybe_refresh( + /* If the data isn't pinned and if the cashed data is older than the upper limit, we flush it out + * entirely. This follows the logic that as long as an entry is pinned the PID reuse is unlikely. */ + if (c->n_ref == 0 && c->timestamp + MAX_USEC < timestamp) { +- client_context_reset(c); ++ client_context_reset(s, c); + goto refresh; + } + +diff --git a/src/journal/journald-context.h b/src/journal/journald-context.h +index 9df3a38eff..5e19c71f14 100644 +--- a/src/journal/journald-context.h ++++ b/src/journal/journald-context.h +@@ -49,6 +49,9 @@ struct ClientContext { + size_t extra_fields_n_iovec; + void *extra_fields_data; + nsec_t extra_fields_mtime; ++ ++ usec_t log_rate_limit_interval; ++ unsigned log_rate_limit_burst; + }; + + int client_context_get( +diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c +index 6a8a36a736..539efb8669 100644 +--- a/src/journal/journald-rate-limit.c ++++ b/src/journal/journald-rate-limit.c +@@ -39,6 +39,10 @@ struct JournalRateLimitGroup { + JournalRateLimit *parent; + + char *id; ++ ++ /* Interval is stored to keep track of when the group expires */ ++ usec_t interval; ++ + JournalRateLimitPool pools[POOLS_MAX]; + uint64_t hash; + +@@ -47,8 +51,6 @@ struct JournalRateLimitGroup { + }; + + struct JournalRateLimit { +- usec_t interval; +- unsigned burst; + + JournalRateLimitGroup* buckets[BUCKETS_MAX]; + JournalRateLimitGroup *lru, *lru_tail; +@@ -58,18 +60,13 @@ struct JournalRateLimit { + uint8_t hash_key[16]; + }; + +-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) { ++JournalRateLimit *journal_rate_limit_new(void) { + JournalRateLimit *r; + +- assert(interval > 0 || burst == 0); +- + r = new0(JournalRateLimit, 1); + if (!r) + return NULL; + +- r->interval = interval; +- r->burst = burst; +- + random_bytes(r->hash_key, sizeof(r->hash_key)); + + return r; +@@ -109,7 +106,7 @@ _pure_ static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, us + assert(g); + + for (i = 0; i < POOLS_MAX; i++) +- if (g->pools[i].begin + g->parent->interval >= ts) ++ if (g->pools[i].begin + g->interval >= ts) + return false; + + return true; +@@ -126,7 +123,7 @@ static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) { + journal_rate_limit_group_free(r->lru_tail); + } + +-static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) { ++static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t interval, usec_t ts) { + JournalRateLimitGroup *g; + struct siphash state; + +@@ -145,6 +142,8 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, + string_hash_func(g->id, &state); + g->hash = siphash24_finalize(&state); + ++ g->interval = interval; ++ + journal_rate_limit_vacuum(r, ts); + + LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g); +@@ -189,7 +188,7 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) { + return burst; + } + +-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) { ++int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available) { + uint64_t h; + JournalRateLimitGroup *g; + JournalRateLimitPool *p; +@@ -209,11 +208,6 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u + if (!r) + return 1; + +- if (r->interval == 0 || r->burst == 0) +- return 1; +- +- burst = burst_modulate(r->burst, available); +- + ts = now(CLOCK_MONOTONIC); + + siphash24_init(&state, r->hash_key); +@@ -226,10 +220,16 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u + break; + + if (!g) { +- g = journal_rate_limit_group_new(r, id, ts); ++ g = journal_rate_limit_group_new(r, id, rl_interval, ts); + if (!g) + return -ENOMEM; +- } ++ } else ++ g->interval = rl_interval; ++ ++ if (rl_interval == 0 || rl_burst == 0) ++ return 1; ++ ++ burst = burst_modulate(rl_burst, available); + + p = &g->pools[priority_map[priority]]; + +@@ -240,7 +240,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u + return 1; + } + +- if (p->begin + r->interval < ts) { ++ if (p->begin + rl_interval < ts) { + unsigned s; + + s = p->suppressed; +diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h +index 3a7f106de0..a2992800fe 100644 +--- a/src/journal/journald-rate-limit.h ++++ b/src/journal/journald-rate-limit.h +@@ -5,6 +5,6 @@ + + typedef struct JournalRateLimit JournalRateLimit; + +-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst); ++JournalRateLimit *journal_rate_limit_new(void); + void journal_rate_limit_free(JournalRateLimit *r); +-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available); ++int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available); +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 8de45552f6..0c983e102a 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -943,7 +943,7 @@ void server_dispatch_message( + if (c && c->unit) { + (void) determine_space(s, &available, NULL); + +- rl = journal_rate_limit_test(s->rate_limit, c->unit, priority & LOG_PRIMASK, available); ++ rl = journal_rate_limit_test(s->rate_limit, c->unit, c->log_rate_limit_interval, c->log_rate_limit_burst, priority & LOG_PRIMASK, available); + if (rl == 0) + return; + +@@ -1852,7 +1852,7 @@ int server_init(Server *s) { + if (!s->udev) + return -ENOMEM; + +- s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst); ++ s->rate_limit = journal_rate_limit_new(); + if (!s->rate_limit) + return -ENOMEM; + +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 3238b442c0..271cc054da 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -755,6 +755,14 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + + return bus_append_parse_nsec(m, field, eq); + ++ if (STR_IN_SET(field, "LogRateLimitIntervalSec")) ++ ++ return bus_append_parse_sec_rename(m, field, eq); ++ ++ if (streq(field, "LogRateLimitBurst")) ++ ++ return bus_append_safe_atou(m, field, eq); ++ + if (streq(field, "MountFlags")) + + return bus_append_mount_propagation_flags_from_string(m, field, eq); +diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +index c2334d3b19..d8d1fc68b8 100644 +--- a/test/fuzz/fuzz-unit-file/directives.service ++++ b/test/fuzz/fuzz-unit-file/directives.service +@@ -792,6 +792,8 @@ LineMax= + LockPersonality= + LogExtraFields= + LogLevelMax= ++LogRateLimitIntervalSec= ++LogRateLimitBurst= + LogsDirectory= + LogsDirectoryMode= + MACVLAN= diff --git a/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch b/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch new file mode 100644 index 0000000..c538f50 --- /dev/null +++ b/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch @@ -0,0 +1,35 @@ +From 55d9d6dfb731d2f1c8c940fb8a7ea0af6c498c4c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 9 Sep 2019 14:38:35 +0200 +Subject: [PATCH] path: stop watching path specs once we triggered the target + unit + +We start watching them again once we get a notification that triggered +unit entered inactive or failed state. + +Fixes: #10503 +(cherry picked from commit 8fca6944c2ee20c63d62154c8badddc77170b176) + +Resolves: #1763161 +--- + src/core/path.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/core/path.c b/src/core/path.c +index 68b13b610a..5ef178a46b 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -478,11 +478,9 @@ static void path_enter_running(Path *p) { + + p->inotify_triggered = false; + +- r = path_watch(p); +- if (r < 0) +- goto fail; +- + path_set_state(p, PATH_RUNNING); ++ path_unwatch(p); ++ + return; + + fail: diff --git a/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch b/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch new file mode 100644 index 0000000..25c91dd --- /dev/null +++ b/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch @@ -0,0 +1,28 @@ +From 33aa231f5bf3335cdacfb38ffba757865019ce4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= + <1163635+rmetrich@users.noreply.github.com> +Date: Mon, 3 Sep 2018 05:42:39 +0200 +Subject: [PATCH] journald: fixed assertion failure when system journal + rotation fails (#9893) + +(cherry picked from commit fd790d6f09b10a87b007b71403cb018f18ff91c9) + +Resolves: #1763619 +--- + src/journal/journald-server.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 0c983e102a..6aecb67d6c 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1041,7 +1041,8 @@ int server_flush_to_var(Server *s, bool require_flag_file) { + r = 0; + + finish: +- journal_file_post_change(s->system_journal); ++ if (s->system_journal) ++ journal_file_post_change(s->system_journal); + + s->runtime_journal = journal_file_close(s->runtime_journal); + diff --git a/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch b/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch new file mode 100644 index 0000000..4599b60 --- /dev/null +++ b/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch @@ -0,0 +1,29 @@ +From a7f18f9ef4abc7e0732d1710ead2a18a38c3ec6d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Mar 2019 10:05:33 +0100 +Subject: [PATCH] test: use PBKDF2 instead of Argon2 in cryptsetup... + +to reduce memory requirements for volume manipulation. Also, +to further improve the test performance, reduce number of PBKDF +iterations to 1000 (allowed minimum). + +(cherry picked from commit 5b69d297c153478f6f5e74ba66e1f4e5b6422baf) + +Related: #1761519 +--- + test/TEST-02-CRYPTSETUP/test.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh +index 545602e17a..c38e56f72e 100755 +--- a/test/TEST-02-CRYPTSETUP/test.sh ++++ b/test/TEST-02-CRYPTSETUP/test.sh +@@ -29,7 +29,7 @@ check_result_qemu() { + test_setup() { + create_empty_image + echo -n test >$TESTDIR/keyfile +- cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile ++ cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile + cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile + mkfs.ext4 -L var /dev/mapper/varcrypt + mkdir -p $TESTDIR/root diff --git a/SOURCES/0238-test-mask-several-unnecessary-services.patch b/SOURCES/0238-test-mask-several-unnecessary-services.patch new file mode 100644 index 0000000..6ff56e8 --- /dev/null +++ b/SOURCES/0238-test-mask-several-unnecessary-services.patch @@ -0,0 +1,252 @@ +From c748b95f5a00b6d9c46026c3d251c40437e6b64a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 1 Nov 2018 17:26:36 +0900 +Subject: [PATCH] test: mask several unnecessary services + +This may make CIs run faster. + +(cherry picked from commit 056ae88152a722bdbea54ff33db815d585c8b9c6) + +Related: #1761519 +--- + test/TEST-02-CRYPTSETUP/test.sh | 8 ++++++++ + test/TEST-03-JOBS/test.sh | 8 ++++++++ + test/TEST-04-JOURNAL/test.sh | 8 ++++++++ + test/TEST-05-RLIMITS/test.sh | 8 ++++++++ + test/TEST-07-ISSUE-1981/test.sh | 8 ++++++++ + test/TEST-11-ISSUE-3166/test.sh | 8 ++++++++ + test/TEST-12-ISSUE-3171/test.sh | 8 ++++++++ + test/TEST-13-NSPAWN-SMOKE/test.sh | 8 ++++++++ + test/TEST-18-FAILUREACTION/test.sh | 7 +++++++ + test/TEST-19-DELEGATE/test.sh | 8 ++++++++ + test/TEST-20-MAINPIDGAMES/test.sh | 8 ++++++++ + test/TEST-23-TYPE-EXEC/test.sh | 8 ++++++++ + 12 files changed, 95 insertions(+) + +diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh +index c38e56f72e..97eb2f409e 100755 +--- a/test/TEST-02-CRYPTSETUP/test.sh ++++ b/test/TEST-02-CRYPTSETUP/test.sh +@@ -45,6 +45,14 @@ test_setup() { + + setup_basic_environment + ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ + # setup the testsuite service + cat >$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system.conf <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service <$initdir/etc/systemd/system/testsuite.service < +Date: Mon, 21 Oct 2019 18:39:39 +0200 +Subject: [PATCH] test: bump the second partition's size to 50M + +The former size (10M) caused systemd-journald to crash with SIGABRT when +used on a LUKS2 partition, as the LUKS2 metadata consume a significant +part of the 10M partition, thus leaving no space for the journal file +itself (relevant for TEST-02-CRYPTSETUP). This change has been present +in upstream for a while anyway. + +Related: #1761519 +rhel-only +--- + test/test-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index af9d16140f..fe25a501da 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -433,7 +433,7 @@ create_empty_image() { + [ -b "$LOOPDEV" ] || return 1 + echo "LOOPDEV=$LOOPDEV" >> $STATEFILE + sfdisk "$LOOPDEV" < +Date: Wed, 25 Jul 2018 08:06:57 -0700 +Subject: [PATCH] shared/sleep-config: exclude zram devices from hibernation + candidates + +On a host with sufficiently large zram but with no actual swap, logind will +respond to CanHibernate() with yes. With this patch, it will correctly respond +no, unless there are other swap devices to consider. + +(cherry picked from commit 411ae92b407bd7b4549b205ad754bcd0e3dfd81f) + +Resolves: #1763617 +--- + src/shared/sleep-config.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c +index 9e4ce183d3..a1523e3f21 100644 +--- a/src/shared/sleep-config.c ++++ b/src/shared/sleep-config.c +@@ -21,6 +21,7 @@ + #include "log.h" + #include "macro.h" + #include "parse-util.h" ++#include "path-util.h" + #include "sleep-config.h" + #include "string-util.h" + #include "strv.h" +@@ -201,9 +202,18 @@ int find_hibernate_location(char **device, char **type, size_t *size, size_t *us + continue; + } + +- if (streq(type_field, "partition") && endswith(dev_field, "\\040(deleted)")) { +- log_warning("Ignoring deleted swapfile '%s'.", dev_field); +- continue; ++ if (streq(type_field, "partition")) { ++ if (endswith(dev_field, "\\040(deleted)")) { ++ log_warning("Ignoring deleted swapfile '%s'.", dev_field); ++ continue; ++ } ++ ++ const char *fn; ++ fn = path_startswith(dev_field, "/dev/"); ++ if (fn && startswith(fn, "zram")) { ++ log_debug("Ignoring compressed ram swap device '%s'.", dev_field); ++ continue; ++ } + } + if (device) + *device = TAKE_PTR(dev_field); diff --git a/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch b/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch new file mode 100644 index 0000000..5845313 --- /dev/null +++ b/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch @@ -0,0 +1,45 @@ +From cc3c020a5f4fc577dbd2da769c22b77e37ae4e30 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 26 Feb 2019 17:33:27 +0100 +Subject: [PATCH] selinux: don't log SELINUX_INFO and SELINUX_WARNING messages + to audit + +Previously we logged even info message from libselinux as USER_AVC's to +audit. For example, setting SELinux to permissive mode generated +following audit message, + +time->Tue Feb 26 11:29:29 2019 +type=USER_AVC msg=audit(1551198569.423:334): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='avc: received setenforce notice (enforcing=0) exe="/usr/lib/systemd/systemd" sauid=0 hostname=? addr=? terminal=?' + +This is unnecessary and wrong at the same time. First, kernel already +records audit event that SELinux was switched to permissive mode, also +the type of the message really shouldn't be USER_AVC. + +Let's ignore SELINUX_WARNING and SELINUX_INFO and forward to audit only +USER_AVC's and errors as these two libselinux message types have clear +mapping to audit message types. + +(cherry picked from commit 6227fc14c48c4c17daed4b91f61cdd4aa375790a) + +Resolves: #1763612 +--- + src/core/selinux-access.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c +index 39e994afd7..ada4f8705c 100644 +--- a/src/core/selinux-access.c ++++ b/src/core/selinux-access.c +@@ -112,7 +112,11 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) { + va_end(ap); + + if (r >= 0) { +- audit_log_user_avc_message(fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0); ++ if (type == SELINUX_AVC) ++ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0); ++ else if (type == SELINUX_ERROR) ++ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_SELINUX_ERR, buf, NULL, NULL, NULL, 0); ++ + return 0; + } + } diff --git a/SOURCES/0242-sd-device-introduce-log_device_-macros.patch b/SOURCES/0242-sd-device-introduce-log_device_-macros.patch new file mode 100644 index 0000000..6b13e77 --- /dev/null +++ b/SOURCES/0242-sd-device-introduce-log_device_-macros.patch @@ -0,0 +1,47 @@ +From 0160499e86642f159a972be0196bf7c8a1d19ea8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Oct 2018 12:04:13 +0900 +Subject: [PATCH] sd-device: introduce log_device_*() macros + +(cherry picked from commit b0cba0ca526ed2d86e283a0fcfebdf0a4d4bea9b) + +Related: #1753369 +--- + src/libsystemd/sd-device/device-util.h | 27 ++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h +index 6dcd2645e6..448dfc63d7 100644 +--- a/src/libsystemd/sd-device/device-util.h ++++ b/src/libsystemd/sd-device/device-util.h +@@ -33,3 +33,30 @@ + for (device = sd_device_enumerator_get_subsystem_first(enumerator); \ + device; \ + device = sd_device_enumerator_get_subsystem_next(enumerator)) ++ ++#define log_device_full(device, level, error, ...) \ ++ ({ \ ++ const char *_sysname = NULL, *_subsystem = NULL; \ ++ sd_device *_d = (device); \ ++ int _level = (level), _error = (error); \ ++ \ ++ if (_d && _unlikely_(log_get_max_level() >= _level)) { \ ++ (void) sd_device_get_sysname(_d, &_sysname); \ ++ (void) sd_device_get_subsystem(_d, &_subsystem); \ ++ } \ ++ log_object_internal(_level, _error, __FILE__, __LINE__, __func__, \ ++ _sysname ? "DEVICE=" : NULL, _sysname, \ ++ _subsystem ? "SUBSYSTEM=" : NULL, _subsystem, ##__VA_ARGS__); \ ++ }) ++ ++#define log_device_debug(link, ...) log_device_full(link, LOG_DEBUG, 0, ##__VA_ARGS__) ++#define log_device_info(link, ...) log_device_full(link, LOG_INFO, 0, ##__VA_ARGS__) ++#define log_device_notice(link, ...) log_device_full(link, LOG_NOTICE, 0, ##__VA_ARGS__) ++#define log_device_warning(link, ...) log_device_full(link, LOG_WARNING, 0, ##__VA_ARGS__) ++#define log_device_error(link, ...) log_device_full(link, LOG_ERR, 0, ##__VA_ARGS__) ++ ++#define log_device_debug_errno(link, error, ...) log_device_full(link, LOG_DEBUG, error, ##__VA_ARGS__) ++#define log_device_info_errno(link, error, ...) log_device_full(link, LOG_INFO, error, ##__VA_ARGS__) ++#define log_device_notice_errno(link, error, ...) log_device_full(link, LOG_NOTICE, error, ##__VA_ARGS__) ++#define log_device_warning_errno(link, error, ...) log_device_full(link, LOG_WARNING, error, ##__VA_ARGS__) ++#define log_device_error_errno(link, error, ...) log_device_full(link, LOG_ERR, error, ##__VA_ARGS__) diff --git a/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch b/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch new file mode 100644 index 0000000..9977fa0 --- /dev/null +++ b/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch @@ -0,0 +1,33 @@ +From c3be943b30689f77ded9f431fdafb666769aea89 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 Aug 2019 19:00:34 +0200 +Subject: [PATCH] shared/but-util: drop trusted annotation from + bus_open_system_watch_bind_with_description() + +https://bugzilla.redhat.com/show_bug.cgi?id=1746057 + +This only affects systemd-resolved. bus_open_system_watch_bind_with_description() +is also used in timesyncd, but it has no methods, only read-only properties, and +in networkd, but it annotates all methods with SD_BUS_VTABLE_UNPRIVILEGED and does +polkit checks. + +Resolves: #1746857 +--- + src/shared/bus-util.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index a4f2deba31..302dbb4c2e 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -1699,10 +1699,6 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri + if (r < 0) + return r; + +- r = sd_bus_set_trusted(bus, true); +- if (r < 0) +- return r; +- + r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); + if (r < 0) + return r; diff --git a/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch b/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch new file mode 100644 index 0000000..bdb144e --- /dev/null +++ b/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch @@ -0,0 +1,50 @@ +From 7e0f9a0cd4053fcc713a99ada3d0d50793b83564 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 Aug 2019 19:00:50 +0200 +Subject: [PATCH] sd-bus: adjust indentation of comments + +Related: #1746857 +--- + src/libsystemd/sd-bus/sd-bus.c | 3 +-- + src/shared/bus-util.c | 7 ++++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 3583e24e64..1c9e967ae0 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -1341,8 +1341,7 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip + b->bus_client = true; + b->is_user = true; + +- /* We don't do any per-method access control on the user +- * bus. */ ++ /* We don't do any per-method access control on the user bus. */ + b->trusted = true; + b->is_local = true; + +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index 302dbb4c2e..2d908eb45c 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -1675,7 +1675,8 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri + + assert(ret); + +- /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */ ++ /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal ++ * turned on. */ + + r = sd_bus_new(&bus); + if (r < 0) +@@ -1890,8 +1891,8 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) { + + assert(m); + +- /* Reply to the specified message with a message containing a dictionary put together from the specified +- * strv */ ++ /* Reply to the specified message with a message containing a dictionary put together from the ++ * specified strv */ + + r = sd_bus_message_new_method_return(m, &reply); + if (r < 0) diff --git a/SOURCES/0246-resolved-do-not-run-loop-twice.patch b/SOURCES/0246-resolved-do-not-run-loop-twice.patch new file mode 100644 index 0000000..70fdf78 --- /dev/null +++ b/SOURCES/0246-resolved-do-not-run-loop-twice.patch @@ -0,0 +1,46 @@ +From d95afbca80cf52f0bc84b2e1b4af6aadda007138 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 Aug 2019 19:02:53 +0200 +Subject: [PATCH] resolved: do not run loop twice + +This doesn't matter much, but let's just do the loop once and allocate +the populate the result set on the fly. If we find an error, it'll get +cleaned up automatically. + +Related: #1746857 +--- + src/resolve/resolved-link-bus.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c +index b1581740d8..46d2b11636 100644 +--- a/src/resolve/resolved-link-bus.c ++++ b/src/resolve/resolved-link-bus.c +@@ -492,6 +492,10 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v + if (r < 0) + return r; + ++ ns = set_new(&dns_name_hash_ops); ++ if (!ns) ++ return -ENOMEM; ++ + r = sd_bus_message_read_strv(message, &ntas); + if (r < 0) + return r; +@@ -501,14 +505,9 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v + if (r < 0) + return r; + if (r == 0) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i); +- } ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ "Invalid negative trust anchor domain: %s", *i); + +- ns = set_new(&dns_name_hash_ops); +- if (!ns) +- return -ENOMEM; +- +- STRV_FOREACH(i, ntas) { + r = set_put_strdup(ns, *i); + if (r < 0) + return r; diff --git a/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch b/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch new file mode 100644 index 0000000..5e2b359 --- /dev/null +++ b/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch @@ -0,0 +1,347 @@ +From ddd08e75b1e7fa1f6dfef3d30a0c1ef8c63e4d07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 Aug 2019 19:25:05 +0200 +Subject: [PATCH] resolved: allow access to Set*Link and Revert methods through + polkit + +This matches what is done in networkd very closely. In fact even the +policy descriptions are all identical (with s/network/resolve), except +for the last one: +resolved has org.freedesktop.resolve1.revert while +networkd has org.freedesktop.network1.revert-ntp and +org.freedesktop.network1.revert-dns so the description is a bit different. + +Conflicts: + src/resolve/resolved-bus.c + src/resolve/resolved-link-bus.c + +Related: #1746857 +--- + src/resolve/org.freedesktop.resolve1.policy | 99 +++++++++++++++++++++ + src/resolve/resolved-bus.c | 22 ++--- + src/resolve/resolved-link-bus.c | 97 +++++++++++++++++--- + 3 files changed, 197 insertions(+), 21 deletions(-) + +diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy +index b65ba3e56a..592c4eb8b0 100644 +--- a/src/resolve/org.freedesktop.resolve1.policy ++++ b/src/resolve/org.freedesktop.resolve1.policy +@@ -40,4 +40,103 @@ + unix-user:systemd-resolve + + ++ ++ Set DNS servers ++ Authentication is required to set DNS servers. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Set domains ++ Authentication is required to set domains. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Set default route ++ Authentication is required to set default route. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Enable/disable LLMNR ++ Authentication is required to enable or disable LLMNR. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Enable/disable multicast DNS ++ Authentication is required to enable or disable multicast DNS. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Enable/disable DNS over TLS ++ Authentication is required to enable or disable DNS over TLS. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Enable/disable DNSSEC ++ Authentication is required to enable or disable DNSSEC. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Set DNSSEC Negative Trust Anchors ++ Authentication is required to set DNSSEC Negative Trust Anchros. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ ++ ++ Revert name resolution settings ++ Authentication is required to revert name resolution settings. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:systemd-resolve ++ ++ + +diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c +index da0a909dd6..4d6cc4fd48 100644 +--- a/src/resolve/resolved-bus.c ++++ b/src/resolve/resolved-bus.c +@@ -1848,18 +1848,18 @@ static const sd_bus_vtable resolve_vtable[] = { + SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0), +- SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0), +- SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, 0), ++ SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0), +- SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0), +- SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0), +- SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0), +- SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, 0), +- SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0), +- SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0), +- SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0), ++ SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED), +diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c +index 46d2b11636..bf3e42264e 100644 +--- a/src/resolve/resolved-link-bus.c ++++ b/src/resolve/resolved-link-bus.c +@@ -1,5 +1,9 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include ++#include ++#include ++ + #include "alloc-util.h" + #include "bus-common-errors.h" + #include "bus-util.h" +@@ -9,6 +13,7 @@ + #include "resolved-link-bus.h" + #include "resolved-resolv-conf.h" + #include "strv.h" ++#include "user-util.h" + + static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported); + static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string); +@@ -235,6 +240,15 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_ + if (r < 0) + return r; + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-dns-servers", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + dns_server_mark_all(l->dns_servers); + + for (i = 0; i < n; i++) { +@@ -298,12 +312,21 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_ + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain"); + } + +- dns_search_domain_mark_all(l->search_domains); +- + r = sd_bus_message_rewind(message, false); + if (r < 0) + return r; + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-domains", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ ++ dns_search_domain_mark_all(l->search_domains); ++ + for (;;) { + DnsSearchDomain *d; + const char *name; +@@ -371,6 +394,15 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr); + } + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-llmnr", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + l->llmnr_support = mode; + link_allocate_scopes(l); + link_add_rrs(l, false); +@@ -405,6 +437,15 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns); + } + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-mdns", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + l->mdns_support = mode; + link_allocate_scopes(l); + link_add_rrs(l, false); +@@ -439,6 +480,15 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls); + } + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-dns-over-tls", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + link_set_dns_over_tls_mode(l, mode); + + (void) link_save_user(l); +@@ -471,6 +521,15 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec); + } + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-dnssec", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + link_set_dnssec_mode(l, mode); + + (void) link_save_user(l); +@@ -513,6 +572,15 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v + return r; + } + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.set-dnssec-negative-trust-anchors", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + set_free_free(l->dnssec_negative_trust_anchors); + l->dnssec_negative_trust_anchors = TAKE_PTR(ns); + +@@ -532,6 +600,15 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error + if (r < 0) + return r; + ++ r = bus_verify_polkit_async(message, CAP_NET_ADMIN, ++ "org.freedesktop.resolve1.revert", ++ NULL, true, UID_INVALID, ++ &l->manager->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + link_flush_settings(l); + link_allocate_scopes(l); + link_add_rrs(l, false); +@@ -556,14 +633,14 @@ const sd_bus_vtable link_vtable[] = { + SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0), + SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0), + +- SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0), +- SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0), +- SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0), +- SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0), +- SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, 0), +- SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0), +- SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0), +- SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0), ++ SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_VTABLE_END + }; diff --git a/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch b/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch new file mode 100644 index 0000000..eac8530 --- /dev/null +++ b/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch @@ -0,0 +1,48 @@ +From 7b00cae817e54ee3398ad3b42ec69a3b63676562 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 27 Aug 2019 19:28:19 +0200 +Subject: [PATCH] resolved: query polkit only after parsing the data + +That's what we do everywhere else because it leads to nicer user experience. + +Related: #1746857 +--- + src/resolve/resolved-bus.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c +index 4d6cc4fd48..3f6a6f9e12 100644 +--- a/src/resolve/resolved-bus.c ++++ b/src/resolve/resolved-bus.c +@@ -1632,15 +1632,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, + if (m->mdns_support != RESOLVE_SUPPORT_YES) + return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled"); + +- r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, +- "org.freedesktop.resolve1.register-service", +- NULL, false, UID_INVALID, +- &m->polkit_registry, error); +- if (r < 0) +- return r; +- if (r == 0) +- return 1; /* Polkit will call us back */ +- + service = new0(DnssdService, 1); + if (!service) + return log_oom(); +@@ -1765,6 +1756,15 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, + if (r < 0) + return r; + ++ r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, ++ "org.freedesktop.resolve1.register-service", ++ NULL, false, UID_INVALID, ++ &m->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Polkit will call us back */ ++ + r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops); + if (r < 0) + return r; diff --git a/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch b/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch new file mode 100644 index 0000000..932a2fc --- /dev/null +++ b/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch @@ -0,0 +1,48 @@ +From 4d2145e3edd6ba6ac2e52a232fa5059ecdacaead Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 24 Dec 2018 00:29:56 +0100 +Subject: [PATCH] journal: rely on _cleanup_free_ to free a temporary string + used in client_context_read_cgroup + +Closes https://github.com/systemd/systemd/issues/11253. + +(cherry picked from commit ef30f7cac18a810814ada7e6a68a31d48cc9fccd) + +Resolves: #1764560 +--- + src/journal/journald-context.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c +index c8e97e16de..3a768094d9 100644 +--- a/src/journal/journald-context.c ++++ b/src/journal/journald-context.c +@@ -282,7 +282,7 @@ static int client_context_read_label( + } + + static int client_context_read_cgroup(Server *s, ClientContext *c, const char *unit_id) { +- char *t = NULL; ++ _cleanup_free_ char *t = NULL; + int r; + + assert(c); +@@ -290,7 +290,6 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u + /* Try to acquire the current cgroup path */ + r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t); + if (r < 0 || empty_or_root(t)) { +- + /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted() + * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup + * on cgroupsv1 and we want to be able to map log messages from them too. */ +@@ -304,10 +303,8 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u + } + + /* Let's shortcut this if the cgroup path didn't change */ +- if (streq_ptr(c->cgroup, t)) { +- free(t); ++ if (streq_ptr(c->cgroup, t)) + return 0; +- } + + free_and_replace(c->cgroup, t); + diff --git a/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch b/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch new file mode 100644 index 0000000..4b03b91 --- /dev/null +++ b/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch @@ -0,0 +1,90 @@ +From 76176de0889c3e8b9b3a176da24e4f8dbbd380a3 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 2 Oct 2019 11:59:41 +0200 +Subject: [PATCH] basic/user-util: allow dots in user names + +(based on commit 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865) + +Resolves: #1717603 +--- + src/basic/user-util.c | 9 ++++++--- + src/test/test-user-util.c | 8 ++++---- + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index c533f67025..d92969c966 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -575,11 +575,14 @@ bool valid_user_group_name(const char *u) { + /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, + * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: + * +- * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator) + * - We require that names fit into the appropriate utmp field + * - We don't allow empty user names + * + * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. ++ * ++ * jsynacek: We now allow dots in user names. The checks are not exhaustive as user names like "..." are allowed ++ * and valid according to POSIX, but can't be created using useradd. However, ".user" can be created. Let's not ++ * complicate the code by adding additional checks for weird corner cases like these, as they don't really matter here. + */ + + if (isempty(u)) +@@ -587,14 +590,14 @@ bool valid_user_group_name(const char *u) { + + if (!(u[0] >= 'a' && u[0] <= 'z') && + !(u[0] >= 'A' && u[0] <= 'Z') && +- u[0] != '_') ++ u[0] != '_' && u[0] != '.') + return false; + + for (i = u+1; *i; i++) { + if (!(*i >= 'a' && *i <= 'z') && + !(*i >= 'A' && *i <= 'Z') && + !(*i >= '0' && *i <= '9') && +- !IN_SET(*i, '_', '-')) ++ !IN_SET(*i, '_', '-', '.')) + return false; + } + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index c1428fab02..9114d30b8c 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -71,8 +71,6 @@ static void test_valid_user_group_name(void) { + assert_se(!valid_user_group_name("-1")); + assert_se(!valid_user_group_name("-kkk")); + assert_se(!valid_user_group_name("rööt")); +- assert_se(!valid_user_group_name(".")); +- assert_se(!valid_user_group_name("eff.eff")); + assert_se(!valid_user_group_name("foo\nbar")); + assert_se(!valid_user_group_name("0123456789012345678901234567890123456789")); + assert_se(!valid_user_group_name_or_id("aaa:bbb")); +@@ -83,6 +81,8 @@ static void test_valid_user_group_name(void) { + assert_se(valid_user_group_name("_kkk")); + assert_se(valid_user_group_name("kkk-")); + assert_se(valid_user_group_name("kk-k")); ++ assert_se(valid_user_group_name(".moo")); ++ assert_se(valid_user_group_name("eff.eff")); + + assert_se(valid_user_group_name("some5")); + assert_se(!valid_user_group_name("5some")); +@@ -102,8 +102,6 @@ static void test_valid_user_group_name_or_id(void) { + assert_se(!valid_user_group_name_or_id("-1")); + assert_se(!valid_user_group_name_or_id("-kkk")); + assert_se(!valid_user_group_name_or_id("rööt")); +- assert_se(!valid_user_group_name_or_id(".")); +- assert_se(!valid_user_group_name_or_id("eff.eff")); + assert_se(!valid_user_group_name_or_id("foo\nbar")); + assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789")); + assert_se(!valid_user_group_name_or_id("aaa:bbb")); +@@ -114,6 +112,8 @@ static void test_valid_user_group_name_or_id(void) { + assert_se(valid_user_group_name_or_id("_kkk")); + assert_se(valid_user_group_name_or_id("kkk-")); + assert_se(valid_user_group_name_or_id("kk-k")); ++ assert_se(valid_user_group_name_or_id(".moo")); ++ assert_se(valid_user_group_name_or_id("eff.eff")); + + assert_se(valid_user_group_name_or_id("some5")); + assert_se(!valid_user_group_name_or_id("5some")); diff --git a/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch b/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch new file mode 100644 index 0000000..5fd7ade --- /dev/null +++ b/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch @@ -0,0 +1,29 @@ +From 62623bafd9ce4842122ddeda83f9527e43b9a21f Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Fri, 8 Nov 2019 14:54:30 +0100 +Subject: [PATCH] sd-bus: bump message queue size again + +Simliarly to issue #4068, the current limit turns out to be too small for a +big storage setup that uses many small disks. Let's bump it further. + +(cherry picked from commit 83a32ea7b03d6707b8e5bb90a0b3a6eb868ef633) +Resolves: #1770189 +--- + src/libsystemd/sd-bus/bus-internal.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 90e6028983..5d773b14c4 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -328,8 +328,8 @@ struct sd_bus { + * with enough entropy yet and might delay the boot */ + #define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC) + +-#define BUS_WQUEUE_MAX (192*1024) +-#define BUS_RQUEUE_MAX (192*1024) ++#define BUS_WQUEUE_MAX (384*1024) ++#define BUS_RQUEUE_MAX (384*1024) + + #define BUS_MESSAGE_SIZE_MAX (128*1024*1024) + #define BUS_AUTH_SIZE_MAX (64*1024) diff --git a/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch b/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch new file mode 100644 index 0000000..532dd60 --- /dev/null +++ b/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch @@ -0,0 +1,109 @@ +From 18a45cf91dbdd075fb55d752f959e84d36f3ab3b Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 7 Sep 2018 06:13:17 +0000 +Subject: [PATCH] tests: put fuzz_journald_processing_function in a .c file + +(cherry picked from commit 231dca5579cfba6175d19eee5347d693893fb5aa) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald.c | 30 ++++++++++++++++++++++++++++++ + src/fuzz/fuzz-journald.h | 24 ++---------------------- + src/fuzz/meson.build | 6 ++++-- + 3 files changed, 36 insertions(+), 24 deletions(-) + create mode 100644 src/fuzz/fuzz-journald.c + +diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c +new file mode 100644 +index 0000000000..f271d7f2fe +--- /dev/null ++++ b/src/fuzz/fuzz-journald.c +@@ -0,0 +1,30 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "alloc-util.h" ++#include "fuzz-journald.h" ++#include "journald-server.h" ++#include "sd-event.h" ++ ++void fuzz_journald_processing_function( ++ const uint8_t *data, ++ size_t size, ++ void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len) ++ ) { ++ Server s = {}; ++ char *label = NULL; ++ size_t label_len = 0; ++ struct ucred *ucred = NULL; ++ struct timeval *tv = NULL; ++ ++ if (size == 0) ++ return; ++ ++ assert_se(sd_event_default(&s.event) >= 0); ++ s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; ++ s.buffer = memdup_suffix0(data, size); ++ assert_se(s.buffer); ++ s.buffer_size = size + 1; ++ s.storage = STORAGE_NONE; ++ (*f)(&s, s.buffer, size, ucred, tv, label, label_len); ++ server_done(&s); ++} +diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h +index e66ef54c9b..e9d32a74aa 100644 +--- a/src/fuzz/fuzz-journald.h ++++ b/src/fuzz/fuzz-journald.h +@@ -1,30 +1,10 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + #pragma once + +-#include "alloc-util.h" + #include "journald-server.h" +-#include "sd-event.h" + +-static void fuzz_journald_processing_function( ++void fuzz_journald_processing_function( + const uint8_t *data, + size_t size, + void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len) +- ) { +- Server s = {}; +- char *label = NULL; +- size_t label_len = 0; +- struct ucred *ucred = NULL; +- struct timeval *tv = NULL; +- +- if (size == 0) +- return; +- +- assert_se(sd_event_default(&s.event) >= 0); +- s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; +- s.buffer = memdup_suffix0(data, size); +- assert_se(s.buffer); +- s.buffer_size = size + 1; +- s.storage = STORAGE_NONE; +- (*f)(&s, s.buffer, size, ucred, tv, label, label_len); +- server_done(&s); +-} ++); +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 483a952421..1f8631bcc0 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -33,12 +33,14 @@ fuzzers += [ + libshared], + [libmount]], + +- [['src/fuzz/fuzz-journald-native.c'], ++ [['src/fuzz/fuzz-journald-native.c', ++ 'src/fuzz/fuzz-journald.c'], + [libjournal_core, + libshared], + [libselinux]], + +- [['src/fuzz/fuzz-journald-syslog.c'], ++ [['src/fuzz/fuzz-journald-syslog.c', ++ 'src/fuzz/fuzz-journald.c'], + [libjournal_core, + libshared], + [libselinux]], diff --git a/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch b/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch new file mode 100644 index 0000000..6e01bbf --- /dev/null +++ b/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch @@ -0,0 +1,129 @@ +From e7e70f575840cd021f6429f264911ae0cbff9741 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Thu, 15 Nov 2018 17:52:57 +0100 +Subject: [PATCH] tests: add a fuzzer for dev_kmsg_record + +(cherry picked from commit 8857fb9beb9dcb95a6ce1be14dc94c4dc4cd3ea3) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-kmsg.c | 29 +++++++++++++++++++ + src/fuzz/meson.build | 5 ++++ + src/journal/journald-kmsg.c | 2 +- + src/journal/journald-kmsg.h | 2 ++ + test/fuzz/fuzz-journald-kmsg/basic | 1 + + test/fuzz/fuzz-journald-kmsg/dev-null | 2 ++ + test/fuzz/fuzz-journald-kmsg/loopback | 2 ++ + .../fuzz-journald-kmsg/subsystem-loopback | 2 ++ + 8 files changed, 44 insertions(+), 1 deletion(-) + create mode 100644 src/fuzz/fuzz-journald-kmsg.c + create mode 100644 test/fuzz/fuzz-journald-kmsg/basic + create mode 100644 test/fuzz/fuzz-journald-kmsg/dev-null + create mode 100644 test/fuzz/fuzz-journald-kmsg/loopback + create mode 100644 test/fuzz/fuzz-journald-kmsg/subsystem-loopback + +diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c +new file mode 100644 +index 0000000000..5d99d244b5 +--- /dev/null ++++ b/src/fuzz/fuzz-journald-kmsg.c +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "fuzz.h" ++#include "journald-kmsg.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ Server s = {}; ++ _cleanup_free_ char *buffer = NULL; ++ ++ if (size == 0) ++ return 0; ++ ++ s = (Server) { ++ .native_fd = -1, ++ .stdout_fd = -1, ++ .dev_kmsg_fd = -1, ++ .audit_fd = -1, ++ .hostname_fd = -1, ++ .notify_fd = -1, ++ .storage = STORAGE_NONE, ++ }; ++ assert_se(sd_event_default(&s.event) >= 0); ++ buffer = memdup(data, size); ++ assert_se(buffer); ++ dev_kmsg_record(&s, buffer, size); ++ server_done(&s); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 1f8631bcc0..0520e448a9 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -33,6 +33,11 @@ fuzzers += [ + libshared], + [libmount]], + ++ [['src/fuzz/fuzz-journald-kmsg.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journald-native.c', + 'src/fuzz/fuzz-journald.c'], + [libjournal_core, +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 7644bebfc8..0cdf1c4794 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -93,7 +93,7 @@ static bool is_us(const char *identifier, const char *pid) { + streq(identifier, program_invocation_short_name); + } + +-static void dev_kmsg_record(Server *s, char *p, size_t l) { ++void dev_kmsg_record(Server *s, char *p, size_t l) { + + _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL; + struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS]; +diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h +index bff24ac310..2326bc8c93 100644 +--- a/src/journal/journald-kmsg.h ++++ b/src/journal/journald-kmsg.h +@@ -9,3 +9,5 @@ int server_flush_dev_kmsg(Server *s); + void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred); + + int server_open_kernel_seqnum(Server *s); ++ ++void dev_kmsg_record(Server *s, char *p, size_t l); +diff --git a/test/fuzz/fuzz-journald-kmsg/basic b/test/fuzz/fuzz-journald-kmsg/basic +new file mode 100644 +index 0000000000..1299cd0869 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-kmsg/basic +@@ -0,0 +1 @@ ++29,456,292891883,-;systemd[1]: Reexecuting. +diff --git a/test/fuzz/fuzz-journald-kmsg/dev-null b/test/fuzz/fuzz-journald-kmsg/dev-null +new file mode 100644 +index 0000000000..de039588b5 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-kmsg/dev-null +@@ -0,0 +1,2 @@ ++12,460,1322026586,-;hey ++ DEVICE=c1:3 +diff --git a/test/fuzz/fuzz-journald-kmsg/loopback b/test/fuzz/fuzz-journald-kmsg/loopback +new file mode 100644 +index 0000000000..ca320177b7 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-kmsg/loopback +@@ -0,0 +1,2 @@ ++12,460,1322026586,-;hey ++ DEVICE=n1 +diff --git a/test/fuzz/fuzz-journald-kmsg/subsystem-loopback b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback +new file mode 100644 +index 0000000000..af9c0d91e5 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback +@@ -0,0 +1,2 @@ ++12,460,1322026586,-;hey ++ DEVICE=+net:lo diff --git a/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch b/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch new file mode 100644 index 0000000..ec38ffc --- /dev/null +++ b/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch @@ -0,0 +1,30 @@ +From 43d72623fdfca8500c8c89a4b5023e35a3f0b259 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 07:05:29 +0100 +Subject: [PATCH] basic: remove an assertion from cunescape_one + +The function takes a pointer to a random block of memory and +the length of that block. It shouldn't crash every time it sees +a zero byte at the beginning there. + +This should help the dev-kmsg fuzzer to keep going. + +(cherry picked from commit 8dc4de966ce6d32470aaff30ed054f6a2688d6d7) + +Resolves: #1764560 +--- + src/basic/escape.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/basic/escape.c b/src/basic/escape.c +index 5004763d97..5f715156fb 100644 +--- a/src/basic/escape.c ++++ b/src/basic/escape.c +@@ -106,7 +106,6 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) + int r = 1; + + assert(p); +- assert(*p); + assert(ret); + + /* Unescapes C style. Returns the unescaped character in ret. diff --git a/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch b/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch new file mode 100644 index 0000000..28a0b3e --- /dev/null +++ b/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch @@ -0,0 +1,25 @@ +From f00d221d5dc92a530e260db5f44fa57653f03e8b Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 07:11:06 +0100 +Subject: [PATCH] journal: fix an off-by-one error in dev_kmsg_record + +(cherry picked from commit 080d112caa0dc948555a69a008c1caf4d5d41ed6) + +Resolves: #1764560 +--- + src/journal/journald-kmsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 0cdf1c4794..726c006ce1 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -239,7 +239,7 @@ void dev_kmsg_record(Server *s, char *p, size_t l) { + ll = udev_device_get_devlinks_list_entry(ud); + udev_list_entry_foreach(ll, ll) { + +- if (j > N_IOVEC_UDEV_FIELDS) ++ if (j >= N_IOVEC_UDEV_FIELDS) + break; + + g = udev_list_entry_get_name(ll); diff --git a/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch b/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch new file mode 100644 index 0000000..14c1223 --- /dev/null +++ b/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch @@ -0,0 +1,25 @@ +From 4caa887ae8eabc087d6f9f2b233c96c220de8b02 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 07:20:44 +0100 +Subject: [PATCH] tests: add a reproducer for a memory leak fixed in + 30eddcd51b8a472e05d3b8d1 in August + +(cherry picked from commit 1dd485b700fe9ad94d7a780f14fcf18a4738ace4) + +Resolves: #1764560 +--- + ...leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 | Bin 0 -> 1847 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + create mode 100644 test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 + +diff --git a/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 b/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 +new file mode 100644 +index 0000000000000000000000000000000000000000..424ae5cb010aa519758e6af90cc981795b68d3fd +GIT binary patch +literal 1847 +zcmXps(lIeJ&@nVNGBPkSGqo_&(Y4MjX0aSiiycD2<{NiEaQE6vG)izFLb8I! +Date: Fri, 16 Nov 2018 07:33:02 +0100 +Subject: [PATCH] tests: add a reproducer for a heap-buffer-overflow fixed in + 937b1171378bc1000a + +(cherry picked from commit f7a6b40187a98751a9ab6867e8b52e4e6f1dad5c) + +Resolves: #1764560 +--- + ...crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 | Bin 0 -> 112 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + create mode 100644 test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 + +diff --git a/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 b/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 +new file mode 100644 +index 0000000000000000000000000000000000000000..19887a1fec9fc29b1f7da8a2d1c5ea5054f2bc02 +GIT binary patch +literal 112 +zcmXpq)Zrxx80r}680lCOP-~&{)k?wIfGehgOM!tQroxI#0Z63Aa4DF?03ibx03hxS +A82|tP + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch b/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch new file mode 100644 index 0000000..3ffa913 --- /dev/null +++ b/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch @@ -0,0 +1,44 @@ +From af471e7402a70b670cd50e45c6139a0ac50a74bd Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 09:23:53 +0100 +Subject: [PATCH] test: initialize syslog_fd in fuzz-journald-kmsg too + +This is a follow-up to 8857fb9beb9dcb that prevents the fuzzer from crashing with +``` +==220==ERROR: AddressSanitizer: ABRT on unknown address 0x0000000000dc (pc 0x7ff4953c8428 bp 0x7ffcf66ec290 sp 0x7ffcf66ec128 T0) +SCARINESS: 10 (signal) + #0 0x7ff4953c8427 in gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35427) + #1 0x7ff4953ca029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029) + #2 0x7ff49666503a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:805:9 + #3 0x7ff496614ecf in safe_close /work/build/../../src/systemd/src/basic/fd-util.c:66:17 + #4 0x548806 in server_done /work/build/../../src/systemd/src/journal/journald-server.c:2064:9 + #5 0x5349fa in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-journald-kmsg.c:26:9 + #6 0x592755 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:571:15 + #7 0x590627 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:480:3 + #8 0x594432 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:708:19 + #9 0x5973c6 in fuzzer::Fuzzer::Loop(std::__1::vector, std::__1::allocator >, fuzzer::fuzzer_allocator, std::__1::allocator > > > const&) /src/libfuzzer/FuzzerLoop.cpp:839:5 + #10 0x574541 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6 + #11 0x5675fc in main /src/libfuzzer/FuzzerMain.cpp:20:10 + #12 0x7ff4953b382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) + #13 0x420f58 in _start (/out/fuzz-journald-kmsg+0x420f58) +``` + +(cherry picked from commit cc55ac0171a2493768c021faa356513642797e7f) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-kmsg.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c +index 5d99d244b5..e2611c6d45 100644 +--- a/src/fuzz/fuzz-journald-kmsg.c ++++ b/src/fuzz/fuzz-journald-kmsg.c +@@ -11,6 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return 0; + + s = (Server) { ++ .syslog_fd = -1, + .native_fd = -1, + .stdout_fd = -1, + .dev_kmsg_fd = -1, diff --git a/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch b/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch new file mode 100644 index 0000000..d6ea02d --- /dev/null +++ b/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch @@ -0,0 +1,99 @@ +From f991a9c7644f3fb5155ff823600ba5a6ea403dc4 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 21:23:56 +0100 +Subject: [PATCH] tests: add a fuzzer for process_audit_string + +(cherry picked from commit 090a20cfaf3d5439fa39c5d8df473b0cfef181dd) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-audit.c | 27 +++++++++++++++++++++++++++ + src/fuzz/meson.build | 5 +++++ + src/journal/journald-audit.c | 2 +- + src/journal/journald-audit.h | 2 ++ + test/fuzz/fuzz-journald-audit/basic | 1 + + 5 files changed, 36 insertions(+), 1 deletion(-) + create mode 100644 src/fuzz/fuzz-journald-audit.c + create mode 100644 test/fuzz/fuzz-journald-audit/basic + +diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c +new file mode 100644 +index 0000000000..fe401c0d98 +--- /dev/null ++++ b/src/fuzz/fuzz-journald-audit.c +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "fuzz.h" ++#include "journald-audit.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ Server s; ++ _cleanup_free_ char *buffer = NULL; ++ ++ s = (Server) { ++ .syslog_fd = -1, ++ .native_fd = -1, ++ .stdout_fd = -1, ++ .dev_kmsg_fd = -1, ++ .audit_fd = -1, ++ .hostname_fd = -1, ++ .notify_fd = -1, ++ .storage = STORAGE_NONE, ++ }; ++ assert_se(sd_event_default(&s.event) >= 0); ++ buffer = memdup_suffix0(data, size); ++ assert_se(buffer); ++ process_audit_string(&s, 0, buffer, size); ++ server_done(&s); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 0520e448a9..5548da3822 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -33,6 +33,11 @@ fuzzers += [ + libshared], + [libmount]], + ++ [['src/fuzz/fuzz-journald-audit.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journald-kmsg.c'], + [libjournal_core, + libshared], +diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c +index 87726684af..7810a0139a 100644 +--- a/src/journal/journald-audit.c ++++ b/src/journal/journald-audit.c +@@ -313,7 +313,7 @@ static int map_all_fields( + } + } + +-static void process_audit_string(Server *s, int type, const char *data, size_t size) { ++void process_audit_string(Server *s, int type, const char *data, size_t size) { + size_t n_iov_allocated = 0, n_iov = 0, z; + _cleanup_free_ struct iovec *iov = NULL; + uint64_t seconds, msec, id; +diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h +index 57bb1711c9..7766618c98 100644 +--- a/src/journal/journald-audit.h ++++ b/src/journal/journald-audit.h +@@ -6,4 +6,6 @@ + + void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const union sockaddr_union *sa, socklen_t salen); + ++void process_audit_string(Server *s, int type, const char *data, size_t size); ++ + int server_open_audit(Server*s); +diff --git a/test/fuzz/fuzz-journald-audit/basic b/test/fuzz/fuzz-journald-audit/basic +new file mode 100644 +index 0000000000..d1ce8cc5f0 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-audit/basic +@@ -0,0 +1 @@ ++audit(1542398162.211:744): pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success' +\ No newline at end of file diff --git a/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch b/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch new file mode 100644 index 0000000..29ce46f --- /dev/null +++ b/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch @@ -0,0 +1,47 @@ +From bef599d1a0e41afe4b6f1d6dfb6fbc86896ab8c5 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 16 Nov 2018 23:32:31 +0100 +Subject: [PATCH] journald: check whether sscanf has changed the value + corresponding to %n + +It's possible for sscanf to receive strings containing all three fields +and not matching the template at the same time. When this happens the +value of k doesn't change, which basically means that process_audit_string +tries to access memory randomly. Sometimes it works and sometimes it doesn't :-) + +See also https://bugzilla.redhat.com/show_bug.cgi?id=1059314. + +(cherry picked from commit 1dab14aba749b9c5ab8176c5730107b70834240b) + +Resolves: #1764560 +--- + src/journal/journald-audit.c | 3 ++- + test/fuzz/fuzz-journald-audit/crash | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + create mode 100644 test/fuzz/fuzz-journald-audit/crash + +diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c +index 7810a0139a..0fd6ab2a84 100644 +--- a/src/journal/journald-audit.c ++++ b/src/journal/journald-audit.c +@@ -341,11 +341,12 @@ void process_audit_string(Server *s, int type, const char *data, size_t size) { + if (!p) + return; + ++ k = 0; + if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n", + &seconds, + &msec, + &id, +- &k) != 3) ++ &k) != 3 || k == 0) + return; + + p += k; +diff --git a/test/fuzz/fuzz-journald-audit/crash b/test/fuzz/fuzz-journald-audit/crash +new file mode 100644 +index 0000000000..91bd85ca6e +--- /dev/null ++++ b/test/fuzz/fuzz-journald-audit/crash +@@ -0,0 +1 @@ ++audit(1542398162.211:744) pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success' diff --git a/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch b/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch new file mode 100644 index 0000000..f4a5225 --- /dev/null +++ b/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch @@ -0,0 +1,172 @@ +From b276c85200786add6c86b6c1fedc888c71ffe5db Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Sat, 17 Nov 2018 13:01:09 +0100 +Subject: [PATCH] tests: introduce dummy_server_init and use it in all journald + fuzzers + +(cherry picked from commit ed62712dc6fb236845c489a7f386c7aff0ec31d6) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-audit.c | 18 +++--------------- + src/fuzz/fuzz-journald-kmsg.c | 20 ++++---------------- + src/fuzz/fuzz-journald.c | 26 +++++++++++++++++++------- + src/fuzz/fuzz-journald.h | 2 ++ + src/fuzz/meson.build | 6 ++++-- + 5 files changed, 32 insertions(+), 40 deletions(-) + +diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c +index fe401c0d98..3f3ce7e8ee 100644 +--- a/src/fuzz/fuzz-journald-audit.c ++++ b/src/fuzz/fuzz-journald-audit.c +@@ -1,26 +1,14 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "fuzz.h" ++#include "fuzz-journald.h" + #include "journald-audit.h" + + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + Server s; +- _cleanup_free_ char *buffer = NULL; + +- s = (Server) { +- .syslog_fd = -1, +- .native_fd = -1, +- .stdout_fd = -1, +- .dev_kmsg_fd = -1, +- .audit_fd = -1, +- .hostname_fd = -1, +- .notify_fd = -1, +- .storage = STORAGE_NONE, +- }; +- assert_se(sd_event_default(&s.event) >= 0); +- buffer = memdup_suffix0(data, size); +- assert_se(buffer); +- process_audit_string(&s, 0, buffer, size); ++ dummy_server_init(&s, data, size); ++ process_audit_string(&s, 0, s.buffer, size); + server_done(&s); + + return 0; +diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c +index e2611c6d45..f7426c8400 100644 +--- a/src/fuzz/fuzz-journald-kmsg.c ++++ b/src/fuzz/fuzz-journald-kmsg.c +@@ -1,29 +1,17 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "fuzz.h" ++#include "fuzz-journald.h" + #include "journald-kmsg.h" + + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { +- Server s = {}; +- _cleanup_free_ char *buffer = NULL; ++ Server s; + + if (size == 0) + return 0; + +- s = (Server) { +- .syslog_fd = -1, +- .native_fd = -1, +- .stdout_fd = -1, +- .dev_kmsg_fd = -1, +- .audit_fd = -1, +- .hostname_fd = -1, +- .notify_fd = -1, +- .storage = STORAGE_NONE, +- }; +- assert_se(sd_event_default(&s.event) >= 0); +- buffer = memdup(data, size); +- assert_se(buffer); +- dev_kmsg_record(&s, buffer, size); ++ dummy_server_init(&s, data, size); ++ dev_kmsg_record(&s, s.buffer, size); + server_done(&s); + + return 0; +diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c +index f271d7f2fe..0659b92ba3 100644 +--- a/src/fuzz/fuzz-journald.c ++++ b/src/fuzz/fuzz-journald.c +@@ -5,12 +5,29 @@ + #include "journald-server.h" + #include "sd-event.h" + ++void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) { ++ *s = (Server) { ++ .syslog_fd = -1, ++ .native_fd = -1, ++ .stdout_fd = -1, ++ .dev_kmsg_fd = -1, ++ .audit_fd = -1, ++ .hostname_fd = -1, ++ .notify_fd = -1, ++ .storage = STORAGE_NONE, ++ }; ++ assert_se(sd_event_default(&s->event) >= 0); ++ s->buffer = memdup_suffix0(buffer, size); ++ assert_se(s->buffer); ++ s->buffer_size = size + 1; ++} ++ + void fuzz_journald_processing_function( + const uint8_t *data, + size_t size, + void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len) + ) { +- Server s = {}; ++ Server s; + char *label = NULL; + size_t label_len = 0; + struct ucred *ucred = NULL; +@@ -19,12 +36,7 @@ void fuzz_journald_processing_function( + if (size == 0) + return; + +- assert_se(sd_event_default(&s.event) >= 0); +- s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1; +- s.buffer = memdup_suffix0(data, size); +- assert_se(s.buffer); +- s.buffer_size = size + 1; +- s.storage = STORAGE_NONE; ++ dummy_server_init(&s, data, size); + (*f)(&s, s.buffer, size, ucred, tv, label, label_len); + server_done(&s); + } +diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h +index e9d32a74aa..77e3b0c064 100644 +--- a/src/fuzz/fuzz-journald.h ++++ b/src/fuzz/fuzz-journald.h +@@ -3,6 +3,8 @@ + + #include "journald-server.h" + ++void dummy_server_init(Server *s, const uint8_t *buffer, size_t size); ++ + void fuzz_journald_processing_function( + const uint8_t *data, + size_t size, +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 5548da3822..897c02e4ae 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -33,12 +33,14 @@ fuzzers += [ + libshared], + [libmount]], + +- [['src/fuzz/fuzz-journald-audit.c'], ++ [['src/fuzz/fuzz-journald-audit.c', ++ 'src/fuzz/fuzz-journald.c'], + [libjournal_core, + libshared], + [libselinux]], + +- [['src/fuzz/fuzz-journald-kmsg.c'], ++ [['src/fuzz/fuzz-journald-kmsg.c', ++ 'src/fuzz/fuzz-journald.c'], + [libjournal_core, + libshared], + [libselinux]], diff --git a/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch b/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch new file mode 100644 index 0000000..03ff6e8 --- /dev/null +++ b/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch @@ -0,0 +1,148 @@ +From e7077e3a551a3faedfcc3d007de6a72fb5e1df62 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Tue, 20 Nov 2018 01:20:32 +0100 +Subject: [PATCH] tests: add a fuzzer for journald streams + +(cherry picked from commit 9541f5ff5c637bb1b3e3c69706cb73e68ff06813) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-stream.c | 35 ++++++++++++++++++++++++++++ + src/fuzz/fuzz-journald.c | 10 +++++--- + src/fuzz/meson.build | 6 +++++ + src/journal/journald-stream.c | 4 ++-- + src/journal/journald-stream.h | 2 ++ + test/fuzz/fuzz-journald-stream/basic | 8 +++++++ + 6 files changed, 60 insertions(+), 5 deletions(-) + create mode 100644 src/fuzz/fuzz-journald-stream.c + create mode 100644 test/fuzz/fuzz-journald-stream/basic + +diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c +new file mode 100644 +index 0000000000..247c0889bc +--- /dev/null ++++ b/src/fuzz/fuzz-journald-stream.c +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++ ++#include "fd-util.h" ++#include "fuzz.h" ++#include "fuzz-journald.h" ++#include "journald-stream.h" ++ ++static int stream_fds[2] = { -1, -1 }; ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ Server s; ++ StdoutStream *stream; ++ int v; ++ ++ if (size == 0) ++ return 0; ++ ++ if (!getenv("SYSTEMD_LOG_LEVEL")) ++ log_set_max_level(LOG_CRIT); ++ ++ assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0); ++ dummy_server_init(&s, NULL, 0); ++ assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0); ++ assert_se(write(stream_fds[1], data, size) == (ssize_t) size); ++ while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v) ++ sd_event_run(s.event, (uint64_t) -1); ++ if (s.n_stdout_streams) ++ stdout_stream_destroy(stream); ++ server_done(&s); ++ stream_fds[1] = safe_close(stream_fds[1]); ++ ++ return 0; ++} +diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c +index 0659b92ba3..950e885cae 100644 +--- a/src/fuzz/fuzz-journald.c ++++ b/src/fuzz/fuzz-journald.c +@@ -15,11 +15,15 @@ void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) { + .hostname_fd = -1, + .notify_fd = -1, + .storage = STORAGE_NONE, ++ .line_max = 64, + }; + assert_se(sd_event_default(&s->event) >= 0); +- s->buffer = memdup_suffix0(buffer, size); +- assert_se(s->buffer); +- s->buffer_size = size + 1; ++ ++ if (buffer) { ++ s->buffer = memdup_suffix0(buffer, size); ++ assert_se(s->buffer); ++ s->buffer_size = size + 1; ++ } + } + + void fuzz_journald_processing_function( +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 897c02e4ae..eea9117360 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -51,6 +51,12 @@ fuzzers += [ + libshared], + [libselinux]], + ++ [['src/fuzz/fuzz-journald-stream.c', ++ 'src/fuzz/fuzz-journald.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journald-syslog.c', + 'src/fuzz/fuzz-journald.c'], + [libjournal_core, +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index dbf3503a82..6f8a4011ff 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -125,7 +125,7 @@ void stdout_stream_free(StdoutStream *s) { + + DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free); + +-static void stdout_stream_destroy(StdoutStream *s) { ++void stdout_stream_destroy(StdoutStream *s) { + if (!s) + return; + +@@ -534,7 +534,7 @@ terminate: + return 0; + } + +-static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { ++int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { + _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL; + sd_id128_t id; + int r; +diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h +index bc5622ab3b..487376e763 100644 +--- a/src/journal/journald-stream.h ++++ b/src/journal/journald-stream.h +@@ -10,4 +10,6 @@ int server_open_stdout_socket(Server *s); + int server_restore_streams(Server *s, FDSet *fds); + + void stdout_stream_free(StdoutStream *s); ++int stdout_stream_install(Server *s, int fd, StdoutStream **ret); ++void stdout_stream_destroy(StdoutStream *s); + void stdout_stream_send_notify(StdoutStream *s); +diff --git a/test/fuzz/fuzz-journald-stream/basic b/test/fuzz/fuzz-journald-stream/basic +new file mode 100644 +index 0000000000..a088f1a539 +--- /dev/null ++++ b/test/fuzz/fuzz-journald-stream/basic +@@ -0,0 +1,8 @@ ++ ++ ++6 ++1 ++0 ++0 ++0 ++hey +\ No newline at end of file diff --git a/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch b/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch new file mode 100644 index 0000000..500af37 --- /dev/null +++ b/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch @@ -0,0 +1,96 @@ +From 76e2fa8ed4bbee7c625e3b790f2e38a59fffd93d Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 23 Nov 2018 00:27:19 +0100 +Subject: [PATCH] tests: add a fuzzer for server_process_native_file + +(cherry picked from commit a4aa59bae206eebb4703b291147144def5d4bb3e) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-native-fd.c | 47 ++++++++++++++++++++++++ + src/fuzz/meson.build | 6 +++ + test/fuzz/fuzz-journald-native-fd/basic | Bin 0 -> 34 bytes + 3 files changed, 53 insertions(+) + create mode 100644 src/fuzz/fuzz-journald-native-fd.c + create mode 100644 test/fuzz/fuzz-journald-native-fd/basic + +diff --git a/src/fuzz/fuzz-journald-native-fd.c b/src/fuzz/fuzz-journald-native-fd.c +new file mode 100644 +index 0000000000..95415d9f85 +--- /dev/null ++++ b/src/fuzz/fuzz-journald-native-fd.c +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "fd-util.h" ++#include "fileio.h" ++#include "fs-util.h" ++#include "fuzz.h" ++#include "fuzz-journald.h" ++#include "journald-native.h" ++#include "memfd-util.h" ++#include "process-util.h" ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ Server s; ++ _cleanup_close_ int sealed_fd = -1, unsealed_fd = -1; ++ _cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX"; ++ char *label = NULL; ++ size_t label_len = 0; ++ struct ucred ucred; ++ struct timeval *tv = NULL; ++ ++ if (!getenv("SYSTEMD_LOG_LEVEL")) ++ log_set_max_level(LOG_CRIT); ++ ++ dummy_server_init(&s, NULL, 0); ++ ++ sealed_fd = memfd_new(NULL); ++ assert_se(sealed_fd >= 0); ++ assert_se(write(sealed_fd, data, size) == (ssize_t) size); ++ assert_se(memfd_set_sealed(sealed_fd) >= 0); ++ assert_se(lseek(sealed_fd, 0, SEEK_SET) == 0); ++ ucred = (struct ucred) { ++ .pid = getpid_cached(), ++ .uid = geteuid(), ++ .gid = getegid(), ++ }; ++ server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len); ++ ++ unsealed_fd = mkostemp_safe(name); ++ assert_se(unsealed_fd >= 0); ++ assert_se(write(unsealed_fd, data, size) == (ssize_t) size); ++ assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0); ++ server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len); ++ ++ server_done(&s); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index eea9117360..5315d2771c 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -51,6 +51,12 @@ fuzzers += [ + libshared], + [libselinux]], + ++ [['src/fuzz/fuzz-journald-native-fd.c', ++ 'src/fuzz/fuzz-journald.c'], ++ [libjournal_core, ++ libshared], ++ [libselinux]], ++ + [['src/fuzz/fuzz-journald-stream.c', + 'src/fuzz/fuzz-journald.c'], + [libjournal_core, +diff --git a/test/fuzz/fuzz-journald-native-fd/basic b/test/fuzz/fuzz-journald-native-fd/basic +new file mode 100644 +index 0000000000000000000000000000000000000000..65f89705a655618851c0e446efaa5c633adf425f +GIT binary patch +literal 34 +kcmeZu4Gwm6cjaPXfB;7>M@KGyCofm$koW*k7h3}^0B8*cRR910 + +literal 0 +HcmV?d00001 + diff --git a/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch b/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch new file mode 100644 index 0000000..798aa6c --- /dev/null +++ b/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch @@ -0,0 +1,47 @@ +From 2d197adc6d7109d5901401a90288530582f3f991 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 26 Feb 2019 13:00:35 +0100 +Subject: [PATCH] fuzz-journal-stream: avoid assertion failure on samples which + don't fit in pipe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11587. +We had a sample which was large enough that write(2) failed to push all the +data into the pipe, and an assert failed. The code could be changed to use +a loop, but then we'd need to interleave writes and sd_event_run (to process +the journal). I don't think the complexity is worth it — fuzzing works best +if the sample is not too huge anyway. So let's just reject samples above 64k, +and tell oss-fuzz about this limit. + +(cherry picked from commit eafadd069c4e30ed62173123326a7237448615d1) + +Resolves: #1764560 +--- + src/fuzz/fuzz-journald-stream.c | 2 +- + src/fuzz/fuzz-journald-stream.options | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + create mode 100644 src/fuzz/fuzz-journald-stream.options + +diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c +index 247c0889bc..693b197d3a 100644 +--- a/src/fuzz/fuzz-journald-stream.c ++++ b/src/fuzz/fuzz-journald-stream.c +@@ -14,7 +14,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + StdoutStream *stream; + int v; + +- if (size == 0) ++ if (size == 0 || size > 65536) + return 0; + + if (!getenv("SYSTEMD_LOG_LEVEL")) +diff --git a/src/fuzz/fuzz-journald-stream.options b/src/fuzz/fuzz-journald-stream.options +new file mode 100644 +index 0000000000..678d526b1e +--- /dev/null ++++ b/src/fuzz/fuzz-journald-stream.options +@@ -0,0 +1,2 @@ ++[libfuzzer] ++max_len = 65536 diff --git a/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch b/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch new file mode 100644 index 0000000..25b1d95 --- /dev/null +++ b/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch @@ -0,0 +1,45 @@ +From 3521217c88b364e2c5b10a1e35d3c036b1ecba64 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 10 Aug 2018 12:55:09 +0000 +Subject: [PATCH] journald: take leading spaces into account in + syslog_parse_identifier + +This is a kind of follow-up to e88baee88fad8bc59d3 which should finally fix +the issue which that commit was supposed to fix. + +(cherry picked from commit 937b1171378bc1000a34fcdfe9534d898227e35f) + +Resolves: #1764560 +--- + src/journal/journald-syslog.c | 3 ++- + src/journal/test-journal-syslog.c | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c +index e0b55cc566..ae966763a0 100644 +--- a/src/journal/journald-syslog.c ++++ b/src/journal/journald-syslog.c +@@ -223,8 +223,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) + if (p[e] != '\0' && strchr(WHITESPACE, p[e])) + e++; + ++ l = (p - *buf) + e; + *buf = p + e; +- return e; ++ return l; + } + + static void syslog_skip_date(char **buf) { +diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c +index 120477cc9f..415b9d23ca 100644 +--- a/src/journal/test-journal-syslog.c ++++ b/src/journal/test-journal-syslog.c +@@ -41,6 +41,8 @@ int main(void) { + test_syslog_parse_identifier(" ", NULL, NULL, " ", 0); + test_syslog_parse_identifier(":", "", NULL, "", 1); + test_syslog_parse_identifier(": ", "", NULL, " ", 2); ++ test_syslog_parse_identifier(" :", "", NULL, "", 2); ++ test_syslog_parse_identifier(" pidu:", "pidu", NULL, "", 8); + test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5); + test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6); + test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0); diff --git a/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch b/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch new file mode 100644 index 0000000..8b0bd5c --- /dev/null +++ b/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch @@ -0,0 +1,43 @@ +From 5df63c2ddf93bab5e7f13e09dfb1f97a011b3451 Mon Sep 17 00:00:00 2001 +From: Taro Yamada +Date: Sun, 27 Jan 2019 13:50:04 +0900 +Subject: [PATCH] Add a warning about the difference in permissions between + existing directories and unit settings. + +To follows the intent of 30c81ce, this change does not execute chmod() and just add warnings. + +(cherry picked from commit 6cff72eb0a18d8547f005a481cd0622d3bc78483) + +Related: #1778384 +--- + src/core/execute.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 8293c522bc..9ddba00421 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2099,8 +2099,21 @@ static int setup_exec_directory( + r = mkdir_label(p, context->directories[type].mode); + if (r < 0 && r != -EEXIST) + goto fail; +- if (r == -EEXIST && !context->dynamic_user) +- continue; ++ if (r == -EEXIST) { ++ struct stat st; ++ ++ if (stat(p, &st) < 0) { ++ r = -errno; ++ goto fail; ++ } ++ if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0) ++ log_warning("%s \'%s\' already exists but the mode is different. " ++ "(filesystem: %o %sMode: %o)", ++ exec_directory_type_to_string(type), *rt, ++ st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777); ++ if (!context->dynamic_user) ++ continue; ++ } + } + + /* Don't change the owner of the configuration directory, as in the common case it is not written to by diff --git a/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch b/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch new file mode 100644 index 0000000..8101159 --- /dev/null +++ b/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch @@ -0,0 +1,32 @@ +From 81ca39b7b38ef1d44cc146efe75bef412e7c4c97 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 14 Mar 2019 17:01:46 +0100 +Subject: [PATCH] execute: remove one redundant comparison check + +(cherry picked from commit d484580ca6f0e79abe6f3f5c677323a22d9e22d7) + +Related: #1778384 +--- + src/core/execute.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 9ddba00421..46aa733937 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2097,11 +2097,12 @@ static int setup_exec_directory( + } + } else { + r = mkdir_label(p, context->directories[type].mode); +- if (r < 0 && r != -EEXIST) +- goto fail; +- if (r == -EEXIST) { ++ if (r < 0) { + struct stat st; + ++ if (r != -EEXIST) ++ goto fail; ++ + if (stat(p, &st) < 0) { + r = -errno; + goto fail; diff --git a/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch b/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch new file mode 100644 index 0000000..faaef74 --- /dev/null +++ b/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch @@ -0,0 +1,88 @@ +From 789806ac06bb13d1b579fef47dbb85f224b6dbb1 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 14 Mar 2019 17:19:30 +0100 +Subject: [PATCH] core: change ownership/mode of the execution directories also + for static users + +It's probably unexpected if we do a recursive chown() when dynamic users +are used but not on static users. + +hence, let's tweak the logic slightly, and recursively chown in both +cases, except when operating on the configuration directory. + +Fixes: #11842 +(cherry picked from commit 206e9864de460dd79d9edd7bedb47dee168765e1) + +Resolves: #1778384 +--- + src/core/execute.c | 47 +++++++++++++++++++++++++--------------------- + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 46aa733937..c42300a41e 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2090,37 +2090,42 @@ static int setup_exec_directory( + if (r < 0) + goto fail; + +- /* Lock down the access mode */ +- if (chmod(pp, context->directories[type].mode) < 0) { +- r = -errno; +- goto fail; +- } + } else { + r = mkdir_label(p, context->directories[type].mode); + if (r < 0) { +- struct stat st; +- + if (r != -EEXIST) + goto fail; + +- if (stat(p, &st) < 0) { +- r = -errno; +- goto fail; +- } +- if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0) +- log_warning("%s \'%s\' already exists but the mode is different. " +- "(filesystem: %o %sMode: %o)", +- exec_directory_type_to_string(type), *rt, +- st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777); +- if (!context->dynamic_user) ++ if (type == EXEC_DIRECTORY_CONFIGURATION) { ++ struct stat st; ++ ++ /* Don't change the owner/access mode of the configuration directory, ++ * as in the common case it is not written to by a service, and shall ++ * not be writable. */ ++ ++ if (stat(p, &st) < 0) { ++ r = -errno; ++ goto fail; ++ } ++ ++ /* Still complain if the access mode doesn't match */ ++ if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0) ++ log_warning("%s \'%s\' already exists but the mode is different. " ++ "(File system: %o %sMode: %o)", ++ exec_directory_type_to_string(type), *rt, ++ st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777); ++ + continue; ++ } + } + } + +- /* Don't change the owner of the configuration directory, as in the common case it is not written to by +- * a service, and shall not be writable. */ +- if (type == EXEC_DIRECTORY_CONFIGURATION) +- continue; ++ /* Lock down the access mode (we use chmod_and_chown() to make this idempotent. We don't ++ * specifiy UID/GID here, so that path_chown_recursive() can optimize things depending on the ++ * current UID/GID ownership.) */ ++ r = chmod_and_chown(pp ?: p, context->directories[type].mode, UID_INVALID, GID_INVALID); ++ if (r < 0) ++ goto fail; + + /* Then, change the ownership of the whole tree, if necessary */ + r = path_chown_recursive(pp ?: p, uid, gid); diff --git a/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch b/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch new file mode 100644 index 0000000..e46f256 --- /dev/null +++ b/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch @@ -0,0 +1,25 @@ +From 5d7e8cb0e12e4642a760cf00cbb6caf4c07b9cd9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 19 May 2019 16:05:02 +0200 +Subject: [PATCH] core/dbus-execute: remove unnecessary initialization + +(cherry picked from commit bd0abfaea1514bdd7cb60228d7a3f94c17ba916d) + +Related: #1734787 +--- + src/core/dbus-execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 33a91c012e..5379545d57 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1552,7 +1552,7 @@ int bus_exec_context_set_transient_property( + #endif + if (streq(name, "CPUAffinity")) { + const void *a; +- size_t n = 0; ++ size_t n; + + r = sd_bus_message_read_array(message, 'y', &a, &n); + if (r < 0) diff --git a/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch b/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch new file mode 100644 index 0000000..5babb33 --- /dev/null +++ b/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch @@ -0,0 +1,215 @@ +From 46b4d26c54a773f7da350e89562039ccc5157a8f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 19 May 2019 18:02:38 +0200 +Subject: [PATCH] shared/cpu-set-util: move the part to print cpu-set into a + separate function + +Also avoid unnecessary asprintf() when we can write to the output area +directly. + +(cherry picked from commit a832893f9c4f0a0329768e90f67e2fa24bb0008e) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 21 +++++++++++++++++++++ + src/basic/cpu-set-util.h | 1 + + src/core/dbus-execute.c | 29 +++++------------------------ + src/test/test-cpu-set-util.c | 29 +++++++++++++++++++++++++++++ + 4 files changed, 56 insertions(+), 24 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index b1c927bcb8..8f24a2601a 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + + #include "alloc-util.h" +@@ -15,6 +16,26 @@ + #include "parse-util.h" + #include "string-util.h" + ++char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) { ++ _cleanup_free_ char *str = NULL; ++ size_t allocated = 0, len = 0; ++ int i, r; ++ ++ for (i = 0; (size_t) i < setsize * 8; i++) { ++ if (!CPU_ISSET_S(i, setsize, set)) ++ continue; ++ ++ if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int))) ++ return NULL; ++ ++ r = sprintf(str + len, len > 0 ? " %d" : "%d", i); ++ assert_se(r > 0); ++ len += r; ++ } ++ ++ return TAKE_PTR(str) ?: strdup(""); ++} ++ + cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + cpu_set_t *c; + unsigned n = 1024; +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 88470fe15a..3c546beb55 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -26,6 +26,7 @@ static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) { + + cpu_set_t* cpu_set_malloc(unsigned *ncpus); + ++char* cpu_set_to_string(const cpu_set_t *set, size_t setsize); + int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue); + + static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) { +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 5379545d57..d9f4445745 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1565,32 +1565,13 @@ int bus_exec_context_set_transient_property( + unit_write_settingf(u, flags, name, "%s=", name); + } else { + _cleanup_free_ char *str = NULL; +- size_t allocated = 0, len = 0, i, ncpus; ++ size_t ncpus; + +- ncpus = CPU_SIZE_TO_NUM(n); +- +- for (i = 0; i < ncpus; i++) { +- _cleanup_free_ char *p = NULL; +- size_t add; +- +- if (!CPU_ISSET_S(i, n, (cpu_set_t*) a)) +- continue; +- +- r = asprintf(&p, "%zu", i); +- if (r < 0) +- return -ENOMEM; +- +- add = strlen(p); +- +- if (!GREEDY_REALLOC(str, allocated, len + add + 2)) +- return -ENOMEM; +- +- strcpy(mempcpy(str + len, p, add), " "); +- len += add + 1; +- } ++ str = cpu_set_to_string(a, n); ++ if (!str) ++ return -ENOMEM; + +- if (len != 0) +- str[len - 1] = '\0'; ++ ncpus = CPU_SIZE_TO_NUM(n); + + if (!c->cpuset || c->cpuset_ncpus < ncpus) { + cpu_set_t *cpuset; +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index c9272459b4..ff5edb2a69 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -6,6 +6,7 @@ + + static void test_parse_cpu_set(void) { + cpu_set_t *c = NULL; ++ _cleanup_free_ char *str = NULL; + int ncpus; + int cpu; + +@@ -15,6 +16,10 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c)); + assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c)); + assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2); ++ ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* A more interesting range */ +@@ -25,6 +30,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Quoted strings */ +@@ -33,6 +41,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Use commas as separators */ +@@ -43,6 +54,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Commas with spaces (and trailing comma, space) */ +@@ -51,6 +65,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); + for (cpu = 0; cpu < 8; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Ranges */ +@@ -61,6 +78,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Ranges with trailing comma, space */ +@@ -71,6 +91,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Negative range (returns empty cpu_set) */ +@@ -85,6 +108,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12); + for (cpu = 0; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Mix ranges and individual CPUs */ +@@ -95,6 +121,9 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c)); + for (cpu = 4; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); + c = cpu_set_mfree(c); + + /* Garbage */ diff --git a/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch b/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch new file mode 100644 index 0000000..8d393c5 --- /dev/null +++ b/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch @@ -0,0 +1,29 @@ +From d6935e61de30967aa82b7722f36193ba782b75e4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 19 May 2019 18:08:39 +0200 +Subject: [PATCH] shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM() + +(cherry picked from commit b12ef7141648be40fd8c4b0209a742f2151736d9) + +Related: #1734787 +--- + src/basic/cpu-set-util.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 3c546beb55..20612a8876 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -9,12 +9,6 @@ + + #include "macro.h" + +-#ifdef __NCPUBITS +-#define CPU_SIZE_TO_NUM(n) ((n) * __NCPUBITS) +-#else +-#define CPU_SIZE_TO_NUM(n) ((n) * sizeof(cpu_set_t) * 8) +-#endif +- + DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE); + #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp) + diff --git a/SOURCES/0272-Rework-cpu-affinity-parsing.patch b/SOURCES/0272-Rework-cpu-affinity-parsing.patch new file mode 100644 index 0000000..f6001e5 --- /dev/null +++ b/SOURCES/0272-Rework-cpu-affinity-parsing.patch @@ -0,0 +1,932 @@ +From 61e5aed87f1b82a51c6ea8ccde96805cb63e5b15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 21 May 2019 08:45:19 +0200 +Subject: [PATCH] Rework cpu affinity parsing + +The CPU_SET_S api is pretty bad. In particular, it has a parameter for the size +of the array, but operations which take two (CPU_EQUAL_S) or even three arrays +(CPU_{AND,OR,XOR}_S) still take just one size. This means that all arrays must +be of the same size, or buffer overruns will occur. This is exactly what our +code would do, if it received an array of unexpected size over the network. +("Unexpected" here means anything different from what cpu_set_malloc() detects +as the "right" size.) + +Let's rework this, and store the size in bytes of the allocated storage area. + +The code will now parse any number up to 8191, independently of what the current +kernel supports. This matches the kernel maximum setting for any architecture, +to make things more portable. + +Fixes #12605. + +(cherry picked from commit 0985c7c4e22c8dbbea4398cf3453da45ebf63800) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 133 +++++++++++++++++++++----- + src/basic/cpu-set-util.h | 47 ++++++--- + src/core/dbus-execute.c | 35 ++----- + src/core/execute.c | 12 +-- + src/core/execute.h | 4 +- + src/core/load-fragment.c | 31 +----- + src/core/main.c | 14 +-- + src/nspawn/nspawn-settings.c | 33 +------ + src/nspawn/nspawn-settings.h | 4 +- + src/nspawn/nspawn.c | 29 +++--- + src/shared/bus-unit-util.c | 4 +- + src/test/test-cpu-set-util.c | 179 +++++++++++++++++++---------------- + src/test/test-sizeof.c | 3 + + 13 files changed, 286 insertions(+), 242 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 8f24a2601a..fe440f6381 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -15,14 +15,15 @@ + #include "macro.h" + #include "parse-util.h" + #include "string-util.h" ++#include "util.h" + +-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) { ++char* cpu_set_to_string(const CPUSet *a) { + _cleanup_free_ char *str = NULL; + size_t allocated = 0, len = 0; + int i, r; + +- for (i = 0; (size_t) i < setsize * 8; i++) { +- if (!CPU_ISSET_S(i, setsize, set)) ++ for (i = 0; (size_t) i < a->allocated * 8; i++) { ++ if (!CPU_ISSET_S(i, a->allocated, a->set)) + continue; + + if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int))) +@@ -65,24 +66,74 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + } + } + +-int parse_cpu_set_internal( ++static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { ++ size_t need; ++ ++ assert(cpu_set); ++ ++ need = CPU_ALLOC_SIZE(ncpus); ++ if (need > cpu_set->allocated) { ++ cpu_set_t *t; ++ ++ t = realloc(cpu_set->set, need); ++ if (!t) ++ return -ENOMEM; ++ ++ memzero((uint8_t*) t + cpu_set->allocated, need - cpu_set->allocated); ++ ++ cpu_set->set = t; ++ cpu_set->allocated = need; ++ } ++ ++ return 0; ++} ++ ++static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) { ++ int r; ++ ++ if (cpu >= 8192) ++ /* As of kernel 5.1, CONFIG_NR_CPUS can be set to 8192 on PowerPC */ ++ return -ERANGE; ++ ++ r = cpu_set_realloc(cpu_set, cpu + 1); ++ if (r < 0) ++ return r; ++ ++ CPU_SET_S(cpu, cpu_set->allocated, cpu_set->set); ++ return 0; ++} ++ ++int cpu_set_add_all(CPUSet *a, const CPUSet *b) { ++ int r; ++ ++ /* Do this backwards, so if we fail, we fail before changing anything. */ ++ for (unsigned cpu_p1 = b->allocated * 8; cpu_p1 > 0; cpu_p1--) ++ if (CPU_ISSET_S(cpu_p1 - 1, b->allocated, b->set)) { ++ r = cpu_set_add(a, cpu_p1 - 1); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ ++int parse_cpu_set_full( + const char *rvalue, +- cpu_set_t **cpu_set, ++ CPUSet *cpu_set, + bool warn, + const char *unit, + const char *filename, + unsigned line, + const char *lvalue) { + +- _cleanup_cpu_free_ cpu_set_t *c = NULL; ++ _cleanup_(cpu_set_reset) CPUSet c = {}; + const char *p = rvalue; +- unsigned ncpus = 0; + +- assert(rvalue); ++ assert(p); + + for (;;) { + _cleanup_free_ char *word = NULL; +- unsigned cpu, cpu_lower, cpu_upper; ++ unsigned cpu_lower, cpu_upper; + int r; + + r = extract_first_word(&p, &word, WHITESPACE ",", EXTRACT_QUOTES); +@@ -93,31 +144,63 @@ int parse_cpu_set_internal( + if (r == 0) + break; + +- if (!c) { +- c = cpu_set_malloc(&ncpus); +- if (!c) +- return warn ? log_oom() : -ENOMEM; +- } +- + r = parse_range(word, &cpu_lower, &cpu_upper); + if (r < 0) + return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word) : r; +- if (cpu_lower >= ncpus || cpu_upper >= ncpus) +- return warn ? log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus) : -EINVAL; + + if (cpu_lower > cpu_upper) { + if (warn) +- log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring", word, cpu_lower, cpu_upper); +- continue; ++ log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring.", ++ word, cpu_lower, cpu_upper); ++ ++ /* Make sure something is allocated, to distinguish this from the empty case */ ++ r = cpu_set_realloc(&c, 1); ++ if (r < 0) ++ return r; + } + +- for (cpu = cpu_lower; cpu <= cpu_upper; cpu++) +- CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c); ++ for (unsigned cpu_p1 = MIN(cpu_upper, UINT_MAX-1) + 1; cpu_p1 > cpu_lower; cpu_p1--) { ++ r = cpu_set_add(&c, cpu_p1 - 1); ++ if (r < 0) ++ return warn ? log_syntax(unit, LOG_ERR, filename, line, r, ++ "Cannot add CPU %u to set: %m", cpu_p1 - 1) : r; ++ } + } + +- /* On success, sets *cpu_set and returns ncpus for the system. */ +- if (c) +- *cpu_set = TAKE_PTR(c); ++ /* On success, transfer ownership to the output variable */ ++ *cpu_set = c; ++ c = (CPUSet) {}; ++ ++ return 0; ++} ++ ++int parse_cpu_set_extend( ++ const char *rvalue, ++ CPUSet *old, ++ bool warn, ++ const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *lvalue) { ++ ++ _cleanup_(cpu_set_reset) CPUSet cpuset = {}; ++ int r; ++ ++ r = parse_cpu_set_full(rvalue, &cpuset, true, unit, filename, line, lvalue); ++ if (r < 0) ++ return r; ++ ++ if (!cpuset.set) { ++ /* An empty assignment resets the CPU list */ ++ cpu_set_reset(old); ++ return 0; ++ } ++ ++ if (!old->set) { ++ *old = cpuset; ++ cpuset = (CPUSet) {}; ++ return 0; ++ } + +- return (int) ncpus; ++ return cpu_set_add_all(old, &cpuset); + } +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 20612a8876..eb31b362fe 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -12,23 +12,40 @@ + DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE); + #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp) + +-static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) { +- if (p) +- CPU_FREE(p); +- return NULL; +-} +- + cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize); +-int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue); +- +-static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) { +- assert(lvalue); +- +- return parse_cpu_set_internal(rvalue, cpu_set, true, unit, filename, line, lvalue); ++/* This wraps the libc interface with a variable to keep the allocated size. */ ++typedef struct CPUSet { ++ cpu_set_t *set; ++ size_t allocated; /* in bytes */ ++} CPUSet; ++ ++static inline void cpu_set_reset(CPUSet *a) { ++ assert((a->allocated > 0) == !!a->set); ++ if (a->set) ++ CPU_FREE(a->set); ++ *a = (CPUSet) {}; + } + +-static inline int parse_cpu_set(const char *rvalue, cpu_set_t **cpu_set){ +- return parse_cpu_set_internal(rvalue, cpu_set, false, NULL, NULL, 0, NULL); ++int cpu_set_add_all(CPUSet *a, const CPUSet *b); ++ ++char* cpu_set_to_string(const CPUSet *a); ++int parse_cpu_set_full( ++ const char *rvalue, ++ CPUSet *cpu_set, ++ bool warn, ++ const char *unit, ++ const char *filename, unsigned line, ++ const char *lvalue); ++int parse_cpu_set_extend( ++ const char *rvalue, ++ CPUSet *old, ++ bool warn, ++ const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *lvalue); ++ ++static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){ ++ return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL); + } +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index d9f4445745..08946627e3 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -220,7 +220,7 @@ static int property_get_cpu_affinity( + assert(reply); + assert(c); + +- return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus)); ++ return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated); + } + + static int property_get_timer_slack_nsec( +@@ -1560,37 +1560,22 @@ int bus_exec_context_set_transient_property( + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (n == 0) { +- c->cpuset = cpu_set_mfree(c->cpuset); +- c->cpuset_ncpus = 0; ++ cpu_set_reset(&c->cpu_set); + unit_write_settingf(u, flags, name, "%s=", name); + } else { + _cleanup_free_ char *str = NULL; +- size_t ncpus; ++ const CPUSet set = {(cpu_set_t*) a, n}; + +- str = cpu_set_to_string(a, n); ++ str = cpu_set_to_string(&set); + if (!str) + return -ENOMEM; + +- ncpus = CPU_SIZE_TO_NUM(n); +- +- if (!c->cpuset || c->cpuset_ncpus < ncpus) { +- cpu_set_t *cpuset; +- +- cpuset = CPU_ALLOC(ncpus); +- if (!cpuset) +- return -ENOMEM; +- +- CPU_ZERO_S(n, cpuset); +- if (c->cpuset) { +- CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, (cpu_set_t*) a); +- CPU_FREE(c->cpuset); +- } else +- CPU_OR_S(n, cpuset, cpuset, (cpu_set_t*) a); +- +- c->cpuset = cpuset; +- c->cpuset_ncpus = ncpus; +- } else +- CPU_OR_S(n, c->cpuset, c->cpuset, (cpu_set_t*) a); ++ /* We forego any optimizations here, and always create the structure using ++ * cpu_set_add_all(), because we don't want to care if the existing size we ++ * got over dbus is appropriate. */ ++ r = cpu_set_add_all(&c->cpu_set, &set); ++ if (r < 0) ++ return r; + + unit_write_settingf(u, flags, name, "%s=%s", name, str); + } +diff --git a/src/core/execute.c b/src/core/execute.c +index c42300a41e..22e5825905 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2991,8 +2991,8 @@ static int exec_child( + } + } + +- if (context->cpuset) +- if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) { ++ if (context->cpu_set.set) ++ if (sched_setaffinity(0, context->cpu_set.allocated, context->cpu_set.set) < 0) { + *exit_status = EXIT_CPUAFFINITY; + return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m"); + } +@@ -3694,7 +3694,7 @@ void exec_context_done(ExecContext *c) { + c->temporary_filesystems = NULL; + c->n_temporary_filesystems = 0; + +- c->cpuset = cpu_set_mfree(c->cpuset); ++ cpu_set_reset(&c->cpu_set); + + c->utmp_id = mfree(c->utmp_id); + c->selinux_context = mfree(c->selinux_context); +@@ -4097,10 +4097,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + prefix, yes_no(c->cpu_sched_reset_on_fork)); + } + +- if (c->cpuset) { ++ if (c->cpu_set.set) { + fprintf(f, "%sCPUAffinity:", prefix); +- for (i = 0; i < c->cpuset_ncpus; i++) +- if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset)) ++ for (i = 0; i < c->cpu_set.allocated * 8; i++) ++ if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set)) + fprintf(f, " %u", i); + fputs("\n", f); + } +diff --git a/src/core/execute.h b/src/core/execute.h +index 8c91636adc..e1e7a494cd 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -14,6 +14,7 @@ typedef struct Manager Manager; + #include + + #include "cgroup-util.h" ++#include "cpu-set-util.h" + #include "fdset.h" + #include "list.h" + #include "missing.h" +@@ -148,8 +149,7 @@ struct ExecContext { + int cpu_sched_policy; + int cpu_sched_priority; + +- cpu_set_t *cpuset; +- unsigned cpuset_ncpus; ++ CPUSet cpu_set; + + ExecInput std_input; + ExecOutput std_output; +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index d9a5094aa0..34ae834188 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1211,42 +1211,13 @@ int config_parse_exec_cpu_affinity(const char *unit, + void *userdata) { + + ExecContext *c = data; +- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; +- int ncpus; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + +- ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue); +- if (ncpus < 0) +- return ncpus; +- +- if (ncpus == 0) { +- /* An empty assignment resets the CPU list */ +- c->cpuset = cpu_set_mfree(c->cpuset); +- c->cpuset_ncpus = 0; +- return 0; +- } +- +- if (!c->cpuset) { +- c->cpuset = TAKE_PTR(cpuset); +- c->cpuset_ncpus = (unsigned) ncpus; +- return 0; +- } +- +- if (c->cpuset_ncpus < (unsigned) ncpus) { +- CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset); +- CPU_FREE(c->cpuset); +- c->cpuset = TAKE_PTR(cpuset); +- c->cpuset_ncpus = (unsigned) ncpus; +- return 0; +- } +- +- CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), c->cpuset, c->cpuset, cpuset); +- +- return 0; ++ return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue); + } + + int config_parse_capability_set( +diff --git a/src/core/main.c b/src/core/main.c +index af7b26d6f1..e62b2756ee 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -537,16 +537,18 @@ static int config_parse_cpu_affinity2( + void *data, + void *userdata) { + +- _cleanup_cpu_free_ cpu_set_t *c = NULL; +- int ncpus; ++ _cleanup_(cpu_set_reset) CPUSet c = {}; ++ int r; + +- ncpus = parse_cpu_set_and_warn(rvalue, &c, unit, filename, line, lvalue); +- if (ncpus < 0) +- return ncpus; ++ r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue); ++ if (r < 0) ++ return r; + +- if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0) ++ if (sched_setaffinity(0, c.allocated, c.set) < 0) + log_warning_errno(errno, "Failed to set CPU affinity: %m"); + ++ // FIXME: parsing and execution should be seperated. ++ + return 0; + } + +diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c +index 62a3486952..21c24a1111 100644 +--- a/src/nspawn/nspawn-settings.c ++++ b/src/nspawn/nspawn-settings.c +@@ -85,7 +85,7 @@ Settings* settings_free(Settings *s) { + strv_free(s->syscall_blacklist); + rlimit_free_all(s->rlimit); + free(s->hostname); +- s->cpuset = cpu_set_mfree(s->cpuset); ++ cpu_set_reset(&s->cpu_set); + + strv_free(s->network_interfaces); + strv_free(s->network_macvlan); +@@ -687,41 +687,12 @@ int config_parse_cpu_affinity( + void *data, + void *userdata) { + +- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; + Settings *settings = data; +- int ncpus; + + assert(rvalue); + assert(settings); + +- ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue); +- if (ncpus < 0) +- return ncpus; +- +- if (ncpus == 0) { +- /* An empty assignment resets the CPU list */ +- settings->cpuset = cpu_set_mfree(settings->cpuset); +- settings->cpuset_ncpus = 0; +- return 0; +- } +- +- if (!settings->cpuset) { +- settings->cpuset = TAKE_PTR(cpuset); +- settings->cpuset_ncpus = (unsigned) ncpus; +- return 0; +- } +- +- if (settings->cpuset_ncpus < (unsigned) ncpus) { +- CPU_OR_S(CPU_ALLOC_SIZE(settings->cpuset_ncpus), cpuset, settings->cpuset, cpuset); +- CPU_FREE(settings->cpuset); +- settings->cpuset = TAKE_PTR(cpuset); +- settings->cpuset_ncpus = (unsigned) ncpus; +- return 0; +- } +- +- CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), settings->cpuset, settings->cpuset, cpuset); +- +- return 0; ++ return parse_cpu_set_extend(rvalue, &settings->cpu_set, true, unit, filename, line, lvalue); + } + + DEFINE_CONFIG_PARSE_ENUM(config_parse_resolv_conf, resolv_conf_mode, ResolvConfMode, "Failed to parse resolv.conf mode"); +diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h +index d522f3cb36..da863ef11c 100644 +--- a/src/nspawn/nspawn-settings.h ++++ b/src/nspawn/nspawn-settings.h +@@ -7,6 +7,7 @@ + #include "sd-id128.h" + + #include "conf-parser.h" ++#include "cpu-set-util.h" + #include "macro.h" + #include "nspawn-expose-ports.h" + #include "nspawn-mount.h" +@@ -123,8 +124,7 @@ typedef struct Settings { + int no_new_privileges; + int oom_score_adjust; + bool oom_score_adjust_set; +- cpu_set_t *cpuset; +- unsigned cpuset_ncpus; ++ CPUSet cpu_set; + ResolvConfMode resolv_conf; + LinkJournal link_journal; + bool link_journal_try; +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index b40411dcd0..08255b5724 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -199,8 +199,7 @@ static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {}; + static bool arg_no_new_privileges = false; + static int arg_oom_score_adjust = 0; + static bool arg_oom_score_adjust_set = false; +-static cpu_set_t *arg_cpuset = NULL; +-static unsigned arg_cpuset_ncpus = 0; ++static CPUSet arg_cpu_set = {}; + static ResolvConfMode arg_resolv_conf = RESOLV_CONF_AUTO; + static TimezoneMode arg_timezone = TIMEZONE_AUTO; + +@@ -1186,17 +1185,14 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_CPU_AFFINITY: { +- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; ++ CPUSet cpuset; + + r = parse_cpu_set(optarg, &cpuset); + if (r < 0) +- return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg); ++ return log_error_errno(r, "Failed to parse CPU affinity mask %s: %m", optarg); + +- if (arg_cpuset) +- CPU_FREE(arg_cpuset); +- +- arg_cpuset = TAKE_PTR(cpuset); +- arg_cpuset_ncpus = r; ++ cpu_set_reset(&arg_cpu_set); ++ arg_cpu_set = cpuset; + arg_settings_mask |= SETTING_CPU_AFFINITY; + break; + } +@@ -2631,8 +2627,8 @@ static int inner_child( + return log_error_errno(r, "Failed to adjust OOM score: %m"); + } + +- if (arg_cpuset) +- if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0) ++ if (arg_cpu_set.set) ++ if (sched_setaffinity(0, arg_cpu_set.allocated, arg_cpu_set.set) < 0) + return log_error_errno(errno, "Failed to set CPU affinity: %m"); + + r = drop_capabilities(); +@@ -3494,15 +3490,14 @@ static int merge_settings(Settings *settings, const char *path) { + } + + if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 && +- settings->cpuset) { ++ settings->cpu_set.set) { + + if (!arg_settings_trusted) + log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path); + else { +- if (arg_cpuset) +- CPU_FREE(arg_cpuset); +- arg_cpuset = TAKE_PTR(settings->cpuset); +- arg_cpuset_ncpus = settings->cpuset_ncpus; ++ cpu_set_reset(&arg_cpu_set); ++ arg_cpu_set = settings->cpu_set; ++ settings->cpu_set = (CPUSet) {}; + } + } + +@@ -4600,7 +4595,7 @@ finish: + rlimit_free_all(arg_rlimit); + strv_free(arg_syscall_whitelist); + strv_free(arg_syscall_blacklist); +- arg_cpuset = cpu_set_mfree(arg_cpuset); ++ cpu_set_reset(&arg_cpu_set); + + return r < 0 ? EXIT_FAILURE : ret; + } +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 271cc054da..75b4aace84 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -932,13 +932,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + } + + if (streq(field, "CPUAffinity")) { +- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; ++ _cleanup_(cpu_set_reset) CPUSet cpuset = {}; + + r = parse_cpu_set(eq, &cpuset); + if (r < 0) + return log_error_errno(r, "Failed to parse %s value: %s", field, eq); + +- return bus_append_byte_array(m, field, cpuset, CPU_ALLOC_SIZE(r)); ++ return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated); + } + + if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) { +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index ff5edb2a69..b9ec29af66 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -1,154 +1,171 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include ++ + #include "alloc-util.h" + #include "cpu-set-util.h" + #include "macro.h" + + static void test_parse_cpu_set(void) { +- cpu_set_t *c = NULL; ++ CPUSet c = {}; + _cleanup_free_ char *str = NULL; +- int ncpus; + int cpu; + + /* Simple range (from CPUAffinity example) */ +- ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2); +- +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.set); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_ISSET_S(1, c.allocated, c.set)); ++ assert_se(CPU_ISSET_S(2, c.allocated, c.set)); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 2); ++ ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* A more interesting range */ +- ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); ++ assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + for (cpu = 8; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Quoted strings */ +- ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4); ++ assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 4); + for (cpu = 8; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Use commas as separators */ +- ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); ++ assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + for (cpu = 8; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Commas with spaces (and trailing comma, space) */ +- ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); ++ assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 8; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Ranges */ +- ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); ++ assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + for (cpu = 8; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Ranges with trailing comma, space */ +- ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8); ++ assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + for (cpu = 8; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Negative range (returns empty cpu_set) */ +- ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0); +- c = cpu_set_mfree(c); ++ assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 0); ++ cpu_set_reset(&c); + + /* Overlapping ranges */ +- ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12); ++ assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 12); + for (cpu = 0; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Mix ranges and individual CPUs */ +- ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus >= 1024); +- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10); +- assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c)); ++ assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 10); ++ assert_se(CPU_ISSET_S(0, c.allocated, c.set)); ++ assert_se(CPU_ISSET_S(1, c.allocated, c.set)); + for (cpu = 4; cpu < 12; cpu++) +- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c)); +- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus))); ++ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); +- c = cpu_set_mfree(c); ++ cpu_set_reset(&c); + + /* Garbage */ +- ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus < 0); +- assert_se(!c); ++ assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL); ++ assert_se(!c.set); ++ assert_se(c.allocated == 0); + + /* Range with garbage */ +- ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus < 0); +- assert_se(!c); ++ assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL); ++ assert_se(!c.set); ++ assert_se(c.allocated == 0); + + /* Empty string */ +- c = NULL; +- ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus == 0); /* empty string returns 0 */ +- assert_se(!c); ++ assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(!c.set); /* empty string returns NULL */ ++ assert_se(c.allocated == 0); + + /* Runaway quoted string */ +- ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity"); +- assert_se(ncpus < 0); +- assert_se(!c); ++ assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL); ++ assert_se(!c.set); ++ assert_se(c.allocated == 0); ++ ++ /* Maximum allocation */ ++ assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 192); ++ assert_se(str = cpu_set_to_string(&c)); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); ++ cpu_set_reset(&c); + } + + int main(int argc, char *argv[]) { ++ log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1)); ++ log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9)); ++ log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64)); ++ log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65)); ++ log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024)); ++ log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025)); ++ log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191)); ++ + test_parse_cpu_set(); + + return 0; +diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c +index 7a1e496ed2..396e68f35f 100644 +--- a/src/test/test-sizeof.c ++++ b/src/test/test-sizeof.c +@@ -1,5 +1,6 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include + #include + #include + +@@ -64,6 +65,8 @@ int main(void) { + info(uid_t); + info(gid_t); + ++ info(__cpu_mask); ++ + info(enum Enum); + info(enum BigEnum); + info(enum BigEnum2); diff --git a/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch b/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch new file mode 100644 index 0000000..43f5d04 --- /dev/null +++ b/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch @@ -0,0 +1,125 @@ +From 42032749e61076b3d9e5004432073c2a5ea737ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 28 May 2019 21:28:31 +0200 +Subject: [PATCH] Move cpus_in_affinity_mask() to cpu-set-util.[ch] + +It just seems to fit better there and it's always better to have things +in shared/ rather than basic/. + +(cherry picked from commit f44b3035d4a698aa0ce08a552199b54d43de3d85) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 34 ++++++++++++++++++++++++++++++++++ + src/basic/cpu-set-util.h | 2 ++ + src/basic/process-util.c | 5 ++--- + src/shared/condition.c | 1 + + src/test/test-condition.c | 1 + + 5 files changed, 40 insertions(+), 3 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index fe440f6381..1803539ac6 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -204,3 +204,37 @@ int parse_cpu_set_extend( + + return cpu_set_add_all(old, &cpuset); + } ++ ++int cpus_in_affinity_mask(void) { ++ size_t n = 16; ++ int r; ++ ++ for (;;) { ++ cpu_set_t *c; ++ ++ c = CPU_ALLOC(n); ++ if (!c) ++ return -ENOMEM; ++ ++ if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) { ++ int k; ++ ++ k = CPU_COUNT_S(CPU_ALLOC_SIZE(n), c); ++ CPU_FREE(c); ++ ++ if (k <= 0) ++ return -EINVAL; ++ ++ return k; ++ } ++ ++ r = -errno; ++ CPU_FREE(c); ++ ++ if (r != -EINVAL) ++ return r; ++ if (n > SIZE_MAX/2) ++ return -ENOMEM; ++ n *= 2; ++ } ++} +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index eb31b362fe..9b026aca09 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -49,3 +49,5 @@ int parse_cpu_set_extend( + static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){ + return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL); + } ++ ++int cpus_in_affinity_mask(void); +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index 6dbeee9dda..0a4a747ba4 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -4,7 +4,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1474,7 +1473,7 @@ static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_NONE] = "none", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", +- [IOPRIO_CLASS_IDLE] = "idle" ++ [IOPRIO_CLASS_IDLE] = "idle", + }; + + DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES); +@@ -1495,7 +1494,7 @@ static const char* const sched_policy_table[] = { + [SCHED_BATCH] = "batch", + [SCHED_IDLE] = "idle", + [SCHED_FIFO] = "fifo", +- [SCHED_RR] = "rr" ++ [SCHED_RR] = "rr", + }; + + DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); +diff --git a/src/shared/condition.c b/src/shared/condition.c +index 2969a89b4e..b829f0528c 100644 +--- a/src/shared/condition.c ++++ b/src/shared/condition.c +@@ -21,6 +21,7 @@ + #include "cap-list.h" + #include "cgroup-util.h" + #include "condition.h" ++#include "cpu-set-util.h" + #include "efivars.h" + #include "extract-word.h" + #include "fd-util.h" +diff --git a/src/test/test-condition.c b/src/test/test-condition.c +index 7ce6ee80ea..24395dafc6 100644 +--- a/src/test/test-condition.c ++++ b/src/test/test-condition.c +@@ -13,6 +13,7 @@ + #include "audit-util.h" + #include "cgroup-util.h" + #include "condition.h" ++#include "cpu-set-util.h" + #include "efivars.h" + #include "hostname-util.h" + #include "id128-util.h" diff --git a/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch b/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch new file mode 100644 index 0000000..026cee1 --- /dev/null +++ b/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch @@ -0,0 +1,40 @@ +From a1ed6bfc5a8c40377b9f1cab1acc3c67a9529427 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 21 May 2019 09:01:34 +0200 +Subject: [PATCH] test-cpu-set-util: add simple test for + cpus_in_affinity_mask() + +(cherry picked from commit 9d1345f0657c707df89b41b2738776efb40aec8e) + +Related: #1734787 +--- + src/test/test-cpu-set-util.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index b9ec29af66..e87e0ca6e6 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -157,6 +157,14 @@ static void test_parse_cpu_set(void) { + cpu_set_reset(&c); + } + ++static void test_cpus_in_affinity_mask(void) { ++ int r; ++ ++ r = cpus_in_affinity_mask(); ++ assert(r > 0); ++ log_info("cpus_in_affinity_mask: %d", r); ++} ++ + int main(int argc, char *argv[]) { + log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1)); + log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9)); +@@ -167,6 +175,7 @@ int main(int argc, char *argv[]) { + log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191)); + + test_parse_cpu_set(); ++ test_cpus_in_affinity_mask(); + + return 0; + } diff --git a/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch b/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch new file mode 100644 index 0000000..cce5c67 --- /dev/null +++ b/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch @@ -0,0 +1,63 @@ +From 69541e93c45efb7ee15d7584c3aa70c3ff0b2200 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 24 May 2019 08:50:41 +0200 +Subject: [PATCH] test-cpu-set-util: add a smoke test for + test_parse_cpu_set_extend() + +(cherry picked from commit b54d7241f25b859c6c008e516c2131c39902e6e4) + +Related: #1734787 +--- + src/test/test-cpu-set-util.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index e87e0ca6e6..81f67647e8 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -11,6 +11,8 @@ static void test_parse_cpu_set(void) { + _cleanup_free_ char *str = NULL; + int cpu; + ++ log_info("/* %s */", __func__); ++ + /* Simple range (from CPUAffinity example) */ + assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.set); +@@ -157,6 +159,28 @@ static void test_parse_cpu_set(void) { + cpu_set_reset(&c); + } + ++static void test_parse_cpu_set_extend(void) { ++ CPUSet c = {}; ++ _cleanup_free_ char *s1 = NULL, *s2 = NULL; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 2); ++ assert_se(s1 = cpu_set_to_string(&c)); ++ log_info("cpu_set_to_string: %s", s1); ++ ++ assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 3); ++ assert_se(s2 = cpu_set_to_string(&c)); ++ log_info("cpu_set_to_string: %s", s2); ++ ++ assert_se(parse_cpu_set_extend("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(!c.set); ++ assert_se(c.allocated == 0); ++ log_info("cpu_set_to_string: (null)"); ++} ++ + static void test_cpus_in_affinity_mask(void) { + int r; + +@@ -175,6 +199,7 @@ int main(int argc, char *argv[]) { + log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191)); + + test_parse_cpu_set(); ++ test_parse_cpu_set_extend(); + test_cpus_in_affinity_mask(); + + return 0; diff --git a/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch b/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch new file mode 100644 index 0000000..948c139 --- /dev/null +++ b/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch @@ -0,0 +1,148 @@ +From 8bf8409c6e08f5aef35d1976e172b3f61b651c8d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 24 May 2019 08:35:51 +0200 +Subject: [PATCH] pid1: parse CPUAffinity= in incremental fashion + +This makes the handling of this option match what we do in unit files. I think +consistency is important here. (As it happens, it is the only option in +system.conf that is "non-atomic", i.e. where there's a list of things which can +be split over multiple assignments. All other options are single-valued, so +there's no issue of how to handle multiple assignments.) + +(cherry picked from commit 61fbbac1d517a0b3498a689c736c6ca918497904) + +Related: #1734787 +--- + man/systemd-system.conf.xml | 13 ++++++++----- + man/systemd.exec.xml | 2 +- + src/core/main.c | 36 ++++++++++++++++++++++++++---------- + 3 files changed, 35 insertions(+), 16 deletions(-) + +diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml +index 085086200a..ab23779ec0 100644 +--- a/man/systemd-system.conf.xml ++++ b/man/systemd-system.conf.xml +@@ -99,11 +99,14 @@ + + CPUAffinity= + +- Configures the initial CPU affinity for the +- init process. Takes a list of CPU indices or ranges separated +- by either whitespace or commas. CPU ranges are specified by +- the lower and upper CPU indices separated by a +- dash. ++ Configures the CPU affinity for the service manager as well as the default CPU ++ affinity for all forked off processes. Takes a list of CPU indices or ranges separated by either ++ whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a ++ dash. This option may be specified more than once, in which case the specified CPU affinity masks are ++ merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have ++ no effect. Individual services may override the CPU affinity for their processes with the ++ CPUAffinity= setting in unit files, see ++ systemd.exec5. + + + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 737c52bcc4..342b8385bc 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -703,7 +703,7 @@ CapabilityBoundingSet=~CAP_B CAP_C + + Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges + separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated +- by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are ++ by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are + merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no + effect. See + sched_setaffinity2 for +diff --git a/src/core/main.c b/src/core/main.c +index e62b2756ee..bc1db2af7b 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -127,6 +127,7 @@ static bool arg_default_tasks_accounting = true; + static uint64_t arg_default_tasks_max = UINT64_MAX; + static sd_id128_t arg_machine_id = {}; + static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; ++static CPUSet arg_cpu_affinity = {}; + + _noreturn_ static void freeze_or_reboot(void) { + +@@ -537,17 +538,11 @@ static int config_parse_cpu_affinity2( + void *data, + void *userdata) { + +- _cleanup_(cpu_set_reset) CPUSet c = {}; +- int r; +- +- r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue); +- if (r < 0) +- return r; ++ CPUSet *affinity = data; + +- if (sched_setaffinity(0, c.allocated, c.set) < 0) +- log_warning_errno(errno, "Failed to set CPU affinity: %m"); ++ assert(affinity); + +- // FIXME: parsing and execution should be seperated. ++ (void) parse_cpu_set_extend(rvalue, affinity, true, unit, filename, line, lvalue); + + return 0; + } +@@ -655,7 +650,7 @@ static int parse_config_file(void) { + { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell }, + { "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot }, + { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status }, +- { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, ++ { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity }, + { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, + { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog }, + { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, +@@ -1483,6 +1478,21 @@ static void initialize_coredump(bool skip_setup) { + #endif + } + ++static void update_cpu_affinity(bool skip_setup) { ++ _cleanup_free_ char *mask = NULL; ++ ++ if (skip_setup || !arg_cpu_affinity.set) ++ return; ++ ++ assert(arg_cpu_affinity.allocated > 0); ++ ++ mask = cpu_set_to_string(&arg_cpu_affinity); ++ log_debug("Setting CPU affinity to %s.", strnull(mask)); ++ ++ if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0) ++ log_warning_errno(errno, "Failed to set CPU affinity: %m"); ++} ++ + static void do_reexecute( + int argc, + char *argv[], +@@ -1655,6 +1665,8 @@ static int invoke_main_loop( + + set_manager_defaults(m); + ++ update_cpu_affinity(false); ++ + if (saved_log_level >= 0) + manager_override_log_level(m, saved_log_level); + if (saved_log_target >= 0) +@@ -1813,6 +1825,8 @@ static int initialize_runtime( + if (arg_action != ACTION_RUN) + return 0; + ++ update_cpu_affinity(skip_setup); ++ + if (arg_system) { + /* Make sure we leave a core dump without panicing the kernel. */ + install_crash_handler(); +@@ -1947,6 +1961,8 @@ static void free_arguments(void) { + arg_join_controllers = strv_free_free(arg_join_controllers); + arg_default_environment = strv_free(arg_default_environment); + arg_syscall_archs = set_free(arg_syscall_archs); ++ ++ cpu_set_reset(&arg_cpu_affinity); + } + + static int load_configuration(int argc, char **argv, const char **ret_error_message) { diff --git a/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch b/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch new file mode 100644 index 0000000..bb8d822 --- /dev/null +++ b/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch @@ -0,0 +1,86 @@ +From f71f3271fa149d2b5f022830d43071d97b022b38 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 24 May 2019 08:59:23 +0200 +Subject: [PATCH] pid1: don't reset setting from /proc/cmdline upon restart + +We have settings which may be set on the kernel command line, and also +in /proc/cmdline (for pid1). The settings in /proc/cmdline have higher priority +of course. When a reload was done, we'd reload just the configuration file, +losing the overrides. + +So read /proc/cmdline again during reload. + +Also, when initially reading the configuration file when program starts, +don't treat any errors as fatal. The configuration done in there doesn't +seem important enough to refuse boot. + +(cherry picked from commit 470a5e6dcec4637439ae953002127af214d396ac) + +Related: #1734787 +--- + src/core/main.c | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index bc1db2af7b..9a9f145080 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -129,6 +129,8 @@ static sd_id128_t arg_machine_id = {}; + static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; + static CPUSet arg_cpu_affinity = {}; + ++static int parse_configuration(void); ++ + _noreturn_ static void freeze_or_reboot(void) { + + if (arg_crash_reboot) { +@@ -1659,9 +1661,7 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + +- r = parse_config_file(); +- if (r < 0) +- log_warning_errno(r, "Failed to parse config file, ignoring: %m"); ++ (void) parse_configuration(); + + set_manager_defaults(m); + +@@ -1965,18 +1965,14 @@ static void free_arguments(void) { + cpu_set_reset(&arg_cpu_affinity); + } + +-static int load_configuration(int argc, char **argv, const char **ret_error_message) { ++static int parse_configuration(void) { + int r; + +- assert(ret_error_message); +- + arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); + + r = parse_config_file(); +- if (r < 0) { +- *ret_error_message = "Failed to parse config file"; +- return r; +- } ++ if (r < 0) ++ log_warning_errno(r, "Failed to parse config file, ignoring: %m"); + + if (arg_system) { + r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); +@@ -1987,6 +1983,16 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess + /* Note that this also parses bits from the kernel command line, including "debug". */ + log_parse_environment(); + ++ return 0; ++} ++ ++static int load_configuration(int argc, char **argv, const char **ret_error_message) { ++ int r; ++ ++ assert(ret_error_message); ++ ++ (void) parse_configuration(); ++ + r = parse_argv(argc, argv); + if (r < 0) { + *ret_error_message = "Failed to parse commandline arguments"; diff --git a/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch b/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch new file mode 100644 index 0000000..1b941cc --- /dev/null +++ b/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch @@ -0,0 +1,208 @@ +From 0387294ba41ceaf80c79621409aab9508732bda0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 24 May 2019 09:41:44 +0200 +Subject: [PATCH] pid1: when reloading configuration, forget old settings + +If we had a configuration setting from a configuration file, and it was +removed, we'd still remember the old value, because there's was no mechanism to +"reset" everything, just to assign new values. + +Note that the effect of this is limited. For settings that have an "ongoing" effect, +like systemd.confirm_spawn, the new value is simply used. But some settings can only +be set at start. + +In particular, CPUAffinity= will be updated if set to a new value, but if +CPUAffinity= is fully removed, it will not be reset, simply because we don't +know what to reset it to. We might have inherited a setting, or we might have +set it ourselves. In principle we could remember the "original" value that was +set when we were executed, but propagate this over reloads and reexecs, but +that would be a lot of work for little gain. So this corner case of removal of +CPUAffinity= is not handled fully, and a reboot is needed to execute the +change. As a work-around, a full mask of CPUAffinity=0-8191 can be specified. + +(cherry picked from commit fb39af4ce42d7ef9af63009f271f404038703704) + +Related: #1734787 +--- + src/core/main.c | 139 +++++++++++++++++++++++++++++++++--------------- + 1 file changed, 95 insertions(+), 44 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 9a9f145080..c74dc641c1 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -88,46 +88,52 @@ static enum { + ACTION_DUMP_CONFIGURATION_ITEMS, + ACTION_DUMP_BUS_PROPERTIES, + } arg_action = ACTION_RUN; +-static char *arg_default_unit = NULL; +-static bool arg_system = false; +-static bool arg_dump_core = true; +-static int arg_crash_chvt = -1; +-static bool arg_crash_shell = false; +-static bool arg_crash_reboot = false; +-static char *arg_confirm_spawn = NULL; +-static ShowStatus arg_show_status = _SHOW_STATUS_UNSET; +-static bool arg_switched_root = false; +-static bool arg_no_pager = false; +-static bool arg_service_watchdogs = true; ++ ++/* Those variables are initalized to 0 automatically, so we avoid uninitialized memory access. ++ * Real defaults are assigned in reset_arguments() below. */ ++static char *arg_default_unit; ++static bool arg_system; ++static bool arg_dump_core; ++static int arg_crash_chvt; ++static bool arg_crash_shell; ++static bool arg_crash_reboot; ++static char *arg_confirm_spawn; ++static ShowStatus arg_show_status; ++static bool arg_switched_root; ++static bool arg_no_pager; ++static bool arg_service_watchdogs; + static char ***arg_join_controllers = NULL; +-static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; +-static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; +-static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC; +-static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; +-static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; +-static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL; +-static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; +-static usec_t arg_runtime_watchdog = 0; +-static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; +-static char *arg_watchdog_device = NULL; +-static char **arg_default_environment = NULL; +-static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {}; +-static uint64_t arg_capability_bounding_set = CAP_ALL; +-static bool arg_no_new_privs = false; +-static nsec_t arg_timer_slack_nsec = NSEC_INFINITY; +-static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE; +-static Set* arg_syscall_archs = NULL; +-static FILE* arg_serialization = NULL; +-static bool arg_default_cpu_accounting = false; +-static bool arg_default_io_accounting = false; +-static bool arg_default_ip_accounting = false; +-static bool arg_default_blockio_accounting = false; +-static bool arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT; +-static bool arg_default_tasks_accounting = true; +-static uint64_t arg_default_tasks_max = UINT64_MAX; +-static sd_id128_t arg_machine_id = {}; +-static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; +-static CPUSet arg_cpu_affinity = {}; ++static ExecOutput arg_default_std_output; ++static ExecOutput arg_default_std_error; ++static usec_t arg_default_restart_usec; ++static usec_t arg_default_timeout_start_usec; ++static usec_t arg_default_timeout_stop_usec; ++static usec_t arg_default_timeout_abort_usec; ++static bool arg_default_timeout_abort_set; ++static usec_t arg_default_start_limit_interval; ++static unsigned arg_default_start_limit_burst; ++static usec_t arg_runtime_watchdog; ++static usec_t arg_shutdown_watchdog; ++static char *arg_early_core_pattern; ++static char *arg_watchdog_device; ++static char **arg_default_environment; ++static struct rlimit *arg_default_rlimit[_RLIMIT_MAX]; ++static uint64_t arg_capability_bounding_set; ++static bool arg_no_new_privs; ++static nsec_t arg_timer_slack_nsec; ++static usec_t arg_default_timer_accuracy_usec; ++static Set* arg_syscall_archs; ++static FILE* arg_serialization; ++static int arg_default_cpu_accounting; ++static bool arg_default_io_accounting; ++static bool arg_default_ip_accounting; ++static bool arg_default_blockio_accounting; ++static bool arg_default_memory_accounting; ++static bool arg_default_tasks_accounting; ++static uint64_t arg_default_tasks_max; ++static sd_id128_t arg_machine_id; ++static EmergencyAction arg_cad_burst_action; ++static CPUSet arg_cpu_affinity; + + static int parse_configuration(void); + +@@ -1951,17 +1957,59 @@ static int do_queue_default_job( + return 0; + } + +-static void free_arguments(void) { +- +- /* Frees all arg_* variables, with the exception of arg_serialization */ +- rlimit_free_all(arg_default_rlimit); ++static void reset_arguments(void) { ++ /* Frees/resets arg_* variables, with a few exceptions commented below. */ + + arg_default_unit = mfree(arg_default_unit); ++ ++ /* arg_system — ignore */ ++ ++ arg_dump_core = true; ++ arg_crash_chvt = -1; ++ arg_crash_shell = false; ++ arg_crash_reboot = false; + arg_confirm_spawn = mfree(arg_confirm_spawn); + arg_join_controllers = strv_free_free(arg_join_controllers); ++ arg_show_status = _SHOW_STATUS_UNSET; ++ arg_switched_root = false; ++ arg_no_pager = false; ++ arg_service_watchdogs = true; ++ arg_default_std_output = EXEC_OUTPUT_JOURNAL; ++ arg_default_std_error = EXEC_OUTPUT_INHERIT; ++ arg_default_restart_usec = DEFAULT_RESTART_USEC; ++ arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; ++ arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; ++ arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC; ++ arg_default_timeout_abort_set = false; ++ arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL; ++ arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; ++ arg_runtime_watchdog = 0; ++ arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; ++ arg_early_core_pattern = NULL; ++ arg_watchdog_device = NULL; ++ + arg_default_environment = strv_free(arg_default_environment); ++ rlimit_free_all(arg_default_rlimit); ++ ++ arg_capability_bounding_set = CAP_ALL; ++ arg_no_new_privs = false; ++ arg_timer_slack_nsec = NSEC_INFINITY; ++ arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE; ++ + arg_syscall_archs = set_free(arg_syscall_archs); + ++ /* arg_serialization — ignore */ ++ ++ arg_default_cpu_accounting = -1; ++ arg_default_io_accounting = false; ++ arg_default_ip_accounting = false; ++ arg_default_blockio_accounting = false; ++ arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT; ++ arg_default_tasks_accounting = true; ++ arg_default_tasks_max = UINT64_MAX; ++ arg_machine_id = (sd_id128_t) {}; ++ arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; ++ + cpu_set_reset(&arg_cpu_affinity); + } + +@@ -1970,6 +2018,9 @@ static int parse_configuration(void) { + + arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); + ++ /* Assign configuration defaults */ ++ reset_arguments(); ++ + r = parse_config_file(); + if (r < 0) + log_warning_errno(r, "Failed to parse config file, ignoring: %m"); +@@ -2460,7 +2511,7 @@ finish: + m = manager_free(m); + } + +- free_arguments(); ++ reset_arguments(); + mac_selinux_finish(); + + if (reexecute) diff --git a/SOURCES/0279-test-execute-use-CPUSet-too.patch b/SOURCES/0279-test-execute-use-CPUSet-too.patch new file mode 100644 index 0000000..2332226 --- /dev/null +++ b/SOURCES/0279-test-execute-use-CPUSet-too.patch @@ -0,0 +1,114 @@ +From 5e6b616ed2708391752ba8c45f183ceb38573d7d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 28 May 2019 21:38:41 +0200 +Subject: [PATCH] test-execute: use CPUSet too + +cpu_set_malloc() was the last user. It doesn't seem useful to keep +it just to save the allocation of a few hundred bytes in a test, so +it is dropped and a fixed maximum is allocated (1024 bytes). + +(cherry picked from commit 167a776dbe9d033523bd6881e5a695f2155dc321) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 31 +------------------------------ + src/basic/cpu-set-util.h | 3 +-- + src/test/test-execute.c | 13 ++++++------- + 3 files changed, 8 insertions(+), 39 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 1803539ac6..c297eab032 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -37,36 +37,7 @@ char* cpu_set_to_string(const CPUSet *a) { + return TAKE_PTR(str) ?: strdup(""); + } + +-cpu_set_t* cpu_set_malloc(unsigned *ncpus) { +- cpu_set_t *c; +- unsigned n = 1024; +- +- /* Allocates the cpuset in the right size */ +- +- for (;;) { +- c = CPU_ALLOC(n); +- if (!c) +- return NULL; +- +- if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) { +- CPU_ZERO_S(CPU_ALLOC_SIZE(n), c); +- +- if (ncpus) +- *ncpus = n; +- +- return c; +- } +- +- CPU_FREE(c); +- +- if (errno != EINVAL) +- return NULL; +- +- n *= 2; +- } +-} +- +-static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { ++int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { + size_t need; + + assert(cpu_set); +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 9b026aca09..b54e737110 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -12,8 +12,6 @@ + DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE); + #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp) + +-cpu_set_t* cpu_set_malloc(unsigned *ncpus); +- + /* This wraps the libc interface with a variable to keep the allocated size. */ + typedef struct CPUSet { + cpu_set_t *set; +@@ -30,6 +28,7 @@ static inline void cpu_set_reset(CPUSet *a) { + int cpu_set_add_all(CPUSet *a, const CPUSet *b); + + char* cpu_set_to_string(const CPUSet *a); ++int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus); + int parse_cpu_set_full( + const char *rvalue, + CPUSet *cpu_set, +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index fa8efdddd2..6c22995b1e 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -144,13 +144,12 @@ static void test_exec_bindpaths(Manager *m) { + } + + static void test_exec_cpuaffinity(Manager *m) { +- _cleanup_cpu_free_ cpu_set_t *c = NULL; +- unsigned n; ++ _cleanup_(cpu_set_reset) CPUSet c = {}; + +- assert_se(c = cpu_set_malloc(&n)); +- assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0); ++ assert_se(cpu_set_realloc(&c, 8192) >= 0); /* just allocate the maximum possible size */ ++ assert_se(sched_getaffinity(0, c.allocated, c.set) >= 0); + +- if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) { ++ if (!CPU_ISSET_S(0, c.allocated, c.set)) { + log_notice("Cannot use CPU 0, skipping %s", __func__); + return; + } +@@ -158,8 +157,8 @@ static void test_exec_cpuaffinity(Manager *m) { + test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED); + test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED); + +- if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 || +- CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) { ++ if (!CPU_ISSET_S(1, c.allocated, c.set) || ++ !CPU_ISSET_S(2, c.allocated, c.set)) { + log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__); + return; + } diff --git a/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch b/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch new file mode 100644 index 0000000..21bf12e --- /dev/null +++ b/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch @@ -0,0 +1,26 @@ +From 7aa32093c3dfc4bf7298f02be553e95c40d7c211 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 28 May 2019 21:40:10 +0200 +Subject: [PATCH] shared/cpu-set-util: drop now-unused cleanup function + +(cherry picked from commit cb0d3acf55ef335001cac5dd9c335ec5e75e9b56) + +Related: #1734787 +--- + src/basic/cpu-set-util.h | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index b54e737110..68a73bf9f7 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -9,9 +9,6 @@ + + #include "macro.h" + +-DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE); +-#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp) +- + /* This wraps the libc interface with a variable to keep the allocated size. */ + typedef struct CPUSet { + cpu_set_t *set; diff --git a/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch b/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch new file mode 100644 index 0000000..d09f290 --- /dev/null +++ b/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch @@ -0,0 +1,126 @@ +From daa0243fda679c8af723648b8b1e501fc55b0ada Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 22 May 2019 13:55:49 +0200 +Subject: [PATCH] shared/cpu-set-util: make transfer of cpu_set_t over bus + endian safe + +(cherry picked from commit c367f996f5f091a63f812f0140b304c649be77fc) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 38 ++++++++++++++++++++++++++++++++++++++ + src/basic/cpu-set-util.h | 3 +++ + src/core/dbus-execute.c | 6 +++++- + src/shared/bus-unit-util.c | 8 +++++++- + 4 files changed, 53 insertions(+), 2 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index c297eab032..74e35e57dd 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -209,3 +209,41 @@ int cpus_in_affinity_mask(void) { + n *= 2; + } + } ++ ++int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated) { ++ uint8_t *out; ++ ++ assert(set); ++ assert(ret); ++ ++ out = new0(uint8_t, set->allocated); ++ if (!out) ++ return -ENOMEM; ++ ++ for (unsigned cpu = 0; cpu < set->allocated * 8; cpu++) ++ if (CPU_ISSET_S(cpu, set->allocated, set->set)) ++ out[cpu / 8] |= 1u << (cpu % 8); ++ ++ *ret = out; ++ *allocated = set->allocated; ++ return 0; ++} ++ ++int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) { ++ _cleanup_(cpu_set_reset) CPUSet s = {}; ++ int r; ++ ++ assert(bits); ++ assert(set); ++ ++ for (unsigned cpu = size * 8; cpu > 0; cpu--) ++ if (bits[(cpu - 1) / 8] & (1u << ((cpu - 1) % 8))) { ++ r = cpu_set_add(&s, cpu - 1); ++ if (r < 0) ++ return r; ++ } ++ ++ *set = s; ++ s = (CPUSet) {}; ++ return 0; ++} +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 68a73bf9f7..415c6ca295 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -46,4 +46,7 @@ static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){ + return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL); + } + ++int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated); ++int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set); ++ + int cpus_in_affinity_mask(void); +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 08946627e3..50ea71a281 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1553,18 +1553,22 @@ int bus_exec_context_set_transient_property( + if (streq(name, "CPUAffinity")) { + const void *a; + size_t n; ++ _cleanup_(cpu_set_reset) CPUSet set = {}; + + r = sd_bus_message_read_array(message, 'y', &a, &n); + if (r < 0) + return r; + ++ r = cpu_set_from_dbus(a, n, &set); ++ if (r < 0) ++ return r; ++ + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (n == 0) { + cpu_set_reset(&c->cpu_set); + unit_write_settingf(u, flags, name, "%s=", name); + } else { + _cleanup_free_ char *str = NULL; +- const CPUSet set = {(cpu_set_t*) a, n}; + + str = cpu_set_to_string(&set); + if (!str) +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 75b4aace84..ec8732c226 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -933,12 +933,18 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + + if (streq(field, "CPUAffinity")) { + _cleanup_(cpu_set_reset) CPUSet cpuset = {}; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; + + r = parse_cpu_set(eq, &cpuset); + if (r < 0) + return log_error_errno(r, "Failed to parse %s value: %s", field, eq); + +- return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated); ++ r = cpu_set_to_dbus(&cpuset, &array, &allocated); ++ if (r < 0) ++ return log_error_errno(r, "Failed to serialize CPUAffinity: %m"); ++ ++ return bus_append_byte_array(m, field, array, allocated); + } + + if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) { diff --git a/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch b/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch new file mode 100644 index 0000000..f6e259a --- /dev/null +++ b/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch @@ -0,0 +1,61 @@ +From fd65eadbbcc068171ee9164610fd1c2016b3bf59 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 29 May 2019 09:44:16 +0200 +Subject: [PATCH] test-cpu-set-util: add test for dbus conversions + +(cherry picked from commit 1bf0d6c28f8c884e187c7dacc1a969c0763ff4e3) + +Related: #1734787 +--- + src/test/test-cpu-set-util.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 81f67647e8..cae51ad7d9 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -181,6 +181,36 @@ static void test_parse_cpu_set_extend(void) { + log_info("cpu_set_to_string: (null)"); + } + ++static void test_cpu_set_to_from_dbus(void) { ++ _cleanup_(cpu_set_reset) CPUSet c = {}, c2 = {}; ++ _cleanup_free_ char *s = NULL; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(s = cpu_set_to_string(&c)); ++ log_info("cpu_set_to_string: %s", s); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 104); ++ ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ static const char expected[32] = ++ "\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00" ++ "\x00\x00\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ++ "\xFF\xFF\xFF\xFF\xFF\x01"; ++ ++ assert_se(cpu_set_to_dbus(&c, &array, &allocated) == 0); ++ assert_se(array); ++ assert_se(allocated == c.allocated); ++ ++ assert(memcmp(array, expected, sizeof expected) == 0); ++ ++ assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0); ++ assert_se(c2.set); ++ assert_se(c2.allocated == c.allocated); ++ assert_se(memcmp(c.set, c2.set, c.allocated) == 0); ++} ++ + static void test_cpus_in_affinity_mask(void) { + int r; + +@@ -201,6 +231,7 @@ int main(int argc, char *argv[]) { + test_parse_cpu_set(); + test_parse_cpu_set_extend(); + test_cpus_in_affinity_mask(); ++ test_cpu_set_to_from_dbus(); + + return 0; + } diff --git a/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch b/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch new file mode 100644 index 0000000..d49553f --- /dev/null +++ b/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch @@ -0,0 +1,203 @@ +From 93777a6dd8c12d5cba094694bf7ed6e8c06c2d6d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 23 May 2019 14:27:18 +0200 +Subject: [PATCH] shared/cpu-set-util: introduce cpu_set_to_range() + +(cherry picked from commit 71b28519b55b496237146f9bcb5a627455f15f7e) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 37 ++++++++++++++++++++++++++ + src/basic/cpu-set-util.h | 2 ++ + src/test/test-cpu-set-util.c | 50 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 89 insertions(+) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 74e35e57dd..bff39ec143 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -37,6 +37,43 @@ char* cpu_set_to_string(const CPUSet *a) { + return TAKE_PTR(str) ?: strdup(""); + } + ++char *cpu_set_to_range_string(const CPUSet *set) { ++ unsigned range_start = 0, range_end; ++ _cleanup_free_ char *str = NULL; ++ size_t allocated = 0, len = 0; ++ bool in_range = false; ++ int r; ++ ++ for (unsigned i = 0; i < set->allocated * 8; i++) ++ if (CPU_ISSET_S(i, set->allocated, set->set)) { ++ if (in_range) ++ range_end++; ++ else { ++ range_start = range_end = i; ++ in_range = true; ++ } ++ } else if (in_range) { ++ in_range = false; ++ ++ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) ++ return NULL; ++ ++ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ assert_se(r > 0); ++ len += r; ++ } ++ ++ if (in_range) { ++ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) ++ return NULL; ++ ++ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ assert_se(r > 0); ++ } ++ ++ return TAKE_PTR(str) ?: strdup(""); ++} ++ + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { + size_t need; + +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 415c6ca295..ec640b2ec9 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -25,7 +25,9 @@ static inline void cpu_set_reset(CPUSet *a) { + int cpu_set_add_all(CPUSet *a, const CPUSet *b); + + char* cpu_set_to_string(const CPUSet *a); ++char *cpu_set_to_range_string(const CPUSet *a); + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus); ++ + int parse_cpu_set_full( + const char *rvalue, + CPUSet *cpu_set, +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index cae51ad7d9..0d2741cd43 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -4,6 +4,7 @@ + + #include "alloc-util.h" + #include "cpu-set-util.h" ++#include "string-util.h" + #include "macro.h" + + static void test_parse_cpu_set(void) { +@@ -13,6 +14,22 @@ static void test_parse_cpu_set(void) { + + log_info("/* %s */", __func__); + ++ /* Single value */ ++ assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(c.set); ++ assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(CPU_ISSET_S(0, c.allocated, c.set)); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 1); ++ ++ assert_se(str = cpu_set_to_string(&c)); ++ log_info("cpu_set_to_string: %s", str); ++ str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-0")); ++ str = mfree(str); ++ cpu_set_reset(&c); ++ + /* Simple range (from CPUAffinity example) */ + assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.set); +@@ -24,6 +41,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "1-2")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* A more interesting range */ +@@ -34,9 +55,14 @@ static void test_parse_cpu_set(void) { + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-3 8-11")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Quoted strings */ +@@ -48,6 +74,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "8-11")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Use commas as separators */ +@@ -72,6 +102,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-7")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Ranges */ +@@ -98,6 +132,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-3 8-11")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Negative range (returns empty cpu_set) */ +@@ -115,6 +153,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-11")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Mix ranges and individual CPUs */ +@@ -128,6 +170,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "0-1 4-11")); ++ str = mfree(str); + cpu_set_reset(&c); + + /* Garbage */ +@@ -156,6 +202,10 @@ static void test_parse_cpu_set(void) { + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); ++ assert_se(str = cpu_set_to_range_string(&c)); ++ log_info("cpu_set_to_range_string: %s", str); ++ assert_se(streq(str, "8000-8191")); ++ str = mfree(str); + cpu_set_reset(&c); + } + diff --git a/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch b/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch new file mode 100644 index 0000000..44d35dd --- /dev/null +++ b/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch @@ -0,0 +1,53 @@ +From fb1244ef318e9f54628a7c13db9e2ffbc712dd38 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 22 May 2019 17:14:21 +0200 +Subject: [PATCH] systemctl: present CPUAffinity mask as a list of CPU index + ranges + +(cherry picked from commit a047f4f10ed2f922d6079c033d24a443b0e95f38) + +Related: #1734787 +--- + src/systemctl/systemctl.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index f072ad0c31..0154b300a3 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -30,6 +30,7 @@ + #include "cgroup-show.h" + #include "cgroup-util.h" + #include "copy.h" ++#include "cpu-set-util.h" + #include "dropin.h" + #include "efivars.h" + #include "env-util.h" +@@ -4876,6 +4877,27 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + + print_prop(name, "%s", h); + ++ return 1; ++ } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) { ++ _cleanup_free_ char *affinity = NULL; ++ _cleanup_(cpu_set_reset) CPUSet set = {}; ++ const void *a; ++ size_t n; ++ ++ r = sd_bus_message_read_array(m, 'y', &a, &n); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ r = cpu_set_from_dbus(a, n, &set); ++ if (r < 0) ++ return log_error_errno(r, "Failed to deserialize CPUAffinity: %m"); ++ ++ affinity = cpu_set_to_range_string(&set); ++ if (!affinity) ++ return log_oom(); ++ ++ print_prop(name, "%s", affinity); ++ + return 1; + } + diff --git a/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch b/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch new file mode 100644 index 0000000..5f34600 --- /dev/null +++ b/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch @@ -0,0 +1,77 @@ +From cabd9055d0d745f7de9625dec6c623d363dd3aa6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 29 May 2019 10:17:43 +0200 +Subject: [PATCH] shared/cpu-set-util: only force range printing one time +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The idea is to have at least one range to make the new format clearly +distinguishable from the old. But it is enough to just do it once. +In particular, in case the affinity would be specified like 0, 2, 4, 6…, +this gives much shorter output. + +(cherry picked from commit 1f57a176af5152d05719bf43740e87a47e37af50) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 10 ++++++++-- + src/test/test-cpu-set-util.c | 7 ++++--- + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index bff39ec143..5024290557 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -58,7 +58,10 @@ char *cpu_set_to_range_string(const CPUSet *set) { + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) + return NULL; + +- r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ if (range_end > range_start || len == 0) ++ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ else ++ r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start); + assert_se(r > 0); + len += r; + } +@@ -67,7 +70,10 @@ char *cpu_set_to_range_string(const CPUSet *set) { + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) + return NULL; + +- r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ if (range_end > range_start || len == 0) ++ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); ++ else ++ r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start); + assert_se(r > 0); + } + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 0d2741cd43..995b981d25 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -31,19 +31,20 @@ static void test_parse_cpu_set(void) { + cpu_set_reset(&c); + + /* Simple range (from CPUAffinity example) */ +- assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.set); + assert_se(c.allocated >= sizeof(__cpu_mask) / 8); + assert_se(CPU_ISSET_S(1, c.allocated, c.set)); + assert_se(CPU_ISSET_S(2, c.allocated, c.set)); +- assert_se(CPU_COUNT_S(c.allocated, c.set) == 2); ++ assert_se(CPU_ISSET_S(4, c.allocated, c.set)); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 3); + + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); + assert_se(str = cpu_set_to_range_string(&c)); + log_info("cpu_set_to_range_string: %s", str); +- assert_se(streq(str, "1-2")); ++ assert_se(streq(str, "1-2 4")); + str = mfree(str); + cpu_set_reset(&c); + diff --git a/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch b/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch new file mode 100644 index 0000000..050478a --- /dev/null +++ b/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch @@ -0,0 +1,36 @@ +From b90f935f8d2268522480a7c12f7e2213a7a5e19d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 31 May 2019 18:02:20 +0200 +Subject: [PATCH] execute: dump CPUAffinity as a range string instead of a list + of CPUs + +We do this already when printing the property in systemctl so be +consistent and do the same for systemd-analyze dump. + +(cherry picked from commit e7fca352ba43988682a927de6b1f629b3f10a415) + +Related: #1734787 +--- + src/core/execute.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 22e5825905..bc26aa66e7 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -4098,11 +4098,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + } + + if (c->cpu_set.set) { +- fprintf(f, "%sCPUAffinity:", prefix); +- for (i = 0; i < c->cpu_set.allocated * 8; i++) +- if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set)) +- fprintf(f, " %u", i); +- fputs("\n", f); ++ _cleanup_free_ char *affinity = NULL; ++ ++ affinity = cpu_set_to_range_string(&c->cpu_set); ++ fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity); + } + + if (c->timer_slack_nsec != NSEC_INFINITY) diff --git a/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch b/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch new file mode 100644 index 0000000..0b2bec0 --- /dev/null +++ b/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch @@ -0,0 +1,95 @@ +From 35894625624f0e8c7d3ca2c200861005c7ad4435 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 3 Jun 2019 10:12:35 +0200 +Subject: [PATCH] cpu-set-util: use %d-%d format in cpu_set_to_range_string() + only for actual ranges + +(cherry picked from commit 71923237b18df35401626993d8a285cd998be78d) + +Related: #1734787 +--- + src/basic/cpu-set-util.c | 4 ++-- + src/test/test-cpu-set-util.c | 16 +++++++++------- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 5024290557..103b9703b3 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -58,7 +58,7 @@ char *cpu_set_to_range_string(const CPUSet *set) { + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) + return NULL; + +- if (range_end > range_start || len == 0) ++ if (range_end > range_start) + r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); + else + r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start); +@@ -70,7 +70,7 @@ char *cpu_set_to_range_string(const CPUSet *set) { + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) + return NULL; + +- if (range_end > range_start || len == 0) ++ if (range_end > range_start) + r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end); + else + r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start); +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 995b981d25..9522582891 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -26,7 +26,7 @@ static void test_parse_cpu_set(void) { + str = mfree(str); + assert_se(str = cpu_set_to_range_string(&c)); + log_info("cpu_set_to_range_string: %s", str); +- assert_se(streq(str, "0-0")); ++ assert_se(streq(str, "0")); + str = mfree(str); + cpu_set_reset(&c); + +@@ -95,17 +95,19 @@ static void test_parse_cpu_set(void) { + cpu_set_reset(&c); + + /* Commas with spaces (and trailing comma, space) */ +- assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.allocated >= sizeof(__cpu_mask) / 8); +- assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); ++ assert_se(CPU_COUNT_S(c.allocated, c.set) == 9); + for (cpu = 0; cpu < 8; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); ++ ++ assert_se(CPU_ISSET_S(63, c.allocated, c.set)); + assert_se(str = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", str); + str = mfree(str); + assert_se(str = cpu_set_to_range_string(&c)); + log_info("cpu_set_to_range_string: %s", str); +- assert_se(streq(str, "0-7")); ++ assert_se(streq(str, "0-7 63")); + str = mfree(str); + cpu_set_reset(&c); + +@@ -161,11 +163,11 @@ static void test_parse_cpu_set(void) { + cpu_set_reset(&c); + + /* Mix ranges and individual CPUs */ +- assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); ++ assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.allocated >= sizeof(__cpu_mask) / 8); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 10); + assert_se(CPU_ISSET_S(0, c.allocated, c.set)); +- assert_se(CPU_ISSET_S(1, c.allocated, c.set)); ++ assert_se(CPU_ISSET_S(2, c.allocated, c.set)); + for (cpu = 4; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); + assert_se(str = cpu_set_to_string(&c)); +@@ -173,7 +175,7 @@ static void test_parse_cpu_set(void) { + str = mfree(str); + assert_se(str = cpu_set_to_range_string(&c)); + log_info("cpu_set_to_range_string: %s", str); +- assert_se(streq(str, "0-1 4-11")); ++ assert_se(streq(str, "0 2 4-11")); + str = mfree(str); + cpu_set_reset(&c); + diff --git a/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch b/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch new file mode 100644 index 0000000..bcfd3a3 --- /dev/null +++ b/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch @@ -0,0 +1,779 @@ +From a735699a8287c19e043b7d2fe9a387a3938e1e2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 18 Nov 2019 12:50:11 +0100 +Subject: [PATCH] core: introduce NUMAPolicy and NUMAMask options + +Make possible to set NUMA allocation policy for manager. Manager's +policy is by default inherited to all forked off processes. However, it +is possible to override the policy on per-service basis. Currently we +support, these policies: default, prefer, bind, interleave, local. +See man 2 set_mempolicy for details on each policy. + +Overall NUMA policy actually consists of two parts. Policy itself and +bitmask representing NUMA nodes where is policy effective. Node mask can +be specified using related option, NUMAMask. Default mask can be +overwritten on per-service level. + +(cherry-picked from commit fe9c54b2188e6cd23262a319f96b13215f2c5e9c) + +Resolves: #1734787 +--- + man/systemd-system.conf.xml | 19 ++++++ + man/systemd.exec.xml | 28 +++++++++ + meson.build | 4 ++ + src/basic/cpu-set-util.c | 91 +++++++++++++++++++++++++++ + src/basic/cpu-set-util.h | 28 +++++++++ + src/basic/exit-status.c | 3 + + src/basic/exit-status.h | 1 + + src/basic/missing_syscall.h | 43 +++++++++++++ + src/core/dbus-execute.c | 65 ++++++++++++++++++- + src/core/execute.c | 20 ++++++ + src/core/execute.h | 1 + + src/core/load-fragment-gperf.gperf.m4 | 2 + + src/core/load-fragment.c | 28 +++++++++ + src/core/load-fragment.h | 2 + + src/core/main.c | 27 ++++++++ + src/core/system.conf.in | 2 + + src/shared/bus-unit-util.c | 28 +++++++++ + src/systemctl/systemctl.c | 18 +++++- + 18 files changed, 405 insertions(+), 5 deletions(-) + +diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml +index ab23779ec0..988c4e7665 100644 +--- a/man/systemd-system.conf.xml ++++ b/man/systemd-system.conf.xml +@@ -132,6 +132,25 @@ + anymore. + + ++ ++ NUMAPolicy= ++ ++ Configures the NUMA memory policy for the service manager and the default NUMA memory policy ++ for all forked off processes. Individual services may override the default policy with the ++ NUMAPolicy= setting in unit files, see ++ systemd.exec5. ++ ++ ++ ++ NUMAMask= ++ ++ Configures the NUMA node mask that will be associated with the selected NUMA policy. Note that ++ and NUMA policies don't require explicit NUMA node mask and ++ value of the option can be empty. Similarly to NUMAPolicy=, value can be overriden ++ by individual services in unit files, see ++ systemd.exec5. ++ ++ + + RuntimeWatchdogSec= + ShutdownWatchdogSec= +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 342b8385bc..87fb8b34f4 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -710,6 +710,28 @@ CapabilityBoundingSet=~CAP_B CAP_C + details. + + ++ ++ NUMAPolicy= ++ ++ Controls the NUMA memory policy of the executed processes. Takes a policy type, one of: ++ , , , and ++ . A list of NUMA nodes that should be associated with the policy must be specified ++ in NUMAMask=. For more details on each policy please see, ++ set_mempolicy2. For overall ++ overview of NUMA support in Linux see, ++ numa7 ++ ++ ++ ++ ++ NUMAMask= ++ ++ Controls the NUMA node list which will be applied alongside with selected NUMA policy. ++ Takes a list of NUMA nodes and has the same syntax as a list of CPUs for CPUAffinity= ++ option. Note that the list of NUMA nodes is not required for and ++ policies and for policy we expect a single NUMA node. ++ ++ + + IOSchedulingClass= + +@@ -2709,6 +2731,12 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy + EXIT_CONFIGURATION_DIRECTORY + Failed to set up unit's configuration directory. See ConfigurationDirectory= above. + ++ ++ 242 ++ EXIT_NUMA_POLICY ++ Failed to set up unit's NUMA memory policy. See NUMAPolicy= and NUMAMask=above. ++ ++ + + + +diff --git a/meson.build b/meson.build +index 613a5133b6..fe82ca4ac2 100644 +--- a/meson.build ++++ b/meson.build +@@ -501,6 +501,10 @@ foreach ident : [ + #include '''], + ['explicit_bzero' , '''#include '''], + ['reallocarray', '''#include '''], ++ ['set_mempolicy', '''#include ++ #include '''], ++ ['get_mempolicy', '''#include ++ #include '''], + ] + + have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE') +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 103b9703b3..36cb017ae7 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -10,11 +10,17 @@ + + #include "alloc-util.h" + #include "cpu-set-util.h" ++#include "dirent-util.h" + #include "extract-word.h" ++#include "fd-util.h" + #include "log.h" + #include "macro.h" ++#include "missing.h" + #include "parse-util.h" ++#include "stat-util.h" + #include "string-util.h" ++#include "string-table.h" ++#include "strv.h" + #include "util.h" + + char* cpu_set_to_string(const CPUSet *a) { +@@ -290,3 +296,88 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) { + s = (CPUSet) {}; + return 0; + } ++ ++bool numa_policy_is_valid(const NUMAPolicy *policy) { ++ assert(policy); ++ ++ if (!mpol_is_valid(numa_policy_get_type(policy))) ++ return false; ++ ++ if (!policy->nodes.set && ++ !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED)) ++ return false; ++ ++ if (policy->nodes.set && ++ numa_policy_get_type(policy) == MPOL_PREFERRED && ++ CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1) ++ return false; ++ ++ return true; ++} ++ ++static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) { ++ unsigned node, bits = 0, ulong_bits; ++ _cleanup_free_ unsigned long *out = NULL; ++ ++ assert(policy); ++ assert(ret_maxnode); ++ assert(ret_nodes); ++ ++ if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) || ++ (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) { ++ *ret_nodes = NULL; ++ *ret_maxnode = 0; ++ return 0; ++ } ++ ++ bits = policy->nodes.allocated * 8; ++ ulong_bits = sizeof(unsigned long) * 8; ++ ++ out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long))); ++ if (!out) ++ return -ENOMEM; ++ ++ /* We don't make any assumptions about internal type libc is using to store NUMA node mask. ++ Hence we need to convert the node mask to the representation expected by set_mempolicy() */ ++ for (node = 0; node < bits; node++) ++ if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set)) ++ out[node / ulong_bits] |= 1ul << (node % ulong_bits); ++ ++ *ret_nodes = TAKE_PTR(out); ++ *ret_maxnode = bits + 1; ++ return 0; ++} ++ ++int apply_numa_policy(const NUMAPolicy *policy) { ++ int r; ++ _cleanup_free_ unsigned long *nodes = NULL; ++ unsigned long maxnode; ++ ++ assert(policy); ++ ++ if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS) ++ return -EOPNOTSUPP; ++ ++ if (!numa_policy_is_valid(policy)) ++ return -EINVAL; ++ ++ r = numa_policy_to_mempolicy(policy, &maxnode, &nodes); ++ if (r < 0) ++ return r; ++ ++ r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode); ++ if (r < 0) ++ return -errno; ++ ++ return 0; ++} ++ ++static const char* const mpol_table[] = { ++ [MPOL_DEFAULT] = "default", ++ [MPOL_PREFERRED] = "preferred", ++ [MPOL_BIND] = "bind", ++ [MPOL_INTERLEAVE] = "interleave", ++ [MPOL_LOCAL] = "local", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(mpol, int); +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index ec640b2ec9..295028cb54 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -8,6 +8,7 @@ + #include + + #include "macro.h" ++#include "missing.h" + + /* This wraps the libc interface with a variable to keep the allocated size. */ + typedef struct CPUSet { +@@ -52,3 +53,30 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated); + int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set); + + int cpus_in_affinity_mask(void); ++ ++static inline bool mpol_is_valid(int t) { ++ return t >= MPOL_DEFAULT && t <= MPOL_LOCAL; ++} ++ ++typedef struct NUMAPolicy { ++ /* Always use numa_policy_get_type() to read the value */ ++ int type; ++ CPUSet nodes; ++} NUMAPolicy; ++ ++bool numa_policy_is_valid(const NUMAPolicy *p); ++ ++static inline int numa_policy_get_type(const NUMAPolicy *p) { ++ return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type; ++} ++ ++static inline void numa_policy_reset(NUMAPolicy *p) { ++ assert(p); ++ cpu_set_reset(&p->nodes); ++ p->type = -1; ++} ++ ++int apply_numa_policy(const NUMAPolicy *policy); ++ ++const char* mpol_to_string(int i) _const_; ++int mpol_from_string(const char *s) _pure_; +diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c +index 21af8c4c71..0a7a53b73d 100644 +--- a/src/basic/exit-status.c ++++ b/src/basic/exit-status.c +@@ -155,6 +155,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { + + case EXIT_CONFIGURATION_DIRECTORY: + return "CONFIGURATION_DIRECTORY"; ++ ++ case EXIT_NUMA_POLICY: ++ return "NUMA_POLICY"; + } + } + +diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h +index c41e8b82c3..dc284aacb1 100644 +--- a/src/basic/exit-status.h ++++ b/src/basic/exit-status.h +@@ -69,6 +69,7 @@ enum { + EXIT_CACHE_DIRECTORY, + EXIT_LOGS_DIRECTORY, /* 240 */ + EXIT_CONFIGURATION_DIRECTORY, ++ EXIT_NUMA_POLICY, + }; + + typedef enum ExitStatusLevel { +diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h +index 93c60458bf..014dd2b326 100644 +--- a/src/basic/missing_syscall.h ++++ b/src/basic/missing_syscall.h +@@ -428,3 +428,46 @@ static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flag + + # define statx missing_statx + #endif ++ ++#if !HAVE_SET_MEMPOLICY ++ ++enum { ++ MPOL_DEFAULT, ++ MPOL_PREFERRED, ++ MPOL_BIND, ++ MPOL_INTERLEAVE, ++ MPOL_LOCAL, ++}; ++ ++static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask, ++ unsigned long maxnode) { ++ long i; ++# ifdef __NR_set_mempolicy ++ i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode); ++# else ++ errno = ENOSYS; ++ i = -1; ++# endif ++ return i; ++} ++ ++# define set_mempolicy missing_set_mempolicy ++#endif ++ ++ ++#if !HAVE_GET_MEMPOLICY ++static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask, ++ unsigned long maxnode, void *addr, ++ unsigned long flags) { ++ long i; ++# ifdef __NR_get_mempolicy ++ i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags); ++# else ++ errno = ENOSYS; ++ i = -1; ++# endif ++ return i; ++} ++ ++#define get_mempolicy missing_get_mempolicy ++#endif +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 50ea71a281..198f149210 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -223,6 +223,48 @@ static int property_get_cpu_affinity( + return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated); + } + ++static int property_get_numa_mask( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ ExecContext *c = userdata; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ assert(bus); ++ assert(reply); ++ assert(c); ++ ++ (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated); ++ ++ return sd_bus_message_append_array(reply, 'y', array, allocated); ++} ++ ++static int property_get_numa_policy( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ExecContext *c = userdata; ++ int32_t policy; ++ ++ assert(bus); ++ assert(reply); ++ assert(c); ++ ++ policy = numa_policy_get_type(&c->numa_policy); ++ ++ return sd_bus_message_append_basic(reply, 'i', &policy); ++} ++ + static int property_get_timer_slack_nsec( + sd_bus *bus, + const char *path, +@@ -698,6 +740,8 @@ const sd_bus_vtable bus_exec_vtable[] = { + SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -1550,9 +1594,10 @@ int bus_exec_context_set_transient_property( + return 1; + } + #endif +- if (streq(name, "CPUAffinity")) { ++ if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) { + const void *a; + size_t n; ++ bool affinity = streq(name, "CPUAffinity"); + _cleanup_(cpu_set_reset) CPUSet set = {}; + + r = sd_bus_message_read_array(message, 'y', &a, &n); +@@ -1565,7 +1610,7 @@ int bus_exec_context_set_transient_property( + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (n == 0) { +- cpu_set_reset(&c->cpu_set); ++ cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes); + unit_write_settingf(u, flags, name, "%s=", name); + } else { + _cleanup_free_ char *str = NULL; +@@ -1577,7 +1622,7 @@ int bus_exec_context_set_transient_property( + /* We forego any optimizations here, and always create the structure using + * cpu_set_add_all(), because we don't want to care if the existing size we + * got over dbus is appropriate. */ +- r = cpu_set_add_all(&c->cpu_set, &set); ++ r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set); + if (r < 0) + return r; + +@@ -1587,6 +1632,20 @@ int bus_exec_context_set_transient_property( + + return 1; + ++ } else if (streq(name, "NUMAPolicy")) { ++ int32_t type; ++ ++ r = sd_bus_message_read(message, "i", &type); ++ if (r < 0) ++ return r; ++ ++ if (!mpol_is_valid(type)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type); ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) ++ c->numa_policy.type = type; ++ ++ return 1; + } else if (streq(name, "IOSchedulingClass")) { + int32_t q; + +diff --git a/src/core/execute.c b/src/core/execute.c +index bc26aa66e7..56aa89e1ec 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2997,6 +2997,16 @@ static int exec_child( + return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m"); + } + ++ if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) { ++ r = apply_numa_policy(&context->numa_policy); ++ if (r == -EOPNOTSUPP) ++ log_unit_debug_errno(unit, r, "NUMA support not available, ignoring."); ++ else if (r < 0) { ++ *exit_status = EXIT_NUMA_POLICY; ++ return log_unit_error_errno(unit, r, "Failed to set NUMA memory policy: %m"); ++ } ++ } ++ + if (context->ioprio_set) + if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { + *exit_status = EXIT_IOPRIO; +@@ -3651,6 +3661,7 @@ void exec_context_init(ExecContext *c) { + assert_cc(NAMESPACE_FLAGS_INITIAL != NAMESPACE_FLAGS_ALL); + c->restrict_namespaces = NAMESPACE_FLAGS_INITIAL; + c->log_level_max = -1; ++ numa_policy_reset(&c->numa_policy); + } + + void exec_context_done(ExecContext *c) { +@@ -3695,6 +3706,7 @@ void exec_context_done(ExecContext *c) { + c->n_temporary_filesystems = 0; + + cpu_set_reset(&c->cpu_set); ++ numa_policy_reset(&c->numa_policy); + + c->utmp_id = mfree(c->utmp_id); + c->selinux_context = mfree(c->selinux_context); +@@ -4104,6 +4116,14 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity); + } + ++ if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) { ++ _cleanup_free_ char *nodes = NULL; ++ ++ nodes = cpu_set_to_range_string(&c->numa_policy.nodes); ++ fprintf(f, "%sNUMAPolicy: %s\n", prefix, mpol_to_string(numa_policy_get_type(&c->numa_policy))); ++ fprintf(f, "%sNUMAMask: %s\n", prefix, strnull(nodes)); ++ } ++ + if (c->timer_slack_nsec != NSEC_INFINITY) + fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec); + +diff --git a/src/core/execute.h b/src/core/execute.h +index e1e7a494cd..b2eb55f8f5 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -150,6 +150,7 @@ struct ExecContext { + int cpu_sched_priority; + + CPUSet cpu_set; ++ NUMAPolicy numa_policy; + + ExecInput std_input; + ExecOutput std_output; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 1066bcfb8f..cdf4d14c4e 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -36,6 +36,8 @@ $1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0, + $1.CPUSchedulingPriority, config_parse_exec_cpu_sched_prio, 0, offsetof($1, exec_context) + $1.CPUSchedulingResetOnFork, config_parse_bool, 0, offsetof($1, exec_context.cpu_sched_reset_on_fork) + $1.CPUAffinity, config_parse_exec_cpu_affinity, 0, offsetof($1, exec_context) ++$1.NUMAPolicy, config_parse_numa_policy, 0, offsetof($1, exec_context.numa_policy.type) ++$1.NUMAMask, config_parse_numa_mask, 0, offsetof($1, exec_context.numa_policy) + $1.UMask, config_parse_mode, 0, offsetof($1, exec_context.umask) + $1.Environment, config_parse_environ, 0, offsetof($1, exec_context.environment) + $1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 34ae834188..35dd595098 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -93,6 +93,7 @@ DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint + DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight"); + DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares"); + DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag"); ++DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_numa_policy, mpol, int, -1, "Invalid NUMA policy type"); + + int config_parse_unit_deps( + const char *unit, +@@ -1159,6 +1160,33 @@ int config_parse_exec_cpu_sched_policy(const char *unit, + return 0; + } + ++int config_parse_numa_mask(const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *section, ++ unsigned section_line, ++ const char *lvalue, ++ int ltype, ++ const char *rvalue, ++ void *data, ++ void *userdata) { ++ int r; ++ NUMAPolicy *p = data; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ assert(data); ++ ++ r = parse_cpu_set_extend(rvalue, &p->nodes, true, unit, filename, line, lvalue); ++ if (r < 0) { ++ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NUMA node mask, ignoring: %s", rvalue); ++ return 0; ++ } ++ ++ return r; ++} ++ + int config_parse_exec_cpu_sched_prio(const char *unit, + const char *filename, + unsigned line, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index dad281ef72..f2ca1b8ee7 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -102,6 +102,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_job_timeout_sec); + CONFIG_PARSER_PROTOTYPE(config_parse_job_running_timeout_sec); + CONFIG_PARSER_PROTOTYPE(config_parse_log_extra_fields); + CONFIG_PARSER_PROTOTYPE(config_parse_collect_mode); ++CONFIG_PARSER_PROTOTYPE(config_parse_numa_policy); ++CONFIG_PARSER_PROTOTYPE(config_parse_numa_mask); + + /* gperf prototypes */ + const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length); +diff --git a/src/core/main.c b/src/core/main.c +index c74dc641c1..83f9dd5878 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -134,6 +134,7 @@ static uint64_t arg_default_tasks_max; + static sd_id128_t arg_machine_id; + static EmergencyAction arg_cad_burst_action; + static CPUSet arg_cpu_affinity; ++static NUMAPolicy arg_numa_policy; + + static int parse_configuration(void); + +@@ -660,6 +661,8 @@ static int parse_config_file(void) { + { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status }, + { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity }, + { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, ++ { "Manager", "NUMAPolicy", config_parse_numa_policy, 0, &arg_numa_policy.type }, ++ { "Manager", "NUMAMask", config_parse_numa_mask, 0, &arg_numa_policy }, + { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog }, + { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, + { "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device }, +@@ -1501,6 +1504,27 @@ static void update_cpu_affinity(bool skip_setup) { + log_warning_errno(errno, "Failed to set CPU affinity: %m"); + } + ++static void update_numa_policy(bool skip_setup) { ++ int r; ++ _cleanup_free_ char *nodes = NULL; ++ const char * policy = NULL; ++ ++ if (skip_setup || !mpol_is_valid(numa_policy_get_type(&arg_numa_policy))) ++ return; ++ ++ if (DEBUG_LOGGING) { ++ policy = mpol_to_string(numa_policy_get_type(&arg_numa_policy)); ++ nodes = cpu_set_to_range_string(&arg_numa_policy.nodes); ++ log_debug("Setting NUMA policy to %s, with nodes %s.", strnull(policy), strnull(nodes)); ++ } ++ ++ r = apply_numa_policy(&arg_numa_policy); ++ if (r == -EOPNOTSUPP) ++ log_debug_errno(r, "NUMA support not available, ignoring."); ++ else if (r < 0) ++ log_warning_errno(r, "Failed to set NUMA memory policy: %m"); ++} ++ + static void do_reexecute( + int argc, + char *argv[], +@@ -1672,6 +1696,7 @@ static int invoke_main_loop( + set_manager_defaults(m); + + update_cpu_affinity(false); ++ update_numa_policy(false); + + if (saved_log_level >= 0) + manager_override_log_level(m, saved_log_level); +@@ -1832,6 +1857,7 @@ static int initialize_runtime( + return 0; + + update_cpu_affinity(skip_setup); ++ update_numa_policy(skip_setup); + + if (arg_system) { + /* Make sure we leave a core dump without panicing the kernel. */ +@@ -2011,6 +2037,7 @@ static void reset_arguments(void) { + arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; + + cpu_set_reset(&arg_cpu_affinity); ++ numa_policy_reset(&arg_numa_policy); + } + + static int parse_configuration(void) { +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index 653ec6b8c9..0d93fbf147 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -24,6 +24,8 @@ + #CtrlAltDelBurstAction=reboot-force + #CPUAffinity=1 2 + #JoinControllers=cpu,cpuacct net_cls,net_prio ++#NUMAPolicy=default ++#NUMAMask= + #RuntimeWatchdogSec=0 + #ShutdownWatchdogSec=10min + #CapabilityBoundingSet= +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index ec8732c226..055edd6e22 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -947,6 +947,34 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + return bus_append_byte_array(m, field, array, allocated); + } + ++ if (streq(field, "NUMAPolicy")) { ++ r = mpol_from_string(eq); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse %s value: %s", field, eq); ++ ++ r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t) r); ++ if (r < 0) ++ return bus_log_create_error(r); ++ ++ return 1; ++ } ++ ++ if (streq(field, "NUMAMask")) { ++ _cleanup_(cpu_set_reset) CPUSet nodes = {}; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ r = parse_cpu_set(eq, &nodes); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse %s value: %s", field, eq); ++ ++ r = cpu_set_to_dbus(&nodes, &array, &allocated); ++ if (r < 0) ++ return log_error_errno(r, "Failed to serialize NUMAMask: %m"); ++ ++ return bus_append_byte_array(m, field, array, allocated); ++ } ++ + if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) { + int whitelist = 1; + const char *p = eq; +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 0154b300a3..7274921e6d 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4573,6 +4573,20 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + + switch (bus_type) { + ++ case SD_BUS_TYPE_INT32: ++ if (streq(name, "NUMAPolicy")) { ++ int32_t i; ++ ++ r = sd_bus_message_read_basic(m, bus_type, &i); ++ if (r < 0) ++ return r; ++ ++ print_prop(name, "%s", strna(mpol_to_string(i))); ++ ++ return 1; ++ } ++ break; ++ + case SD_BUS_TYPE_STRUCT: + + if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) { +@@ -4878,7 +4892,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + print_prop(name, "%s", h); + + return 1; +- } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) { ++ } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask")) { + _cleanup_free_ char *affinity = NULL; + _cleanup_(cpu_set_reset) CPUSet set = {}; + const void *a; +@@ -4890,7 +4904,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + + r = cpu_set_from_dbus(a, n, &set); + if (r < 0) +- return log_error_errno(r, "Failed to deserialize CPUAffinity: %m"); ++ return log_error_errno(r, "Failed to deserialize %s: %m", name); + + affinity = cpu_set_to_range_string(&set); + if (!affinity) diff --git a/SOURCES/0289-core-disable-CPUAccounting-by-default.patch b/SOURCES/0289-core-disable-CPUAccounting-by-default.patch new file mode 100644 index 0000000..d250c03 --- /dev/null +++ b/SOURCES/0289-core-disable-CPUAccounting-by-default.patch @@ -0,0 +1,25 @@ +From b47f26558e5234ec8cf2ecc3674c94a87f20ec69 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 28 Nov 2019 15:47:43 +0100 +Subject: [PATCH] core: disable CPUAccounting by default + +Related: #1734787 + +[RHEL-only] +--- + src/core/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 83f9dd5878..c83249a8dc 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2026,7 +2026,7 @@ static void reset_arguments(void) { + + /* arg_serialization — ignore */ + +- arg_default_cpu_accounting = -1; ++ arg_default_cpu_accounting = 0; + arg_default_io_accounting = false; + arg_default_ip_accounting = false; + arg_default_blockio_accounting = false; diff --git a/SOURCES/0290-set-kptr_restrict-1.patch b/SOURCES/0290-set-kptr_restrict-1.patch new file mode 100644 index 0000000..5005756 --- /dev/null +++ b/SOURCES/0290-set-kptr_restrict-1.patch @@ -0,0 +1,24 @@ +From cf1a9df1171273fc1ed3f977b5ec52aba27674bf Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 3 Dec 2019 14:04:00 +0100 +Subject: [PATCH] set kptr_restrict=1 + +Resolves: #1689346 +--- + sysctl.d/50-default.conf | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index e263cf0628..e0afc9c702 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -21,6 +21,9 @@ kernel.sysrq = 16 + # Append the PID to the core filename + kernel.core_uses_pid = 1 + ++# https://bugzilla.redhat.com/show_bug.cgi?id=1689346 ++kernel.kptr_restrict = 1 ++ + # Source route verification + net.ipv4.conf.all.rp_filter = 1 + diff --git a/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch b/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch new file mode 100644 index 0000000..48f41cf --- /dev/null +++ b/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch @@ -0,0 +1,34 @@ +From 40612e4e7690c613cba7ac87b9d782724e623a39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Wed, 27 Nov 2019 14:27:58 +0100 +Subject: [PATCH] cryptsetup: reduce the chance that we will be OOM killed + +cryptsetup introduced optional locking scheme that should serialize +unlocking keyslots which use memory hard key derivation +function (argon2). Using the serialization should prevent OOM situation +in early boot while unlocking encrypted volumes. + +(cherry picked from commit 408c81f62454684dfbff1c95ce3210d06f256e58) + +Resolves: #1696602 +--- + src/cryptsetup/cryptsetup.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 4e1b3eff19..9071126c2e 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -656,6 +656,12 @@ int main(int argc, char *argv[]) { + if (arg_discards) + flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS; + ++#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF ++ /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */ ++ /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */ ++ flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF; ++#endif ++ + if (arg_timeout == USEC_INFINITY) + until = 0; + else diff --git a/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch b/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch new file mode 100644 index 0000000..4bfb5ef --- /dev/null +++ b/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch @@ -0,0 +1,136 @@ +From cb084637ba1c8558f1538ce300c5520a6764dc76 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Mon, 28 Oct 2019 19:35:24 +0900 +Subject: [PATCH] core, job: fix breakage of ordering dependencies by systemctl + reload command + +Currently, systemctl reload command breaks ordering dependencies if it's +executed when its target service unit is in activating state. + +For example, prepare A.service, B.service and C.target as follows: + + # systemctl cat A.service B.service C.target + # /etc/systemd/system/A.service + [Unit] + Description=A + + [Service] + Type=oneshot + ExecStart=/usr/bin/echo A1 + ExecStart=/usr/bin/sleep 60 + ExecStart=/usr/bin/echo A2 + ExecReload=/usr/bin/echo A reloaded + RemainAfterExit=yes + + # /etc/systemd/system/B.service + [Unit] + Description=B + After=A.service + + [Service] + Type=oneshot + ExecStart=/usr/bin/echo B + RemainAfterExit=yes + + # /etc/systemd/system/C.target + [Unit] + Description=C + Wants=A.service B.service + +Start them. + + # systemctl daemon-reload + # systemctl start C.target + +Then, we have: + + # LANG=C journalctl --no-pager -u A.service -u B.service -u C.target -b + -- Logs begin at Mon 2019-09-09 00:25:06 EDT, end at Thu 2019-10-24 22:28:47 EDT. -- + Oct 24 22:27:47 localhost.localdomain systemd[1]: Starting A... + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Child 967 belongs to A.service. + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start. + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/sleep 60 + Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/sleep as 968 + Oct 24 22:27:47 localhost.localdomain systemd[968]: A.service: Executing: /usr/bin/sleep 60 + Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Trying to enqueue job A.service/reload/replace + Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Merged into running job, re-running: A.service/reload as 1288 + Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Enqueued job A.service/reload as 1288 + Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Unit cannot be reloaded because it is inactive. + Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Job 1288 A.service/reload finished, result=invalid + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Passing 0 fds to service + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: About to execute: /usr/bin/echo B + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Forked /usr/bin/echo as 970 + Oct 24 22:27:52 localhost.localdomain systemd[970]: B.service: Executing: /usr/bin/echo B + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Failed to send unit change signal for B.service: Connection reset by peer + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed dead -> start + Oct 24 22:27:52 localhost.localdomain systemd[1]: Starting B... + Oct 24 22:27:52 localhost.localdomain echo[970]: B + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Child 970 belongs to B.service. + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Main process exited, code=exited, status=0/SUCCESS + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed start -> exited + Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Job 1371 B.service/start finished, result=done + Oct 24 22:27:52 localhost.localdomain systemd[1]: Started B. + Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Job 1287 C.target/start finished, result=done + Oct 24 22:27:52 localhost.localdomain systemd[1]: Reached target C. + Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Failed to send unit change signal for C.target: Connection reset by peer + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 968 belongs to A.service. + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start. + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/echo A2 + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/echo as 972 + Oct 24 22:28:47 localhost.localdomain systemd[972]: A.service: Executing: /usr/bin/echo A2 + Oct 24 22:28:47 localhost.localdomain echo[972]: A2 + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 972 belongs to A.service. + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS + Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Changed start -> exited + +The issue occurs not only in reload command, i.e.: + + - reload + - try-restart + - reload-or-restart + - reload-or-try-restart commands + +The cause of this issue is that job_type_collapse() doesn't take care of the +activating state. + +Fixes: #10464 +(cherry picked from commit d1559793df555212271e490a4a72f55826caf5b4) + +Resolves: #1766417 +--- + src/core/job.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 8552ffb704..769ed6d603 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -403,21 +403,21 @@ JobType job_type_collapse(JobType t, Unit *u) { + + case JOB_TRY_RESTART: + s = unit_active_state(u); +- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s)) ++ if (!UNIT_IS_ACTIVE_OR_RELOADING(s)) + return JOB_NOP; + + return JOB_RESTART; + + case JOB_TRY_RELOAD: + s = unit_active_state(u); +- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s)) ++ if (!UNIT_IS_ACTIVE_OR_RELOADING(s)) + return JOB_NOP; + + return JOB_RELOAD; + + case JOB_RELOAD_OR_START: + s = unit_active_state(u); +- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s)) ++ if (!UNIT_IS_ACTIVE_OR_RELOADING(s)) + return JOB_START; + + return JOB_RELOAD; diff --git a/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch b/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch new file mode 100644 index 0000000..fb40563 --- /dev/null +++ b/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch @@ -0,0 +1,149 @@ +From 613a02b7d67864af1860e9137e2ee101d603463e Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 25 Apr 2019 12:19:16 +0200 +Subject: [PATCH] debug-generator: enable custom systemd.debug_shell tty + +(cherry picked from commit 93912e872fb14e9c372e090409e429084a6450f5) + +Resolves: #1723722 +--- + man/custom-entities.ent.in | 1 + + man/systemd-debug-generator.xml | 13 ++++++--- + meson.build | 1 + + src/debug-generator/debug-generator.c | 41 +++++++++++++++++++++------ + 4 files changed, 43 insertions(+), 13 deletions(-) + +diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in +index e2bd44e5e7..85805777a0 100644 +--- a/man/custom-entities.ent.in ++++ b/man/custom-entities.ent.in +@@ -8,3 +8,4 @@ + + + ++ +diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml +index fa88e8ac01..25d8b1a873 100644 +--- a/man/systemd-debug-generator.xml ++++ b/man/systemd-debug-generator.xml +@@ -1,6 +1,10 @@ + + +- ++ ++%entities; ++]> + +@@ -57,9 +61,10 @@ + option is + specified, the debug shell service + debug-shell.service is pulled into the boot +- transaction. It will spawn a debug shell on tty9 during early +- system startup. Note that the shell may also be turned on +- persistently by enabling it with ++ transaction and a debug shell will be spawned during early boot. ++ By default, &DEBUGTTY; is used, but a specific tty can also be set, ++ either with or without the /dev/ prefix. ++ Note that the shell may also be turned on persistently by enabling it with + systemctl1's + enable command. + is honored only by initial +diff --git a/meson.build b/meson.build +index fe82ca4ac2..70811c29cf 100644 +--- a/meson.build ++++ b/meson.build +@@ -768,6 +768,7 @@ conf.set_quoted('GETTEXT_PACKAGE', meson.project_name()) + + substs.set('SUSHELL', get_option('debug-shell')) + substs.set('DEBUGTTY', get_option('debug-tty')) ++conf.set_quoted('DEBUGTTY', get_option('debug-tty')) + + enable_debug_hashmap = false + enable_debug_mmap_cache = false +diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c +index 800d31cebe..ddef385833 100644 +--- a/src/debug-generator/debug-generator.c ++++ b/src/debug-generator/debug-generator.c +@@ -1,8 +1,11 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "alloc-util.h" ++#include "dropin.h" ++#include "generator.h" + #include "mkdir.h" + #include "parse-util.h" ++#include "path-util.h" + #include "proc-cmdline.h" + #include "special.h" + #include "string-util.h" +@@ -14,7 +17,7 @@ static char *arg_default_unit = NULL; + static const char *arg_dest = "/tmp"; + static char **arg_mask = NULL; + static char **arg_wants = NULL; +-static bool arg_debug_shell = false; ++static char *arg_debug_shell = NULL; + + static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { + int r; +@@ -50,15 +53,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + return log_oom(); + + } else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) { ++ const char *t = NULL; + +- if (value) { +- r = parse_boolean(value); +- if (r < 0) +- log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value); +- else +- arg_debug_shell = r; +- } else +- arg_debug_shell = true; ++ r = value ? parse_boolean(value) : 1; ++ if (r < 0) ++ t = skip_dev_prefix(value); ++ else if (r > 0) ++ t = skip_dev_prefix(DEBUGTTY); ++ ++ if (free_and_strdup(&arg_debug_shell, t) < 0) ++ return log_oom(); + + } else if (streq(key, "systemd.unit")) { + +@@ -136,6 +140,23 @@ static int generate_wants_symlinks(void) { + return r; + } + ++static void install_debug_shell_dropin(const char *dir) { ++ int r; ++ ++ if (streq(arg_debug_shell, skip_dev_prefix(DEBUGTTY))) ++ return; ++ ++ r = write_drop_in_format(dir, "debug-shell.service", 50, "tty", ++ "[Unit]\n" ++ "Description=Early root shell on /dev/%s FOR DEBUGGING ONLY\n" ++ "ConditionPathExists=\n" ++ "[Service]\n" ++ "TTYPath=/dev/%s", ++ arg_debug_shell, arg_debug_shell); ++ if (r < 0) ++ log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m"); ++} ++ + int main(int argc, char *argv[]) { + int r, q; + +@@ -164,6 +185,8 @@ int main(int argc, char *argv[]) { + r = log_oom(); + goto finish; + } ++ ++ install_debug_shell_dropin(arg_dest); + } + + r = generate_mask_symlinks(); diff --git a/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch b/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch new file mode 100644 index 0000000..490a14f --- /dev/null +++ b/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch @@ -0,0 +1,118 @@ +From f4344bb4055cab8dc3bbe82a7f3d97fc6fabcb7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 4 Jun 2019 09:19:04 +0200 +Subject: [PATCH] test-cpu-set-util: fix comparison for allocation size + +On i386, __cpu_mask is 4 bytes, so we'd check if c.allocated >= 0, and +gcc would warn about a bogus comparison. Let's round up. + +Fixes #12726. + +(cherry picked from commit a299ce058b41b21c87f36e77e2c563b0ddd1be0d) + +Related: #1734787 +--- + src/test/test-cpu-set-util.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 9522582891..3456add989 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -17,7 +17,7 @@ static void test_parse_cpu_set(void) { + /* Single value */ + assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.set); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_ISSET_S(0, c.allocated, c.set)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 1); + +@@ -33,7 +33,7 @@ static void test_parse_cpu_set(void) { + /* Simple range (from CPUAffinity example) */ + assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); + assert_se(c.set); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_ISSET_S(1, c.allocated, c.set)); + assert_se(CPU_ISSET_S(2, c.allocated, c.set)); + assert_se(CPU_ISSET_S(4, c.allocated, c.set)); +@@ -50,7 +50,7 @@ static void test_parse_cpu_set(void) { + + /* A more interesting range */ + assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -68,7 +68,7 @@ static void test_parse_cpu_set(void) { + + /* Quoted strings */ + assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 4); + for (cpu = 8; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -83,7 +83,7 @@ static void test_parse_cpu_set(void) { + + /* Use commas as separators */ + assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -96,7 +96,7 @@ static void test_parse_cpu_set(void) { + + /* Commas with spaces (and trailing comma, space) */ + assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 9); + for (cpu = 0; cpu < 8; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -113,7 +113,7 @@ static void test_parse_cpu_set(void) { + + /* Ranges */ + assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -126,7 +126,7 @@ static void test_parse_cpu_set(void) { + + /* Ranges with trailing comma, space */ + assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 8); + for (cpu = 0; cpu < 4; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -143,13 +143,13 @@ static void test_parse_cpu_set(void) { + + /* Negative range (returns empty cpu_set) */ + assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 0); + cpu_set_reset(&c); + + /* Overlapping ranges */ + assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 12); + for (cpu = 0; cpu < 12; cpu++) + assert_se(CPU_ISSET_S(cpu, c.allocated, c.set)); +@@ -164,7 +164,7 @@ static void test_parse_cpu_set(void) { + + /* Mix ranges and individual CPUs */ + assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0); +- assert_se(c.allocated >= sizeof(__cpu_mask) / 8); ++ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8)); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 10); + assert_se(CPU_ISSET_S(0, c.allocated, c.set)); + assert_se(CPU_ISSET_S(2, c.allocated, c.set)); diff --git a/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch b/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch new file mode 100644 index 0000000..cbb8483 --- /dev/null +++ b/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch @@ -0,0 +1,30 @@ +From 3cf9361996b796eae0bda12aec8c92ddae1d5d48 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 4 Jun 2019 09:40:38 +0200 +Subject: [PATCH] test-cpu-set-util: fix allocation size check on i386 + +We get just 28 bytes not 32 as on 64-bit architectures (__cpu_set_t is 4 bytes, +we need at least 26, so 28 satisfies the constraints). + +(cherry picked from commit 64412970ac0d4b6f5c4bbd8816edc9bff9eab2de) + +Related: #1734787 +--- + src/test/test-cpu-set-util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 3456add989..136eaca82d 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -256,7 +256,9 @@ static void test_cpu_set_to_from_dbus(void) { + assert_se(array); + assert_se(allocated == c.allocated); + +- assert(memcmp(array, expected, sizeof expected) == 0); ++ assert_se(allocated <= sizeof expected); ++ assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */ ++ assert(memcmp(array, expected, allocated) == 0); + + assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0); + assert_se(c2.set); diff --git a/SOURCES/0296-catalog-fix-name-of-variable.patch b/SOURCES/0296-catalog-fix-name-of-variable.patch new file mode 100644 index 0000000..1e752eb --- /dev/null +++ b/SOURCES/0296-catalog-fix-name-of-variable.patch @@ -0,0 +1,531 @@ +From c3513c7bcc27210c89edad1740e1190e693df86f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 15 Oct 2018 22:41:49 +0200 +Subject: [PATCH] catalog: fix name of variable + +All the messages would (literally) say "The start-up result is RESULT." +because @RESULT@ was not defined. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1639482 +and the first part of #8005. + +Fixup for 646cc98dc81c4d0edbc1b57e7bca0f474b47e270. + +(cherry picked from commit 65d51875c2a7b27b61de090f1bd6311b0cef2016) + +Resolves: #1677768 +--- + catalog/systemd.be.catalog.in | 6 +++--- + catalog/systemd.be@latin.catalog.in | 6 +++--- + catalog/systemd.bg.catalog.in | 6 +++--- + catalog/systemd.catalog.in | 6 +++--- + catalog/systemd.da.catalog.in | 6 +++--- + catalog/systemd.fr.catalog.in | 6 +++--- + catalog/systemd.hr.catalog.in | 6 +++--- + catalog/systemd.hu.catalog.in | 6 +++--- + catalog/systemd.it.catalog.in | 6 +++--- + catalog/systemd.ko.catalog.in | 6 +++--- + catalog/systemd.pl.catalog.in | 6 +++--- + catalog/systemd.pt_BR.catalog.in | 6 +++--- + catalog/systemd.ru.catalog.in | 6 +++--- + catalog/systemd.sr.catalog.in | 6 +++--- + catalog/systemd.zh_CN.catalog.in | 6 +++--- + catalog/systemd.zh_TW.catalog.in | 6 +++--- + 16 files changed, 48 insertions(+), 48 deletions(-) + +diff --git a/catalog/systemd.be.catalog.in b/catalog/systemd.be.catalog.in +index 5011ea268d..2c59898683 100644 +--- a/catalog/systemd.be.catalog.in ++++ b/catalog/systemd.be.catalog.in +@@ -175,7 +175,7 @@ Support: %SUPPORT_URL% + + Працэс запуску юніта @UNIT@ завершаны. + +-Вынік: @RESULT@. ++Вынік: @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Юніт @UNIT@ спыняецца +@@ -198,7 +198,7 @@ Support: %SUPPORT_URL% + + Збой юніта @UNIT@. + +-Вынік: @RESULT@. ++Вынік: @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Юніт @UNIT@ перачытвае сваю канфігурацыю +@@ -214,7 +214,7 @@ Support: %SUPPORT_URL% + + Юніт @UNIT@ перачытаў сваю канфігурацыю. + +-Вынік: @RESULT@. ++Вынік: @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Працэс @EXECUTABLE@ не можа быць выкананы +diff --git a/catalog/systemd.be@latin.catalog.in b/catalog/systemd.be@latin.catalog.in +index 6a8b092669..1d024fea12 100644 +--- a/catalog/systemd.be@latin.catalog.in ++++ b/catalog/systemd.be@latin.catalog.in +@@ -178,7 +178,7 @@ Support: %SUPPORT_URL% + + Praces zapusku junita @UNIT@ zavieršany. + +-Vynik: @RESULT@. ++Vynik: @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Junit @UNIT@ spyniajecca +@@ -201,7 +201,7 @@ Support: %SUPPORT_URL% + + Zboj junita @UNIT@. + +-Vynik: @RESULT@. ++Vynik: @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Junit @UNIT@ pieračytvaje svaju kanfihuracyju +@@ -217,7 +217,7 @@ Support: %SUPPORT_URL% + + Junit @UNIT@ pieračytaŭ svaju kanfihuracyju. + +-Vynik: @RESULT@. ++Vynik: @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Praces @EXECUTABLE@ nie moža być vykanany +diff --git a/catalog/systemd.bg.catalog.in b/catalog/systemd.bg.catalog.in +index 64d616f381..41f7b21bce 100644 +--- a/catalog/systemd.bg.catalog.in ++++ b/catalog/systemd.bg.catalog.in +@@ -178,7 +178,7 @@ Support: %SUPPORT_URL% + + Стартирането на модул „@UNIT@“ завърши. + +-Резултатът е: @RESULT@ ++Резултатът е: @JOB_RESULT@ + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Модул „@UNIT@“ се спира +@@ -201,7 +201,7 @@ Support: %SUPPORT_URL% + + Модулът „@UNIT@“ не успя да стартира. + +-Резултатът е: @RESULT@ ++Резултатът е: @JOB_RESULT@ + + -- d34d037fff1847e6ae669a370e694725 + Subject: Модулът „@UNIT@“ започна презареждане на настройките си +@@ -217,7 +217,7 @@ Support: %SUPPORT_URL% + + Модулът „@UNIT@“ завърши презареждането на настройките си. + +-Резултатът e: @RESULT@ ++Резултатът e: @JOB_RESULT@ + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Програмата „@EXECUTABLE@“ не успя да се стартира +diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in +index 8234e387cf..49a45890f6 100644 +--- a/catalog/systemd.catalog.in ++++ b/catalog/systemd.catalog.in +@@ -202,7 +202,7 @@ Support: %SUPPORT_URL% + + Unit @UNIT@ has finished starting up. + +-The start-up result is @RESULT@. ++The start-up result is @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Unit @UNIT@ has begun shutting down +@@ -225,7 +225,7 @@ Support: %SUPPORT_URL% + + Unit @UNIT@ has failed. + +-The result is @RESULT@. ++The result is @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Unit @UNIT@ has begun reloading its configuration +@@ -241,7 +241,7 @@ Support: %SUPPORT_URL% + + Unit @UNIT@ has finished reloading its configuration + +-The result is @RESULT@. ++The result is @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Process @EXECUTABLE@ could not be executed +diff --git a/catalog/systemd.da.catalog.in b/catalog/systemd.da.catalog.in +index 4e2bec8a0f..aecfafa05f 100644 +--- a/catalog/systemd.da.catalog.in ++++ b/catalog/systemd.da.catalog.in +@@ -159,7 +159,7 @@ Support: %SUPPORT_URL% + + Enhed @UNIT@ er færdig med at starte op. + +-Resultat for opstart er @RESULT@. ++Resultat for opstart er @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Enhed @UNIT@ har påbegyndt nedlukning +@@ -182,7 +182,7 @@ Support: %SUPPORT_URL% + + Enhed @UNIT@ har fejlet. + +-Resultatet er @RESULT@ ++Resultatet er @JOB_RESULT@ + + -- d34d037fff1847e6ae669a370e694725 + Subject: Enhed @UNIT@ har påbegyndt genindlæsning af sin konfiguration +@@ -198,7 +198,7 @@ Support: %SUPPORT_URL% + + Enhed @UNIT@ er færdig med at genindlæse sin konfiguration + +-Resultatet er: @RESULT@. ++Resultatet er: @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Process @EXECUTABLE@ kunne ikke eksekveres +diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in +index 156b1a37dc..13edd083cb 100644 +--- a/catalog/systemd.fr.catalog.in ++++ b/catalog/systemd.fr.catalog.in +@@ -191,7 +191,7 @@ Subject: L'unité (unit) @UNIT@ a terminé son démarrage + Defined-By: systemd + Support: %SUPPORT_URL% + +-L'unité (unit) @UNIT@ a terminé son démarrage, avec le résultat @RESULT@. ++L'unité (unit) @UNIT@ a terminé son démarrage, avec le résultat @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: L'unité (unit) @UNIT@ a commencé à s'arrêter +@@ -212,7 +212,7 @@ Subject: L'unité (unit) @UNIT@ a échoué + Defined-By: systemd + Support: %SUPPORT_URL% + +-L'unité (unit) @UNIT@ a échoué, avec le résultat @RESULT@. ++L'unité (unit) @UNIT@ a échoué, avec le résultat @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: L'unité (unit) @UNIT@ a commencé à recharger sa configuration +@@ -227,7 +227,7 @@ Defined-By: systemd + Support: %SUPPORT_URL% + + L'unité (unit) @UNIT@ a terminé de recharger configuration, +-avec le résultat @RESULT@. ++avec le résultat @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Le processus @EXECUTABLE@ n'a pas pu être exécuté +diff --git a/catalog/systemd.hr.catalog.in b/catalog/systemd.hr.catalog.in +index c4808b4c7d..4526ae2a8c 100644 +--- a/catalog/systemd.hr.catalog.in ++++ b/catalog/systemd.hr.catalog.in +@@ -173,7 +173,7 @@ Support: %SUPPORT_URL% + + Jedinica @UNIT@ je završila pokretanje. + +-Rezultat pokretanja je @RESULT@. ++Rezultat pokretanja je @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Jedinica @UNIT@ je započela isključivanje +@@ -196,7 +196,7 @@ Support: %SUPPORT_URL% + + Jedinica @UNIT@ nije uspjela. + +-Rezultat je @RESULT@. ++Rezultat je @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Jedinica @UNIT@ je započela ponovno učitavati podešavanja +@@ -212,7 +212,7 @@ Support: %SUPPORT_URL% + + Jedinica @UNIT@ je završila ponovno učitavati podešavanja + +-Rezultat je @RESULT@. ++Rezultat je @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Proces @EXECUTABLE@ se ne može pokrenuti +diff --git a/catalog/systemd.hu.catalog.in b/catalog/systemd.hu.catalog.in +index 6c6d7e7934..5565b80b2a 100644 +--- a/catalog/systemd.hu.catalog.in ++++ b/catalog/systemd.hu.catalog.in +@@ -161,7 +161,7 @@ Support: %SUPPORT_URL% + + A(z) @UNIT@ egység befejezte az indulást + +-Az indítás eredménye: @RESULT@. ++Az indítás eredménye: @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: A(z) @UNIT@ egység megkezdte a leállást +@@ -184,7 +184,7 @@ Support: %SUPPORT_URL% + + A(z) @UNIT@ egység hibát jelzett. + +-Az eredmény: @RESULT@. ++Az eredmény: @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: A(z) @UNIT@ egység megkezdte a beállításainak újratöltését +@@ -200,7 +200,7 @@ Support: %SUPPORT_URL% + + A(z) @UNIT@ egység befejezte a beállításainak újratöltését. + +-Az eredmény: @RESULT@. ++Az eredmény: @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: A folyamat végrehajtása sikertelen: @EXECUTABLE@ +diff --git a/catalog/systemd.it.catalog.in b/catalog/systemd.it.catalog.in +index 4fd1f2a933..8ce4fa5d92 100644 +--- a/catalog/systemd.it.catalog.in ++++ b/catalog/systemd.it.catalog.in +@@ -191,7 +191,7 @@ Support: %SUPPORT_URL% + + L'unità @UNIT@ ha terminato la fase di avvio. + +-La fase di avvio è @RESULT@. ++La fase di avvio è @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: L'unità @UNIT@ inizia la fase di spegnimento +@@ -214,7 +214,7 @@ Support: %SUPPORT_URL% + + L'unità @UNIT@ è fallita. + +-Il risultato è @RESULT@. ++Il risultato è @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: L'unità @UNIT@ inizia a caricare la propria configurazione +@@ -230,7 +230,7 @@ Support: %SUPPORT_URL% + + L'unità @UNIT@ è terminata ricaricando la propria configurazione + +-Il risultato è @RESULT@. ++Il risultato è @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Il processo @EXECUTABLE@ non può essere eseguito +diff --git a/catalog/systemd.ko.catalog.in b/catalog/systemd.ko.catalog.in +index fc0faad02c..59fbde8b62 100644 +--- a/catalog/systemd.ko.catalog.in ++++ b/catalog/systemd.ko.catalog.in +@@ -182,7 +182,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 유닛 시동을 마쳤습니다. + +-시동 결과는 @RESULT@ 입니다. ++시동 결과는 @JOB_RESULT@ 입니다. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: @UNIT@ 유닛 끝내기 동작 시작 +@@ -205,7 +205,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 유닛 동작에 실패했습니다. + +-결과는 @RESULT@ 입니다. ++결과는 @JOB_RESULT@ 입니다. + + -- d34d037fff1847e6ae669a370e694725 + Subject: @UNIT@ 유닛 설정 다시 읽기 시작 +@@ -221,7 +221,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 유닛의 설정 다시 읽기 동작을 끝냈습니다. + +-결과는 @RESULT@ 입니다. ++결과는 @JOB_RESULT@ 입니다. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: @EXECUTABLE@ 프로세스 시작할 수 없음 +diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in +index 998894bd0a..b73f56ca11 100644 +--- a/catalog/systemd.pl.catalog.in ++++ b/catalog/systemd.pl.catalog.in +@@ -201,7 +201,7 @@ Support: %SUPPORT_URL% + + Jednostka @UNIT@ ukończyła uruchamianie. + +-Wynik uruchamiania: @RESULT@. ++Wynik uruchamiania: @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Rozpoczęto wyłączanie jednostki @UNIT@ +@@ -224,7 +224,7 @@ Support: %SUPPORT_URL% + + Jednostka @UNIT@ się nie powiodła. + +-Wynik: @RESULT@. ++Wynik: @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Rozpoczęto ponowne wczytywanie konfiguracji jednostki @UNIT@ +@@ -240,7 +240,7 @@ Support: %SUPPORT_URL% + + Jednostka @UNIT@ ukończyła ponowne wczytywanie swojej konfiguracji. + +-Wynik: @RESULT@. ++Wynik: @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Nie można wykonać procesu @EXECUTABLE@ +diff --git a/catalog/systemd.pt_BR.catalog.in b/catalog/systemd.pt_BR.catalog.in +index db1cb03198..edaefb7164 100644 +--- a/catalog/systemd.pt_BR.catalog.in ++++ b/catalog/systemd.pt_BR.catalog.in +@@ -162,7 +162,7 @@ Support: %SUPPORT_URL% + + A unidade @UNIT@ concluiu a inicialização. + +-The start-up result is @RESULT@. ++The start-up result is @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Unidade @UNIT@ sendo desligado +@@ -185,7 +185,7 @@ Support: %SUPPORT_URL% + + A unidade @UNIT@ falhou. + +-O resultado é @RESULT@. ++O resultado é @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Unidade @UNIT@ iniciou recarregamento de sua configuração +@@ -201,7 +201,7 @@ Support: %SUPPORT_URL% + + A unidade @UNIT@ concluiu o recarregamento de sua configuração. + +-O resultado é @RESULT@. ++O resultado é @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Processo @EXECUTABLE@ não pôde ser executado +diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in +index 645edaa922..ccdc685037 100644 +--- a/catalog/systemd.ru.catalog.in ++++ b/catalog/systemd.ru.catalog.in +@@ -227,7 +227,7 @@ Support: %SUPPORT_URL% + + Процесс запуска юнита @UNIT@ был завершен. + +-Результат: @RESULT@. ++Результат: @JOB_RESULT@. + + # Subject: Unit @UNIT@ has begun shutting down + -- de5b426a63be47a7b6ac3eaac82e2f6f +@@ -253,7 +253,7 @@ Support: %SUPPORT_URL% + + Произошел сбой юнита @UNIT@. + +-Результат: @RESULT@. ++Результат: @JOB_RESULT@. + + # Subject: Unit @UNIT@ has begun with reloading its configuration + -- d34d037fff1847e6ae669a370e694725 +@@ -271,7 +271,7 @@ Support: %SUPPORT_URL% + + Юнит @UNIT@ завершил процесс перечитывания своей конфигурации. + +-Результат: @RESULT@. ++Результат: @JOB_RESULT@. + + # Subject: Process @EXECUTABLE@ could not be executed + -- 641257651c1b4ec9a8624d7a40a9e1e7 +diff --git a/catalog/systemd.sr.catalog.in b/catalog/systemd.sr.catalog.in +index f5746715a4..7cb6546d43 100644 +--- a/catalog/systemd.sr.catalog.in ++++ b/catalog/systemd.sr.catalog.in +@@ -158,7 +158,7 @@ Support: %SUPPORT_URL% + + Јединица @UNIT@ је завршила са покретањем. + +-Исход покретања је @RESULT@. ++Исход покретања је @JOB_RESULT@. + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: Јединица @UNIT@ је почела са гашењем +@@ -181,7 +181,7 @@ Support: %SUPPORT_URL% + + Јединица @UNIT@ је пукла. + +-Исход је @RESULT@. ++Исход је @JOB_RESULT@. + + -- d34d037fff1847e6ae669a370e694725 + Subject: Јединица @UNIT@ је почела са поновним учитавањем свог подешавања +@@ -197,7 +197,7 @@ Support: %SUPPORT_URL% + + Јединица @UNIT@ је завршила са поновним учитавањем свог подешавања + +-Исход је @RESULT@. ++Исход је @JOB_RESULT@. + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: Процес @EXECUTABLE@ није могао бити извршен +diff --git a/catalog/systemd.zh_CN.catalog.in b/catalog/systemd.zh_CN.catalog.in +index fa58448acf..d6ac2592b8 100644 +--- a/catalog/systemd.zh_CN.catalog.in ++++ b/catalog/systemd.zh_CN.catalog.in +@@ -156,7 +156,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 单元已结束启动。 + +-启动结果为“@RESULT@”。 ++启动结果为“@JOB_RESULT@”。 + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: @UNIT@ 单元已开始停止操作 +@@ -179,7 +179,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 单元已失败。 + +-结果为“@RESULT@”。 ++结果为“@JOB_RESULT@”。 + + -- d34d037fff1847e6ae669a370e694725 + Subject: @UNIT@ 单元已开始重新载入其配置 +@@ -195,7 +195,7 @@ Support: %SUPPORT_URL% + + @UNIT@ 单元已结束配置重载入操作。 + +-结果为“@RESULT@”。 ++结果为“@JOB_RESULT@”。 + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: 进程 @EXECUTABLE@ 无法执行 +diff --git a/catalog/systemd.zh_TW.catalog.in b/catalog/systemd.zh_TW.catalog.in +index 17bd2bc9af..a468c2f6bf 100644 +--- a/catalog/systemd.zh_TW.catalog.in ++++ b/catalog/systemd.zh_TW.catalog.in +@@ -160,7 +160,7 @@ Support: %SUPPORT_URL% + + 單位 @UNIT@ 啟動已結束。 + +-啟動結果為 @RESULT@。 ++啟動結果為 @JOB_RESULT@。 + + -- de5b426a63be47a7b6ac3eaac82e2f6f + Subject: 單位 @UNIT@ 已開始關閉 +@@ -183,7 +183,7 @@ Support: %SUPPORT_URL% + + 單位 @UNIT@ 已失敗。 + +-結果為 @RESULT@。 ++結果為 @JOB_RESULT@。 + + -- d34d037fff1847e6ae669a370e694725 + Subject: 單位 @UNIT@ 已開始重新載入其設定 +@@ -199,7 +199,7 @@ Support: %SUPPORT_URL% + + 單位 @UNIT@ 已結束重新載入其設定 + +-結果為 @RESULT@。 ++結果為 @JOB_RESULT@。 + + -- 641257651c1b4ec9a8624d7a40a9e1e7 + Subject: 行程 @EXECUTABLE@ 無法執行 diff --git a/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch b/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch new file mode 100644 index 0000000..8e99e2f --- /dev/null +++ b/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch @@ -0,0 +1,273 @@ +From 0f7a4f49a7ce95e87061afe03ac40662a1eb0e2d Mon Sep 17 00:00:00 2001 +From: shinygold <10763595+shinygold@users.noreply.github.com> +Date: Tue, 16 Jul 2019 13:06:16 +0200 +Subject: [PATCH] cryptsetup: add keyfile-timeout to allow a keydev timeout and + allow to fallback to a password if it fails. + +(cherry picked from commit 50d2eba27b9bfc77ef6b40e5721713846815418b) + +Resolves: #1763155 +--- + src/cryptsetup/cryptsetup-generator.c | 119 ++++++++++++++++++-------- + src/cryptsetup/cryptsetup.c | 5 +- + 2 files changed, 89 insertions(+), 35 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 52c1262728..1e8e3ba00d 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -40,10 +40,39 @@ static Hashmap *arg_disks = NULL; + static char *arg_default_options = NULL; + static char *arg_default_keyfile = NULL; + +-static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) { +- _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL; ++static int split_keyspec(const char *keyspec, char **keyfile, char **keydev) { ++ _cleanup_free_ char *kfile = NULL, *kdev = NULL; ++ char *c; ++ ++ assert(keyspec); ++ assert(keyfile); ++ assert(keydev); ++ ++ c = strrchr(keyspec, ':'); ++ if (c) { ++ kfile = strndup(keyspec, c-keyspec); ++ kdev = strdup(c + 1); ++ if (!*kfile || !*kdev) ++ return log_oom(); ++ } else { ++ /* No keydev specified */ ++ kfile = strdup(keyspec); ++ kdev = NULL; ++ if (!*kfile) ++ return log_oom(); ++ } ++ ++ *keyfile = TAKE_PTR(kfile); ++ *keydev = TAKE_PTR(kdev); ++ ++ return 0; ++} ++ ++static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) { ++ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; ++ usec_t timeout_us; + + assert(name); + assert(keydev); +@@ -88,7 +117,25 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un + "[Mount]\n" + "What=%s\n" + "Where=%s\n" +- "Options=ro\n", what, where); ++ "Options=ro%s\n", what, where, canfail ? ",nofail" : ""); ++ ++ if (keydev_timeout) { ++ r = parse_sec_fix_0(keydev_timeout, &timeout_us); ++ if (r >= 0) { ++ r = unit_name_from_path(what, ".device", &device_unit); ++ if (r < 0) ++ return log_error_errno(r, "Failed to generate unit name: %m"); ++ ++ r = write_drop_in_format(arg_dest, device_unit, 90, "device-timeout", ++ "# Automatically generated by systemd-cryptsetup-generator \n\n" ++ "[Unit]\nJobRunningTimeoutSec=%s", keydev_timeout); ++ if (r < 0) ++ return log_error_errno(r, "Failed to write device drop-in: %m"); ++ ++ } else ++ log_warning_errno(r, "Failed to parse %s, ignoring: %m", keydev_timeout); ++ ++ } + + r = fflush_and_check(f); + if (r < 0) +@@ -103,16 +150,17 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un + static int create_disk( + const char *name, + const char *device, +- const char *keydev, + const char *password, ++ const char *keydev, + const char *options) { + + _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL, +- *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *keydev_mount = NULL; ++ *keydev_mount = NULL, *keyfile_timeout_value = NULL, *password_escaped = NULL, ++ *filtered = NULL, *u_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL; + _cleanup_fclose_ FILE *f = NULL; + const char *dmname; + bool noauto, nofail, tmp, swap, netdev; +- int r; ++ int r, keyfile_can_timeout; + + assert(name); + assert(device); +@@ -123,6 +171,10 @@ static int create_disk( + swap = fstab_test_option(options, "swap\0"); + netdev = fstab_test_option(options, "_netdev\0"); + ++ keyfile_can_timeout = fstab_filter_options(options, "keyfile-timeout\0", NULL, &keyfile_timeout_value, NULL); ++ if (keyfile_can_timeout < 0) ++ return log_error_errno(keyfile_can_timeout, "Failed to parse keyfile-timeout= option value: %m"); ++ + if (tmp && swap) { + log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); + return -EINVAL; +@@ -152,12 +204,6 @@ static int create_disk( + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + +- if (password) { +- password_escaped = specifier_escape(password); +- if (!password_escaped) +- return log_oom(); +- } +- + if (keydev && !password) { + log_error("Key device is specified, but path to the password file is missing."); + return -EINVAL; +@@ -178,10 +224,16 @@ static int create_disk( + "After=%s\n", + netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target"); + ++ if (password) { ++ password_escaped = specifier_escape(password); ++ if (!password_escaped) ++ return log_oom(); ++ } ++ + if (keydev) { + _cleanup_free_ char *unit = NULL, *p = NULL; + +- r = generate_keydev_mount(name, keydev, &unit, &keydev_mount); ++ r = generate_keydev_mount(name, keydev, keyfile_timeout_value, keyfile_can_timeout > 0, &unit, &keydev_mount); + if (r < 0) + return log_error_errno(r, "Failed to generate keydev mount unit: %m"); + +@@ -190,6 +242,12 @@ static int create_disk( + return log_oom(); + + free_and_replace(password_escaped, p); ++ ++ fprintf(f, "After=%s\n", unit); ++ if (keyfile_can_timeout > 0) ++ fprintf(f, "Wants=%s\n", unit); ++ else ++ fprintf(f, "Requires=%s\n", unit); + } + + if (!nofail) +@@ -197,7 +255,7 @@ static int create_disk( + "Before=%s\n", + netdev ? "remote-cryptsetup.target" : "cryptsetup.target"); + +- if (password) { ++ if (password && !keydev) { + if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random")) + fputs("After=systemd-random-seed.service\n", f); + else if (!STR_IN_SET(password, "-", "none")) { +@@ -271,7 +329,7 @@ static int create_disk( + + if (keydev) + fprintf(f, +- "ExecStartPost=" UMOUNT_PATH " %s\n\n", ++ "ExecStartPost=-" UMOUNT_PATH " %s\n\n", + keydev_mount); + + r = fflush_and_check(f); +@@ -394,7 +452,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + } else if (streq(key, "luks.key")) { + size_t n; + _cleanup_free_ char *keyfile = NULL, *keydev = NULL; +- char *c; + const char *keyspec; + + if (proc_cmdline_value_missing(key, value)) +@@ -421,23 +478,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + return log_oom(); + + keyspec = value + n + 1; +- c = strrchr(keyspec, ':'); +- if (c) { +- *c = '\0'; +- keyfile = strdup(keyspec); +- keydev = strdup(c + 1); +- +- if (!keyfile || !keydev) +- return log_oom(); +- } else { +- /* No keydev specified */ +- keyfile = strdup(keyspec); +- if (!keyfile) +- return log_oom(); +- } ++ r = split_keyspec(keyspec, &keyfile, &keydev); ++ if (r < 0) ++ return r; + + free_and_replace(d->keyfile, keyfile); + free_and_replace(d->keydev, keydev); ++ + } else if (streq(key, "luks.name")) { + + if (proc_cmdline_value_missing(key, value)) +@@ -485,7 +532,7 @@ static int add_crypttab_devices(void) { + int r, k; + char line[LINE_MAX], *l, *uuid; + crypto_device *d = NULL; +- _cleanup_free_ char *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL; ++ _cleanup_free_ char *name = NULL, *device = NULL, *keydev = NULL, *keyfile = NULL, *keyspec = NULL, *options = NULL; + + if (!fgets(line, sizeof(line), f)) + break; +@@ -496,7 +543,7 @@ static int add_crypttab_devices(void) { + if (IN_SET(*l, 0, '#')) + continue; + +- k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyfile, &options); ++ k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyspec, &options); + if (k < 2 || k > 4) { + log_error("Failed to parse /etc/crypttab:%u, ignoring.", crypttab_line); + continue; +@@ -515,7 +562,11 @@ static int add_crypttab_devices(void) { + continue; + } + +- r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options); ++ r = split_keyspec(keyspec, &keyfile, &keydev); ++ if (r < 0) ++ return r; ++ ++ r = create_disk(name, device, keyfile, keydev, (d && d->options) ? d->options : options); + if (r < 0) + return r; + +@@ -555,7 +606,7 @@ static int add_proc_cmdline_devices(void) { + else + options = "timeout=0"; + +- r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options); ++ r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, d->keydev, options); + if (r < 0) + return r; + } +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 9071126c2e..0881aea915 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -69,7 +69,10 @@ static int parse_one_option(const char *option) { + assert(option); + + /* Handled outside of this tool */ +- if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev")) ++ if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev", "keyfile-timeout")) ++ return 0; ++ ++ if (startswith(option, "keyfile-timeout=")) + return 0; + + if ((val = startswith(option, "cipher="))) { diff --git a/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch b/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch new file mode 100644 index 0000000..c43658a --- /dev/null +++ b/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch @@ -0,0 +1,44 @@ +From fdb86185b56619c59602c6546fd0710eec4a6e85 Mon Sep 17 00:00:00 2001 +From: shinygold <10763595+shinygold@users.noreply.github.com> +Date: Tue, 16 Jul 2019 13:05:34 +0200 +Subject: [PATCH] cryptsetup: add documentation for keyfile-timeout + +(cherry picked from commit 4e1334512debb27f4a0c4a6da237a4b8d59fea08) + +Related: #1763155 +--- + man/crypttab.xml | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/man/crypttab.xml b/man/crypttab.xml +index 3574ce00da..6074315980 100644 +--- a/man/crypttab.xml ++++ b/man/crypttab.xml +@@ -150,6 +150,17 @@ + sequential order. + + ++ ++ ++ ++ Specifies the timeout for the device on ++ which the key file resides and falls back to a password if ++ it could not be mounted. See ++ systemd-cryptsetup-generator8 ++ for key files on external devices. ++ ++ ++ + + + +@@ -417,7 +428,8 @@ + luks UUID=2505567a-9e27-4efe-a4d5-15ad146c258b + swap /dev/sda7 /dev/urandom swap + truecrypt /dev/sda2 /etc/container_password tcrypt +-hidden /mnt/tc_hidden /dev/null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile ++hidden /mnt/tc_hidden /dev/null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile ++external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s + + + diff --git a/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch b/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch new file mode 100644 index 0000000..be86edd --- /dev/null +++ b/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch @@ -0,0 +1,63 @@ +From 0577d8378645c1ecd909b74403cefe31ed569398 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 1 Aug 2019 08:13:13 +0200 +Subject: [PATCH] cryptsetup: use unabbrieviated variable names + +Now that "ret_" has been added to the output variables, we can name +the internal variables without artificial abbrevs. + +(cherry picked from commit 5d2100dc4c32abbce4109e75cbfbbef6e1b2b7b1) + +Related: #1763155 +--- + src/cryptsetup/cryptsetup-generator.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 1e8e3ba00d..7b234e37be 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -40,30 +40,30 @@ static Hashmap *arg_disks = NULL; + static char *arg_default_options = NULL; + static char *arg_default_keyfile = NULL; + +-static int split_keyspec(const char *keyspec, char **keyfile, char **keydev) { +- _cleanup_free_ char *kfile = NULL, *kdev = NULL; +- char *c; ++static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_keydev) { ++ _cleanup_free_ char *keyfile = NULL, *keydev = NULL; ++ const char *c; + + assert(keyspec); +- assert(keyfile); +- assert(keydev); ++ assert(ret_keyfile); ++ assert(ret_keydev); + + c = strrchr(keyspec, ':'); + if (c) { +- kfile = strndup(keyspec, c-keyspec); +- kdev = strdup(c + 1); +- if (!*kfile || !*kdev) ++ keyfile = strndup(keyspec, c-keyspec); ++ keydev = strdup(c + 1); ++ if (!keyfile || !keydev) + return log_oom(); + } else { + /* No keydev specified */ +- kfile = strdup(keyspec); +- kdev = NULL; +- if (!*kfile) ++ keyfile = strdup(keyspec); ++ keydev = NULL; ++ if (!keyfile) + return log_oom(); + } + +- *keyfile = TAKE_PTR(kfile); +- *keydev = TAKE_PTR(kdev); ++ *ret_keyfile = TAKE_PTR(keyfile); ++ *ret_keydev = TAKE_PTR(keydev); + + return 0; + } diff --git a/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch b/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch new file mode 100644 index 0000000..7154dca --- /dev/null +++ b/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch @@ -0,0 +1,37 @@ +From 5cdb2b0b2a0f8f89f97053b0633b8419506d4e28 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 1 Aug 2019 08:15:43 +0200 +Subject: [PATCH] cryptsetup: don't assert on variable which is optional + +https://github.com/systemd/systemd/commit/50d2eba27b9bfc77ef6b40e5721713846815418b#commitcomment-34519739 + +In add_crypttab_devices() split_keyspec is called on the keyfile argument, +which may be NULL. + +(cherry picked from commit fef716b28be6e866b8afe995805d5ebe2af6bbfa) + +Related: #1763155 +--- + src/cryptsetup/cryptsetup-generator.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index 7b234e37be..a09983b576 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -44,10 +44,14 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key + _cleanup_free_ char *keyfile = NULL, *keydev = NULL; + const char *c; + +- assert(keyspec); + assert(ret_keyfile); + assert(ret_keydev); + ++ if (!keyspec) { ++ *ret_keyfile = *ret_keydev = NULL; ++ return 0; ++ } ++ + c = strrchr(keyspec, ':'); + if (c) { + keyfile = strndup(keyspec, c-keyspec); diff --git a/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch b/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch new file mode 100644 index 0000000..0f394ac --- /dev/null +++ b/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch @@ -0,0 +1,100 @@ +From 9040e15cd3cba546b47aeae0ea133afa1a6ad292 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 13 Nov 2019 10:32:30 +0100 +Subject: [PATCH] cryptsetup-generator: guess whether the keyfile argument is + two items or one + +Fixes #13615. + +See the inline comment for documentation. + +(cherry picked from commit 32c6237a7c2e697d2fc4f3403319db16858fb8e3) + +Related: #1763155 +--- + src/cryptsetup/cryptsetup-generator.c | 45 ++++++++++++++++++--------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c +index a09983b576..4117930925 100644 +--- a/src/cryptsetup/cryptsetup-generator.c ++++ b/src/cryptsetup/cryptsetup-generator.c +@@ -54,17 +54,36 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key + + c = strrchr(keyspec, ':'); + if (c) { +- keyfile = strndup(keyspec, c-keyspec); +- keydev = strdup(c + 1); +- if (!keyfile || !keydev) ++ /* The keydev part has to be either an absolute path to device node (/dev/something, ++ * /dev/foo/something, or even possibly /dev/foo/something:part), or a fstab device ++ * specification starting with LABEL= or similar. The keyfile part has the same syntax. ++ * ++ * Let's try to guess if the second part looks like a keydev specification, or just part of a ++ * filename with a colon. fstab_node_to_udev_node() will convert the fstab device syntax to ++ * an absolute path. If we didn't get an absolute path, assume that it is just part of the ++ * first keyfile argument. */ ++ ++ keydev = fstab_node_to_udev_node(c + 1); ++ if (!keydev) + return log_oom(); +- } else { ++ ++ if (path_is_absolute(keydev)) ++ keyfile = strndup(keyspec, c-keyspec); ++ else { ++ log_debug("Keyspec argument contains a colon, but \"%s\" doesn't look like a device specification.\n" ++ "Assuming that \"%s\" is a single device specification.", ++ c + 1, keyspec); ++ keydev = mfree(keydev); ++ c = NULL; ++ } ++ } ++ ++ if (!c) + /* No keydev specified */ + keyfile = strdup(keyspec); +- keydev = NULL; +- if (!keyfile) +- return log_oom(); +- } ++ ++ if (!keyfile) ++ return log_oom(); + + *ret_keyfile = TAKE_PTR(keyfile); + *ret_keydev = TAKE_PTR(keydev); +@@ -73,7 +92,7 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key + } + + static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) { +- _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL; ++ _cleanup_free_ char *u = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; + usec_t timeout_us; +@@ -111,22 +130,18 @@ static int generate_keydev_mount(const char *name, const char *keydev, const cha + if (r < 0) + return r; + +- what = fstab_node_to_udev_node(keydev); +- if (!what) +- return -ENOMEM; +- + fprintf(f, + "[Unit]\n" + "DefaultDependencies=no\n\n" + "[Mount]\n" + "What=%s\n" + "Where=%s\n" +- "Options=ro%s\n", what, where, canfail ? ",nofail" : ""); ++ "Options=ro%s\n", keydev, where, canfail ? ",nofail" : ""); + + if (keydev_timeout) { + r = parse_sec_fix_0(keydev_timeout, &timeout_us); + if (r >= 0) { +- r = unit_name_from_path(what, ".device", &device_unit); ++ r = unit_name_from_path(keydev, ".device", &device_unit); + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + diff --git a/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch b/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch new file mode 100644 index 0000000..f7c2454 --- /dev/null +++ b/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch @@ -0,0 +1,46 @@ +From 05e184dea3f0182e5787812adfd52b68cff9418d Mon Sep 17 00:00:00 2001 +From: Jan Janssen +Date: Mon, 25 Jun 2018 20:33:31 +0200 +Subject: [PATCH] crypt-util: Translate libcryptsetup log level instead of + using log_debug() + +This makes sure that errors reported by libcryptsetup are shown to the +user instead of getting swallowed up by log_debug(). + +(cherry picked from commit aa2cc005d77890b07e8c579f25e1333ff8ba8dac) + +Resolves: #1776408 +--- + src/basic/crypt-util.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/src/basic/crypt-util.c b/src/basic/crypt-util.c +index b181ba3ba0..20bdc5489e 100644 +--- a/src/basic/crypt-util.c ++++ b/src/basic/crypt-util.c +@@ -5,6 +5,24 @@ + #include "log.h" + + void cryptsetup_log_glue(int level, const char *msg, void *usrptr) { +- log_debug("%s", msg); ++ switch (level) { ++ case CRYPT_LOG_NORMAL: ++ level = LOG_NOTICE; ++ break; ++ case CRYPT_LOG_ERROR: ++ level = LOG_ERR; ++ break; ++ case CRYPT_LOG_VERBOSE: ++ level = LOG_INFO; ++ break; ++ case CRYPT_LOG_DEBUG: ++ level = LOG_DEBUG; ++ break; ++ default: ++ log_error("Unknown libcryptsetup log level: %d", level); ++ level = LOG_ERR; ++ } ++ ++ log_full(level, "%s", msg); + } + #endif diff --git a/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch b/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch new file mode 100644 index 0000000..e8f6f83 --- /dev/null +++ b/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch @@ -0,0 +1,25 @@ +From ea0c4c31f6dff7d01e585bd8d5f962b373844544 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Jan 2019 20:13:11 +0100 +Subject: [PATCH] cryptsetup: add some commenting about EAGAIN generation + +(cherry picked from commit b7a0fead10959b03a1fa642a5ae7aca3a6a3dee9) + +Related: #1776408 +--- + src/cryptsetup/cryptsetup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 0881aea915..f2b2557497 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -455,7 +455,7 @@ static int attach_tcrypt( + r = read_one_line_file(key_file, &passphrase); + if (r < 0) { + log_error_errno(r, "Failed to read password file '%s': %m", key_file); +- return -EAGAIN; ++ return -EAGAIN; /* log with the actual error, but return EAGAIN */ + } + + params.passphrase = passphrase; diff --git a/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch b/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch new file mode 100644 index 0000000..cd853ee --- /dev/null +++ b/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch @@ -0,0 +1,25 @@ +From 3bbacfb22a9266769a41dee6f8f594fbeb6287fc Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Jan 2019 20:19:57 +0100 +Subject: [PATCH] cryptsetup: downgrade a log message we ignore + +(cherry picked from commit 44ce4255147ab308c1f13580147c693204c322e8) + +Related: #1776408 +--- + src/cryptsetup/cryptsetup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index f2b2557497..53fe04a73f 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -621,7 +621,7 @@ int main(int argc, char *argv[]) { + !streq(argv[4], "none")) { + + if (!path_is_absolute(argv[4])) +- log_error("Password file path '%s' is not absolute. Ignoring.", argv[4]); ++ log_warning("Password file path '%s' is not absolute. Ignoring.", argv[4]); + else + key_file = argv[4]; + } diff --git a/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch b/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch new file mode 100644 index 0000000..5b357c3 --- /dev/null +++ b/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch @@ -0,0 +1,102 @@ +From 966ecf0011a02c7823083a7868b8589fdf850be8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Jan 2019 20:20:35 +0100 +Subject: [PATCH] cryptsetup: rework how we log about activation failures + +First of all let's always log where the errors happen, and not in an +upper stackframe, in all cases. Previously we'd do this somethis one way +and sometimes another, which resulted in sometimes duplicate logging and +sometimes none. + +When we cannot activate something due to bad password the kernel gives +us EPERM. Let's uniformly return this EAGAIN, so tha the next password +is tried. (previously this was done in most cases but not in all) + +When we get EPERM let's also explicitly indicate that this probably +means the password is simply wrong. + +Fixes: #11498 +(cherry picked from commit 6f177c7dc092eb68762b4533d41b14244adb2a73) + +Related: #1776408 +--- + src/cryptsetup/cryptsetup.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 53fe04a73f..33c215eaa1 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -469,10 +469,15 @@ static int attach_tcrypt( + log_error("Failed to activate using password file '%s'.", key_file); + return -EAGAIN; + } +- return r; ++ ++ return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", crypt_get_device_name(cd)); + } + +- return crypt_activate_by_volume_key(cd, name, NULL, 0, flags); ++ r = crypt_activate_by_volume_key(cd, name, NULL, 0, flags); ++ if (r < 0) ++ return log_error_errno(r, "Failed to activate tcrypt device %s: %m", crypt_get_device_name(cd)); ++ ++ return 0; + } + + static int attach_luks_or_plain(struct crypt_device *cd, +@@ -549,22 +554,30 @@ static int attach_luks_or_plain(struct crypt_device *cd, + + if (key_file) { + r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags); +- if (r < 0) { +- log_error_errno(r, "Failed to activate with key file '%s': %m", key_file); +- return -EAGAIN; ++ if (r == -EPERM) { ++ log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); ++ return -EAGAIN; /* Log actual error, but return EAGAIN */ + } ++ if (r < 0) ++ return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file); + } else { + char **p; + ++ r = -EINVAL; + STRV_FOREACH(p, passwords) { + if (pass_volume_key) + r = crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags); + else + r = crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags); +- + if (r >= 0) + break; + } ++ if (r == -EPERM) { ++ log_error_errno(r, "Failed to activate with specified passphrase. (Passphrase incorrect?)"); ++ return -EAGAIN; /* log actual error, but return EAGAIN */ ++ } ++ if (r < 0) ++ return log_error_errno(r, "Failed to activate with specified passphrase: %m"); + } + + return r; +@@ -726,16 +739,11 @@ int main(int argc, char *argv[]) { + flags); + if (r >= 0) + break; +- if (r == -EAGAIN) { +- key_file = NULL; +- continue; +- } +- if (r != -EPERM) { +- log_error_errno(r, "Failed to activate: %m"); ++ if (r != -EAGAIN) + goto finish; +- } + +- log_warning("Invalid passphrase."); ++ /* Passphrase not correct? Let's try again! */ ++ key_file = NULL; + } + + if (arg_tries != 0 && tries >= arg_tries) { diff --git a/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch b/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch new file mode 100644 index 0000000..2451c00 --- /dev/null +++ b/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch @@ -0,0 +1,41 @@ +From b7f9d757dd6f276203b8b04f0c0ba1c61bcf8937 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 18 Dec 2019 09:41:29 +0100 +Subject: [PATCH] rules: reintroduce 60-alias-kmsg.rules + +Resolves:#1739353 +rhel-only +--- + rules/60-alias-kmsg.rules | 10 ++++++++++ + rules/meson.build | 1 + + 2 files changed, 11 insertions(+) + create mode 100644 rules/60-alias-kmsg.rules + +diff --git a/rules/60-alias-kmsg.rules b/rules/60-alias-kmsg.rules +new file mode 100644 +index 0000000000..9c7236a730 +--- /dev/null ++++ b/rules/60-alias-kmsg.rules +@@ -0,0 +1,10 @@ ++SUBSYSTEM!="block", GOTO="log_end" ++KERNEL=="loop*|ram*", GOTO="log_end" ++ACTION=="remove", GOTO="log_end" ++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="log_end" ++ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="log_end" ++ ++IMPORT{cmdline}="udev.alias" ++ENV{udev.alias}=="1", RUN+="/bin/sh -c 'echo udev-alias: $name \($links\) > /dev/kmsg'" ++ ++LABEL="log_end" +diff --git a/rules/meson.build b/rules/meson.build +index 6363f8bf2e..7b5b2472de 100644 +--- a/rules/meson.build ++++ b/rules/meson.build +@@ -3,6 +3,7 @@ + rules = files(''' + 40-redhat.rules + 40-elevator.rules ++ 60-alias-kmsg.rules + 60-block.rules + 60-cdrom_id.rules + 60-drm.rules diff --git a/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch b/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch new file mode 100644 index 0000000..65374a7 --- /dev/null +++ b/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch @@ -0,0 +1,49 @@ +From 1d8e642b0b67f07b0bf469c25126b878380bae6a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:13:03 +0100 +Subject: [PATCH] sd-bus: make rqueue/wqueue sizes of type size_t + +Let's do this like we usually do and size arrays with size_t. + +We already do this for the "allocated" counter correctly, and externally +we expose the queue sizes as uint64_t anyway, hence there's really no +point in usigned "unsigned" internally. + +(cherry picked from commit 143d4e045a798ccc87889b2a8a60d7fbe44be441) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/bus-internal.h | 4 ++-- + src/libsystemd/sd-bus/sd-bus.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 5d773b14c4..06bd7862cb 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -221,11 +221,11 @@ struct sd_bus { + size_t rbuffer_size; + + sd_bus_message **rqueue; +- unsigned rqueue_size; ++ size_t rqueue_size; + size_t rqueue_allocated; + + sd_bus_message **wqueue; +- unsigned wqueue_size; ++ size_t wqueue_size; + size_t windex; + size_t wqueue_allocated; + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 1c9e967ae0..64026f7ee1 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2080,7 +2080,7 @@ _public_ int sd_bus_call( + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m); + usec_t timeout; + uint64_t cookie; +- unsigned i; ++ size_t i; + int r; + + bus_assert_return(m, -EINVAL, error); diff --git a/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch b/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch new file mode 100644 index 0000000..89004d8 --- /dev/null +++ b/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch @@ -0,0 +1,51 @@ +From 9c23ceef0a08ffdf4aed7a96ec440e1b110568ac Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:14:17 +0100 +Subject: [PATCH] sd-bus: reorder bus ref and bus message ref handling + +Let's always place handling of these references together, so that all +reference counting during allocation is at a single place. + +(cherry picked from commit e593b6a87a335267e5f7238b14683b7f840a01a3) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/bus-message.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 19cb2b9a97..e9cdf46c91 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -461,7 +461,6 @@ int bus_message_from_header( + if (!m) + return -ENOMEM; + +- m->n_ref = 1; + m->sealed = true; + m->header = header; + m->header_accessible = header_accessible; +@@ -515,7 +514,9 @@ int bus_message_from_header( + m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT; + } + ++ m->n_ref = 1; + m->bus = sd_bus_ref(bus); ++ + *ret = TAKE_PTR(m); + + return 0; +@@ -588,13 +589,13 @@ _public_ int sd_bus_message_new( + return -ENOMEM; + + t->n_ref = 1; ++ t->bus = sd_bus_ref(bus); + t->header = (struct bus_header*) ((uint8_t*) t + ALIGN(sizeof(struct sd_bus_message))); + t->header->endian = BUS_NATIVE_ENDIAN; + t->header->type = type; + t->header->version = bus->message_version; + t->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING); + t->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(t); +- t->bus = sd_bus_ref(bus); + + if (bus->allow_interactive_authorization) + t->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION; diff --git a/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch b/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch new file mode 100644 index 0000000..9c7b804 --- /dev/null +++ b/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch @@ -0,0 +1,32 @@ +From 19a9c67b79ebb9a65bc2aec8d8f2799262ef0cb2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:15:37 +0100 +Subject: [PATCH] sd-bus: make sure dispatch_rqueue() initializes return + parameter on all types of success + +Let's make sure our own code follows coding style and initializes all +return values on all types of success (and leaves it uninitialized in +all types of failure). + +(cherry picked from commit c0bc4ec5cc17ac61773d1e9362b0ffa8382c1ff1) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/sd-bus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 64026f7ee1..55b008cc9f 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -1814,8 +1814,10 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd + r = bus_read_message(bus, hint_priority, priority); + if (r < 0) + return r; +- if (r == 0) ++ if (r == 0) { ++ *m = NULL; + return ret; ++ } + + ret = 1; + } diff --git a/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch b/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch new file mode 100644 index 0000000..da2330b --- /dev/null +++ b/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch @@ -0,0 +1,31 @@ +From 7e9944795e3f0046857379a5f878b365597ed373 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:18:18 +0100 +Subject: [PATCH] sd-bus: drop two inappropriate empty lines + +(cherry picked from commit 39feb2ce417e54cf9746e64b5dfd610cef6ac440) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/sd-bus.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 55b008cc9f..01060d105c 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2634,7 +2634,6 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) { + SD_BUS_ERROR_UNKNOWN_METHOD, + "Unknown method '%s' on interface '%s'.", m->member, m->interface); + } +- + if (r < 0) + return r; + +@@ -2758,7 +2757,6 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd + return r; + + *ret = TAKE_PTR(m); +- + return 1; + } + diff --git a/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch b/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch new file mode 100644 index 0000000..d91eb20 --- /dev/null +++ b/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch @@ -0,0 +1,33 @@ +From 247d4f826ab189c4dfc4706aaa94782342655218 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 21:06:30 +0100 +Subject: [PATCH] sd-bus: initialize mutex after we allocated the wqueue + +That way the mutex doesn't have to be destroyed when we exit early due +to OOM. + +(cherry picked from commit 2fe9a10d7695c4c3a748969a0d1662c624e50e5e) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/sd-bus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 01060d105c..e49d58137d 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -248,12 +248,12 @@ _public_ int sd_bus_new(sd_bus **ret) { + b->original_pid = getpid_cached(); + b->n_groups = (size_t) -1; + +- assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0); +- + /* We guarantee that wqueue always has space for at least one entry */ + if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1)) + return -ENOMEM; + ++ assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0); ++ + *ret = TAKE_PTR(b); + return 0; + } diff --git a/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch b/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch new file mode 100644 index 0000000..4e2883a --- /dev/null +++ b/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch @@ -0,0 +1,74 @@ +From 6180d5ee908c9c742f816c6922c229aefd533117 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 21:07:42 +0100 +Subject: [PATCH] sd-bus: always go through sd_bus_unref() to free messages + +Don't try to be smart, don't bypass the ref counting logic if there's no +real reason to. + +This matters if we want to tweak the ref counting logic later. + +(cherry picked from commit b41812d1e308de03c879cfca490105216d528c4b) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/bus-message.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index e9cdf46c91..306b6d6816 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -138,8 +138,6 @@ static sd_bus_message* message_free(sd_bus_message *m) { + return mfree(m); + } + +-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free); +- + static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) { + void *op, *np; + size_t old_size, new_size, start; +@@ -531,7 +529,7 @@ int bus_message_from_malloc( + const char *label, + sd_bus_message **ret) { + +- _cleanup_(message_freep) sd_bus_message *m = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + size_t sz; + int r; + +@@ -651,7 +649,7 @@ _public_ int sd_bus_message_new_method_call( + const char *interface, + const char *member) { + +- _cleanup_(message_freep) sd_bus_message *t = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL; + int r; + + assert_return(bus, -ENOTCONN); +@@ -696,7 +694,7 @@ static int message_new_reply( + uint8_t type, + sd_bus_message **m) { + +- _cleanup_(message_freep) sd_bus_message *t = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL; + uint64_t cookie; + int r; + +@@ -747,7 +745,7 @@ _public_ int sd_bus_message_new_method_error( + sd_bus_message **m, + const sd_bus_error *e) { + +- _cleanup_(message_freep) sd_bus_message *t = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL; + int r; + + assert_return(sd_bus_error_is_set(e), -EINVAL); +@@ -850,7 +848,7 @@ int bus_message_new_synthetic_error( + const sd_bus_error *e, + sd_bus_message **m) { + +- _cleanup_(message_freep) sd_bus_message *t = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL; + int r; + + assert(bus); diff --git a/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch b/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch new file mode 100644 index 0000000..7eb554d --- /dev/null +++ b/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch @@ -0,0 +1,182 @@ +From bc2d7df4fc21e9e54413169d5aad21616314d65e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:18:54 +0100 +Subject: [PATCH] bus-message: introduce two kinds of references to bus + messages + +Before this commit bus messages had a single reference count: when it +reached zero the message would be freed. This simple approach meant a +cyclic dependency was typically seen: a message that was enqueued in a +bus connection object would reference the bus connection object but also +itself be referenced by the bus connection object. So far out strategy +to avoid cases like this was: make sure to process the bus connection +regularly so that messages don#t stay queued, and at exit flush/close +the connection so that the message queued would be emptied, and thus the +cyclic dependencies resolved. Im many cases this isn't done properly +however. + +With this change, let's address the issue more systematically: let's +break the reference cycle. Specifically, there are now two types of +references to a bus message: + +1. A regular one, which keeps both the message and the bus object it is + associated with pinned. + +2. A "queue" reference, which is weaker: it pins the message, but not + the bus object it is associated with. + +The idea is then that regular user handling uses regular references, but +when a message is enqueued on its connection, then this takes a "queue" +reference instead. This then means that a queued message doesn't imply +the connection itself remains pinned, only regular references to the +connection or a message associated with it do. Thus, if we end up in the +situation where a user allocates a bus and a message and enqueues the +latter in the former and drops all refs to both, then this will detect +this case and free both. + +Note that this scheme isn't perfect, it only covers references between +messages and the busses they are associated with. If OTOH a bus message +is enqueued on a different bus than it is associated with cyclic deps +cannot be recognized with this simple algorithm, and thus if you enqueue +a message associated with a bus A on a bus B, and another message +associated with bus B on a bus A, a cyclic ref will be in effect and not +be discovered. However, given that this is an exotic case (though one +that happens, consider systemd-bus-stdio-bridge), it should be OK not to +cover with this, and people have to explicit flush all queues on exit in +that case. + +Note that this commit only establishes the separate reference counters +per message. A follow-up commit will start making use of this from the +bus connection object. + +(cherry picked from commit 1b3f9dd759ca0ea215e7b89f8ce66d1b724497b9) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/bus-message.c | 60 ++++++++++++++++++++++++++--- + src/libsystemd/sd-bus/bus-message.h | 14 ++++++- + 2 files changed, 68 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 306b6d6816..7fe8929f82 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -120,7 +120,8 @@ static sd_bus_message* message_free(sd_bus_message *m) { + + message_reset_parts(m); + +- sd_bus_unref(m->bus); ++ /* Note that we don't unref m->bus here. That's already done by sd_bus_message_unref() as each user ++ * reference to the bus message also is considered a reference to the bus connection itself. */ + + if (m->free_fds) { + close_many(m->fds, m->n_fds); +@@ -893,27 +894,76 @@ int bus_message_new_synthetic_error( + } + + _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) { +- + if (!m) + return NULL; + +- assert(m->n_ref > 0); ++ /* We are fine if this message so far was either explicitly reffed or not reffed but queued into at ++ * least one bus connection object. */ ++ assert(m->n_ref > 0 || m->n_queued > 0); ++ + m->n_ref++; + ++ /* Each user reference to a bus message shall also be considered a ref on the bus */ ++ sd_bus_ref(m->bus); + return m; + } + + _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) { +- + if (!m) + return NULL; + + assert(m->n_ref > 0); ++ ++ sd_bus_unref(m->bus); /* Each regular ref is also a ref on the bus connection. Let's hence drop it ++ * here. Note we have to do this before decrementing our own n_ref here, since ++ * otherwise, if this message is currently queued sd_bus_unref() might call ++ * bus_message_unref_queued() for this which might then destroy the message ++ * while we are still processing it. */ + m->n_ref--; + +- if (m->n_ref > 0) ++ if (m->n_ref > 0 || m->n_queued > 0) + return NULL; + ++ /* Unset the bus field if neither the user has a reference nor this message is queued. We are careful ++ * to reset the field only after the last reference to the bus is dropped, after all we might keep ++ * multiple references to the bus, once for each reference kept on outselves. */ ++ m->bus = NULL; ++ ++ return message_free(m); ++} ++ ++sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus) { ++ if (!m) ++ return NULL; ++ ++ /* If this is a different bus than the message is associated with, then implicitly turn this into a ++ * regular reference. This means that you can create a memory leak by enqueuing a message generated ++ * on one bus onto another at the same time as enqueueing a message from the second one on the first, ++ * as we'll not detect the cyclic references there. */ ++ if (bus != m->bus) ++ return sd_bus_message_ref(m); ++ ++ assert(m->n_ref > 0 || m->n_queued > 0); ++ m->n_queued++; ++ ++ return m; ++} ++ ++sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus) { ++ if (!m) ++ return NULL; ++ ++ if (bus != m->bus) ++ return sd_bus_message_unref(m); ++ ++ assert(m->n_queued > 0); ++ m->n_queued--; ++ ++ if (m->n_ref > 0 || m->n_queued > 0) ++ return NULL; ++ ++ m->bus = NULL; ++ + return message_free(m); + } + +diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h +index 97f6060e30..ded88005e2 100644 +--- a/src/libsystemd/sd-bus/bus-message.h ++++ b/src/libsystemd/sd-bus/bus-message.h +@@ -51,7 +51,16 @@ struct bus_body_part { + }; + + struct sd_bus_message { +- unsigned n_ref; ++ /* Caveat: a message can be referenced in two different ways: the main (user-facing) way will also ++ * pin the bus connection object the message is associated with. The secondary way ("queued") is used ++ * when a message is in the read or write queues of the bus connection object, which will not pin the ++ * bus connection object. This is necessary so that we don't have to have a pair of cyclic references ++ * between a message that is queued and its connection: as soon as a message is only referenced by ++ * the connection (by means of being queued) and the connection itself has no other references it ++ * will be freed. */ ++ ++ unsigned n_ref; /* Counter of references that pin the connection */ ++ unsigned n_queued; /* Counter of references that do not pin the connection */ + + sd_bus *bus; + +@@ -216,3 +225,6 @@ int bus_message_append_sender(sd_bus_message *m, const char *sender); + + void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m); + void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m); ++ ++sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus); ++sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus); diff --git a/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch b/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch new file mode 100644 index 0000000..fdafc3d --- /dev/null +++ b/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch @@ -0,0 +1,74 @@ +From 8efdae75ddf035c8c04983820f8d8cf767cc17b1 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Fri, 31 Jan 2020 11:34:45 +0100 +Subject: [PATCH] sd-bus: introduce API for re-enqueuing incoming messages + +When authorizing via PolicyKit we want to process incoming method calls +twice: once to process and figure out that we need PK authentication, +and a second time after we aquired PK authentication to actually execute +the operation. With this new call sd_bus_enqueue_for_read() we have a +way to put an incoming message back into the read queue for this +purpose. + +This might have other uses too, for example debugging. +Related: CVE-2020-1712 +--- + src/libsystemd/libsystemd.sym | 1 + + src/libsystemd/sd-bus/sd-bus.c | 24 ++++++++++++++++++++++++ + src/systemd/sd-bus.h | 1 + + 3 files changed, 26 insertions(+) + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 1eec17db50..e9972593a6 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -569,4 +569,5 @@ global: + sd_event_source_get_inotify_mask; + sd_event_source_set_destroy_callback; + sd_event_source_get_destroy_callback; ++ sd_bus_enqueue_for_read; + } LIBSYSTEMD_238; +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index e49d58137d..68ad6cbe89 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -4120,3 +4120,27 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) { + *ret = bus->wqueue_size; + return 0; + } ++ ++_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) { ++ int r; ++ ++ assert_return(bus, -EINVAL); ++ assert_return(bus = bus_resolve(bus), -ENOPKG); ++ assert_return(m, -EINVAL); ++ assert_return(m->sealed, -EINVAL); ++ assert_return(!bus_pid_changed(bus), -ECHILD); ++ ++ if (!BUS_IS_OPEN(bus->state)) ++ return -ENOTCONN; ++ ++ /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication, ++ * where we want accept a message, then determine we need to interactively authenticate the user, and ++ * when we have that process the message again. */ ++ ++ r = bus_rqueue_make_room(bus); ++ if (r < 0) ++ return r; ++ ++ bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus); ++ return 0; ++} +diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h +index 54c4b1ca83..9ba757b13d 100644 +--- a/src/systemd/sd-bus.h ++++ b/src/systemd/sd-bus.h +@@ -193,6 +193,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r); + int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r); + int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec); + int sd_bus_flush(sd_bus *bus); ++int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m); + + sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus); + sd_bus_message* sd_bus_get_current_message(sd_bus *bus); diff --git a/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch b/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch new file mode 100644 index 0000000..1748190 --- /dev/null +++ b/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch @@ -0,0 +1,130 @@ +From 73b87f8c73af714a32e7b56b217cd4e4f46a5ea7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 8 May 2019 14:39:57 +0200 +Subject: [PATCH] sd-event: add sd_event_source_disable_unref() helper + +(cherry picked from commit afd15bbb4b6414b9356799c63029e36642dae8e4) +Related: CVE-2020-1712 +--- + man/rules/meson.build | 4 +++- + man/sd_event_source_unref.xml | 30 +++++++++++++++++++----------- + src/libsystemd/libsystemd.sym | 1 + + src/libsystemd/sd-event/sd-event.c | 6 ++++++ + src/systemd/sd-event.h | 1 + + 5 files changed, 30 insertions(+), 12 deletions(-) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 989d11c9b9..7ae94ea265 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -340,7 +340,9 @@ manpages = [ + ['sd_event_source_set_userdata', '3', ['sd_event_source_get_userdata'], ''], + ['sd_event_source_unref', + '3', +- ['sd_event_source_ref', 'sd_event_source_unrefp'], ++ ['sd_event_source_disable_unref', ++ 'sd_event_source_ref', ++ 'sd_event_source_unrefp'], + ''], + ['sd_event_wait', + '3', +diff --git a/man/sd_event_source_unref.xml b/man/sd_event_source_unref.xml +index d1b83c57aa..af8fed33f2 100644 +--- a/man/sd_event_source_unref.xml ++++ b/man/sd_event_source_unref.xml +@@ -22,6 +22,7 @@ + sd_event_source_unref + sd_event_source_unrefp + sd_event_source_ref ++ sd_event_source_disable_unref + + Increase or decrease event source reference counters + +@@ -45,6 +46,10 @@ + sd_event_source *source + + ++ ++ sd_event_source* sd_event_source_disable_unref ++ sd_event_source *source ++ + + + +@@ -80,23 +85,26 @@ + the passed event source object is + NULL. + +- Note that event source objects stay alive and may be +- dispatched as long as they have a reference counter greater than +- zero. In order to drop a reference of an event source and make +- sure the associated event source handler function is not called +- anymore it is recommended to combine a call of ++ Note that event source objects stay alive and may be dispatched as long as they have a reference ++ counter greater than zero. In order to drop a reference of an event source and make sure the associated ++ event source handler function is not called anymore it is recommended to combine a call of + sd_event_source_unref() with a prior call to +- sd_event_source_set_enabled() with +- SD_EVENT_OFF. ++ sd_event_source_set_enabled() with SD_EVENT_OFF or call ++ sd_event_source_disable_unref(), see below. ++ ++ sd_event_source_disable_unref() combines a call to ++ sd_event_source_set_enabled() with SD_EVENT_OFF with ++ sd_event_source_unref(). This ensures that the source is disabled before the local ++ reference to it is lost. The source parameter is allowed to be ++ NULL. + + + + Return Value + +- sd_event_source_unref() always returns +- NULL. +- sd_event_source_ref() always returns the +- event source object passed in. ++ sd_event_source_unref() and ++ sd_event_source_disable_unref() always return NULL. ++ sd_event_source_ref() always returns the event source object passed in. + + + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index e9972593a6..778e88a16c 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -570,4 +570,5 @@ global: + sd_event_source_set_destroy_callback; + sd_event_source_get_destroy_callback; + sd_bus_enqueue_for_read; ++ sd_event_source_disable_unref; + } LIBSYSTEMD_238; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index d53b9a7026..0d3bf5cbb6 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -580,6 +580,12 @@ _public_ sd_event* sd_event_unref(sd_event *e) { + return NULL; + } + ++_public_ sd_event_source* sd_event_source_disable_unref(sd_event_source *s) { ++ if (s) ++ (void) sd_event_source_set_enabled(s, SD_EVENT_OFF); ++ return sd_event_source_unref(s); ++} ++ + static bool event_pid_changed(sd_event *e) { + assert(e); + +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index 7fcae4ac49..9876be01c6 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -113,6 +113,7 @@ int sd_event_get_iteration(sd_event *e, uint64_t *ret); + + sd_event_source* sd_event_source_ref(sd_event_source *s); + sd_event_source* sd_event_source_unref(sd_event_source *s); ++sd_event_source* sd_event_source_disable_unref(sd_event_source *s); + + sd_event *sd_event_source_get_event(sd_event_source *s); + void* sd_event_source_get_userdata(sd_event_source *s); diff --git a/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch b/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch new file mode 100644 index 0000000..da3d850 --- /dev/null +++ b/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch @@ -0,0 +1,156 @@ +From 2ec3c78b1d1ba907cd888aac3cdc3a86c03cda90 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Fri, 31 Jan 2020 15:17:25 +0100 +Subject: [PATCH] polkit: when authorizing via PK let's re-resolve + callback/userdata instead of caching it + +Previously, when doing an async PK query we'd store the original +callback/userdata pair and call it again after the PK request is +complete. This is problematic, since PK queries might be slow and in the +meantime the userdata might be released and re-acquired. Let's avoid +this by always traversing through the message handlers so that we always +re-resolve the callback and userdata pair and thus can be sure it's +up-to-date and properly valid. + +Resolves: CVE-2020-1712 +--- + src/shared/bus-util.c | 74 +++++++++++++++++++++++++++++-------------- + 1 file changed, 50 insertions(+), 24 deletions(-) + +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index 2d908eb45c..5ed68429be 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -319,10 +319,10 @@ int bus_test_polkit( + + typedef struct AsyncPolkitQuery { + sd_bus_message *request, *reply; +- sd_bus_message_handler_t callback; +- void *userdata; + sd_bus_slot *slot; ++ + Hashmap *registry; ++ sd_event_source *defer_event_source; + } AsyncPolkitQuery; + + static void async_polkit_query_free(AsyncPolkitQuery *q) { +@@ -338,9 +338,22 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) { + sd_bus_message_unref(q->request); + sd_bus_message_unref(q->reply); + ++ sd_event_source_disable_unref(q->defer_event_source); + free(q); + } + ++static int async_polkit_defer(sd_event_source *s, void *userdata) { ++ AsyncPolkitQuery *q = userdata; ++ ++ assert(s); ++ ++ /* This is called as idle event source after we processed the async polkit reply, hopefully after the ++ * method call we re-enqueued has been properly processed. */ ++ ++ async_polkit_query_free(q); ++ return 0; ++} ++ + static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { + _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; + AsyncPolkitQuery *q = userdata; +@@ -349,19 +362,45 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e + assert(reply); + assert(q); + ++ assert(q->slot); + q->slot = sd_bus_slot_unref(q->slot); ++ ++ assert(!q->reply); + q->reply = sd_bus_message_ref(reply); + ++ /* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the ++ * whole message processing again, and thus re-validating and re-retrieving the "userdata" field ++ * again. ++ * ++ * We install an idle event loop event to clean-up the PolicyKit request data when we are idle again, ++ * i.e. after the second time the message is processed is complete. */ ++ ++ assert(!q->defer_event_source); ++ r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q); ++ if (r < 0) ++ goto fail; ++ ++ r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE); ++ if (r < 0) ++ goto fail; ++ ++ r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT); ++ if (r < 0) ++ goto fail; ++ + r = sd_bus_message_rewind(q->request, true); +- if (r < 0) { +- r = sd_bus_reply_method_errno(q->request, r, NULL); +- goto finish; +- } ++ if (r < 0) ++ goto fail; + +- r = q->callback(q->request, q->userdata, &error_buffer); +- r = bus_maybe_reply_error(q->request, r, &error_buffer); ++ r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request); ++ if (r < 0) ++ goto fail; + +-finish: ++ return 1; ++ ++fail: ++ log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m"); ++ (void) sd_bus_reply_method_errno(q->request, r, NULL); + async_polkit_query_free(q); + + return r; +@@ -382,11 +421,9 @@ int bus_verify_polkit_async( + #if ENABLE_POLKIT + _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL; + AsyncPolkitQuery *q; +- const char *sender, **k, **v; +- sd_bus_message_handler_t callback; +- void *userdata; + int c; + #endif ++ const char *sender, **k, **v; + int r; + + assert(call); +@@ -444,20 +481,11 @@ int bus_verify_polkit_async( + else if (r > 0) + return 1; + +-#if ENABLE_POLKIT +- if (sd_bus_get_current_message(call->bus) != call) +- return -EINVAL; +- +- callback = sd_bus_get_current_handler(call->bus); +- if (!callback) +- return -EINVAL; +- +- userdata = sd_bus_get_current_userdata(call->bus); +- + sender = sd_bus_message_get_sender(call); + if (!sender) + return -EBADMSG; + ++#if ENABLE_POLKIT + c = sd_bus_message_get_allow_interactive_authorization(call); + if (c < 0) + return c; +@@ -509,8 +537,6 @@ int bus_verify_polkit_async( + return -ENOMEM; + + q->request = sd_bus_message_ref(call); +- q->callback = callback; +- q->userdata = userdata; + + r = hashmap_put(*registry, call, q); + if (r < 0) { diff --git a/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch b/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch new file mode 100644 index 0000000..d7523ce --- /dev/null +++ b/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch @@ -0,0 +1,70 @@ +From b9be2c6b48227642ba85c5a741f121cc99655904 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 6 Jan 2020 12:30:58 +0100 +Subject: [PATCH] sysctl: let's by default increase the numeric PID range from + 2^16 to 2^22 + +This should PID collisions a tiny bit less likely, and thus improve +security and robustness. + +2^22 isn't particularly a lot either, but it's the current kernel +limitation. + +Bumping this limit was suggested by Linus himself: + +https://lwn.net/ml/linux-kernel/CAHk-=wiZ40LVjnXSi9iHLE_-ZBsWFGCgdmNiYZUXn1-V5YBg2g@mail.gmail.com/ + +Let's experiment with this in systemd upstream first. Downstreams and +users can after all still comment this easily. + +Besides compat concern the most often heard issue with such high PIDs is +usability, since they are potentially hard to type. I am not entirely sure though +whether 4194304 (as largest new PID) is that much worse to type or to +copy than 65563. + +This should also simplify management of per system tasks limits as by +this move the sysctl /proc/sys/kernel/threads-max becomes the primary +knob to control how many processes to have in parallel. + +Resolves: #1744214 +--- + sysctl.d/50-pid-max.conf | 17 +++++++++++++++++ + sysctl.d/meson.build | 1 + + 2 files changed, 18 insertions(+) + create mode 100644 sysctl.d/50-pid-max.conf + +diff --git a/sysctl.d/50-pid-max.conf b/sysctl.d/50-pid-max.conf +new file mode 100644 +index 0000000000..3a8393d185 +--- /dev/null ++++ b/sysctl.d/50-pid-max.conf +@@ -0,0 +1,17 @@ ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++ ++# See sysctl.d(5) and core(5) for documentation. ++ ++# To override settings in this file, create a local file in /etc ++# (e.g. /etc/sysctl.d/90-override.conf), and put any assignments ++# there. ++ ++# Bump the numeric PID range to its maximum of 2^22 (from the in-kernel default ++# of 2^16), to make PID collisions less likely. ++kernel.pid_max = 4194304 ++ +diff --git a/sysctl.d/meson.build b/sysctl.d/meson.build +index 64f6ce942e..a95957ad7d 100644 +--- a/sysctl.d/meson.build ++++ b/sysctl.d/meson.build +@@ -2,6 +2,7 @@ + + install_data( + '50-default.conf', ++ '50-pid-max.conf', + install_dir : sysctldir) + + in_files = [] diff --git a/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch b/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch new file mode 100644 index 0000000..9ebc71d --- /dev/null +++ b/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch @@ -0,0 +1,49 @@ +From dc4c3a5aa35a5e88adcf210471d9460262c8c0d9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 28 May 2019 12:40:17 +0900 +Subject: [PATCH] journal: do not trigger assertion when journal_file_close() + get NULL + +We generally expect destructors to not complain if a NULL argument is passed. + +Closes #12400. + +(cherry picked from commit c377a6f3ad3d9bed4ce7e873e8e9ec6b1650c57d) +Resolves: #1788085 +--- + src/journal/journal-file.c | 3 ++- + src/journal/journald-server.c | 7 ++----- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c +index efc3ee052b..8249b11b23 100644 +--- a/src/journal/journal-file.c ++++ b/src/journal/journal-file.c +@@ -335,7 +335,8 @@ bool journal_file_is_offlining(JournalFile *f) { + } + + JournalFile* journal_file_close(JournalFile *f) { +- assert(f); ++ if (!f) ++ return NULL; + + #if HAVE_GCRYPT + /* Write the final tag */ +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 6aecb67d6c..6250eab831 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1906,11 +1906,8 @@ void server_done(Server *s) { + + client_context_flush_all(s); + +- if (s->system_journal) +- (void) journal_file_close(s->system_journal); +- +- if (s->runtime_journal) +- (void) journal_file_close(s->runtime_journal); ++ (void) journal_file_close(s->system_journal); ++ (void) journal_file_close(s->runtime_journal); + + ordered_hashmap_free_with_destructor(s->user_journals, journal_file_close); + diff --git a/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch b/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch new file mode 100644 index 0000000..9ca0d60 --- /dev/null +++ b/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch @@ -0,0 +1,58 @@ +From ceacf935ac9f59bc08b5901f70f227958a2bcf52 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 28 May 2019 18:07:01 +0900 +Subject: [PATCH] journal: use cleanup attribute at one more place + +(cherry picked from commit 627df1dc42b68a74b0882b06366d1185b1a34332) + +Conflicts: + src/journal/journald-server.c + +Related: #1788085 +--- + src/journal/journal-file.h | 1 + + src/journal/journald-server.c | 9 ++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h +index cd8a48a364..6a44fd39d2 100644 +--- a/src/journal/journal-file.h ++++ b/src/journal/journal-file.h +@@ -144,6 +144,7 @@ int journal_file_open( + int journal_file_set_offline(JournalFile *f, bool wait); + bool journal_file_is_offlining(JournalFile *f); + JournalFile* journal_file_close(JournalFile *j); ++DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close); + + int journal_file_open_reliably( + const char *fname, +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 6250eab831..7632e2d9d0 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -253,8 +253,9 @@ static int open_journal( + bool seal, + JournalMetrics *metrics, + JournalFile **ret) { ++ ++ _cleanup_(journal_file_closep) JournalFile *f = NULL; + int r; +- JournalFile *f; + + assert(s); + assert(fname); +@@ -271,12 +272,10 @@ static int open_journal( + return r; + + r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC); +- if (r < 0) { +- (void) journal_file_close(f); ++ if (r < 0) + return r; +- } + +- *ret = f; ++ *ret = TAKE_PTR(f); + return r; + } + diff --git a/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch b/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch new file mode 100644 index 0000000..f8ff1d5 --- /dev/null +++ b/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch @@ -0,0 +1,183 @@ +From 781a055c17400e953bb7929434fe7a2e6517d5e8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 18:31:59 +0100 +Subject: [PATCH] sd-bus: use "queue" message references for managing r/w + message queues in connection objects + +Let's make use of the new concept the previous commit added. + +See: #4846 +(cherry picked from commit c1757a70eac0382c4837a3833d683919f6a48ed7) +Related: CVE-2020-1712 +--- + src/libsystemd/sd-bus/bus-socket.c | 6 ++- + src/libsystemd/sd-bus/sd-bus.c | 60 ++++++++++++++---------------- + 2 files changed, 32 insertions(+), 34 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 17cfa8e1fd..4a72795d2b 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1116,8 +1116,10 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { + bus->fds = NULL; + bus->n_fds = 0; + +- if (t) +- bus->rqueue[bus->rqueue_size++] = t; ++ if (t) { ++ bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(t, bus); ++ sd_bus_message_unref(t); ++ } + + return 1; + } +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 68ad6cbe89..a3509f7e89 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -148,13 +148,13 @@ static void bus_reset_queues(sd_bus *b) { + assert(b); + + while (b->rqueue_size > 0) +- sd_bus_message_unref(b->rqueue[--b->rqueue_size]); ++ bus_message_unref_queued(b->rqueue[--b->rqueue_size], b); + + b->rqueue = mfree(b->rqueue); + b->rqueue_allocated = 0; + + while (b->wqueue_size > 0) +- sd_bus_message_unref(b->wqueue[--b->wqueue_size]); ++ bus_message_unref_queued(b->wqueue[--b->wqueue_size], b); + + b->wqueue = mfree(b->wqueue); + b->wqueue_allocated = 0; +@@ -493,7 +493,7 @@ static int synthesize_connected_signal(sd_bus *bus) { + + /* Insert at the very front */ + memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size); +- bus->rqueue[0] = TAKE_PTR(m); ++ bus->rqueue[0] = bus_message_ref_queued(m, bus); + bus->rqueue_size++; + + return 0; +@@ -1760,7 +1760,7 @@ static int dispatch_wqueue(sd_bus *bus) { + * anyway. */ + + bus->wqueue_size--; +- sd_bus_message_unref(bus->wqueue[0]); ++ bus_message_unref_queued(bus->wqueue[0], bus); + memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size); + bus->windex = 0; + +@@ -1789,6 +1789,15 @@ int bus_rqueue_make_room(sd_bus *bus) { + return 0; + } + ++static void rqueue_drop_one(sd_bus *bus, size_t i) { ++ assert(bus); ++ assert(i < bus->rqueue_size); ++ ++ bus_message_unref_queued(bus->rqueue[i], bus); ++ memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1)); ++ bus->rqueue_size--; ++} ++ + static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) { + int r, ret = 0; + +@@ -1803,10 +1812,8 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd + for (;;) { + if (bus->rqueue_size > 0) { + /* Dispatch a queued message */ +- +- *m = bus->rqueue[0]; +- bus->rqueue_size--; +- memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size); ++ *m = sd_bus_message_ref(bus->rqueue[0]); ++ rqueue_drop_one(bus, 0); + return 1; + } + +@@ -1884,7 +1891,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) { + * of the wqueue array is always allocated so + * that we always can remember how much was + * written. */ +- bus->wqueue[0] = sd_bus_message_ref(m); ++ bus->wqueue[0] = bus_message_ref_queued(m, bus); + bus->wqueue_size = 1; + bus->windex = idx; + } +@@ -1898,7 +1905,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) { + if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1)) + return -ENOMEM; + +- bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m); ++ bus->wqueue[bus->wqueue_size++] = bus_message_ref_queued(m, bus); + } + + finish: +@@ -2124,37 +2131,30 @@ _public_ int sd_bus_call( + usec_t left; + + while (i < bus->rqueue_size) { +- sd_bus_message *incoming = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *incoming = NULL; + +- incoming = bus->rqueue[i]; ++ incoming = sd_bus_message_ref(bus->rqueue[i]); + + if (incoming->reply_cookie == cookie) { + /* Found a match! */ + +- memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1)); +- bus->rqueue_size--; ++ rqueue_drop_one(bus, i); + log_debug_bus_message(incoming); + + if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) { + + if (incoming->n_fds <= 0 || bus->accept_fd) { + if (reply) +- *reply = incoming; +- else +- sd_bus_message_unref(incoming); ++ *reply = TAKE_PTR(incoming); + + return 1; + } + +- r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry."); +- sd_bus_message_unref(incoming); +- return r; ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry."); + +- } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) { +- r = sd_bus_error_copy(error, &incoming->error); +- sd_bus_message_unref(incoming); +- return r; +- } else { ++ } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) ++ return sd_bus_error_copy(error, &incoming->error); ++ else { + r = -EIO; + goto fail; + } +@@ -2164,15 +2164,11 @@ _public_ int sd_bus_call( + incoming->sender && + streq(bus->unique_name, incoming->sender)) { + +- memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1)); +- bus->rqueue_size--; ++ rqueue_drop_one(bus, i); + +- /* Our own message? Somebody is trying +- * to send its own client a message, +- * let's not dead-lock, let's fail +- * immediately. */ ++ /* Our own message? Somebody is trying to send its own client a message, ++ * let's not dead-lock, let's fail immediately. */ + +- sd_bus_message_unref(incoming); + r = -ELOOP; + goto fail; + } diff --git a/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch b/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch new file mode 100644 index 0000000..2ca5b14 --- /dev/null +++ b/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch @@ -0,0 +1,261 @@ +From 77a273e02c1c811485d13ddca0f844512aed2cff Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 12 Feb 2020 12:58:54 +0100 +Subject: [PATCH] pid1: make sure to restore correct default values for some + rlimits + +Commit fb39af4ce42d7ef9af63009f271f404038703704 forgot to restore the default +rlimit values (RLIMIT_NOFILE and RLIMIT_MEMLOCK) while PID1 is reloading. + +This patch extracts the code in charge of initializing the default values for +those rlimits in order to create dedicated functions, which take care of their +initialization. + +These functions are then called in parse_configuration() so we make sure that +the default values for these rlimits get restored every time PID1 is reloading +its configuration. + +(cherry picked from commit a9fd4cd1206832a61aaf61fff583bb133e6cb965) +Resolves: #1789930 +--- + src/core/main.c | 135 +++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 106 insertions(+), 29 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index c83249a8dc..b8c1e567ad 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -136,7 +136,8 @@ static EmergencyAction arg_cad_burst_action; + static CPUSet arg_cpu_affinity; + static NUMAPolicy arg_numa_policy; + +-static int parse_configuration(void); ++static int parse_configuration(const struct rlimit *saved_rlimit_nofile, ++ const struct rlimit *saved_rlimit_memlock); + + _noreturn_ static void freeze_or_reboot(void) { + +@@ -1149,25 +1150,6 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching + static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { + int r, nr; + +- assert(saved_rlimit); +- +- /* Save the original RLIMIT_NOFILE so that we can reset it +- * later when transitioning from the initrd to the main +- * systemd or suchlike. */ +- if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) +- return log_warning_errno(errno, "Reading RLIMIT_NOFILE failed, ignoring: %m"); +- +- /* Make sure forked processes get the default kernel setting */ +- if (!arg_default_rlimit[RLIMIT_NOFILE]) { +- struct rlimit *rl; +- +- rl = newdup(struct rlimit, saved_rlimit, 1); +- if (!rl) +- return log_oom(); +- +- arg_default_rlimit[RLIMIT_NOFILE] = rl; +- } +- + /* Bump up the resource limit for ourselves substantially, all the way to the maximum the kernel allows */ + nr = read_nr_open(); + r = setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(nr)); +@@ -1180,16 +1162,12 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { + static int bump_rlimit_memlock(struct rlimit *saved_rlimit) { + int r; + +- assert(saved_rlimit); + assert(getuid() == 0); + + /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even though we have CAP_IPC_LOCK which + * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's + * bump the value high enough for the root user. */ + +- if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit) < 0) +- return log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m"); +- + r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL)); + if (r < 0) + return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m"); +@@ -1651,6 +1629,8 @@ static void do_reexecute( + + static int invoke_main_loop( + Manager *m, ++ const struct rlimit *saved_rlimit_nofile, ++ const struct rlimit *saved_rlimit_memlock, + bool *ret_reexecute, + int *ret_retval, /* Return parameters relevant for shutting down */ + const char **ret_shutdown_verb, /* … */ +@@ -1662,6 +1642,8 @@ static int invoke_main_loop( + int r; + + assert(m); ++ assert(saved_rlimit_nofile); ++ assert(saved_rlimit_memlock); + assert(ret_reexecute); + assert(ret_retval); + assert(ret_shutdown_verb); +@@ -1691,7 +1673,7 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + +- (void) parse_configuration(); ++ (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + set_manager_defaults(m); + +@@ -1983,6 +1965,80 @@ static int do_queue_default_job( + return 0; + } + ++static void save_rlimits(struct rlimit *saved_rlimit_nofile, ++ struct rlimit *saved_rlimit_memlock) { ++ ++ assert(saved_rlimit_nofile); ++ assert(saved_rlimit_memlock); ++ ++ if (getrlimit(RLIMIT_NOFILE, saved_rlimit_nofile) < 0) ++ log_warning_errno(errno, "Reading RLIMIT_NOFILE failed, ignoring: %m"); ++ ++ if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock) < 0) ++ log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m"); ++} ++ ++static void fallback_rlimit_nofile(const struct rlimit *saved_rlimit_nofile) { ++ struct rlimit *rl; ++ ++ if (arg_default_rlimit[RLIMIT_NOFILE]) ++ return; ++ ++ /* Make sure forked processes get limits based on the original kernel setting */ ++ ++ rl = newdup(struct rlimit, saved_rlimit_nofile, 1); ++ if (!rl) { ++ log_oom(); ++ return; ++ } ++ ++ /* Bump the hard limit for system services to a substantially higher value. The default ++ * hard limit current kernels set is pretty low (4K), mostly for historical ++ * reasons. According to kernel developers, the fd handling in recent kernels has been ++ * optimized substantially enough, so that we can bump the limit now, without paying too ++ * high a price in memory or performance. Note however that we only bump the hard limit, ++ * not the soft limit. That's because select() works the way it works, and chokes on fds ++ * >= 1024. If we'd bump the soft limit globally, it might accidentally happen to ++ * unexpecting programs that they get fds higher than what they can process using ++ * select(). By only bumping the hard limit but leaving the low limit as it is we avoid ++ * this pitfall: programs that are written by folks aware of the select() problem in mind ++ * (and thus use poll()/epoll instead of select(), the way everybody should) can ++ * explicitly opt into high fds by bumping their soft limit beyond 1024, to the hard limit ++ * we pass. */ ++ if (arg_system) { ++ int nr; ++ ++ /* Get the underlying absolute limit the kernel enforces */ ++ nr = read_nr_open(); ++ ++ rl->rlim_max = MIN((rlim_t) nr, MAX(rl->rlim_max, (rlim_t) HIGH_RLIMIT_NOFILE)); ++ } ++ ++ /* If for some reason we were invoked with a soft limit above 1024 (which should never ++ * happen!, but who knows what we get passed in from pam_limit when invoked as --user ++ * instance), then lower what we pass on to not confuse our children */ ++ rl->rlim_cur = MIN(rl->rlim_cur, (rlim_t) FD_SETSIZE); ++ ++ arg_default_rlimit[RLIMIT_NOFILE] = rl; ++} ++ ++static void fallback_rlimit_memlock(const struct rlimit *saved_rlimit_memlock) { ++ struct rlimit *rl; ++ ++ /* Pass the original value down to invoked processes */ ++ ++ if (arg_default_rlimit[RLIMIT_MEMLOCK]) ++ return; ++ ++ rl = newdup(struct rlimit, saved_rlimit_memlock, 1); ++ if (!rl) { ++ log_oom(); ++ return; ++ } ++ ++ arg_default_rlimit[RLIMIT_MEMLOCK] = rl; ++} ++ + static void reset_arguments(void) { + /* Frees/resets arg_* variables, with a few exceptions commented below. */ + +@@ -2040,9 +2096,13 @@ static void reset_arguments(void) { + numa_policy_reset(&arg_numa_policy); + } + +-static int parse_configuration(void) { ++static int parse_configuration(const struct rlimit *saved_rlimit_nofile, ++ const struct rlimit *saved_rlimit_memlock) { + int r; + ++ assert(saved_rlimit_nofile); ++ assert(saved_rlimit_memlock); ++ + arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); + + /* Assign configuration defaults */ +@@ -2058,18 +2118,29 @@ static int parse_configuration(void) { + log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + } + ++ /* Initialize some default rlimits for services if they haven't been configured */ ++ fallback_rlimit_nofile(saved_rlimit_nofile); ++ fallback_rlimit_memlock(saved_rlimit_memlock); ++ + /* Note that this also parses bits from the kernel command line, including "debug". */ + log_parse_environment(); + + return 0; + } + +-static int load_configuration(int argc, char **argv, const char **ret_error_message) { ++static int load_configuration( ++ int argc, ++ char **argv, ++ const struct rlimit *saved_rlimit_nofile, ++ const struct rlimit *saved_rlimit_memlock, ++ const char **ret_error_message) { + int r; + ++ assert(saved_rlimit_nofile); ++ assert(saved_rlimit_memlock); + assert(ret_error_message); + +- (void) parse_configuration(); ++ (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + r = parse_argv(argc, argv); + if (r < 0) { +@@ -2403,11 +2474,15 @@ int main(int argc, char *argv[]) { + } + } + ++ /* Save the original RLIMIT_NOFILE/RLIMIT_MEMLOCK so that we can reset it later when ++ * transitioning from the initrd to the main systemd or suchlike. */ ++ save_rlimits(&saved_rlimit_nofile, &saved_rlimit_memlock); ++ + /* Reset all signal handlers. */ + (void) reset_all_signal_handlers(); + (void) ignore_signals(SIGNALS_IGNORE, -1); + +- r = load_configuration(argc, argv, &error_message); ++ r = load_configuration(argc, argv, &saved_rlimit_nofile, &saved_rlimit_memlock, &error_message); + if (r < 0) + goto finish; + +@@ -2522,6 +2597,8 @@ int main(int argc, char *argv[]) { + } + + (void) invoke_main_loop(m, ++ &saved_rlimit_nofile, ++ &saved_rlimit_memlock, + &reexecute, + &retval, + &shutdown_verb, diff --git a/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch b/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch new file mode 100644 index 0000000..72ec11c --- /dev/null +++ b/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch @@ -0,0 +1,37 @@ +From 0528a880ddf797a42b2de274e5c7bd2d9896c991 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 11 Oct 2018 18:31:11 +0200 +Subject: [PATCH] main: introduce a define HIGH_RLIMIT_MEMLOCK similar to + HIGH_RLIMIT_NOFILE + +(cherry picked from commit c8884aceefc85245b9bdfb626e2daf27521259bd) +Related: #1789930 +--- + src/basic/def.h | 3 +++ + src/core/main.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/basic/def.h b/src/basic/def.h +index 4d515c11b6..65ad659999 100644 +--- a/src/basic/def.h ++++ b/src/basic/def.h +@@ -75,3 +75,6 @@ + _CONF_PATHS_SPLIT_USR(n)) + + #define LONG_LINE_MAX (1U*1024U*1024U) ++ ++#define HIGH_RLIMIT_NOFILE (256*1024) ++#define HIGH_RLIMIT_MEMLOCK (1024ULL*1024ULL*64ULL) +diff --git a/src/core/main.c b/src/core/main.c +index b8c1e567ad..d6550ea161 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1168,7 +1168,7 @@ static int bump_rlimit_memlock(struct rlimit *saved_rlimit) { + * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's + * bump the value high enough for the root user. */ + +- r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL)); ++ r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(HIGH_RLIMIT_MEMLOCK)); + if (r < 0) + return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m"); + diff --git a/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch b/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch new file mode 100644 index 0000000..d63169b --- /dev/null +++ b/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch @@ -0,0 +1,178 @@ +From 5a62c0daff82e8343d24f98e1761d27bf8015782 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 19:00:28 +0100 +Subject: [PATCH] seccomp: introduce seccomp_restrict_suid_sgid() for blocking + chmod() for suid/sgid files + +(cherry picked from commit 3c27973b13724ede05a06a5d346a569794cda433) +Related: #1687512 +--- + src/shared/seccomp-util.c | 132 ++++++++++++++++++++++++++++++++++++++ + src/shared/seccomp-util.h | 1 + + 2 files changed, 133 insertions(+) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index 92910acf0e..fd46b9f88d 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -1,12 +1,14 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + + #include "af-list.h" + #include "alloc-util.h" +@@ -1747,3 +1749,133 @@ int seccomp_lock_personality(unsigned long personality) { + + return 0; + } ++ ++int seccomp_restrict_suid_sgid(void) { ++ uint32_t arch; ++ int r; ++ ++ SECCOMP_FOREACH_LOCAL_ARCH(arch) { ++ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; ++ ++ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW); ++ if (r < 0) ++ return r; ++ ++ /* Checks the mode_t parameter of the following system calls: ++ * ++ * → chmod() + fchmod() + fchmodat() ++ * → open() + creat() + openat() ++ * → mkdir() + mkdirat() ++ * → mknod() + mknodat() ++ */ ++ ++ for (unsigned bit = 0; bit < 2; bit ++) { ++ /* Block S_ISUID in the first iteration, S_ISGID in the second */ ++ mode_t m = bit == 0 ? S_ISUID : S_ISGID; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(chmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdir), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdirat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(open), ++ 2, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(openat), ++ 2, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A3(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(creat), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ break; ++ } ++ if (r < 0) { ++ log_debug_errno(r, "Failed to add suid/sgid rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); ++ continue; ++ } ++ ++ r = seccomp_load(seccomp); ++ if (IN_SET(r, -EPERM, -EACCES)) ++ return r; ++ if (r < 0) ++ log_debug_errno(r, "Failed to apply suid/sgid restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); ++ } ++ ++ return 0; ++} +diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h +index d8a36c4e21..602f092255 100644 +--- a/src/shared/seccomp-util.h ++++ b/src/shared/seccomp-util.h +@@ -85,6 +85,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist); + int seccomp_restrict_realtime(void); + int seccomp_memory_deny_write_execute(void); + int seccomp_lock_personality(unsigned long personality); ++int seccomp_restrict_suid_sgid(void); + + extern const uint32_t seccomp_local_archs[]; + diff --git a/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch b/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch new file mode 100644 index 0000000..c04084f --- /dev/null +++ b/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch @@ -0,0 +1,265 @@ +From b39697a80ad388e2063c54e56333882f4307c1a1 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Tue, 12 Nov 2019 13:27:49 +0100 +Subject: [PATCH] test: add test case for restrict_suid_sgid() + +(cherry picked from commit 167fc10cb352b04d442c9010dab4f8dc24219749) +Related: #1687512 +--- + src/test/test-seccomp.c | 226 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 226 insertions(+) + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index d177515ac7..4021a06e0e 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -17,9 +17,11 @@ + #include "nsflags.h" + #include "process-util.h" + #include "raw-clone.h" ++#include "rm-rf.h" + #include "seccomp-util.h" + #include "set.h" + #include "string-util.h" ++#include "umask-util.h" + #include "util.h" + #include "virt.h" + +@@ -666,6 +668,229 @@ static void test_filter_sets_ordered(void) { + } + } + ++static int mkostemp_safe(char *pattern) { ++ _unused_ _cleanup_umask_ mode_t u = umask(0077); ++ int fd; ++ ++ assert(pattern); ++ ++ fd = mkostemp(pattern, O_CLOEXEC); ++ if (fd < 0) ++ return -errno; ++ ++ return fd; ++} ++ ++static int real_open(const char *path, int flags, mode_t mode) { ++ /* glibc internally calls openat() when open() is requested. Let's hence define our own wrapper for ++ * testing purposes that calls the real syscall, on architectures where SYS_open is defined. On ++ * other architectures, let's just fall back to the glibc call. */ ++ ++#ifdef SYS_open ++ return (int) syscall(SYS_open, path, flags, mode); ++#else ++ return open(path, flags, mode); ++#endif ++} ++ ++static void test_restrict_suid_sgid(void) { ++ pid_t pid; ++ ++ log_info("/* %s */", __func__); ++ ++ if (!is_seccomp_available()) { ++ log_notice("Seccomp not available, skipping %s", __func__); ++ return; ++ } ++ if (geteuid() != 0) { ++ log_notice("Not root, skipping %s", __func__); ++ return; ++ } ++ ++ pid = fork(); ++ assert_se(pid >= 0); ++ ++ if (pid == 0) { ++ char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX"; ++ int fd = -1, k = -1; ++ const char *z; ++ ++ fd = mkostemp_safe(path); ++ assert_se(fd >= 0); ++ ++ assert_se(mkdtemp(dir)); ++ z = strjoina(dir, "/test"); ++ ++ assert_se(chmod(path, 0755 | S_ISUID) >= 0); ++ assert_se(chmod(path, 0755 | S_ISGID) >= 0); ++ assert_se(chmod(path, 0755 | S_ISGID | S_ISUID) >= 0); ++ assert_se(chmod(path, 0755) >= 0); ++ ++ assert_se(fchmod(fd, 0755 | S_ISUID) >= 0); ++ assert_se(fchmod(fd, 0755 | S_ISGID) >= 0); ++ assert_se(fchmod(fd, 0755 | S_ISGID | S_ISUID) >= 0); ++ assert_se(fchmod(fd, 0755) >= 0); ++ ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0); ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0); ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0); ++ assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); ++ ++ k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = creat(z, 0644 | S_ISUID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = creat(z, 0644 | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = creat(z, 0644 | S_ISUID | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = creat(z, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(mkdir(z, 0755 | S_ISUID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdir(z, 0755 | S_ISGID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdir(z, 0755) >= 0); ++ assert_se(rmdir(z) >= 0); ++ ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) >= 0); ++ assert_se(rmdir(z) >= 0); ++ assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0); ++ assert_se(rmdir(z) >= 0); ++ ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknod(z, S_IFREG | 0755, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(seccomp_restrict_suid_sgid() >= 0); ++ ++ assert_se(chmod(path, 0775 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(chmod(path, 0775 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(chmod(path, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM); ++ assert_se(chmod(path, 0775) >= 0); ++ ++ assert_se(fchmod(fd, 0775 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(fchmod(fd, 0775 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(fchmod(fd, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM); ++ assert_se(fchmod(fd, 0775) >= 0); ++ ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM); ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM); ++ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM); ++ assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); ++ ++ assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM); ++ k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(creat(z, 0644 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(creat(z, 0644 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(creat(z, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM); ++ k = creat(z, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM); ++ k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644); ++ k = safe_close(k); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(mkdir(z, 0755 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(mkdir(z, 0755 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM); ++ assert_se(mkdir(z, 0755) >= 0); ++ assert_se(rmdir(z) >= 0); ++ ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) < 0 && errno == EPERM); ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) < 0 && errno == EPERM); ++ assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM); ++ assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0); ++ assert_se(rmdir(z) >= 0); ++ ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM); ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM); ++ assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM); ++ assert_se(mknod(z, S_IFREG | 0755, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM); ++ assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0); ++ assert_se(unlink(z) >= 0); ++ ++ assert_se(unlink(path) >= 0); ++ assert_se(rm_rf(dir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); ++ ++ _exit(EXIT_SUCCESS); ++ } ++ ++ assert_se(wait_for_terminate_and_check("suidsgidseccomp", pid, WAIT_LOG) == EXIT_SUCCESS); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -684,6 +909,7 @@ int main(int argc, char *argv[]) { + test_load_syscall_filter_set_raw(); + test_lock_personality(); + test_filter_sets_ordered(); ++ test_restrict_suid_sgid(); + + return 0; + } diff --git a/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch b/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch new file mode 100644 index 0000000..7d8d98a --- /dev/null +++ b/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch @@ -0,0 +1,157 @@ +From f79283a86531e3bbf0854b5f126b7b291fadfb43 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 19:09:09 +0100 +Subject: [PATCH] core: expose SUID/SGID restriction as new unit setting + RestrictSUIDSGID= + +(cherry picked from commit f69567cbe26d09eac9d387c0be0fc32c65a83ada) +Related: #1687512 +--- + src/core/dbus-execute.c | 4 ++++ + src/core/execute.c | 22 +++++++++++++++++++++ + src/core/execute.h | 1 + + src/core/load-fragment-gperf.gperf.m4 | 2 ++ + src/shared/bus-unit-util.c | 2 +- + test/fuzz/fuzz-unit-file/directives.service | 1 + + 6 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 198f149210..e7c0b893d1 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -815,6 +815,7 @@ const sd_bus_vtable bus_exec_vtable[] = { + SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), +@@ -1179,6 +1180,9 @@ int bus_exec_context_set_transient_property( + if (streq(name, "RestrictRealtime")) + return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error); + ++ if (streq(name, "RestrictSUIDSGID")) ++ return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error); ++ + if (streq(name, "DynamicUser")) + return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error); + +diff --git a/src/core/execute.c b/src/core/execute.c +index 56aa89e1ec..f012023224 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1366,6 +1366,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) { + return context_has_address_families(c) || + c->memory_deny_write_execute || + c->restrict_realtime || ++ c->restrict_suid_sgid || + exec_context_restrict_namespaces_set(c) || + c->protect_kernel_tunables || + c->protect_kernel_modules || +@@ -1470,6 +1471,19 @@ static int apply_restrict_realtime(const Unit* u, const ExecContext *c) { + return seccomp_restrict_realtime(); + } + ++static int apply_restrict_suid_sgid(const Unit* u, const ExecContext *c) { ++ assert(u); ++ assert(c); ++ ++ if (!c->restrict_suid_sgid) ++ return 0; ++ ++ if (skip_seccomp_unavailable(u, "RestrictSUIDSGID=")) ++ return 0; ++ ++ return seccomp_restrict_suid_sgid(); ++} ++ + static int apply_protect_sysctl(const Unit *u, const ExecContext *c) { + assert(u); + assert(c); +@@ -3404,6 +3418,12 @@ static int exec_child( + return log_unit_error_errno(unit, r, "Failed to apply realtime restrictions: %m"); + } + ++ r = apply_restrict_suid_sgid(unit, context); ++ if (r < 0) { ++ *exit_status = EXIT_SECCOMP; ++ return log_unit_error_errno(unit, r, "Failed to apply SUID/SGID restrictions: %m"); ++ } ++ + r = apply_restrict_namespaces(unit, context); + if (r < 0) { + *exit_status = EXIT_SECCOMP; +@@ -4023,6 +4043,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + "%sIgnoreSIGPIPE: %s\n" + "%sMemoryDenyWriteExecute: %s\n" + "%sRestrictRealtime: %s\n" ++ "%sRestrictSUIDSGID: %s\n" + "%sKeyringMode: %s\n", + prefix, c->umask, + prefix, c->working_directory ? c->working_directory : "/", +@@ -4041,6 +4062,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + prefix, yes_no(c->ignore_sigpipe), + prefix, yes_no(c->memory_deny_write_execute), + prefix, yes_no(c->restrict_realtime), ++ prefix, yes_no(c->restrict_suid_sgid), + prefix, exec_keyring_mode_to_string(c->keyring_mode)); + + if (c->root_image) +diff --git a/src/core/execute.h b/src/core/execute.h +index b2eb55f8f5..2266355962 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -245,6 +245,7 @@ struct ExecContext { + * that the autofs logic detects that it belongs to us and we + * don't enter a trigger loop. */ + bool same_pgrp; ++ bool restrict_suid_sgid; + + unsigned long personality; + bool lock_personality; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index cdf4d14c4e..49e938d0ce 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -76,6 +76,7 @@ $1.SystemCallErrorNumber, config_parse_syscall_errno, 0, + $1.MemoryDenyWriteExecute, config_parse_bool, 0, offsetof($1, exec_context.memory_deny_write_execute) + $1.RestrictNamespaces, config_parse_restrict_namespaces, 0, offsetof($1, exec_context) + $1.RestrictRealtime, config_parse_bool, 0, offsetof($1, exec_context.restrict_realtime) ++$1.RestrictSUIDSGID, config_parse_bool, 0, offsetof($1, exec_context.restrict_suid_sgid) + $1.RestrictAddressFamilies, config_parse_address_families, 0, offsetof($1, exec_context) + $1.LockPersonality, config_parse_bool, 0, offsetof($1, exec_context.lock_personality)', + `$1.SystemCallFilter, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 +@@ -84,6 +85,7 @@ $1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CO + $1.MemoryDenyWriteExecute, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 + $1.RestrictNamespaces, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 + $1.RestrictRealtime, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 ++$1.RestrictSUIDSGID, config_parse_warn_compat, DISABLED_CONFIGURATION 0 + $1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 + $1.LockPersonality, config_parse_warn_compat, DISABLED_CONFIGURATION, 0') + $1.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 055edd6e22..3c42e97b7a 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -697,7 +697,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + "PrivateMounts", "NoNewPrivileges", "SyslogLevelPrefix", + "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC", + "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups", +- "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality")) ++ "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality" "RestrictSUIDSGID")) + + return bus_append_parse_boolean(m, field, eq); + +diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +index d8d1fc68b8..eab1820e20 100644 +--- a/test/fuzz/fuzz-unit-file/directives.service ++++ b/test/fuzz/fuzz-unit-file/directives.service +@@ -849,6 +849,7 @@ ReserveVT= + RestrictAddressFamilies= + RestrictNamespaces= + RestrictRealtime= ++RestrictSUIDSGID= + RuntimeDirectory= + RuntimeDirectoryMode= + RuntimeDirectoryPreserve= diff --git a/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch b/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch new file mode 100644 index 0000000..ffdc4bf --- /dev/null +++ b/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch @@ -0,0 +1,52 @@ +From 3d338556760632b9c8b646a719d56e02e3ad2088 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 19:20:35 +0100 +Subject: [PATCH] analyze: check for RestrictSUIDSGID= in "systemd-analyze + security" + +And let's give it a heigh weight, since it pretty much can be used for +bad things only. + +(cherry picked from commit 9d880b70ba5c6ca83c82952f4c90e86e56c7b70c) +Related: #1687512 +--- + src/analyze/analyze-security.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +index eec040d5c3..969101c57b 100644 +--- a/src/analyze/analyze-security.c ++++ b/src/analyze/analyze-security.c +@@ -69,6 +69,7 @@ struct security_info { + + uint64_t restrict_namespaces; + bool restrict_realtime; ++ bool restrict_suid_sgid; + + char *root_directory; + char *root_image; +@@ -1130,6 +1131,16 @@ static const struct security_assessor security_assessor_table[] = { + .assess = assess_bool, + .offset = offsetof(struct security_info, restrict_realtime), + }, ++ { ++ .id = "RestrictSUIDSGID=", ++ .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictSUIDSGID=", ++ .description_good = "SUID/SGID file creation by service is restricted", ++ .description_bad = "Service may create SUID/SGID files", ++ .weight = 1000, ++ .range = 1, ++ .assess = assess_bool, ++ .offset = offsetof(struct security_info, restrict_suid_sgid), ++ }, + { + .id = "RestrictNamespaces=~CLONE_NEWUSER", + .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=", +@@ -1862,6 +1873,7 @@ static int acquire_security_info(sd_bus *bus, const char *name, struct security_ + { "RestrictAddressFamilies", "(bas)", property_read_restrict_address_families, 0 }, + { "RestrictNamespaces", "t", NULL, offsetof(struct security_info, restrict_namespaces) }, + { "RestrictRealtime", "b", NULL, offsetof(struct security_info, restrict_realtime) }, ++ { "RestrictSUIDSGID", "b", NULL, offsetof(struct security_info, restrict_suid_sgid) }, + { "RootDirectory", "s", NULL, offsetof(struct security_info, root_directory) }, + { "RootImage", "s", NULL, offsetof(struct security_info, root_image) }, + { "SupplementaryGroups", "as", NULL, offsetof(struct security_info, supplementary_groups) }, diff --git a/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch b/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch new file mode 100644 index 0000000..f362587 --- /dev/null +++ b/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch @@ -0,0 +1,83 @@ +From 797ebaa8240aefc39de3d1713468b221c83ed3f5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 19:45:32 +0100 +Subject: [PATCH] man: document the new RestrictSUIDSGID= setting + +(cherry picked from commit 7445db6eb70e8d5989f481d0c5a08ace7047ae5b) +Related: #1687512 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.exec.xml | 41 +++++++++++++++++++++++++++------------ + 2 files changed, 30 insertions(+), 12 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 0ea444b133..c2b5c0dcce 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -149,6 +149,7 @@ All execution-related settings are available for transient units. + ✓ MemoryDenyWriteExecute= + ✓ RestrictNamespaces= + ✓ RestrictRealtime= ++✓ RestrictSUIDSGID= + ✓ RestrictAddressFamilies= + ✓ LockPersonality= + ✓ LimitCPU= +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 87fb8b34f4..45ed1864f8 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -348,18 +348,19 @@ CapabilityBoundingSet=~CAP_B CAP_C + + NoNewPrivileges= + +- Takes a boolean argument. If true, ensures that the service process and all its children can +- never gain new privileges through execve() (e.g. via setuid or setgid bits, or filesystem +- capabilities). This is the simplest and most effective way to ensure that a process and its children can never +- elevate privileges again. Defaults to false, but certain settings override this and ignore the value of this +- setting. This is the case when SystemCallFilter=, +- SystemCallArchitectures=, RestrictAddressFamilies=, +- RestrictNamespaces=, PrivateDevices=, +- ProtectKernelTunables=, ProtectKernelModules=, +- MemoryDenyWriteExecute=, RestrictRealtime=, or +- LockPersonality= are specified. Note that even if this setting is overridden by them, +- systemctl show shows the original value of this setting. Also see +- No New Privileges ++ Takes a boolean argument. If true, ensures that the service process and all its ++ children can never gain new privileges through execve() (e.g. via setuid or ++ setgid bits, or filesystem capabilities). This is the simplest and most effective way to ensure that ++ a process and its children can never elevate privileges again. Defaults to false, but certain ++ settings override this and ignore the value of this setting. This is the case when ++ SystemCallFilter=, SystemCallArchitectures=, ++ RestrictAddressFamilies=, RestrictNamespaces=, ++ PrivateDevices=, ProtectKernelTunables=, ++ ProtectKernelModules=, MemoryDenyWriteExecute=, ++ RestrictRealtime=, RestrictSUIDSGID= or ++ LockPersonality= are specified. Note that even if this setting is overridden by ++ them, systemctl show shows the original value of this setting. Also see No New Privileges + Flag. + + +@@ -1274,6 +1275,22 @@ RestrictNamespaces=~cgroup net + that actually require them. Defaults to off. + + ++ ++ RestrictSUIDSGID= ++ ++ Takes a boolean argument. If set, any attempts to set the set-user-ID (SUID) or ++ set-group-ID (SGID) bits on files or directories will be denied (for details on these bits see ++ inode7). If ++ running in user mode, or in system mode, but without the CAP_SYS_ADMIN ++ capability (e.g. setting User=), NoNewPrivileges=yes is ++ implied. As the SUID/SGID bits are mechanisms to elevate privileges, and allows users to acquire the ++ identity of other users, it is recommended to restrict creation of SUID/SGID files to the few ++ programs that actually require them. Note that this restricts marking of any type of file system ++ object with these bits, including both regular files and directories (where the SGID is a different ++ meaning than for files, see documentation). Defaults to off. ++ ++ + + RemoveIPC= + diff --git a/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch b/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch new file mode 100644 index 0000000..8a9917f --- /dev/null +++ b/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch @@ -0,0 +1,157 @@ +From b0573f1a6f8022aed4954d5ca19cc037d25cd5e7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 19:52:20 +0100 +Subject: [PATCH] units: turn on RestrictSUIDSGID= in most of our long-running + daemons + +(cherry picked from commit 62aa29247c3d74bcec0607c347f2be23cd90675d) +Related: #1687512 +--- + units/systemd-coredump@.service.in | 1 + + units/systemd-hostnamed.service.in | 1 + + units/systemd-journal-remote.service.in | 1 + + units/systemd-journald.service.in | 1 + + units/systemd-localed.service.in | 1 + + units/systemd-logind.service.in | 1 + + units/systemd-networkd.service.in | 1 + + units/systemd-resolved.service.in | 1 + + units/systemd-timedated.service.in | 1 + + units/systemd-timesyncd.service.in | 1 + + units/systemd-udevd.service.in | 3 ++- + 11 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in +index 68a68a5055..d69ebd8b24 100644 +--- a/units/systemd-coredump@.service.in ++++ b/units/systemd-coredump@.service.in +@@ -33,6 +33,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native +diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in +index 4e5470dd29..97d4e142bc 100644 +--- a/units/systemd-hostnamed.service.in ++++ b/units/systemd-hostnamed.service.in +@@ -29,6 +29,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service sethostname + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native +diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in +index a94265f215..3c914f5a40 100644 +--- a/units/systemd-journal-remote.service.in ++++ b/units/systemd-journal-remote.service.in +@@ -28,6 +28,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 ++RestrictSUIDSGID=yes + SystemCallArchitectures=native + LockPersonality=yes + LogsDirectory=journal/remote +diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in +index e109b25792..ab9ec35ff8 100644 +--- a/units/systemd-journald.service.in ++++ b/units/systemd-journald.service.in +@@ -21,6 +21,7 @@ Sockets=systemd-journald.socket systemd-journald-dev-log.socket + ExecStart=@rootlibexecdir@/systemd-journald + Restart=always + RestartSec=0 ++RestrictSUIDSGID=yes + StandardOutput=null + WatchdogSec=3min + FileDescriptorStoreMax=4224 +diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in +index ce043db154..b87d60e9eb 100644 +--- a/units/systemd-localed.service.in ++++ b/units/systemd-localed.service.in +@@ -29,6 +29,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native +diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in +index 6953fac55b..086338e03b 100644 +--- a/units/systemd-logind.service.in ++++ b/units/systemd-logind.service.in +@@ -30,6 +30,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX AF_NETLINK ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native +diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in +index 371ab3a9cf..a0f34ac738 100644 +--- a/units/systemd-networkd.service.in ++++ b/units/systemd-networkd.service.in +@@ -39,6 +39,7 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes ++RestrictSUIDSGID=yes + RuntimeDirectory=systemd/netif + RuntimeDirectoryPreserve=yes + +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index aaed406ab2..6c2ad5ca86 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -41,6 +41,7 @@ SystemCallFilter=@system-service + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native + LockPersonality=yes ++RestrictSUIDSGID=yes + RuntimeDirectory=systemd/resolve + RuntimeDirectoryPreserve=yes + +diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in +index 662b39557a..1da2bc4bb0 100644 +--- a/units/systemd-timedated.service.in ++++ b/units/systemd-timedated.service.in +@@ -27,6 +27,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service @clock + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native +diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in +index 4a490b6e16..c2b9551726 100644 +--- a/units/systemd-timesyncd.service.in ++++ b/units/systemd-timesyncd.service.in +@@ -37,6 +37,7 @@ MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes + RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 ++RestrictSUIDSGID=yes + RuntimeDirectory=systemd/timesync + SystemCallFilter=@system-service @clock + SystemCallErrorNumber=EPERM +diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in +index fd9ead3bb8..970cf0f290 100644 +--- a/units/systemd-udevd.service.in ++++ b/units/systemd-udevd.service.in +@@ -27,8 +27,9 @@ WatchdogSec=3min + TasksMax=infinity + PrivateMounts=yes + MemoryDenyWriteExecute=yes +-RestrictRealtime=yes + RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 ++RestrictRealtime=yes ++RestrictSUIDSGID=yes + SystemCallFilter=@system-service @module @raw-io + SystemCallErrorNumber=EPERM + SystemCallArchitectures=native diff --git a/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch b/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch new file mode 100644 index 0000000..df4279c --- /dev/null +++ b/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch @@ -0,0 +1,89 @@ +From 11f5677752f9b78239214b3064e5a2c3712d71b1 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Mar 2019 20:19:38 +0100 +Subject: [PATCH] core: imply NNP and SUID/SGID restriction for DynamicUser=yes + service + +Let's be safe, rather than sorry. This way DynamicUser=yes services can +neither take benefit of, nor create SUID/SGID binaries. + +Given that DynamicUser= is a recent addition only we should be able to +get away with turning this on, even though this is strictly speaking a +binary compatibility breakage. + +(cherry picked from commit bf65b7e0c9fc215897b676ab9a7c9d1c688143ba) +Resolves: #1687512 +--- + man/systemd.exec.xml | 16 ++++++++++------ + src/core/unit.c | 10 ++++++++-- + 2 files changed, 18 insertions(+), 8 deletions(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 45ed1864f8..bdaed68162 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -229,7 +229,9 @@ + created by the executed processes is bound to the runtime of the service, and hence the lifetime of the dynamic + user/group. Since /tmp and /var/tmp are usually the only + world-writable directories on a system this ensures that a unit making use of dynamic user/group allocation +- cannot leave files around after unit termination. Moreover ProtectSystem=strict and ++ cannot leave files around after unit termination. Furthermore NoNewPrivileges= and ++ RestrictSUIDSGID= are implicitly enabled to ensure that processes invoked cannot take benefit ++ or create SUID/SGID files or directories. Moreover ProtectSystem=strict and + ProtectHome=read-only are implied, thus prohibiting the service to write to arbitrary file + system locations. In order to allow the service to write to certain directories, they have to be whitelisted + using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't create +@@ -357,11 +359,12 @@ CapabilityBoundingSet=~CAP_B CAP_C + RestrictAddressFamilies=, RestrictNamespaces=, + PrivateDevices=, ProtectKernelTunables=, + ProtectKernelModules=, MemoryDenyWriteExecute=, +- RestrictRealtime=, RestrictSUIDSGID= or +- LockPersonality= are specified. Note that even if this setting is overridden by +- them, systemctl show shows the original value of this setting. Also see RestrictRealtime=, RestrictSUIDSGID=, ++ DynamicUser= or LockPersonality= are specified. Note that even ++ if this setting is overridden by them, systemctl show shows the original value of ++ this setting. Also see No New Privileges +- Flag. ++ Flag. + + + +@@ -1288,7 +1291,8 @@ RestrictNamespaces=~cgroup net + identity of other users, it is recommended to restrict creation of SUID/SGID files to the few + programs that actually require them. Note that this restricts marking of any type of file system + object with these bits, including both regular files and directories (where the SGID is a different +- meaning than for files, see documentation). Defaults to off. ++ meaning than for files, see documentation). This option is implied if DynamicUser= ++ is enabled. Defaults to off. + + + +diff --git a/src/core/unit.c b/src/core/unit.c +index 115739f4c6..e1f5e6f7bd 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4161,14 +4161,20 @@ int unit_patch_contexts(Unit *u) { + return -ENOMEM; + } + +- /* If the dynamic user option is on, let's make sure that the unit can't leave its UID/GID +- * around in the file system or on IPC objects. Hence enforce a strict sandbox. */ ++ /* If the dynamic user option is on, let's make sure that the unit can't leave its ++ * UID/GID around in the file system or on IPC objects. Hence enforce a strict ++ * sandbox. */ + + ec->private_tmp = true; + ec->remove_ipc = true; + ec->protect_system = PROTECT_SYSTEM_STRICT; + if (ec->protect_home == PROTECT_HOME_NO) + ec->protect_home = PROTECT_HOME_READ_ONLY; ++ ++ /* Make sure this service can neither benefit from SUID/SGID binaries nor create ++ * them. */ ++ ec->no_new_privileges = true; ++ ec->restrict_suid_sgid = true; + } + } + diff --git a/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch b/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch new file mode 100644 index 0000000..d8d2f87 --- /dev/null +++ b/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch @@ -0,0 +1,555 @@ +From b55c9b8e717d1967e6aa16c1e2646fc81d899ab7 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Mon, 29 Jul 2019 17:50:05 +0200 +Subject: [PATCH] cgroup: introduce support for cgroup v2 CPUSET controller + +Introduce support for configuring cpus and mems for processes using +cgroup v2 CPUSET controller. This allows users to limit which cpus +and memory NUMA nodes can be used by processes to better utilize +system resources. + +The cgroup v2 interfaces to control it are cpuset.cpus and cpuset.mems +where the requested configuration is written. However, it doesn't mean +that the requested configuration will be actually used as parent cgroup +may limit the cpus or mems as well. In order to reflect the real +configuration cgroup v2 provides read-only files cpuset.cpus.effective +and cpuset.mems.effective which are exported to users as well. + +(cherry picked from commit 047f5d63d7a1ab75073f8485e2f9b550d25b0772) + +Related: #1724617 +--- + doc/TRANSIENT-SETTINGS.md | 2 + + man/systemd.resource-control.xml | 30 +++++++++++++ + src/basic/cgroup-util.c | 1 + + src/basic/cgroup-util.h | 2 + + src/core/cgroup.c | 63 +++++++++++++++++++++++++++ + src/core/cgroup.h | 5 +++ + src/core/dbus-cgroup.c | 59 +++++++++++++++++++++++++ + src/core/dbus-unit.c | 48 ++++++++++++++++++++ + src/core/load-fragment-gperf.gperf.m4 | 2 + + src/core/load-fragment.c | 38 ++++++++++++++++ + src/core/load-fragment.h | 2 + + src/shared/bus-unit-util.c | 16 +++++++ + src/systemctl/systemctl.c | 2 +- + src/test/test-cgroup-mask.c | 3 +- + 14 files changed, 271 insertions(+), 2 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index c2b5c0dcce..0b2ad66dcb 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -218,6 +218,8 @@ All cgroup/resource control settings are available for transient units + ✓ CPUShares= + ✓ StartupCPUShares= + ✓ CPUQuota= ++✓ AllowedCPUs= ++✓ AllowedMemoryNodes= + ✓ MemoryAccounting= + ✓ MemoryLow= + ✓ MemoryHigh= +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 370c110592..4329742e94 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -201,6 +201,36 @@ + + + ++ ++ AllowedCPUs= ++ ++ ++ Restrict processes to be executed on specific CPUs. Takes a list of CPU indices or ranges separated by either ++ whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a dash. ++ ++ Setting AllowedCPUs= doesn't guarantee that all of the CPUs will be used by the processes ++ as it may be limited by parent units. The effective configuration is reported as EffectiveCPUs=. ++ ++ This setting is supported only with the unified control group hierarchy. ++ ++ ++ ++ ++ AllowedMemoryNodes= ++ ++ ++ Restrict processes to be executed on specific memory NUMA nodes. Takes a list of memory NUMA nodes indices ++ or ranges separated by either whitespace or commas. Memory NUMA nodes ranges are specified by the lower and upper ++ CPU indices separated by a dash. ++ ++ Setting AllowedMemoryNodes= doesn't guarantee that all of the memory NUMA nodes will ++ be used by the processes as it may be limited by parent units. The effective configuration is reported as ++ EffectiveMemoryNodes=. ++ ++ This setting is supported only with the unified control group hierarchy. ++ ++ ++ + + MemoryAccounting= + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 038ece4b06..6f47c3aacb 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -2763,6 +2763,7 @@ bool fd_is_cgroup_fs(int fd) { + static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = { + [CGROUP_CONTROLLER_CPU] = "cpu", + [CGROUP_CONTROLLER_CPUACCT] = "cpuacct", ++ [CGROUP_CONTROLLER_CPUSET] = "cpuset", + [CGROUP_CONTROLLER_IO] = "io", + [CGROUP_CONTROLLER_BLKIO] = "blkio", + [CGROUP_CONTROLLER_MEMORY] = "memory", +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index 26e3ae0404..b414600dca 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -21,6 +21,7 @@ + typedef enum CGroupController { + CGROUP_CONTROLLER_CPU, + CGROUP_CONTROLLER_CPUACCT, /* v1 only */ ++ CGROUP_CONTROLLER_CPUSET, /* v2 only */ + CGROUP_CONTROLLER_IO, /* v2 only */ + CGROUP_CONTROLLER_BLKIO, /* v1 only */ + CGROUP_CONTROLLER_MEMORY, +@@ -36,6 +37,7 @@ typedef enum CGroupController { + typedef enum CGroupMask { + CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU), + CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT), ++ CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET), + CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO), + CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO), + CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY), +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 76eafdc082..664d269483 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -161,9 +161,14 @@ void cgroup_context_done(CGroupContext *c) { + + c->ip_address_allow = ip_address_access_free_all(c->ip_address_allow); + c->ip_address_deny = ip_address_access_free_all(c->ip_address_deny); ++ ++ cpu_set_reset(&c->cpuset_cpus); ++ cpu_set_reset(&c->cpuset_mems); + } + + void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { ++ _cleanup_free_ char *cpuset_cpus = NULL; ++ _cleanup_free_ char *cpuset_mems = NULL; + CGroupIODeviceLimit *il; + CGroupIODeviceWeight *iw; + CGroupBlockIODeviceBandwidth *b; +@@ -177,6 +182,9 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + + prefix = strempty(prefix); + ++ cpuset_cpus = cpu_set_to_range_string(&c->cpuset_cpus); ++ cpuset_mems = cpu_set_to_range_string(&c->cpuset_mems); ++ + fprintf(f, + "%sCPUAccounting=%s\n" + "%sIOAccounting=%s\n" +@@ -189,6 +197,8 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sCPUShares=%" PRIu64 "\n" + "%sStartupCPUShares=%" PRIu64 "\n" + "%sCPUQuotaPerSecSec=%s\n" ++ "%sAllowedCPUs=%s\n" ++ "%sAllowedMemoryNodes=%s\n" + "%sIOWeight=%" PRIu64 "\n" + "%sStartupIOWeight=%" PRIu64 "\n" + "%sBlockIOWeight=%" PRIu64 "\n" +@@ -212,6 +222,8 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + prefix, c->cpu_shares, + prefix, c->startup_cpu_shares, + prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1), ++ prefix, cpuset_cpus, ++ prefix, cpuset_mems, + prefix, c->io_weight, + prefix, c->startup_io_weight, + prefix, c->blockio_weight, +@@ -541,6 +553,21 @@ static uint64_t cgroup_cpu_weight_to_shares(uint64_t weight) { + CGROUP_CPU_SHARES_MIN, CGROUP_CPU_SHARES_MAX); + } + ++static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) { ++ _cleanup_free_ char *buf = NULL; ++ int r; ++ ++ buf = cpu_set_to_range_string(&cpus); ++ if (!buf) ++ return; ++ ++ r = cg_set_attribute("cpuset", u->cgroup_path, name, buf); ++ if (r < 0) ++ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to set %s: %m", name); ++ ++} ++ + static bool cgroup_context_has_io_config(CGroupContext *c) { + return c->io_accounting || + c->io_weight != CGROUP_WEIGHT_INVALID || +@@ -766,6 +793,11 @@ static void cgroup_context_apply( + } + } + ++ if ((apply_mask & CGROUP_MASK_CPUSET) && !is_root) { ++ cgroup_apply_unified_cpuset(u, c->cpuset_cpus, "cpuset.cpus"); ++ cgroup_apply_unified_cpuset(u, c->cpuset_mems, "cpuset.mems"); ++ } ++ + if (apply_mask & CGROUP_MASK_IO) { + bool has_io = cgroup_context_has_io_config(c); + bool has_blockio = cgroup_context_has_blockio_config(c); +@@ -1068,6 +1100,9 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) { + c->cpu_quota_per_sec_usec != USEC_INFINITY) + mask |= CGROUP_MASK_CPUACCT | CGROUP_MASK_CPU; + ++ if (c->cpuset_cpus.set || c->cpuset_mems.set) ++ mask |= CGROUP_MASK_CPUSET; ++ + if (cgroup_context_has_io_config(c) || cgroup_context_has_blockio_config(c)) + mask |= CGROUP_MASK_IO | CGROUP_MASK_BLKIO; + +@@ -2697,4 +2732,32 @@ static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = + [CGROUP_STRICT] = "strict", + }; + ++int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) { ++ _cleanup_free_ char *v = NULL; ++ int r; ++ ++ assert(u); ++ assert(cpus); ++ ++ if (!u->cgroup_path) ++ return -ENODATA; ++ ++ if ((u->cgroup_realized_mask & CGROUP_MASK_CPUSET) == 0) ++ return -ENODATA; ++ ++ r = cg_all_unified(); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return -ENODATA; ++ if (r > 0) ++ r = cg_get_attribute("cpuset", u->cgroup_path, name, &v); ++ if (r == -ENOENT) ++ return -ENODATA; ++ if (r < 0) ++ return r; ++ ++ return parse_cpu_set_full(v, cpus, false, NULL, NULL, 0, NULL); ++} ++ + DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy); +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 2d2ff6fc3c..da10575394 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -4,6 +4,7 @@ + #include + + #include "cgroup-util.h" ++#include "cpu-set-util.h" + #include "ip-address-access.h" + #include "list.h" + #include "time-util.h" +@@ -77,6 +78,9 @@ struct CGroupContext { + uint64_t startup_cpu_weight; + usec_t cpu_quota_per_sec_usec; + ++ CPUSet cpuset_cpus; ++ CPUSet cpuset_mems; ++ + uint64_t io_weight; + uint64_t startup_io_weight; + LIST_HEAD(CGroupIODeviceWeight, io_device_weights); +@@ -205,3 +209,4 @@ const char* cgroup_device_policy_to_string(CGroupDevicePolicy i) _const_; + CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_; + + bool unit_cgroup_delegate(Unit *u); ++int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name); +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 540bc77aed..30d4e83932 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -53,6 +53,27 @@ static int property_get_delegate_controllers( + return sd_bus_message_close_container(reply); + } + ++static int property_get_cpuset( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ CPUSet *cpus = userdata; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ assert(bus); ++ assert(reply); ++ assert(cpus); ++ ++ (void) cpu_set_to_dbus(cpus, &array, &allocated); ++ return sd_bus_message_append_array(reply, 'y', array, allocated); ++} ++ + static int property_get_io_device_weight( + sd_bus *bus, + const char *path, +@@ -283,6 +304,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0), + SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0), + SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0), ++ SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus), 0), ++ SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0), + SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0), + SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0), + SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0), +@@ -671,6 +694,42 @@ int bus_cgroup_set_property( + + return 1; + ++ } else if (STR_IN_SET(name, "AllowedCPUs", "AllowedMemoryNodes")) { ++ const void *a; ++ size_t n; ++ _cleanup_(cpu_set_reset) CPUSet new_set = {}; ++ ++ r = sd_bus_message_read_array(message, 'y', &a, &n); ++ if (r < 0) ++ return r; ++ ++ r = cpu_set_from_dbus(a, n, &new_set); ++ if (r < 0) ++ return r; ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ _cleanup_free_ char *setstr = NULL; ++ _cleanup_free_ char *data = NULL; ++ CPUSet *set; ++ ++ setstr = cpu_set_to_range_string(&new_set); ++ ++ if (streq(name, "AllowedCPUs")) ++ set = &c->cpuset_cpus; ++ else ++ set = &c->cpuset_mems; ++ ++ if (asprintf(&data, "%s=%s", name, setstr) < 0) ++ return -ENOMEM; ++ ++ cpu_set_reset(set); ++ cpu_set_add_all(set, &new_set); ++ unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET); ++ unit_write_setting(u, flags, name, data); ++ } ++ ++ return 1; ++ + } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) { + const char *path; + unsigned n = 0; +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index c5bca10979..aa15e47754 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -752,6 +752,52 @@ static int property_get_cpu_usage( + return sd_bus_message_append(reply, "t", ns); + } + ++static int property_get_cpuset_cpus( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ Unit *u = userdata; ++ _cleanup_(cpu_set_reset) CPUSet cpus = {}; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ assert(bus); ++ assert(reply); ++ assert(u); ++ ++ (void) unit_get_cpuset(u, &cpus, "cpuset.cpus.effective"); ++ (void) cpu_set_to_dbus(&cpus, &array, &allocated); ++ return sd_bus_message_append_array(reply, 'y', array, allocated); ++} ++ ++static int property_get_cpuset_mems( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ Unit *u = userdata; ++ _cleanup_(cpu_set_reset) CPUSet mems = {}; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ assert(bus); ++ assert(reply); ++ assert(u); ++ ++ (void) unit_get_cpuset(u, &mems, "cpuset.mems.effective"); ++ (void) cpu_set_to_dbus(&mems, &array, &allocated); ++ return sd_bus_message_append_array(reply, 'y', array, allocated); ++} ++ + static int property_get_cgroup( + sd_bus *bus, + const char *path, +@@ -1074,6 +1120,8 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = { + SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0), + SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0), + SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0), ++ SD_BUS_PROPERTY("EffectiveCPUs", "ay", property_get_cpuset_cpus, 0, 0), ++ SD_BUS_PROPERTY("EffectiveMemoryNodes", "ay", property_get_cpuset_mems, 0, 0), + SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0), + SD_BUS_PROPERTY("IPIngressBytes", "t", property_get_ip_counter, 0, 0), + SD_BUS_PROPERTY("IPIngressPackets", "t", property_get_ip_counter, 0, 0), +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 49e938d0ce..ebb44df487 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -167,6 +167,8 @@ $1.StartupCPUWeight, config_parse_cg_weight, 0, + $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.cpu_shares) + $1.StartupCPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.startup_cpu_shares) + $1.CPUQuota, config_parse_cpu_quota, 0, offsetof($1, cgroup_context) ++$1.CPUSetCpus, config_parse_cpuset_cpus, 0, offsetof($1, cgroup_context) ++$1.CPUSetMems, config_parse_cpuset_mems, 0, offsetof($1, cgroup_context) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 35dd595098..6debf82401 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3011,6 +3011,44 @@ int config_parse_cpu_quota( + return 0; + } + ++int config_parse_cpuset_cpus( ++ 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) { ++ ++ CGroupContext *c = data; ++ ++ (void) parse_cpu_set_extend(rvalue, &c->cpuset_cpus, true, unit, filename, line, lvalue); ++ ++ return 0; ++} ++ ++int config_parse_cpuset_mems( ++ 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) { ++ ++ CGroupContext *c = data; ++ ++ (void) parse_cpu_set_extend(rvalue, &c->cpuset_mems, true, unit, filename, line, lvalue); ++ ++ return 0; ++} ++ + int config_parse_memory_limit( + const char *unit, + const char *filename, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index f2ca1b8ee7..6612e1fb32 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -86,6 +86,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_set_status); + CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv); + CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems); + CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota); ++CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_cpus); ++CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_mems); + CONFIG_PARSER_PROTOTYPE(config_parse_protect_home); + CONFIG_PARSER_PROTOTYPE(config_parse_protect_system); + CONFIG_PARSER_PROTOTYPE(config_parse_bus_name); +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 3c42e97b7a..8f3b463c6b 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -396,6 +396,22 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + + return bus_append_cg_cpu_shares_parse(m, field, eq); + ++ if (STR_IN_SET(field, "AllowedCPUs", "AllowedMemoryNodes")) { ++ _cleanup_(cpu_set_reset) CPUSet cpuset = {}; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; ++ ++ r = parse_cpu_set(eq, &cpuset); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse %s value: %s", field, eq); ++ ++ r = cpu_set_to_dbus(&cpuset, &array, &allocated); ++ if (r < 0) ++ return log_error_errno(r, "Failed to serialize CPUSet: %m"); ++ ++ return bus_append_byte_array(m, field, array, allocated); ++ } ++ + if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) + + return bus_append_cg_blkio_weight_parse(m, field, eq); +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 7274921e6d..a3074bc5e3 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4892,7 +4892,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + print_prop(name, "%s", h); + + return 1; +- } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask")) { ++ } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask", "AllowedCPUs", "AllowedMemoryNodes", "EffectiveCPUs", "EffectiveMemoryNodes")) { + _cleanup_free_ char *affinity = NULL; + _cleanup_(cpu_set_reset) CPUSet set = {}; + const void *a; +diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c +index d65959edf1..93c3f5d856 100644 +--- a/src/test/test-cgroup-mask.c ++++ b/src/test/test-cgroup-mask.c +@@ -104,9 +104,10 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) { + + static void test_cg_mask_to_string(void) { + test_cg_mask_to_string_one(0, NULL); +- test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct io blkio memory devices pids"); ++ test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids"); + test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu"); + test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct"); ++ test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset"); + test_cg_mask_to_string_one(CGROUP_MASK_IO, "io"); + test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio"); + test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory"); diff --git a/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch b/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch new file mode 100644 index 0000000..0a146a3 --- /dev/null +++ b/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch @@ -0,0 +1,38 @@ +From e809564cfa5af01a26075682d49f81a987c41dd8 Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Wed, 2 Oct 2019 11:58:16 +0200 +Subject: [PATCH] pid1: fix DefaultTasksMax initialization + +Otherwise DefaultTasksMax is always set to "inifinity". + +This was broken by fb39af4ce42. + +(cherry picked from commit c0000de87d2c7934cb1f4ba66a533a85277600ff) + +Resolves: #1809037 +--- + src/core/main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index d6550ea161..45d09b1e11 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2088,7 +2088,7 @@ static void reset_arguments(void) { + arg_default_blockio_accounting = false; + arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT; + arg_default_tasks_accounting = true; +- arg_default_tasks_max = UINT64_MAX; ++ arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); + arg_machine_id = (sd_id128_t) {}; + arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; + +@@ -2103,8 +2103,6 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + assert(saved_rlimit_nofile); + assert(saved_rlimit_memlock); + +- arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U); +- + /* Assign configuration defaults */ + reset_arguments(); + diff --git a/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch b/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch new file mode 100644 index 0000000..d2c0d2e --- /dev/null +++ b/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch @@ -0,0 +1,40 @@ +From 5fc2d94fbf8271bb340e834f832af5d890c267bf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Tue, 3 Mar 2020 11:45:00 +0100 +Subject: [PATCH] cgroup: make sure that cpuset is supported on cgroup v2 and + disabled with v1 + +Resolves: #1808940 + +(rhel-only) +--- + src/basic/cgroup-util.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 6f47c3aacb..92bc1f2543 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -2353,10 +2353,10 @@ int cg_mask_supported(CGroupMask *ret) { + if (r < 0) + return r; + +- /* Currently, we support the cpu, memory, io and pids ++ /* Currently, we support the cpu, memory, io, pids and cpuset + * controller in the unified hierarchy, mask + * everything else off. */ +- mask &= CGROUP_MASK_CPU | CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS; ++ mask &= CGROUP_MASK_CPU | CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS | CGROUP_MASK_CPUSET; + + } else { + CGroupController c; +@@ -2367,6 +2367,9 @@ int cg_mask_supported(CGroupMask *ret) { + for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { + const char *n; + ++ if (c == CGROUP_CONTROLLER_CPUSET) ++ continue; ++ + n = cgroup_controller_to_string(c); + if (controller_is_accessible(n) >= 0) + mask |= CGROUP_CONTROLLER_TO_MASK(c); diff --git a/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch b/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch new file mode 100644 index 0000000..811b91e --- /dev/null +++ b/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch @@ -0,0 +1,380 @@ +From 90dda340e4adeb1126639a849d4f31ae327fdc4b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 25 Jun 2019 23:01:40 +0200 +Subject: [PATCH] test: introduce TEST-36-NUMAPOLICY + +(cherry picked from commit 8f65e26508969610ac934d1aadbade8223bfcaac) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/Makefile | 1 + + test/TEST-36-NUMAPOLICY/test.sh | 51 +++++ + test/TEST-36-NUMAPOLICY/testsuite.sh | 292 +++++++++++++++++++++++++++ + 3 files changed, 344 insertions(+) + create mode 120000 test/TEST-36-NUMAPOLICY/Makefile + create mode 100755 test/TEST-36-NUMAPOLICY/test.sh + create mode 100755 test/TEST-36-NUMAPOLICY/testsuite.sh + +diff --git a/test/TEST-36-NUMAPOLICY/Makefile b/test/TEST-36-NUMAPOLICY/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-36-NUMAPOLICY/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +new file mode 100755 +index 0000000000..a0d8623e8e +--- /dev/null ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -0,0 +1,51 @@ ++#!/bin/bash ++set -e ++TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options" ++TEST_NO_NSPAWN=1 ++QEMU_OPTIONS="-numa node,nodeid=0" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ inst_binary mktemp ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < $journalLog ++} ++ ++stopJournalctl() { ++ # Wait a few seconds until the messages get properly queued... ++ sleep $journalSleep ++ # ...and then force journald to write them to the backing storage ++ # Also, using journalctl --sync should be better than using SIGRTMIN+1, as ++ # the --sync wait until the synchronization is complete ++ echo "Force journald to write all queued messages" ++ journalctl --sync ++ kill -s TERM $COPROC_PID ++} ++ ++checkNUMA() { ++ # NUMA enabled system should have at least NUMA node0 ++ test -e /sys/devices/system/node/node0 ++} ++ ++writePID1NUMAPolicy() { ++ echo [Manager] > $confDir/numa.conf ++ echo NUMAPolicy=$1 >> $confDir/numa.conf ++ echo NUMAMask=$2>> $confDir/numa.conf ++} ++ ++writeTestUnit() { ++ echo [Service] > $testUnitFile ++ echo ExecStart=/bin/sleep 3600 >> $testUnitFile ++ mkdir -p $testUnitFile.d/ ++} ++ ++writeTestUnitNUMAPolicy() { ++ echo [Service] > $testUnitNUMAConf ++ echo NUMAPolicy=$1 >> $testUnitNUMAConf ++ echo NUMAMask=$2>> $testUnitNUMAConf ++ systemctl daemon-reload ++} ++ ++pid1ReloadWithStrace() { ++ startStrace ++ systemctl daemon-reload ++ stopStrace ++} ++ ++pid1ReloadWithJournal() { ++ startJournalctl ++ systemctl daemon-reload ++ stopJournalctl ++} ++ ++pid1StartUnitWithStrace() { ++ startStrace '-f' ++ systemctl start $1 ++ sleep $sleepAfterStart ++ stopStrace ++} ++ ++pid1StartUnitWithJournal() { ++ startJournalctl ++ systemctl start $1 ++ sleep $sleepAfterStart ++ stopJournalctl ++} ++ ++pid1StopUnit() { ++ systemctl stop $1 ++} ++ ++systemctlCheckNUMAProperties() { ++ local LOGFILE="$(mktemp)" ++ systemctl show -p NUMAPolicy $1 > "$LOGFILE" ++ grep "NUMAPolicy=$2" "$LOGFILE" ++ ++ > "$LOGFILE" ++ ++ if [ -n $3 ]; then ++ systemctl show -p NUMAMask $1 > "$LOGFILE" ++ grep "NUMAMask=$3" "$LOGFILE" ++ fi ++} ++ ++checkNUMA ++writeTestUnit ++ ++# Create systemd config drop-in directory ++confDir="/etc/systemd/system.conf.d/" ++mkdir -p "$confDir" ++ ++echo "PID1 NUMAPolicy support - Default policy w/o mask" ++writePID1NUMAPolicy "default" ++pid1ReloadWithStrace ++# Kernel requires that nodemask argument is set to NULL when setting default policy ++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++echo "PID1 NUMAPolicy support - Default policy w/ mask" ++writePID1NUMAPolicy "default" "0" ++pid1ReloadWithStrace ++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++echo "PID1 NUMAPolicy support - Bind policy w/o mask" ++writePID1NUMAPolicy "bind" ++pid1ReloadWithJournal ++grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++echo "PID1 NUMAPolicy support - Bind policy w/ mask" ++writePID1NUMAPolicy "bind" "0" ++pid1ReloadWithStrace ++grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog ++ ++echo "PID1 NUMAPolicy support - Interleave policy w/o mask" ++writePID1NUMAPolicy "interleave" ++pid1ReloadWithJournal ++grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++echo "PID1 NUMAPolicy support - Interleave policy w/ mask" ++writePID1NUMAPolicy "interleave" "0" ++pid1ReloadWithStrace ++grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog ++ ++echo "PID1 NUMAPolicy support - Preferred policy w/o mask" ++writePID1NUMAPolicy "preferred" ++pid1ReloadWithJournal ++# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default ++! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++echo "PID1 NUMAPolicy support - Preferred policy w/ mask" ++writePID1NUMAPolicy "preferred" "0" ++pid1ReloadWithStrace ++grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog ++ ++echo "PID1 NUMAPolicy support - Local policy w/o mask" ++writePID1NUMAPolicy "local" ++pid1ReloadWithStrace ++# Kernel requires that nodemask argument is set to NULL when setting default policy ++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++ ++echo "PID1 NUMAPolicy support - Local policy w/ mask" ++writePID1NUMAPolicy "local" "0" ++pid1ReloadWithStrace ++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++ ++echo "Unit file NUMAPolicy support - Default policy w/o mask" ++writeTestUnitNUMAPolicy "default" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "default" ++pid1StopUnit $testUnit ++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++echo "Unit file NUMAPolicy support - Default policy w/ mask" ++writeTestUnitNUMAPolicy "default" "0" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "default" "0" ++pid1StopUnit $testUnit ++# Maks must be ignored ++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++echo "Unit file NUMAPolicy support - Bind policy w/o mask" ++writeTestUnitNUMAPolicy "bind" ++pid1StartUnitWithJournal $testUnit ++pid1StopUnit $testUnit ++grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++echo "Unit file NUMAPolicy support - Bind policy w/ mask" ++writeTestUnitNUMAPolicy "bind" "0" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "bind" "0" ++pid1StopUnit $testUnit ++grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog ++ ++echo "Unit file NUMAPolicy support - Interleave policy w/o mask" ++writeTestUnitNUMAPolicy "interleave" ++pid1StartUnitWithStrace $testUnit ++pid1StopUnit $testUnit ++grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++echo "Unit file NUMAPolicy support - Interleave policy w/ mask" ++writeTestUnitNUMAPolicy "interleave" "0" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "interleave" "0" ++pid1StopUnit $testUnit ++grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog ++ ++echo "Unit file NUMAPolicy support - Preferred policy w/o mask" ++writeTestUnitNUMAPolicy "preferred" ++pid1StartUnitWithJournal $testUnit ++systemctlCheckNUMAProperties $testUnit "preferred" ++pid1StopUnit $testUnit ++! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++echo "Unit file NUMAPolicy support - Preferred policy w/ mask" ++writeTestUnitNUMAPolicy "preferred" "0" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "preferred" "0" ++pid1StopUnit $testUnit ++grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog ++ ++echo "Unit file NUMAPolicy support - Local policy w/o mask" ++writeTestUnitNUMAPolicy "local" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "local" ++pid1StopUnit $testUnit ++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++ ++echo "Unit file NUMAPolicy support - Local policy w/ mask" ++writeTestUnitNUMAPolicy "local" "0" ++pid1StartUnitWithStrace $testUnit ++systemctlCheckNUMAProperties $testUnit "local" "0" ++pid1StopUnit $testUnit ++# Maks must be ignored ++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++ ++echo "systemd-run NUMAPolicy support" ++runUnit='numa-systemd-run-test.service' ++ ++systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "default" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "default" "" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "bind" "0" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "interleave" "0" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "preferred" "0" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "local" ++pid1StopUnit $runUnit ++ ++systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000 ++systemctlCheckNUMAProperties $runUnit "local" "" ++pid1StopUnit $runUnit ++ ++# Cleanup ++rm -rf $testDir ++rm -rf $confDir ++systemctl daemon-reload ++ ++systemd-analyze log-level info ++ ++echo OK > /testok ++ ++exit 0 diff --git a/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch b/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch new file mode 100644 index 0000000..afe81ee --- /dev/null +++ b/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch @@ -0,0 +1,52 @@ +From b93a2617d49d9636801130d974995cabe6335b71 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 1 Jul 2019 09:27:59 +0200 +Subject: [PATCH] test: replace `tail -f` with journal cursor which should + be... + +more reliable + +(cherry picked from commit d0b2178f3e79f302702bd7140766eee03643f734) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/testsuite.sh | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index e15087b137..306a96b517 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -29,6 +29,9 @@ testUnitNUMAConf="$testUnitFile.d/numa.conf" + journalSleep=5 + sleepAfterStart=1 + ++# Journal cursor for easier navigation ++journalCursorFile="jounalCursorFile" ++ + startStrace() { + coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1 + } +@@ -38,18 +41,16 @@ stopStrace() { + } + + startJournalctl() { +- coproc journalctl -u init.scope -f > $journalLog ++ # Save journal's cursor for later navigation ++ journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat + } + + stopJournalctl() { +- # Wait a few seconds until the messages get properly queued... +- sleep $journalSleep +- # ...and then force journald to write them to the backing storage +- # Also, using journalctl --sync should be better than using SIGRTMIN+1, as ++ # Using journalctl --sync should be better than using SIGRTMIN+1, as + # the --sync wait until the synchronization is complete + echo "Force journald to write all queued messages" + journalctl --sync +- kill -s TERM $COPROC_PID ++ journalctl -u init.scope --cursor-file="$journalCursorFile" > "$journalLog" + } + + checkNUMA() { diff --git a/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch b/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch new file mode 100644 index 0000000..88a2e32 --- /dev/null +++ b/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch @@ -0,0 +1,58 @@ +From d6d43b81df76d571d57f83ceb050c8b4ac4701b8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 1 Jul 2019 13:08:26 +0200 +Subject: [PATCH] test: support MPOL_LOCAL matching in unpatched strace + versions + +The MPOL_LOCAL constant is not recognized in current strace versions. +Let's match at least the numerical value of this constant until the +strace patch is approved & merged. + +(cherry picked from commit ac14396d027023e1be910327989cb422cb2f6724) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/testsuite.sh | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index 306a96b517..a4134bdeca 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -173,12 +173,16 @@ echo "PID1 NUMAPolicy support - Local policy w/o mask" + writePID1NUMAPolicy "local" + pid1ReloadWithStrace + # Kernel requires that nodemask argument is set to NULL when setting default policy +-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++# The unpatched versions of strace don't recognize the MPOL_LOCAL constant and ++# return a numerical constant instead (with a comment): ++# set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0 ++# Let's cover this scenario as well ++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog + + echo "PID1 NUMAPolicy support - Local policy w/ mask" + writePID1NUMAPolicy "local" "0" + pid1ReloadWithStrace +-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog + + echo "Unit file NUMAPolicy support - Default policy w/o mask" + writeTestUnitNUMAPolicy "default" +@@ -240,7 +244,7 @@ writeTestUnitNUMAPolicy "local" + pid1StartUnitWithStrace $testUnit + systemctlCheckNUMAProperties $testUnit "local" + pid1StopUnit $testUnit +-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog + + echo "Unit file NUMAPolicy support - Local policy w/ mask" + writeTestUnitNUMAPolicy "local" "0" +@@ -248,7 +252,7 @@ pid1StartUnitWithStrace $testUnit + systemctlCheckNUMAProperties $testUnit "local" "0" + pid1StopUnit $testUnit + # Maks must be ignored +-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog ++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog + + echo "systemd-run NUMAPolicy support" + runUnit='numa-systemd-run-test.service' diff --git a/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch b/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch new file mode 100644 index 0000000..24d38b3 --- /dev/null +++ b/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch @@ -0,0 +1,50 @@ +From 60813b55f9b5b44b14f38bbc1b8c0d2b30e3f6c7 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 1 Jul 2019 19:53:45 +0200 +Subject: [PATCH] test: make sure the strace process is indeed dead + +It may take a few moments for the strace process to properly terminate +and write all logs to the backing storage + +(cherry picked from commit 56425e54a2140f47b4560b51c5db08aa2de199a6) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/test.sh | 2 +- + test/TEST-36-NUMAPOLICY/testsuite.sh | 3 +++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +index a0d8623e8e..f0a321e7a1 100755 +--- a/test/TEST-36-NUMAPOLICY/test.sh ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -16,7 +16,7 @@ test_setup() { + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment +- inst_binary mktemp ++ dracut_install mktemp + + # mask some services that we do not want to run in these tests + ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index a4134bdeca..daed8fcc1c 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -38,6 +38,8 @@ startStrace() { + + stopStrace() { + kill -s TERM $COPROC_PID ++ # Make sure the strace process is indeed dead ++ while kill -0 $COPROC_PID 2>/dev/null; do sleep 0.1; done + } + + startJournalctl() { +@@ -80,6 +82,7 @@ writeTestUnitNUMAPolicy() { + pid1ReloadWithStrace() { + startStrace + systemctl daemon-reload ++ sleep $sleepAfterStart + stopStrace + } + diff --git a/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch b/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch new file mode 100644 index 0000000..eef7e87 --- /dev/null +++ b/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch @@ -0,0 +1,36 @@ +From ad3e4a0f010c9497b01d89de54213af982f8afd2 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 2 Jul 2019 09:52:45 +0200 +Subject: [PATCH] test: skip the test on systems without NUMA support + +(cherry picked from commit b030847163e9bd63d3dd6eec6ac7f336411faba6) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/testsuite.sh | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index daed8fcc1c..4b715d305a 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -123,7 +123,18 @@ systemctlCheckNUMAProperties() { + fi + } + +-checkNUMA ++if ! checkNUMA; then ++ echo >&2 "NUMA is not supported on this machine, skipping the test" ++ ++ # FIXME: add some sanity checks to verify systemd behaves correctly with ++ # NUMA disabled together with NUMAPolicy= and NUMAMask= ++ ++ systemd-analyze log-level info ++ echo OK > /testok ++ ++ exit 0 ++fi ++ + writeTestUnit + + # Create systemd config drop-in directory diff --git a/SOURCES/0338-test-give-strace-some-time-to-initialize.patch b/SOURCES/0338-test-give-strace-some-time-to-initialize.patch new file mode 100644 index 0000000..6cd3426 --- /dev/null +++ b/SOURCES/0338-test-give-strace-some-time-to-initialize.patch @@ -0,0 +1,30 @@ +From 66f6f6304d87b2fe0c4f91373c7d1b836de1b054 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 23 Jul 2019 00:56:04 +0200 +Subject: [PATCH] test: give strace some time to initialize + +The `coproc` implementation seems to be a little bit different in older +bash versions, so the `strace` is sometimes started AFTER `systemctl +daemon-reload`, which causes unexpected fails. Let's help it a little by +sleeping for a bit. + +(cherry picked from commit c7367d7cfdfdcec98f8659f0ed3f1d7b77123903) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/testsuite.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index 4b715d305a..1c8cf7e6b6 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -34,6 +34,8 @@ journalCursorFile="jounalCursorFile" + + startStrace() { + coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1 ++ # Wait for strace to properly "initialize" ++ sleep $sleepAfterStart + } + + stopStrace() { diff --git a/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch b/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch new file mode 100644 index 0000000..2bb77a3 --- /dev/null +++ b/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch @@ -0,0 +1,391 @@ +From 8239ecf0b4b8bbe5b3c17964d230d13cee4d900a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 5 Aug 2019 14:38:45 +0200 +Subject: [PATCH] test: add a simple sanity check for systems without NUMA + support + +(cherry picked from commit 92f8e978923f962a57d744c5f358520ac06f7892) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/testsuite.sh | 350 ++++++++++++++------------- + 1 file changed, 180 insertions(+), 170 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index 1c8cf7e6b6..a5ac788178 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -50,11 +50,12 @@ startJournalctl() { + } + + stopJournalctl() { ++ local unit="${1:-init.scope}" + # Using journalctl --sync should be better than using SIGRTMIN+1, as + # the --sync wait until the synchronization is complete + echo "Force journald to write all queued messages" + journalctl --sync +- journalctl -u init.scope --cursor-file="$journalCursorFile" > "$journalLog" ++ journalctl -u $unit --cursor-file="$journalCursorFile" > "$journalLog" + } + + checkNUMA() { +@@ -125,181 +126,190 @@ systemctlCheckNUMAProperties() { + fi + } + +-if ! checkNUMA; then +- echo >&2 "NUMA is not supported on this machine, skipping the test" +- +- # FIXME: add some sanity checks to verify systemd behaves correctly with +- # NUMA disabled together with NUMAPolicy= and NUMAMask= +- +- systemd-analyze log-level info +- echo OK > /testok +- +- exit 0 +-fi +- + writeTestUnit + + # Create systemd config drop-in directory + confDir="/etc/systemd/system.conf.d/" + mkdir -p "$confDir" + +-echo "PID1 NUMAPolicy support - Default policy w/o mask" +-writePID1NUMAPolicy "default" +-pid1ReloadWithStrace +-# Kernel requires that nodemask argument is set to NULL when setting default policy +-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog +- +-echo "PID1 NUMAPolicy support - Default policy w/ mask" +-writePID1NUMAPolicy "default" "0" +-pid1ReloadWithStrace +-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog +- +-echo "PID1 NUMAPolicy support - Bind policy w/o mask" +-writePID1NUMAPolicy "bind" +-pid1ReloadWithJournal +-grep "Failed to set NUMA memory policy: Invalid argument" $journalLog +- +-echo "PID1 NUMAPolicy support - Bind policy w/ mask" +-writePID1NUMAPolicy "bind" "0" +-pid1ReloadWithStrace +-grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog +- +-echo "PID1 NUMAPolicy support - Interleave policy w/o mask" +-writePID1NUMAPolicy "interleave" +-pid1ReloadWithJournal +-grep "Failed to set NUMA memory policy: Invalid argument" $journalLog +- +-echo "PID1 NUMAPolicy support - Interleave policy w/ mask" +-writePID1NUMAPolicy "interleave" "0" +-pid1ReloadWithStrace +-grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog +- +-echo "PID1 NUMAPolicy support - Preferred policy w/o mask" +-writePID1NUMAPolicy "preferred" +-pid1ReloadWithJournal +-# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default +-! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog +- +-echo "PID1 NUMAPolicy support - Preferred policy w/ mask" +-writePID1NUMAPolicy "preferred" "0" +-pid1ReloadWithStrace +-grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog +- +-echo "PID1 NUMAPolicy support - Local policy w/o mask" +-writePID1NUMAPolicy "local" +-pid1ReloadWithStrace +-# Kernel requires that nodemask argument is set to NULL when setting default policy +-# The unpatched versions of strace don't recognize the MPOL_LOCAL constant and +-# return a numerical constant instead (with a comment): +-# set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0 +-# Let's cover this scenario as well +-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog +- +-echo "PID1 NUMAPolicy support - Local policy w/ mask" +-writePID1NUMAPolicy "local" "0" +-pid1ReloadWithStrace +-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog +- +-echo "Unit file NUMAPolicy support - Default policy w/o mask" +-writeTestUnitNUMAPolicy "default" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "default" +-pid1StopUnit $testUnit +-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog +- +-echo "Unit file NUMAPolicy support - Default policy w/ mask" +-writeTestUnitNUMAPolicy "default" "0" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "default" "0" +-pid1StopUnit $testUnit +-# Maks must be ignored +-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog +- +-echo "Unit file NUMAPolicy support - Bind policy w/o mask" +-writeTestUnitNUMAPolicy "bind" +-pid1StartUnitWithJournal $testUnit +-pid1StopUnit $testUnit +-grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog +- +-echo "Unit file NUMAPolicy support - Bind policy w/ mask" +-writeTestUnitNUMAPolicy "bind" "0" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "bind" "0" +-pid1StopUnit $testUnit +-grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog +- +-echo "Unit file NUMAPolicy support - Interleave policy w/o mask" +-writeTestUnitNUMAPolicy "interleave" +-pid1StartUnitWithStrace $testUnit +-pid1StopUnit $testUnit +-grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog +- +-echo "Unit file NUMAPolicy support - Interleave policy w/ mask" +-writeTestUnitNUMAPolicy "interleave" "0" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "interleave" "0" +-pid1StopUnit $testUnit +-grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog +- +-echo "Unit file NUMAPolicy support - Preferred policy w/o mask" +-writeTestUnitNUMAPolicy "preferred" +-pid1StartUnitWithJournal $testUnit +-systemctlCheckNUMAProperties $testUnit "preferred" +-pid1StopUnit $testUnit +-! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog +- +-echo "Unit file NUMAPolicy support - Preferred policy w/ mask" +-writeTestUnitNUMAPolicy "preferred" "0" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "preferred" "0" +-pid1StopUnit $testUnit +-grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog +- +-echo "Unit file NUMAPolicy support - Local policy w/o mask" +-writeTestUnitNUMAPolicy "local" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "local" +-pid1StopUnit $testUnit +-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog +- +-echo "Unit file NUMAPolicy support - Local policy w/ mask" +-writeTestUnitNUMAPolicy "local" "0" +-pid1StartUnitWithStrace $testUnit +-systemctlCheckNUMAProperties $testUnit "local" "0" +-pid1StopUnit $testUnit +-# Maks must be ignored +-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog +- +-echo "systemd-run NUMAPolicy support" +-runUnit='numa-systemd-run-test.service' +- +-systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "default" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "default" "" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "bind" "0" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "interleave" "0" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "preferred" "0" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "local" +-pid1StopUnit $runUnit +- +-systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000 +-systemctlCheckNUMAProperties $runUnit "local" "" +-pid1StopUnit $runUnit ++if ! checkNUMA; then ++ echo >&2 "NUMA is not supported on this machine, switching to a simple sanity check" ++ ++ echo "PID1 NUMAPolicy=default && NUMAMask=0 check without NUMA support" ++ writePID1NUMAPolicy "default" "0" ++ startJournalctl ++ systemctl daemon-reload ++ stopJournalctl ++ grep "NUMA support not available, ignoring" "$journalLog" ++ ++ echo "systemd-run NUMAPolicy=default && NUMAMask=0 check without NUMA support" ++ runUnit='numa-systemd-run-test.service' ++ startJournalctl ++ systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000 ++ sleep $sleepAfterStart ++ pid1StopUnit $runUnit ++ stopJournalctl $runUnit ++ grep "NUMA support not available, ignoring" "$journalLog" ++ ++else ++ echo "PID1 NUMAPolicy support - Default policy w/o mask" ++ writePID1NUMAPolicy "default" ++ pid1ReloadWithStrace ++ # Kernel requires that nodemask argument is set to NULL when setting default policy ++ grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Default policy w/ mask" ++ writePID1NUMAPolicy "default" "0" ++ pid1ReloadWithStrace ++ grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Bind policy w/o mask" ++ writePID1NUMAPolicy "bind" ++ pid1ReloadWithJournal ++ grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++ echo "PID1 NUMAPolicy support - Bind policy w/ mask" ++ writePID1NUMAPolicy "bind" "0" ++ pid1ReloadWithStrace ++ grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Interleave policy w/o mask" ++ writePID1NUMAPolicy "interleave" ++ pid1ReloadWithJournal ++ grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++ echo "PID1 NUMAPolicy support - Interleave policy w/ mask" ++ writePID1NUMAPolicy "interleave" "0" ++ pid1ReloadWithStrace ++ grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Preferred policy w/o mask" ++ writePID1NUMAPolicy "preferred" ++ pid1ReloadWithJournal ++ # Preferred policy with empty node mask is actually allowed and should reset allocation policy to default ++ ! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog ++ ++ echo "PID1 NUMAPolicy support - Preferred policy w/ mask" ++ writePID1NUMAPolicy "preferred" "0" ++ pid1ReloadWithStrace ++ grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Local policy w/o mask" ++ writePID1NUMAPolicy "local" ++ pid1ReloadWithStrace ++ # Kernel requires that nodemask argument is set to NULL when setting default policy ++ # The unpatched versions of strace don't recognize the MPOL_LOCAL constant and ++ # return a numerical constant instead (with a comment): ++ # set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0 ++ # Let's cover this scenario as well ++ grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog ++ ++ echo "PID1 NUMAPolicy support - Local policy w/ mask" ++ writePID1NUMAPolicy "local" "0" ++ pid1ReloadWithStrace ++ grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Default policy w/o mask" ++ writeTestUnitNUMAPolicy "default" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "default" ++ pid1StopUnit $testUnit ++ grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Default policy w/ mask" ++ writeTestUnitNUMAPolicy "default" "0" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "default" "0" ++ pid1StopUnit $testUnit ++ # Maks must be ignored ++ grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Bind policy w/o mask" ++ writeTestUnitNUMAPolicy "bind" ++ pid1StartUnitWithJournal $testUnit ++ pid1StopUnit $testUnit ++ grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++ echo "Unit file NUMAPolicy support - Bind policy w/ mask" ++ writeTestUnitNUMAPolicy "bind" "0" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "bind" "0" ++ pid1StopUnit $testUnit ++ grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Interleave policy w/o mask" ++ writeTestUnitNUMAPolicy "interleave" ++ pid1StartUnitWithStrace $testUnit ++ pid1StopUnit $testUnit ++ grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++ echo "Unit file NUMAPolicy support - Interleave policy w/ mask" ++ writeTestUnitNUMAPolicy "interleave" "0" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "interleave" "0" ++ pid1StopUnit $testUnit ++ grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Preferred policy w/o mask" ++ writeTestUnitNUMAPolicy "preferred" ++ pid1StartUnitWithJournal $testUnit ++ systemctlCheckNUMAProperties $testUnit "preferred" ++ pid1StopUnit $testUnit ++ ! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog ++ ++ echo "Unit file NUMAPolicy support - Preferred policy w/ mask" ++ writeTestUnitNUMAPolicy "preferred" "0" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "preferred" "0" ++ pid1StopUnit $testUnit ++ grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Local policy w/o mask" ++ writeTestUnitNUMAPolicy "local" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "local" ++ pid1StopUnit $testUnit ++ grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog ++ ++ echo "Unit file NUMAPolicy support - Local policy w/ mask" ++ writeTestUnitNUMAPolicy "local" "0" ++ pid1StartUnitWithStrace $testUnit ++ systemctlCheckNUMAProperties $testUnit "local" "0" ++ pid1StopUnit $testUnit ++ # Maks must be ignored ++ grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog ++ ++ echo "systemd-run NUMAPolicy support" ++ runUnit='numa-systemd-run-test.service' ++ ++ systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "default" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "default" "" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "bind" "0" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "interleave" "0" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "preferred" "0" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "local" ++ pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "local" "" ++ pid1StopUnit $runUnit ++fi + + # Cleanup + rm -rf $testDir diff --git a/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch b/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch new file mode 100644 index 0000000..716dcf2 --- /dev/null +++ b/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch @@ -0,0 +1,35 @@ +From 772f08f8255d7ab921c344ab4243249cbd1c37fc Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sat, 10 Aug 2019 16:05:07 +0200 +Subject: [PATCH] test: drop the missed || exit 1 expression + +...as we've already done in the rest of the testsuite, see +cc469c3dfc398210f38f819d367e68646c71d8da + +(cherry picked from commit 67c434b03f8a24f5350f017dfb4b2464406046db) + +Related: #1808940 +--- + test/TEST-36-NUMAPOLICY/test.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +index f0a321e7a1..3b3b120423 100755 +--- a/test/TEST-36-NUMAPOLICY/test.sh ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -1,5 +1,6 @@ + #!/bin/bash + set -e ++ + TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options" + TEST_NO_NSPAWN=1 + QEMU_OPTIONS="-numa node,nodeid=0" +@@ -41,7 +42,7 @@ EOF + cp testsuite.sh $initdir/ + + setup_testsuite +- ) || return 1 ++ ) + setup_nspawn_root + + ddebug "umount $TESTDIR/root" diff --git a/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch b/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch new file mode 100644 index 0000000..83a7f55 --- /dev/null +++ b/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch @@ -0,0 +1,59 @@ +From 0bef8805c81eecfe3960bf00b6022837e4979198 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 3 Mar 2020 15:54:29 +0100 +Subject: [PATCH] test: replace cursor file with a plain cursor + +systemd in RHEL 8 doesn't support the --cursor-file option, so let's +fall back to a plain cursor string + +Related: #1808940 +rhel-only +--- + test/TEST-36-NUMAPOLICY/test.sh | 2 +- + test/TEST-36-NUMAPOLICY/testsuite.sh | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh +index 3b3b120423..7cc909765b 100755 +--- a/test/TEST-36-NUMAPOLICY/test.sh ++++ b/test/TEST-36-NUMAPOLICY/test.sh +@@ -17,7 +17,7 @@ test_setup() { + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment +- dracut_install mktemp ++ dracut_install mktemp awk + + # mask some services that we do not want to run in these tests + ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index a5ac788178..bffac4ffe6 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -30,7 +30,7 @@ journalSleep=5 + sleepAfterStart=1 + + # Journal cursor for easier navigation +-journalCursorFile="jounalCursorFile" ++journalCursor="" + + startStrace() { + coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1 +@@ -46,7 +46,7 @@ stopStrace() { + + startJournalctl() { + # Save journal's cursor for later navigation +- journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat ++ journalCursor="$(journalctl --no-pager --show-cursor -n0 -ocat | awk '{print $3}')" + } + + stopJournalctl() { +@@ -55,7 +55,7 @@ stopJournalctl() { + # the --sync wait until the synchronization is complete + echo "Force journald to write all queued messages" + journalctl --sync +- journalctl -u $unit --cursor-file="$journalCursorFile" > "$journalLog" ++ journalctl -u $unit --after-cursor="$journalCursor" > "$journalLog" + } + + checkNUMA() { diff --git a/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch b/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch new file mode 100644 index 0000000..4fee429 --- /dev/null +++ b/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch @@ -0,0 +1,32 @@ +From ed282d8d84fa32aaef21994d92d1d3dbfa281094 Mon Sep 17 00:00:00 2001 +From: Ryan Gonzalez +Date: Fri, 22 Feb 2019 23:45:03 -0600 +Subject: [PATCH] cryptsetup: Treat key file errors as a failed password + attempt + +6f177c7dc092eb68762b4533d41b14244adb2a73 caused key file errors to immediately fail, which would make it hard to correct an issue due to e.g. a crypttab typo or a damaged key file. + +Closes #11723. + +(cherry picked from commit c20db3887569e0c0d9c0e2845c5286e7edf0133a) + +Related: #1763155 +--- + src/cryptsetup/cryptsetup.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 33c215eaa1..11162eb722 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -558,6 +558,10 @@ static int attach_luks_or_plain(struct crypt_device *cd, + log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); + return -EAGAIN; /* Log actual error, but return EAGAIN */ + } ++ if (r == -EINVAL) { ++ log_error_errno(r, "Failed to activate with key file '%s'. (Key file missing?)", key_file); ++ return -EAGAIN; /* Log actual error, but return EAGAIN */ ++ } + if (r < 0) + return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file); + } else { diff --git a/SOURCES/0343-swap-finish-the-secondary-swap-units-jobs-if-deactiv.patch b/SOURCES/0343-swap-finish-the-secondary-swap-units-jobs-if-deactiv.patch new file mode 100644 index 0000000..b196d0e --- /dev/null +++ b/SOURCES/0343-swap-finish-the-secondary-swap-units-jobs-if-deactiv.patch @@ -0,0 +1,79 @@ +From b89a1a9d19aa806feb984c8dba25116b5b5a52bc Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Wed, 24 Jul 2019 23:54:48 -0400 +Subject: [PATCH] swap: finish the secondary swap units' jobs if deactivation + of the primary swap unit fails + +Currently, if deactivation of the primary swap unit fails: + + # LANG=C systemctl --no-pager stop dev-mapper-fedora\\x2dswap.swap + Job for dev-mapper-fedora\x2dswap.swap failed. + See "systemctl status "dev-mapper-fedora\\x2dswap.swap"" and "journalctl -xe" for details. + +then there are still the running stop jobs for all the secondary swap units +that follow the primary one: + + # systemctl list-jobs + JOB UNIT TYPE STATE + 3233 dev-disk-by\x2duuid-2dc8b9b1\x2da0a5\x2d44d8\x2d89c4\x2d6cdd26cd5ce0.swap stop running + 3232 dev-dm\x2d1.swap stop running + 3231 dev-disk-by\x2did-dm\x2duuid\x2dLVM\x2dyuXWpCCIurGzz2nkGCVnUFSi7GH6E3ZcQjkKLnF0Fil0RJmhoLN8fcOnDybWCMTj.swap stop running + 3230 dev-disk-by\x2did-dm\x2dname\x2dfedora\x2dswap.swap stop running + 3234 dev-fedora-swap.swap stop running + + 5 jobs listed. + +This remains endlessly because their JobTimeoutUSec is infinity: + + # LANG=C systemctl show -p JobTimeoutUSec dev-fedora-swap.swap + JobTimeoutUSec=infinity + +If this issue happens during system shutdown, the system shutdown appears to +get hang and the system will be forcibly shutdown or rebooted 30 minutes later +by the following configuration: + + # grep -E "^JobTimeout" /usr/lib/systemd/system/reboot.target + JobTimeoutSec=30min + JobTimeoutAction=reboot-force + +The scenario in the real world seems that there is some service unit with +KillMode=none, processes whose memory is being swapped out are not killed +during stop operation in the service unit and then swapoff command fails. + +On the other hand, it works well in successful case of swapoff command because +the secondary jobs monitor /proc/swaps file and can detect deletion of the +corresponding swap file. + +This commit fixes the issue by finishing the secondary swap units' jobs if +deactivation of the primary swap unit fails. + +Fixes: #11577 +(cherry picked from commit 9c1f969d40f84d5cc98d810bab8b24148b2d8928) + +Resolves: #1749622 +--- + src/core/swap.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/core/swap.c b/src/core/swap.c +index e717dbb54a..66a62d8a37 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -682,9 +682,15 @@ static void swap_enter_active(Swap *s, SwapResult f) { + static void swap_enter_dead_or_active(Swap *s, SwapResult f) { + assert(s); + +- if (s->from_proc_swaps) ++ if (s->from_proc_swaps) { ++ Swap *other; ++ + swap_enter_active(s, f); +- else ++ ++ LIST_FOREACH_OTHERS(same_devnode, other, s) ++ if (UNIT(other)->job) ++ swap_enter_dead_or_active(other, f); ++ } else + swap_enter_dead(s, f); + } + diff --git a/SOURCES/0344-resolved-Recover-missing-PrivateTmp-yes-and-ProtectS.patch b/SOURCES/0344-resolved-Recover-missing-PrivateTmp-yes-and-ProtectS.patch new file mode 100644 index 0000000..9c59bdc --- /dev/null +++ b/SOURCES/0344-resolved-Recover-missing-PrivateTmp-yes-and-ProtectS.patch @@ -0,0 +1,41 @@ +From d9ae3222cfbd5d2a48e6dbade6617085cc76f1c1 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Tue, 25 Feb 2020 13:35:50 -0500 +Subject: [PATCH] resolved: Recover missing PrivateTmp=yes and + ProtectSystem=strict + +Since the commit b61e8046ebcb28225423fc0073183d68d4c577c4, +systemd-resolved.service often fails to start with the following message: + + Failed at step NAMESPACE spawning /usr/bin/mount: Read-only file system + +This is because dropping DynamicUser=yes dropped implicit PrivateTmp=yes and +also implicit After=systemd-tmpfiles-setup.service, and thus +systemd-resolved.service can start before systemd-remount-fs.service. As a +result, mount operations associated with PrivateDevices= can be performed to +still read-only filesystems. + +To fix this issue, it's better to recover PrivateTmp=yes and +ProtectSystem=strict just as the upstream commit +62fb7e80fcc45a1530ed58a84980be8cfafa9b3e (Revert "resolve: enable DynamicUser= +for systemd-resolved.service"). + +Resolves: #1810869 +--- + units/systemd-resolved.service.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index 6c2ad5ca86..aad1a53a5f 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -28,7 +28,9 @@ WatchdogSec=3min + User=systemd-resolve + CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE ++PrivateTmp=yes + PrivateDevices=yes ++ProtectSystems=strict + ProtectHome=yes + ProtectControlGroups=yes + ProtectKernelTunables=yes diff --git a/SOURCES/0345-bus_open-leak-sd_event_source-when-udevadm-trigger.patch b/SOURCES/0345-bus_open-leak-sd_event_source-when-udevadm-trigger.patch new file mode 100644 index 0000000..b5536da --- /dev/null +++ b/SOURCES/0345-bus_open-leak-sd_event_source-when-udevadm-trigger.patch @@ -0,0 +1,30 @@ +From 448b34284c09469eaa2168291ccb34afc3e4cc1d Mon Sep 17 00:00:00 2001 +From: ven <2988994+hexiaowen@users.noreply.github.com> +Date: Wed, 22 May 2019 14:24:28 +0800 +Subject: [PATCH] =?UTF-8?q?bus=5Fopen=20leak=20sd=5Fevent=5Fsource=20when?= + =?UTF-8?q?=20udevadm=20trigger=E3=80=82?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On my host, when executing the udevadm trigger, I only receive the change event, which causes memleak + +(cherry picked from commit b2774a3ae692113e1f47a336a6c09bac9cfb49ad) + +Resolves: #1798504 +--- + src/login/logind-button.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/login/logind-button.c b/src/login/logind-button.c +index 0defa6b9ba..9944eb2316 100644 +--- a/src/login/logind-button.c ++++ b/src/login/logind-button.c +@@ -341,6 +341,7 @@ int button_open(Button *b) { + + (void) button_set_mask(b); + ++ b->io_event_source = sd_event_source_unref(b->io_event_source); + r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b); + if (r < 0) { + log_error_errno(r, "Failed to add button event: %m"); diff --git a/SOURCES/0346-core-rework-StopWhenUnneeded-logic.patch b/SOURCES/0346-core-rework-StopWhenUnneeded-logic.patch new file mode 100644 index 0000000..fcddae3 --- /dev/null +++ b/SOURCES/0346-core-rework-StopWhenUnneeded-logic.patch @@ -0,0 +1,339 @@ +From 5458256264c97eee521caf07c705f549a0f0bd55 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 9 Aug 2018 16:26:27 +0200 +Subject: [PATCH] core: rework StopWhenUnneeded= logic + +Previously, we'd act immediately on StopWhenUnneeded= when a unit state +changes. With this rework we'll maintain a queue instead: whenever +there's the chance that StopWhenUneeded= might have an effect we enqueue +the unit, and process it later when we have nothing better to do. + +This should make the implementation a bit more reliable, as the unit notify event +cannot immediately enqueue tons of side-effect jobs that might +contradict each other, but we do so only in a strictly ordered fashion, +from the main event loop. + +This slightly changes the check when to consider a unit "unneeded". +Previously, we'd assume that a unit in "deactivating" state could also +be cleaned up. With this new logic we'll only consider units unneeded +that are fully up and have no job queued. This means that whenever +there's something pending for a unit we won't clean it up. + +(cherry picked from commit a3c1168ac293f16d9343d248795bb4c246aaff4a) + +Resolves: #1798046 +--- + src/core/manager.c | 43 ++++++++++++++++ + src/core/manager.h | 3 ++ + src/core/unit.c | 122 +++++++++++++++++++++++++-------------------- + src/core/unit.h | 7 +++ + 4 files changed, 120 insertions(+), 55 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 0eae7d46fb..4c04896aaa 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1211,6 +1211,45 @@ static unsigned manager_dispatch_gc_job_queue(Manager *m) { + return n; + } + ++static unsigned manager_dispatch_stop_when_unneeded_queue(Manager *m) { ++ unsigned n = 0; ++ Unit *u; ++ int r; ++ ++ assert(m); ++ ++ while ((u = m->stop_when_unneeded_queue)) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ assert(m->stop_when_unneeded_queue); ++ ++ assert(u->in_stop_when_unneeded_queue); ++ LIST_REMOVE(stop_when_unneeded_queue, m->stop_when_unneeded_queue, u); ++ u->in_stop_when_unneeded_queue = false; ++ ++ n++; ++ ++ if (!unit_is_unneeded(u)) ++ continue; ++ ++ log_unit_debug(u, "Unit is not needed anymore."); ++ ++ /* If stopping a unit fails continuously we might enter a stop loop here, hence stop acting on the ++ * service being unnecessary after a while. */ ++ ++ if (!ratelimit_below(&u->auto_stop_ratelimit)) { ++ log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently."); ++ continue; ++ } ++ ++ /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ ++ r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, &error, NULL); ++ if (r < 0) ++ log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r)); ++ } ++ ++ return n; ++} ++ + static void manager_clear_jobs_and_units(Manager *m) { + Unit *u; + +@@ -1228,6 +1267,7 @@ static void manager_clear_jobs_and_units(Manager *m) { + assert(!m->cleanup_queue); + assert(!m->gc_unit_queue); + assert(!m->gc_job_queue); ++ assert(!m->stop_when_unneeded_queue); + + assert(hashmap_isempty(m->jobs)); + assert(hashmap_isempty(m->units)); +@@ -2824,6 +2864,9 @@ int manager_loop(Manager *m) { + if (manager_dispatch_cgroup_realize_queue(m) > 0) + continue; + ++ if (manager_dispatch_stop_when_unneeded_queue(m) > 0) ++ continue; ++ + if (manager_dispatch_dbus_queue(m) > 0) + continue; + +diff --git a/src/core/manager.h b/src/core/manager.h +index fa47952d24..40568d3c8b 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -130,6 +130,9 @@ struct Manager { + /* Target units whose default target dependencies haven't been set yet */ + LIST_HEAD(Unit, target_deps_queue); + ++ /* Units that might be subject to StopWhenUnneeded= clean-up */ ++ LIST_HEAD(Unit, stop_when_unneeded_queue); ++ + sd_event *event; + + /* This maps PIDs we care about to units that are interested in. We allow multiple units to he interested in +diff --git a/src/core/unit.c b/src/core/unit.c +index e1f5e6f7bd..40f138d25c 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -438,6 +438,22 @@ void unit_add_to_dbus_queue(Unit *u) { + u->in_dbus_queue = true; + } + ++void unit_add_to_stop_when_unneeded_queue(Unit *u) { ++ assert(u); ++ ++ if (u->in_stop_when_unneeded_queue) ++ return; ++ ++ if (!u->stop_when_unneeded) ++ return; ++ ++ if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) ++ return; ++ ++ LIST_PREPEND(stop_when_unneeded_queue, u->manager->stop_when_unneeded_queue, u); ++ u->in_stop_when_unneeded_queue = true; ++} ++ + static void bidi_set_free(Unit *u, Hashmap *h) { + Unit *other; + Iterator i; +@@ -634,6 +650,9 @@ void unit_free(Unit *u) { + if (u->in_target_deps_queue) + LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u); + ++ if (u->in_stop_when_unneeded_queue) ++ LIST_REMOVE(stop_when_unneeded_queue, u->manager->stop_when_unneeded_queue, u); ++ + safe_close(u->ip_accounting_ingress_map_fd); + safe_close(u->ip_accounting_egress_map_fd); + +@@ -1950,55 +1969,71 @@ bool unit_can_reload(Unit *u) { + return UNIT_VTABLE(u)->reload; + } + +-static void unit_check_unneeded(Unit *u) { +- +- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- +- static const UnitDependency needed_dependencies[] = { ++bool unit_is_unneeded(Unit *u) { ++ static const UnitDependency deps[] = { + UNIT_REQUIRED_BY, + UNIT_REQUISITE_OF, + UNIT_WANTED_BY, + UNIT_BOUND_BY, + }; +- +- unsigned j; +- int r; ++ size_t j; + + assert(u); + +- /* If this service shall be shut down when unneeded then do +- * so. */ +- + if (!u->stop_when_unneeded) +- return; ++ return false; + +- if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) +- return; ++ /* Don't clean up while the unit is transitioning or is even inactive. */ ++ if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) ++ return false; ++ if (u->job) ++ return false; + +- for (j = 0; j < ELEMENTSOF(needed_dependencies); j++) { ++ for (j = 0; j < ELEMENTSOF(deps); j++) { + Unit *other; + Iterator i; + void *v; + +- HASHMAP_FOREACH_KEY(v, other, u->dependencies[needed_dependencies[j]], i) +- if (unit_active_or_pending(other) || unit_will_restart(other)) +- return; +- } ++ /* If a dependending unit has a job queued, or is active (or in transitioning), or is marked for ++ * restart, then don't clean this one up. */ + +- /* If stopping a unit fails continuously we might enter a stop +- * loop here, hence stop acting on the service being +- * unnecessary after a while. */ +- if (!ratelimit_below(&u->auto_stop_ratelimit)) { +- log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently."); +- return; ++ HASHMAP_FOREACH_KEY(v, other, u->dependencies[deps[j]], i) { ++ if (u->job) ++ return false; ++ ++ if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) ++ return false; ++ ++ if (unit_will_restart(other)) ++ return false; ++ } + } + +- log_unit_info(u, "Unit not needed anymore. Stopping."); ++ return true; ++} + +- /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ +- r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, &error, NULL); +- if (r < 0) +- log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r)); ++static void check_unneeded_dependencies(Unit *u) { ++ ++ static const UnitDependency deps[] = { ++ UNIT_REQUIRES, ++ UNIT_REQUISITE, ++ UNIT_WANTS, ++ UNIT_BINDS_TO, ++ }; ++ size_t j; ++ ++ assert(u); ++ ++ /* Add all units this unit depends on to the queue that processes StopWhenUnneeded= behaviour. */ ++ ++ for (j = 0; j < ELEMENTSOF(deps); j++) { ++ Unit *other; ++ Iterator i; ++ void *v; ++ ++ HASHMAP_FOREACH_KEY(v, other, u->dependencies[deps[j]], i) ++ unit_add_to_stop_when_unneeded_queue(other); ++ } + } + + static void unit_check_binds_to(Unit *u) { +@@ -2098,29 +2133,6 @@ static void retroactively_stop_dependencies(Unit *u) { + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL); + } + +-static void check_unneeded_dependencies(Unit *u) { +- Unit *other; +- Iterator i; +- void *v; +- +- assert(u); +- assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); +- +- /* Garbage collect services that might not be needed anymore, if enabled */ +- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRES], i) +- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- unit_check_unneeded(other); +- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_WANTS], i) +- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- unit_check_unneeded(other); +- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUISITE], i) +- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- unit_check_unneeded(other); +- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], i) +- if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- unit_check_unneeded(other); +-} +- + void unit_start_on_failure(Unit *u) { + Unit *other; + Iterator i; +@@ -2423,7 +2435,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + } + + /* stop unneeded units regardless if going down was expected or not */ +- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) ++ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + check_unneeded_dependencies(u); + + if (ns != os && ns == UNIT_FAILED) { +@@ -2483,7 +2495,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + + if (!MANAGER_IS_RELOADING(u->manager)) { + /* Maybe we finished startup and are now ready for being stopped because unneeded? */ +- unit_check_unneeded(u); ++ unit_add_to_stop_when_unneeded_queue(u); + + /* Maybe we finished startup, but something we needed has vanished? Let's die then. (This happens when + * something BindsTo= to a Type=oneshot unit, as these units go directly from starting to inactive, +diff --git a/src/core/unit.h b/src/core/unit.h +index 99755823eb..595ee88d43 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -212,6 +212,9 @@ typedef struct Unit { + /* Target dependencies queue */ + LIST_FIELDS(Unit, target_deps_queue); + ++ /* Queue of units with StopWhenUnneeded set that shell be checked for clean-up. */ ++ LIST_FIELDS(Unit, stop_when_unneeded_queue); ++ + /* PIDs we keep an eye on. Note that a unit might have many + * more, but these are the ones we care enough about to + * process SIGCHLD for */ +@@ -322,6 +325,7 @@ typedef struct Unit { + bool in_cgroup_realize_queue:1; + bool in_cgroup_empty_queue:1; + bool in_target_deps_queue:1; ++ bool in_stop_when_unneeded_queue:1; + + bool sent_dbus_new_signal:1; + +@@ -615,6 +619,7 @@ void unit_add_to_dbus_queue(Unit *u); + void unit_add_to_cleanup_queue(Unit *u); + void unit_add_to_gc_queue(Unit *u); + void unit_add_to_target_deps_queue(Unit *u); ++void unit_add_to_stop_when_unneeded_queue(Unit *u); + + int unit_merge(Unit *u, Unit *other); + int unit_merge_by_name(Unit *u, const char *other); +@@ -751,6 +756,8 @@ bool unit_type_supported(UnitType t); + + bool unit_is_pristine(Unit *u); + ++bool unit_is_unneeded(Unit *u); ++ + pid_t unit_control_pid(Unit *u); + pid_t unit_main_pid(Unit *u); + diff --git a/SOURCES/0347-pid1-fix-the-names-of-AllowedCPUs-and-AllowedMemoryN.patch b/SOURCES/0347-pid1-fix-the-names-of-AllowedCPUs-and-AllowedMemoryN.patch new file mode 100644 index 0000000..0431571 --- /dev/null +++ b/SOURCES/0347-pid1-fix-the-names-of-AllowedCPUs-and-AllowedMemoryN.patch @@ -0,0 +1,81 @@ +From 6ecf0a945d6d4187995de7e79e3ed75f4827289a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 24 Nov 2019 14:14:43 +0100 +Subject: [PATCH] pid1: fix the names of AllowedCPUs= and AllowedMemoryNodes= + +The original PR was submitted with CPUSetCpus and CPUSetMems, which was later +changed to AllowedCPUs and AllowedMemmoryNodes everywhere (including the parser +used by systemd-run), but not in the parser for unit files. + +Since we already released -rc1, let's keep support for the old names. I think +we can remove it in a release or two if anyone remembers to do that. + +Fixes #14126. Follow-up for 047f5d63d7a1ab75073f8485e2f9b550d25b0772. + +(cherry picked from commit 0b8d3075872a05e0449906d24421ce192f50c29f) + +Related: #1818054 +--- + src/core/load-fragment-gperf.gperf.m4 | 4 ++-- + src/core/load-fragment.c | 4 ++-- + src/core/load-fragment.h | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index ebb44df487..161c5a2c82 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -161,14 +161,14 @@ $1.KillSignal, config_parse_signal, 0, + )m4_dnl + m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', + `$1.Slice, config_parse_unit_slice, 0, 0 ++$1.AllowedCPUs, config_parse_allowed_cpus, 0, offsetof($1, cgroup_context) ++$1.AllowedMemoryNodes, config_parse_allowed_mems, 0, offsetof($1, cgroup_context) + $1.CPUAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.cpu_accounting) + $1.CPUWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.cpu_weight) + $1.StartupCPUWeight, config_parse_cg_weight, 0, offsetof($1, cgroup_context.startup_cpu_weight) + $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.cpu_shares) + $1.StartupCPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.startup_cpu_shares) + $1.CPUQuota, config_parse_cpu_quota, 0, offsetof($1, cgroup_context) +-$1.CPUSetCpus, config_parse_cpuset_cpus, 0, offsetof($1, cgroup_context) +-$1.CPUSetMems, config_parse_cpuset_mems, 0, offsetof($1, cgroup_context) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 6debf82401..2082166afb 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3011,7 +3011,7 @@ int config_parse_cpu_quota( + return 0; + } + +-int config_parse_cpuset_cpus( ++int config_parse_allowed_cpus( + const char *unit, + const char *filename, + unsigned line, +@@ -3030,7 +3030,7 @@ int config_parse_cpuset_cpus( + return 0; + } + +-int config_parse_cpuset_mems( ++int config_parse_allowed_mems( + const char *unit, + const char *filename, + unsigned line, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index 6612e1fb32..424fa478a7 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -86,8 +86,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_set_status); + CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv); + CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems); + CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota); +-CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_cpus); +-CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_mems); ++CONFIG_PARSER_PROTOTYPE(config_parse_allowed_cpus); ++CONFIG_PARSER_PROTOTYPE(config_parse_allowed_mems); + CONFIG_PARSER_PROTOTYPE(config_parse_protect_home); + CONFIG_PARSER_PROTOTYPE(config_parse_protect_system); + CONFIG_PARSER_PROTOTYPE(config_parse_bus_name); diff --git a/SOURCES/0348-core-fix-re-realization-of-cgroup-siblings.patch b/SOURCES/0348-core-fix-re-realization-of-cgroup-siblings.patch new file mode 100644 index 0000000..173b2e3 --- /dev/null +++ b/SOURCES/0348-core-fix-re-realization-of-cgroup-siblings.patch @@ -0,0 +1,62 @@ +From ca843e40587fb87fe20bd0561b6ccb42aaafc4ab Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 9 Jan 2020 17:30:31 +0100 +Subject: [PATCH] core: fix re-realization of cgroup siblings + +This is a fix-up for eef85c4a3f8054d29383a176f6cebd1ef3a15b9a which +broke this. + +Tracked down by @w-simon + +Fixes: #14453 +(cherry picked from commit 65f6b6bdcb500c576674b5838e4cc4c35e18bfde) + +Related: #1818054 +--- + src/core/cgroup.c | 21 +++++++-------------- + 1 file changed, 7 insertions(+), 14 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 664d269483..3f7665b755 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1796,32 +1796,25 @@ unsigned manager_dispatch_cgroup_realize_queue(Manager *m) { + static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + Unit *slice; + +- /* This adds the siblings of the specified unit and the +- * siblings of all parent units to the cgroup queue. (But +- * neither the specified unit itself nor the parents.) */ ++ /* This adds the siblings of the specified unit and the siblings of all parent units to the cgroup ++ * queue. (But neither the specified unit itself nor the parents.) */ + + while ((slice = UNIT_DEREF(u->slice))) { + Iterator i; + Unit *m; + void *v; + +- HASHMAP_FOREACH_KEY(v, m, u->dependencies[UNIT_BEFORE], i) { +- if (m == u) +- continue; +- +- /* Skip units that have a dependency on the slice +- * but aren't actually in it. */ ++ HASHMAP_FOREACH_KEY(v, m, slice->dependencies[UNIT_BEFORE], i) { ++ /* Skip units that have a dependency on the slice but aren't actually in it. */ + if (UNIT_DEREF(m->slice) != slice) + continue; + +- /* No point in doing cgroup application for units +- * without active processes. */ ++ /* No point in doing cgroup application for units without active processes. */ + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(m))) + continue; + +- /* If the unit doesn't need any new controllers +- * and has current ones realized, it doesn't need +- * any changes. */ ++ /* If the unit doesn't need any new controllers and has current ones realized, it ++ * doesn't need any changes. */ + if (unit_has_mask_realized(m, + unit_get_target_mask(m), + unit_get_enable_mask(m), diff --git a/SOURCES/0349-basic-use-comma-as-separator-in-cpuset-cgroup-cpu-ra.patch b/SOURCES/0349-basic-use-comma-as-separator-in-cpuset-cgroup-cpu-ra.patch new file mode 100644 index 0000000..8d42493 --- /dev/null +++ b/SOURCES/0349-basic-use-comma-as-separator-in-cpuset-cgroup-cpu-ra.patch @@ -0,0 +1,99 @@ +From 9fe3b9c7165afeedcf9f31959c436bcec233bb4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Tue, 14 Apr 2020 16:16:45 +0200 +Subject: [PATCH] basic: use comma as separator in cpuset cgroup cpu ranges + +This is a workaround for +https://bugzilla.redhat.com/show_bug.cgi?id=1819152 and should be +reverted in RHEL-8.3. + +RHEL-only + +Related: #1818054 +--- + src/basic/cpu-set-util.c | 45 ++++++++++++++++++++++++++++++++++++++++ + src/basic/cpu-set-util.h | 1 + + src/core/cgroup.c | 2 +- + 3 files changed, 47 insertions(+), 1 deletion(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 36cb017ae7..51752ad1a6 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -86,6 +86,51 @@ char *cpu_set_to_range_string(const CPUSet *set) { + return TAKE_PTR(str) ?: strdup(""); + } + ++/* XXX(msekleta): this is the workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1819152, remove in 8.3 */ ++char *cpu_set_to_range_string_kernel(const CPUSet *set) { ++ unsigned range_start = 0, range_end; ++ _cleanup_free_ char *str = NULL; ++ size_t allocated = 0, len = 0; ++ bool in_range = false; ++ int r; ++ ++ for (unsigned i = 0; i < set->allocated * 8; i++) ++ if (CPU_ISSET_S(i, set->allocated, set->set)) { ++ if (in_range) ++ range_end++; ++ else { ++ range_start = range_end = i; ++ in_range = true; ++ } ++ } else if (in_range) { ++ in_range = false; ++ ++ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) ++ return NULL; ++ ++ if (range_end > range_start) ++ r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); ++ else ++ r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); ++ assert_se(r > 0); ++ len += r; ++ } ++ ++ if (in_range) { ++ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) ++ return NULL; ++ ++ if (range_end > range_start) ++ r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); ++ else ++ r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); ++ assert_se(r > 0); ++ } ++ ++ return TAKE_PTR(str) ?: strdup(""); ++} ++ ++ + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { + size_t need; + +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 295028cb54..8519a9b6c8 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -27,6 +27,7 @@ int cpu_set_add_all(CPUSet *a, const CPUSet *b); + + char* cpu_set_to_string(const CPUSet *a); + char *cpu_set_to_range_string(const CPUSet *a); ++char *cpu_set_to_range_string_kernel(const CPUSet *a); + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus); + + int parse_cpu_set_full( +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 3f7665b755..9e4c3c7dac 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -557,7 +557,7 @@ static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) + _cleanup_free_ char *buf = NULL; + int r; + +- buf = cpu_set_to_range_string(&cpus); ++ buf = cpu_set_to_range_string_kernel(&cpus); + if (!buf) + return; + diff --git a/SOURCES/0350-core-transition-to-FINAL_SIGTERM-state-after-ExecSto.patch b/SOURCES/0350-core-transition-to-FINAL_SIGTERM-state-after-ExecSto.patch new file mode 100644 index 0000000..e9ae6e2 --- /dev/null +++ b/SOURCES/0350-core-transition-to-FINAL_SIGTERM-state-after-ExecSto.patch @@ -0,0 +1,159 @@ +From 6e732b6e44ad8eb3e94c47459c64f0bc6ef2fcb0 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Sat, 25 Jan 2020 16:46:16 +0100 +Subject: [PATCH] core: transition to FINAL_SIGTERM state after ExecStopPost= + +Fixes #14566 + +(cherry picked from commit c1566ef0d22ed786b9ecf4c476e53b8a91e67578) + +Resolves: #1766479 +--- + src/core/service.c | 10 +++++ + test/TEST-47-ISSUE-14566/Makefile | 1 + + test/TEST-47-ISSUE-14566/repro.sh | 5 +++ + test/TEST-47-ISSUE-14566/test.sh | 55 +++++++++++++++++++++++++++ + test/TEST-47-ISSUE-14566/testsuite.sh | 23 +++++++++++ + 5 files changed, 94 insertions(+) + create mode 120000 test/TEST-47-ISSUE-14566/Makefile + create mode 100755 test/TEST-47-ISSUE-14566/repro.sh + create mode 100755 test/TEST-47-ISSUE-14566/test.sh + create mode 100755 test/TEST-47-ISSUE-14566/testsuite.sh + +diff --git a/src/core/service.c b/src/core/service.c +index b1ec52d220..5035dcacac 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -3280,6 +3280,12 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + break; + + case SERVICE_STOP_POST: ++ ++ if (control_pid_good(s) <= 0) ++ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); ++ ++ break; ++ + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + +@@ -3415,6 +3421,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + break; + + case SERVICE_STOP_POST: ++ if (main_pid_good(s) <= 0) ++ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); ++ break; ++ + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + if (main_pid_good(s) <= 0) +diff --git a/test/TEST-47-ISSUE-14566/Makefile b/test/TEST-47-ISSUE-14566/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-47-ISSUE-14566/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-47-ISSUE-14566/repro.sh b/test/TEST-47-ISSUE-14566/repro.sh +new file mode 100755 +index 0000000000..5217602257 +--- /dev/null ++++ b/test/TEST-47-ISSUE-14566/repro.sh +@@ -0,0 +1,5 @@ ++#!/bin/bash ++ ++sleep infinity & ++echo $! > /leakedtestpid ++wait $! +diff --git a/test/TEST-47-ISSUE-14566/test.sh b/test/TEST-47-ISSUE-14566/test.sh +new file mode 100755 +index 0000000000..0ce772164a +--- /dev/null ++++ b/test/TEST-47-ISSUE-14566/test.sh +@@ -0,0 +1,55 @@ ++#!/bin/bash ++set -e ++TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over proccesses with ExecStopPost=" ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < $initdir/etc/systemd/system/issue_14566_test.service << EOF ++[Unit] ++Description=Issue 14566 Repro ++ ++[Service] ++ExecStart=/repro.sh ++ExecStopPost=/bin/true ++KillMode=mixed ++EOF ++ ++ cp testsuite.sh $initdir/ ++ cp repro.sh $initdir/ ++ ++ setup_testsuite ++ ) ++ setup_nspawn_root ++ ++ ddebug "umount $TESTDIR/root" ++ umount $TESTDIR/root ++} ++ ++do_test "$@" +diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh +new file mode 100755 +index 0000000000..d917cf52ff +--- /dev/null ++++ b/test/TEST-47-ISSUE-14566/testsuite.sh +@@ -0,0 +1,23 @@ ++#!/bin/bash ++set -ex ++set -o pipefail ++ ++systemd-analyze log-level debug ++systemd-analyze log-target console ++ ++systemctl start issue_14566_test ++systemctl status issue_14566_test ++ ++leaked_pid=$(cat /leakedtestpid) ++ ++systemctl stop issue_14566_test ++ ++# Leaked PID will still be around if we're buggy. ++# I personally prefer to see 42. ++ps -p "$leaked_pid" && exit 42 ++ ++systemd-analyze log-level info ++ ++echo OK > /testok ++ ++exit 0 diff --git a/SOURCES/0351-sd-journal-close-journal-files-that-were-deleted-by-.patch b/SOURCES/0351-sd-journal-close-journal-files-that-were-deleted-by-.patch new file mode 100644 index 0000000..ce44405 --- /dev/null +++ b/SOURCES/0351-sd-journal-close-journal-files-that-were-deleted-by-.patch @@ -0,0 +1,75 @@ +From 45275461f4a5293f15191ec5cb3bb80219ef2474 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Tue, 4 Feb 2020 14:23:14 +0100 +Subject: [PATCH] sd-journal: close journal files that were deleted by journald + before we've setup inotify watch + +Fixes #14695 + +(cherry picked from commit 28ca867abdb20d0e4ac1901e2ed669cdb41ea3f6) + +Related: #1796128 +--- + src/journal/journal-file.c | 2 +- + src/journal/journal-file.h | 1 + + src/journal/sd-journal.c | 15 +++++++++++++++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c +index 8249b11b23..7ab3c47fc9 100644 +--- a/src/journal/journal-file.c ++++ b/src/journal/journal-file.c +@@ -597,7 +597,7 @@ static int journal_file_verify_header(JournalFile *f) { + return 0; + } + +-static int journal_file_fstat(JournalFile *f) { ++int journal_file_fstat(JournalFile *f) { + int r; + + assert(f); +diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h +index 6a44fd39d2..6069b35234 100644 +--- a/src/journal/journal-file.h ++++ b/src/journal/journal-file.h +@@ -144,6 +144,7 @@ int journal_file_open( + int journal_file_set_offline(JournalFile *f, bool wait); + bool journal_file_is_offlining(JournalFile *f); + JournalFile* journal_file_close(JournalFile *j); ++int journal_file_fstat(JournalFile *f); + DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close); + + int journal_file_open_reliably( +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 323300baec..c06255e273 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -2584,6 +2584,8 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { + assert_return(!journal_pid_changed(j), -ECHILD); + + if (j->inotify_fd < 0) { ++ Iterator i; ++ JournalFile *f; + + /* This is the first invocation, hence create the + * inotify watch */ +@@ -2591,6 +2593,19 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { + if (r < 0) + return r; + ++ /* Server might have done some vacuuming while we weren't watching. ++ Get rid of the deleted files now so they don't stay around indefinitely. */ ++ ORDERED_HASHMAP_FOREACH(f, j->files, i) { ++ r = journal_file_fstat(f); ++ if (r < 0) { ++ log_debug_errno(r,"Failed to fstat() journal file '%s' : %m", f->path); ++ continue; ++ } ++ ++ if (f->last_stat.st_nlink <= 0) ++ remove_file_real(j, f); ++ } ++ + /* The journal might have changed since the context + * object was created and we weren't watching before, + * hence don't wait for anything, and return diff --git a/SOURCES/0352-sd-journal-remove-the-dead-code-and-actually-fix-146.patch b/SOURCES/0352-sd-journal-remove-the-dead-code-and-actually-fix-146.patch new file mode 100644 index 0000000..40e4870 --- /dev/null +++ b/SOURCES/0352-sd-journal-remove-the-dead-code-and-actually-fix-146.patch @@ -0,0 +1,42 @@ +From 0f7ee0007b8267cc66b638a44da6ddd984ece412 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 27 Mar 2020 17:01:59 +0100 +Subject: [PATCH] sd-journal: remove the dead code and actually fix #14695 + +journal_file_fstat() returns an error if we call it on already unlinked +journal file and hence we never reach remove_file_real() which is the +entire point. + +I must have made some mistake while testing the fix that got me thinking +the issue is gone while opposite was true. + +Fixes #14695 + +(cherry picked from commit 8581b9f9732d4c158bb5f773230a65ce77f2c292) + +Resolves: #1796128 +--- + src/journal/sd-journal.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index c06255e273..4c502978de 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -2597,13 +2597,12 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { + Get rid of the deleted files now so they don't stay around indefinitely. */ + ORDERED_HASHMAP_FOREACH(f, j->files, i) { + r = journal_file_fstat(f); +- if (r < 0) { ++ if (r == -EIDRM) ++ remove_file_real(j, f); ++ else if (r < 0) { + log_debug_errno(r,"Failed to fstat() journal file '%s' : %m", f->path); + continue; + } +- +- if (f->last_stat.st_nlink <= 0) +- remove_file_real(j, f); + } + + /* The journal might have changed since the context diff --git a/SOURCES/0353-udev-downgrade-message-when-we-fail-to-set-inotify-w.patch b/SOURCES/0353-udev-downgrade-message-when-we-fail-to-set-inotify-w.patch new file mode 100644 index 0000000..0df7140 --- /dev/null +++ b/SOURCES/0353-udev-downgrade-message-when-we-fail-to-set-inotify-w.patch @@ -0,0 +1,43 @@ +From 38532765172a4e60624b9c24b8d081b34d9f7b86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 13 Nov 2018 14:53:04 +0100 +Subject: [PATCH] udev: downgrade message when we fail to set inotify watch up + +My logs are full of: + +systemd-udevd[6586]: seq 13515 queued, 'add' 'block' +systemd-udevd[6586]: seq 13516 queued, 'change' 'block' +systemd-udevd[6586]: seq 13517 queued, 'change' 'block' +systemd-udevd[6586]: seq 13518 queued, 'remove' 'bdi' +systemd-udevd[6586]: seq 13519 queued, 'remove' 'block' +systemd-udevd[9865]: seq 13514 processed +systemd-udevd[9865]: seq 13515 running +systemd-udevd[9865]: GROUP 6 /usr/lib/udev/rules.d/50-udev-default.rules:59 +systemd-udevd[9865]: IMPORT builtin 'blkid' /usr/lib/udev/rules.d/60-persistent-storage.rules:95 +systemd-udevd[9865]: IMPORT builtin 'blkid' fails: No such file or directory +systemd-udevd[9865]: loop4: Failed to add device '/dev/loop4' to watch: No such file or directory +(the last line is at error level). +If we are too slow to set up a watch and the device is already gone by the time +we try, this is not an error. + +(cherry picked from commit 7fe0d0d5c0ad5aa3f069bb282868938d414d7ad1) + +Resolves: #1808051 +--- + src/udev/udev-watch.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c +index 7864f57aa5..9c82196add 100644 +--- a/src/udev/udev-watch.c ++++ b/src/udev/udev-watch.c +@@ -87,7 +87,8 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) { + log_debug("adding watch on '%s'", udev_device_get_devnode(dev)); + wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE); + if (wd < 0) { +- log_error_errno(errno, "inotify_add_watch(%d, %s, %o) failed: %m", ++ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, ++ errno, "inotify_add_watch(%d, %s, %o) failed: %m", + inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE); + return; + } diff --git a/SOURCES/0354-logind-check-PolicyKit-before-allowing-VT-switch.patch b/SOURCES/0354-logind-check-PolicyKit-before-allowing-VT-switch.patch new file mode 100644 index 0000000..6eacf48 --- /dev/null +++ b/SOURCES/0354-logind-check-PolicyKit-before-allowing-VT-switch.patch @@ -0,0 +1,195 @@ +From af20a66874296f71618819ebce9d4335b195728c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 22 Jan 2020 12:04:38 +0100 +Subject: [PATCH] logind: check PolicyKit before allowing VT switch + +Let's lock this down a bit. Effectively nothing much changes, since the +default PK policy will allow users on the VT to change VT. Only users +with no local VT session won't be able to switch VTs. + +(cherry picked from commit 4acf0cfd2f92edb94ad48d04f1ce6c9ab4e19d55) + +Resolves: #1797679 +--- + src/login/logind-dbus.c | 16 +++++++ + src/login/logind-seat-dbus.c | 58 ++++++++++++++++++++++++- + src/login/logind-session-dbus.c | 15 +++++++ + src/login/org.freedesktop.login1.policy | 10 +++++ + 4 files changed, 98 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index dca7f4a30f..3f122fcbd9 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -913,6 +913,8 @@ static int method_activate_session(sd_bus_message *message, void *userdata, sd_b + if (r < 0) + return r; + ++ /* PolicyKit is done by bus_session_method_activate() */ ++ + return bus_session_method_activate(message, session, error); + } + +@@ -944,6 +946,20 @@ static int method_activate_session_on_seat(sd_bus_message *message, void *userda + if (session->seat != seat) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name); + ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &m->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ ++ + r = session_activate(session); + if (r < 0) + return r; +diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c +index c4d9b067c6..2e590a8f21 100644 +--- a/src/login/logind-seat-dbus.c ++++ b/src/login/logind-seat-dbus.c +@@ -174,6 +174,20 @@ static int method_activate_session(sd_bus_message *message, void *userdata, sd_b + if (session->seat != s) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id); + ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &s->manager->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ ++ + r = session_activate(session); + if (r < 0) + return r; +@@ -194,7 +208,21 @@ static int method_switch_to(sd_bus_message *message, void *userdata, sd_bus_erro + return r; + + if (to <= 0) +- return -EINVAL; ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid virtual terminal"); ++ ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &s->manager->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ + + r = seat_switch_to(s, to); + if (r < 0) +@@ -210,6 +238,20 @@ static int method_switch_to_next(sd_bus_message *message, void *userdata, sd_bus + assert(message); + assert(s); + ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &s->manager->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ ++ + r = seat_switch_to_next(s); + if (r < 0) + return r; +@@ -224,6 +266,20 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd + assert(message); + assert(s); + ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &s->manager->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ ++ + r = seat_switch_to_previous(s); + if (r < 0) + return r; +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index 25c4981dc0..88a2d33dc8 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -13,6 +13,7 @@ + #include "logind.h" + #include "signal-util.h" + #include "strv.h" ++#include "user-util.h" + #include "util.h" + + static int property_get_user( +@@ -182,6 +183,20 @@ int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_ + assert(message); + assert(s); + ++ r = bus_verify_polkit_async( ++ message, ++ CAP_SYS_ADMIN, ++ "org.freedesktop.login1.chvt", ++ NULL, ++ false, ++ UID_INVALID, ++ &s->manager->polkit_registry, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* Will call us back */ ++ + r = session_activate(s); + if (r < 0) + return r; +diff --git a/src/login/org.freedesktop.login1.policy b/src/login/org.freedesktop.login1.policy +index f1d1f956d3..83760e1580 100644 +--- a/src/login/org.freedesktop.login1.policy ++++ b/src/login/org.freedesktop.login1.policy +@@ -357,4 +357,14 @@ + + + ++ ++ Change Session ++ Authentication is required for changing the virtual terminal. ++ ++ auth_admin_keep ++ auth_admin_keep ++ yes ++ ++ ++ + diff --git a/SOURCES/0355-test-do-not-use-global-variable-to-pass-error.patch b/SOURCES/0355-test-do-not-use-global-variable-to-pass-error.patch new file mode 100644 index 0000000..89e07ba --- /dev/null +++ b/SOURCES/0355-test-do-not-use-global-variable-to-pass-error.patch @@ -0,0 +1,58 @@ +From 35e9e01b2879854a2adb8d571d0204990cad38d9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 14 Sep 2018 13:25:02 +0900 +Subject: [PATCH] test: do not use global variable to pass error + +(cherry picked from commit 0013fac248a15be3acce84c17a65e3ae0377294b) + +Resolves: #1823767 +--- + test/TEST-21-SYSUSERS/test.sh | 1 + + test/test-functions | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-21-SYSUSERS/test.sh b/test/TEST-21-SYSUSERS/test.sh +index 73cbe10b69..b1049e720d 100755 +--- a/test/TEST-21-SYSUSERS/test.sh ++++ b/test/TEST-21-SYSUSERS/test.sh +@@ -15,6 +15,7 @@ prepare_testdir() { + for i in $1.initial-{passwd,group,shadow}; do + test -f $i && cp $i $TESTDIR/etc/${i#*.initial-} + done ++ return 0 + } + + preprocess() { +diff --git a/test/test-functions b/test/test-functions +index fe25a501da..da83891f46 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -449,7 +449,7 @@ EOF + } + + check_result_nspawn() { +- ret=1 ++ local ret=1 + [[ -e $TESTDIR/$1/testok ]] && ret=0 + [[ -f $TESTDIR/$1/failed ]] && cp -a $TESTDIR/$1/failed $TESTDIR + cp -a $TESTDIR/$1/var/log/journal $TESTDIR +@@ -462,7 +462,7 @@ check_result_nspawn() { + + # can be overridden in specific test + check_result_qemu() { +- ret=1 ++ local ret=1 + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + [[ -e $TESTDIR/root/testok ]] && ret=0 +@@ -1527,7 +1527,9 @@ do_test() { + case $1 in + --run) + echo "TEST RUN: $TEST_DESCRIPTION" +- if test_run; then ++ test_run ++ ret=$? ++ if (( $ret == 0 )); then + echo "TEST RUN: $TEST_DESCRIPTION [OK]" + else + echo "TEST RUN: $TEST_DESCRIPTION [FAILED]" diff --git a/SOURCES/0356-test-install-libraries-required-by-tests.patch b/SOURCES/0356-test-install-libraries-required-by-tests.patch new file mode 100644 index 0000000..e14e742 --- /dev/null +++ b/SOURCES/0356-test-install-libraries-required-by-tests.patch @@ -0,0 +1,25 @@ +From 98e4c0d39a83a325038d0b39715fc534c7613bef Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 12 Sep 2018 18:19:45 +0900 +Subject: [PATCH] test: install libraries required by tests + +(cherry picked from commit e3d3dada248c5f30e2978840ca1f0a03a4675b53) + +Resolves: #1823767 +--- + test/test-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index da83891f46..f7ca3ad975 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -420,7 +420,7 @@ get_ldpath() { + + install_missing_libraries() { + # install possible missing libraries +- for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/*; do ++ for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/{,tests/{,manual/,unsafe/}}*; do + LD_LIBRARY_PATH=$(get_ldpath $i) inst_libs $i + done + } diff --git a/SOURCES/0357-test-introduce-install_zoneinfo.patch b/SOURCES/0357-test-introduce-install_zoneinfo.patch new file mode 100644 index 0000000..ba58935 --- /dev/null +++ b/SOURCES/0357-test-introduce-install_zoneinfo.patch @@ -0,0 +1,32 @@ +From 73781e52f331f816924232f96c7bfc92ee763e70 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 12 Sep 2018 18:20:31 +0900 +Subject: [PATCH] test: introduce install_zoneinfo() + +But it is not called by default. + +(cherry picked from commit 7d10ec1cda8fed20c36b16d2387f529583645cda) + +Resolves: #1823767 +--- + test/test-functions | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index f7ca3ad975..4d76ed1f82 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -628,6 +628,13 @@ install_keymaps() { + done + } + ++install_zoneinfo() { ++ for i in /usr/share/zoneinfo/{,*/,*/*/}*; do ++ [[ -f $i ]] || continue ++ inst $i ++ done ++} ++ + install_fonts() { + for i in \ + /usr/lib/kbd/consolefonts/eurlatgr* \ diff --git a/SOURCES/0358-test-replace-duplicated-Makefile-by-symbolic-link.patch b/SOURCES/0358-test-replace-duplicated-Makefile-by-symbolic-link.patch new file mode 100644 index 0000000..11032a9 --- /dev/null +++ b/SOURCES/0358-test-replace-duplicated-Makefile-by-symbolic-link.patch @@ -0,0 +1,151 @@ +From e39c4e6aee6c2ece5d9b51cc0e7a772016546f5a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 13 Sep 2018 03:01:42 +0900 +Subject: [PATCH] test: replace duplicated Makefile by symbolic link + +(cherry picked from commit dd75c133d81f07c56c82ee4e7a80f391ffebd9ce) + +Resolves: #1823767 +--- + test/TEST-17-UDEV-WANTS/Makefile | 5 +---- + test/TEST-18-FAILUREACTION/Makefile | 5 +---- + test/TEST-19-DELEGATE/Makefile | 5 +---- + test/TEST-20-MAINPIDGAMES/Makefile | 5 +---- + test/TEST-21-SYSUSERS/Makefile | 5 +---- + test/TEST-22-TMPFILES/Makefile | 5 +---- + test/TEST-23-TYPE-EXEC/Makefile | 5 +---- + 7 files changed, 7 insertions(+), 28 deletions(-) + mode change 100644 => 120000 test/TEST-17-UDEV-WANTS/Makefile + mode change 100644 => 120000 test/TEST-18-FAILUREACTION/Makefile + mode change 100644 => 120000 test/TEST-19-DELEGATE/Makefile + mode change 100644 => 120000 test/TEST-20-MAINPIDGAMES/Makefile + mode change 100644 => 120000 test/TEST-21-SYSUSERS/Makefile + mode change 100644 => 120000 test/TEST-22-TMPFILES/Makefile + mode change 100644 => 120000 test/TEST-23-TYPE-EXEC/Makefile + +diff --git a/test/TEST-17-UDEV-WANTS/Makefile b/test/TEST-17-UDEV-WANTS/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-17-UDEV-WANTS/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-17-UDEV-WANTS/Makefile b/test/TEST-17-UDEV-WANTS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-17-UDEV-WANTS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-18-FAILUREACTION/Makefile b/test/TEST-18-FAILUREACTION/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-18-FAILUREACTION/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-18-FAILUREACTION/Makefile b/test/TEST-18-FAILUREACTION/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-18-FAILUREACTION/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-19-DELEGATE/Makefile b/test/TEST-19-DELEGATE/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-19-DELEGATE/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-19-DELEGATE/Makefile b/test/TEST-19-DELEGATE/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-19-DELEGATE/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-20-MAINPIDGAMES/Makefile b/test/TEST-20-MAINPIDGAMES/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-20-MAINPIDGAMES/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-20-MAINPIDGAMES/Makefile b/test/TEST-20-MAINPIDGAMES/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-20-MAINPIDGAMES/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-21-SYSUSERS/Makefile b/test/TEST-21-SYSUSERS/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-21-SYSUSERS/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-21-SYSUSERS/Makefile b/test/TEST-21-SYSUSERS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-21-SYSUSERS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-22-TMPFILES/Makefile b/test/TEST-22-TMPFILES/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-22-TMPFILES/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-22-TMPFILES/Makefile b/test/TEST-22-TMPFILES/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-22-TMPFILES/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-23-TYPE-EXEC/Makefile b/test/TEST-23-TYPE-EXEC/Makefile +deleted file mode 100644 +index 34d7cc6cdf..0000000000 +--- a/test/TEST-23-TYPE-EXEC/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-BUILD_DIR=$(shell ../../tools/find-build-dir.sh) +- +-all setup clean run: +- @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ +diff --git a/test/TEST-23-TYPE-EXEC/Makefile b/test/TEST-23-TYPE-EXEC/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-23-TYPE-EXEC/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file diff --git a/SOURCES/0359-test-add-paths-of-keymaps-in-install_keymaps.patch b/SOURCES/0359-test-add-paths-of-keymaps-in-install_keymaps.patch new file mode 100644 index 0000000..3ef2cdf --- /dev/null +++ b/SOURCES/0359-test-add-paths-of-keymaps-in-install_keymaps.patch @@ -0,0 +1,34 @@ +From 1599be6d3625700ded28108c0747b000448fa5dc Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 19 Sep 2018 10:54:16 +0900 +Subject: [PATCH] test: add paths of keymaps in install_keymaps() + +It seems that the paths of directories storing keymaps are changed. + +(cherry picked from commit 83a7051ee1edbfe8cd2278477d23083beb385409) + +Resolves: #1823767 +--- + test/test-functions | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index 4d76ed1f82..546928c516 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -619,10 +619,14 @@ install_pam() { + } + + install_keymaps() { ++ # The first three paths may be deprecated. ++ # It seems now the last two paths are used by many distributions. + for i in \ + /usr/lib/kbd/keymaps/include/* \ + /usr/lib/kbd/keymaps/i386/include/* \ +- /usr/lib/kbd/keymaps/i386/qwerty/us.*; do ++ /usr/lib/kbd/keymaps/i386/qwerty/us.* \ ++ /usr/lib/kbd/keymaps/legacy/include/* \ ++ /usr/lib/kbd/keymaps/legacy/i386/qwerty/us.*; do + [[ -f $i ]] || continue + inst $i + done diff --git a/SOURCES/0360-test-make-install_keymaps-optionally-install-more-ke.patch b/SOURCES/0360-test-make-install_keymaps-optionally-install-more-ke.patch new file mode 100644 index 0000000..52dff88 --- /dev/null +++ b/SOURCES/0360-test-make-install_keymaps-optionally-install-more-ke.patch @@ -0,0 +1,33 @@ +From 8dbd01f7018947fd15d00c25b1aa0ffc72278cb6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 19 Sep 2018 10:54:28 +0900 +Subject: [PATCH] test: make install_keymaps() optionally install more keymaps + +(cherry picked from commit ad931fee506e1313e8a520ae0ecc1c8e275d9941) + +Resolves: #1823767 +--- + test/test-functions | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index 546928c516..0938e6e826 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -630,6 +630,16 @@ install_keymaps() { + [[ -f $i ]] || continue + inst $i + done ++ ++ # When it takes any argument, then install more keymaps. ++ if [[ -n $1 ]]; then ++ for i in \ ++ /usr/lib/kbd/keymaps/i386/*/* \ ++ /usr/lib/kbd/keymaps/legacy/i386/*/*; do ++ [[ -f $i ]] || continue ++ inst $i ++ done ++ fi + } + + install_zoneinfo() { diff --git a/SOURCES/0361-test-fs-util-skip-some-tests-when-running-in-unprivi.patch b/SOURCES/0361-test-fs-util-skip-some-tests-when-running-in-unprivi.patch new file mode 100644 index 0000000..d461fa5 --- /dev/null +++ b/SOURCES/0361-test-fs-util-skip-some-tests-when-running-in-unprivi.patch @@ -0,0 +1,47 @@ +From 15ab55eca3d1f7feb86e55bdc147069f36d198eb Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 14 Sep 2018 15:51:04 +0900 +Subject: [PATCH] test-fs-util: skip some tests when running in unprivileged + container + +(cherry picked from commit 9590065f37be040996f1c2b9a246b9952fdc0c0b) + +Resolves: #1823767 +--- + src/test/test-fs-util.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c +index 7b7990bb70..e3338ea440 100644 +--- a/src/test/test-fs-util.c ++++ b/src/test/test-fs-util.c +@@ -17,6 +17,7 @@ + #include "strv.h" + #include "user-util.h" + #include "util.h" ++#include "virt.h" + + static void test_chase_symlinks(void) { + _cleanup_free_ char *result = NULL; +@@ -468,6 +469,7 @@ static void test_touch_file(void) { + struct stat st; + const char *a; + usec_t test_mtime; ++ int r; + + test_uid = geteuid() == 0 ? 65534 : getuid(); + test_gid = geteuid() == 0 ? 65534 : getgid(); +@@ -517,7 +519,12 @@ static void test_touch_file(void) { + + if (geteuid() == 0) { + a = strjoina(p, "/cdev"); +- assert_se(mknod(a, 0775 | S_IFCHR, makedev(0, 0)) >= 0); ++ r = mknod(a, 0775 | S_IFCHR, makedev(0, 0)); ++ if (r < 0 && errno == EPERM && detect_container() > 0) { ++ log_notice("Running in unprivileged container? Skipping remaining tests in %s", __func__); ++ return; ++ } ++ assert_se(r >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); diff --git a/SOURCES/0362-test-process-util-skip-several-verifications-when-ru.patch b/SOURCES/0362-test-process-util-skip-several-verifications-when-ru.patch new file mode 100644 index 0000000..c3edf03 --- /dev/null +++ b/SOURCES/0362-test-process-util-skip-several-verifications-when-ru.patch @@ -0,0 +1,39 @@ +From b550cc33e762fa209b0740f1874f75ef780b8d90 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 20 Sep 2018 16:08:38 +0900 +Subject: [PATCH] test-process-util: skip several verifications when running in + unprivileged container + +(cherry picked from commit 767eab47501b06327a0e6030e5c54860a3fc427f) + +Resolves: #1823767 +--- + src/test/test-process-util.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c +index fd4d17408d..26e3247993 100644 +--- a/src/test/test-process-util.c ++++ b/src/test/test-process-util.c +@@ -394,12 +394,17 @@ static void test_rename_process_now(const char *p, int ret) { + log_info("comm = <%s>", comm); + assert_se(strneq(comm, p, TASK_COMM_LEN-1)); + +- assert_se(get_process_cmdline(0, 0, false, &cmdline) >= 0); ++ r = get_process_cmdline(0, 0, false, &cmdline); ++ assert_se(r >= 0); + /* we cannot expect cmdline to be renamed properly without privileges */ + if (geteuid() == 0) { +- log_info("cmdline = <%s>", cmdline); +- assert_se(strneq(p, cmdline, STRLEN("test-process-util"))); +- assert_se(startswith(p, cmdline)); ++ if (r == 0 && detect_container() > 0) ++ log_info("cmdline = <%s> (not verified, Running in unprivileged container?)", cmdline); ++ else { ++ log_info("cmdline = <%s>", cmdline); ++ assert_se(strneq(p, cmdline, STRLEN("test-process-util"))); ++ assert_se(startswith(p, cmdline)); ++ } + } else + log_info("cmdline = <%s> (not verified)", cmdline); + } diff --git a/SOURCES/0363-test-execute-also-check-python3-is-installed-or-not.patch b/SOURCES/0363-test-execute-also-check-python3-is-installed-or-not.patch new file mode 100644 index 0000000..7bfe287 --- /dev/null +++ b/SOURCES/0363-test-execute-also-check-python3-is-installed-or-not.patch @@ -0,0 +1,59 @@ +From a3a3d861496b8c0d061c6ba21278d0326c50f37d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 12 Sep 2018 18:18:33 +0900 +Subject: [PATCH] test-execute: also check python3 is installed or not + +(cherry picked from commit 738c74d7b163ea18e3c68115c3ed8ceed166cbf7) + +Resolves: #1823767 +--- + src/test/test-execute.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 6c22995b1e..af64427bc7 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -317,6 +317,8 @@ static void test_exec_temporaryfilesystem(Manager *m) { + + static void test_exec_systemcallfilter(Manager *m) { + #if HAVE_SECCOMP ++ int r; ++ + if (!is_seccomp_available()) { + log_notice("Seccomp not available, skipping %s", __func__); + return; +@@ -326,6 +328,13 @@ static void test_exec_systemcallfilter(Manager *m) { + test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED); + test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED); + test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED); ++ ++ r = find_binary("python3", NULL); ++ if (r < 0) { ++ log_notice_errno(r, "Skipping remaining tests in %s, could not find python3 binary: %m", __func__); ++ return; ++ } ++ + test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED); + test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED); + #endif +@@ -333,11 +342,19 @@ static void test_exec_systemcallfilter(Manager *m) { + + static void test_exec_systemcallerrornumber(Manager *m) { + #if HAVE_SECCOMP ++ int r; ++ + if (!is_seccomp_available()) { + log_notice("Seccomp not available, skipping %s", __func__); + return; + } + ++ r = find_binary("python3", NULL); ++ if (r < 0) { ++ log_notice_errno(r, "Skipping %s, could not find python3 binary: %m", __func__); ++ return; ++ } ++ + test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED); + test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED); + #endif diff --git a/SOURCES/0364-test-execute-skip-several-tests-when-running-in-cont.patch b/SOURCES/0364-test-execute-skip-several-tests-when-running-in-cont.patch new file mode 100644 index 0000000..472d8ff --- /dev/null +++ b/SOURCES/0364-test-execute-skip-several-tests-when-running-in-cont.patch @@ -0,0 +1,42 @@ +From fb66f2dbf1d228adc6f15edbbdf0ce53eb3be982 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 14 Sep 2018 15:47:42 +0900 +Subject: [PATCH] test-execute: skip several tests when running in container + +(cherry picked from commit 642d1a6d6e98204ade25816bcc429cb67df92a29) + +Resolves: #1823767 +--- + src/test/test-execute.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index af64427bc7..637ffe96bb 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -616,14 +616,24 @@ static void test_exec_privatenetwork(Manager *m) { + + static void test_exec_oomscoreadjust(Manager *m) { + test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED); ++ ++ if (detect_container() > 0) { ++ log_notice("Testing in container, skipping remaining tests in %s", __func__); ++ return; ++ } + test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED); + } + + static void test_exec_ioschedulingclass(Manager *m) { + test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED); + test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED); +- test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED); + test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED); ++ ++ if (detect_container() > 0) { ++ log_notice("Testing in container, skipping remaining tests in %s", __func__); ++ return; ++ } ++ test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED); + } + + static void test_exec_unsetenvironment(Manager *m) { diff --git a/SOURCES/0365-test-introduce-test_is_running_from_builddir.patch b/SOURCES/0365-test-introduce-test_is_running_from_builddir.patch new file mode 100644 index 0000000..c572849 --- /dev/null +++ b/SOURCES/0365-test-introduce-test_is_running_from_builddir.patch @@ -0,0 +1,70 @@ +From b69552ccc0e33f713ae3a2baf1b0173cf221507d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 09:17:22 +0900 +Subject: [PATCH] test: introduce test_is_running_from_builddir() + +(cherry picked from commit 8cb10a4f4dabc508a04f76ea55f23ef517881b61) + +Resolves: #1823767 +--- + src/shared/tests.c | 23 ++++++++++++++++++++--- + src/shared/tests.h | 1 + + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/src/shared/tests.c b/src/shared/tests.c +index b10343650f..c77eb00924 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -19,6 +19,24 @@ char* setup_fake_runtime_dir(void) { + return p; + } + ++bool test_is_running_from_builddir(char **exedir) { ++ _cleanup_free_ char *s = NULL; ++ bool r; ++ ++ /* Check if we're running from the builddir. Optionally, this returns ++ * the path to the directory where the binary is located. */ ++ ++ assert_se(readlink_and_make_absolute("/proc/self/exe", &s) >= 0); ++ r = path_startswith(s, ABS_BUILD_DIR); ++ ++ if (exedir) { ++ dirname(s); ++ *exedir = TAKE_PTR(s); ++ } ++ ++ return r; ++} ++ + const char* get_testdata_dir(const char *suffix) { + const char *env; + /* convenience: caller does not need to free result */ +@@ -35,14 +53,13 @@ const char* get_testdata_dir(const char *suffix) { + strncpy(testdir, env, sizeof(testdir) - 1); + } else { + _cleanup_free_ char *exedir = NULL; +- assert_se(readlink_and_make_absolute("/proc/self/exe", &exedir) >= 0); + + /* Check if we're running from the builddir. If so, use the compiled in path. */ +- if (path_startswith(exedir, ABS_BUILD_DIR)) ++ if (test_is_running_from_builddir(&exedir)) + assert_se(snprintf(testdir, sizeof(testdir), "%s/test", ABS_SRC_DIR) > 0); + else + /* Try relative path, according to the install-test layout */ +- assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", dirname(exedir)) > 0); ++ assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", exedir) > 0); + + /* test this without the suffix, as it may contain a glob */ + if (access(testdir, F_OK) < 0) { +diff --git a/src/shared/tests.h b/src/shared/tests.h +index cad21169f8..7f45c32d32 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -2,5 +2,6 @@ + #pragma once + + char* setup_fake_runtime_dir(void); ++bool test_is_running_from_builddir(char **exedir); + const char* get_testdata_dir(const char *suffix); + void test_setup_logging(int level); diff --git a/SOURCES/0366-test-make-test-catalog-relocatable.patch b/SOURCES/0366-test-make-test-catalog-relocatable.patch new file mode 100644 index 0000000..7af676f --- /dev/null +++ b/SOURCES/0366-test-make-test-catalog-relocatable.patch @@ -0,0 +1,103 @@ +From ac476ab0ce970e4a269fee34a15e24f6b20962b7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 09:18:33 +0900 +Subject: [PATCH] test: make test-catalog relocatable + +Fixes #10045. + +(cherry picked from commit d9b6baa69968132d33e4ad8627c7fe0bd527c859) + +Resolves: #1823767 +--- + catalog/meson.build | 1 - + src/journal/test-catalog.c | 27 +++++++++++++++++++-------- + src/test/meson.build | 2 +- + 3 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/catalog/meson.build b/catalog/meson.build +index 1b13150894..3db8e390f2 100644 +--- a/catalog/meson.build ++++ b/catalog/meson.build +@@ -17,7 +17,6 @@ in_files = ''' + + support_url = get_option('support-url') + support_sed = 's~%SUPPORT_URL%~@0@~'.format(support_url) +-build_catalog_dir = meson.current_build_dir() + + foreach file : in_files + custom_target( +diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c +index 8eae993780..0c4da29f31 100644 +--- a/src/journal/test-catalog.c ++++ b/src/journal/test-catalog.c +@@ -14,14 +14,13 @@ + #include "fileio.h" + #include "log.h" + #include "macro.h" ++#include "path-util.h" + #include "string-util.h" ++#include "strv.h" ++#include "tests.h" + #include "util.h" + +-static const char *catalog_dirs[] = { +- CATALOG_DIR, +- NULL, +-}; +- ++static char** catalog_dirs = NULL; + static const char *no_catalog_dirs[] = { + "/bin/hopefully/with/no/catalog", + NULL +@@ -167,8 +166,8 @@ static void test_catalog_update(const char *database) { + assert_se(r == 0); + + /* Make sure that we at least have some files loaded or the +- catalog_list below will fail. */ +- r = catalog_update(database, NULL, catalog_dirs); ++ * catalog_list below will fail. */ ++ r = catalog_update(database, NULL, (const char * const *) catalog_dirs); + assert_se(r == 0); + } + +@@ -202,14 +201,26 @@ static void test_catalog_file_lang(void) { + + int main(int argc, char *argv[]) { + _cleanup_(unlink_tempfilep) char database[] = "/tmp/test-catalog.XXXXXX"; +- _cleanup_free_ char *text = NULL; ++ _cleanup_free_ char *text = NULL, *catalog_dir = NULL; + int r; + + setlocale(LC_ALL, "de_DE.UTF-8"); + ++ log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + ++ /* If test-catalog is located at the build directory, then use catalogs in that. ++ * If it is not, e.g. installed by systemd-tests package, then use installed catalogs. */ ++ if (test_is_running_from_builddir(NULL)) { ++ assert_se(catalog_dir = path_join(NULL, ABS_BUILD_DIR, "catalog")); ++ catalog_dirs = STRV_MAKE(catalog_dir); ++ } else ++ catalog_dirs = STRV_MAKE(CATALOG_DIR); ++ ++ assert_se(access(catalog_dirs[0], F_OK) >= 0); ++ log_notice("Using catalog directory '%s'", catalog_dirs[0]); ++ + test_catalog_file_lang(); + + test_catalog_import_invalid(); +diff --git a/src/test/meson.build b/src/test/meson.build +index 4259421f98..ead000e30c 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -766,7 +766,7 @@ tests += [ + [threads, + libxz, + liblz4], +- '', '', '-DCATALOG_DIR="@0@"'.format(build_catalog_dir)], ++ '', '', '-DCATALOG_DIR="@0@"'.format(catalogdir)], + + [['src/journal/test-compress.c'], + [libjournal_core, diff --git a/SOURCES/0367-test-parallelize-tasks-in-TEST-24-UNIT-TESTS.patch b/SOURCES/0367-test-parallelize-tasks-in-TEST-24-UNIT-TESTS.patch new file mode 100644 index 0000000..fff67d8 --- /dev/null +++ b/SOURCES/0367-test-parallelize-tasks-in-TEST-24-UNIT-TESTS.patch @@ -0,0 +1,137 @@ +From 7ba4a6f5a02f6142d0e28fd475fd008532fb1083 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 5 Mar 2019 13:50:28 +0100 +Subject: [PATCH] test: parallelize tasks in TEST-24-UNIT-TESTS + +(cherry picked from commit 2f2a0454efd07644a4e0ccb3f00f1db2d7043391) + +Related: #1823767 +--- + test/TEST-24-UNIT-TESTS/test.sh | 2 + + test/TEST-24-UNIT-TESTS/testsuite.sh | 97 +++++++++++++++++++++------- + 2 files changed, 77 insertions(+), 22 deletions(-) + +diff --git a/test/TEST-24-UNIT-TESTS/test.sh b/test/TEST-24-UNIT-TESTS/test.sh +index 014ee52277..fc8c89fe0a 100755 +--- a/test/TEST-24-UNIT-TESTS/test.sh ++++ b/test/TEST-24-UNIT-TESTS/test.sh +@@ -78,6 +78,8 @@ test_setup() { + setup_basic_environment + install_keymaps yes + install_zoneinfo ++ # Install nproc to determine # of CPUs for correct parallelization ++ inst_binary nproc + + # setup the testsuite service + cat >$initdir/etc/systemd/system/testsuite.service < /$NAME.log 2>&1 +- ret=$? +- if (( $ret && $ret != 77 )); then +- echo "$NAME failed with $ret" +- echo $NAME >> /failed-tests +- echo "--- $NAME begin ---" >> /failed +- cat /$NAME.log >> /failed +- echo "--- $NAME end ---" >> /failed +- elif (( $ret == 77 )); then +- echo "$NAME skipped" +- echo $NAME >> /skipped-tests +- echo "--- $NAME begin ---" >> /skipped +- cat /$NAME.log >> /skipped +- echo "--- $NAME end ---" >> /skipped ++NPROC=$(nproc) ++MAX_QUEUE_SIZE=${NPROC:-2} ++IFS=$'\n' TEST_LIST=($(ls /usr/lib/systemd/tests/test-*)) ++ ++# Check & report test results ++# Arguments: ++# $1: test path ++# $2: test exit code ++function report_result() { ++ if [[ $# -ne 2 ]]; then ++ echo >&2 "check_result: missing arguments" ++ exit 1 ++ fi ++ ++ local name="${1##*/}" ++ local ret=$2 ++ ++ if [[ $ret -ne 0 && $ret != 77 ]]; then ++ echo "$name failed with $ret" ++ echo "$name" >> /failed-tests ++ { ++ echo "--- $name begin ---" ++ cat "/$name.log" ++ echo "--- $name end ---" ++ } >> /failed ++ elif [[ $ret == 77 ]]; then ++ echo "$name skipped" ++ echo "$name" >> /skipped-tests ++ { ++ echo "--- $name begin ---" ++ cat "/$name.log" ++ echo "--- $name end ---" ++ } >> /skipped + else +- echo "$NAME OK" +- echo $NAME >> /testok ++ echo "$name OK" ++ echo "$name" >> /testok ++ fi ++ ++ systemd-cat echo "--- $name ---" ++ systemd-cat cat "/$name.log" ++} ++ ++# Associative array for running tasks, where running[test-path]=PID ++declare -A running=() ++for task in "${TEST_LIST[@]}"; do ++ # If there's MAX_QUEUE_SIZE running tasks, keep checking the running queue ++ # until one of the tasks finishes, so we can replace it. ++ while [[ ${#running[@]} -ge $MAX_QUEUE_SIZE ]]; do ++ for key in "${!running[@]}"; do ++ if ! kill -0 ${running[$key]} &>/dev/null; then ++ # Task has finished, report its result and drop it from the queue ++ wait ${running[$key]} ++ ec=$? ++ report_result "$key" $ec ++ unset running["$key"] ++ # Break from inner for loop and outer while loop to skip ++ # the sleep below when we find a free slot in the queue ++ break 2 ++ fi ++ done ++ ++ # Precisely* calculated constant to keep the spinlock from burning the CPU(s) ++ sleep 0.01 ++ done ++ ++ if [[ -x $task ]]; then ++ log_file="/${task##*/}.log" ++ $task &> "$log_file" & ++ running[$task]=$! + fi ++done + +- systemd-cat echo "--- $NAME ---" +- systemd-cat cat /$NAME.log ++# Wait for remaining running tasks ++for key in "${!running[@]}"; do ++ wait ${running[$key]} ++ ec=$? ++ report_result "$key" $ec ++ unset running["$key"] + done + + exit 0 diff --git a/SOURCES/0368-test-try-to-determine-QEMU_SMP-dynamically.patch b/SOURCES/0368-test-try-to-determine-QEMU_SMP-dynamically.patch new file mode 100644 index 0000000..a53b7b2 --- /dev/null +++ b/SOURCES/0368-test-try-to-determine-QEMU_SMP-dynamically.patch @@ -0,0 +1,41 @@ +From fe6e09aa0931112e7e3750801858c66129c7a3a8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 5 Mar 2019 16:08:00 +0100 +Subject: [PATCH] test: try to determine QEMU_SMP dynamically + +If the QEMU_SMP value has not been explicitly set, try to determine it +from the number of online CPUs using the nproc utility. If this approach +fails, fall back to the default value QEMU_SMP=1. + +This change should significantly help when running integration tests +under QEMU on multicore systems. + +(cherry picked from commit 5bfb2a93a4a36bba0d24199553dcda6e560cbb75) + +Related: #1823767 +--- + test/test-functions | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index 0938e6e826..3f1c327f3c 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -120,7 +120,16 @@ run_qemu() { + fi + fi + +- [ "$QEMU_SMP" ] || QEMU_SMP=1 ++ # If QEMU_SMP was not explicitly set, try to determine the value 'dynamically' ++ # i.e. use the number of online CPUs on the host machine. If the nproc utility ++ # is not installed or there's some other error when calling it, fall back ++ # to the original value (QEMU_SMP=1). ++ if ! [ "$QEMU_SMP" ]; then ++ if ! QEMU_SMP=$(nproc); then ++ dwarn "nproc utility is not installed, falling back to QEMU_SMP=1" ++ QEMU_SMP=1 ++ fi ++ fi + + find_qemu_bin || return 1 + diff --git a/SOURCES/0369-test-store-coredumps-in-journal.patch b/SOURCES/0369-test-store-coredumps-in-journal.patch new file mode 100644 index 0000000..ca9f771 --- /dev/null +++ b/SOURCES/0369-test-store-coredumps-in-journal.patch @@ -0,0 +1,31 @@ +From 8df2d39a562416e1218e3ff191f3f3af1f9d4844 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 13 Aug 2019 00:14:54 +0200 +Subject: [PATCH] test: store coredumps in journal + +To make debugging much easier, especially for crashes in tests under +QEMU, let's store the entire coredump bundle in the systemd journal, +which is usually kept around by various CIs. Right now, we usually end +up with a journal, but without the coredump itself, which is pretty +useless. + +(cherry picked from commit 215bffe1b8d7cb72fe9f72ed53682d52d5c2a9c5) + +Related: #1823767 +--- + test/test-functions | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index 3f1c327f3c..7c4230b078 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -420,6 +420,8 @@ install_systemd() { + + # enable debug logging in PID1 + echo LogLevel=debug >> $initdir/etc/systemd/system.conf ++ # store coredumps in journal ++ echo Storage=journal >> $initdir/etc/systemd/coredump.conf + } + + get_ldpath() { diff --git a/SOURCES/0370-pid1-add-new-kernel-cmdline-arg-systemd.cpu_affinity.patch b/SOURCES/0370-pid1-add-new-kernel-cmdline-arg-systemd.cpu_affinity.patch new file mode 100644 index 0000000..340e056 --- /dev/null +++ b/SOURCES/0370-pid1-add-new-kernel-cmdline-arg-systemd.cpu_affinity.patch @@ -0,0 +1,62 @@ +From 82156850f6642a363aa2ff06677ad089a460104e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Nov 2019 09:46:00 +0100 +Subject: [PATCH] pid1: add new kernel cmdline arg systemd.cpu_affinity= + +Let's allow configuration of the CPU affinity via the kernel cmdline, +overriding CPUAffinity= in /etc/systemd/system.conf + +Prompted by: + +https://lists.freedesktop.org/archives/systemd-devel/2019-November/043754.html + +(cherry picked from commit 68d58f38693e586b5ce5785274f8e42a79625196) + +Resolves: #1812894 +--- + man/kernel-command-line.xml | 11 +++++++++++ + src/core/main.c | 9 +++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml +index 0545f9d84b..4d8cb4e50e 100644 +--- a/man/kernel-command-line.xml ++++ b/man/kernel-command-line.xml +@@ -366,6 +366,17 @@ + + + ++ ++ systemd.cpu_affinity= ++ ++ ++ Overrides the CPU affinity mask for the service manager and the default for all child ++ processes it forks. This takes precedence over CPUAffinity=, see ++ systemd-system.conf5 ++ for details. ++ ++ ++ + + modules_load= + rd.modules_load= +diff --git a/src/core/main.c b/src/core/main.c +index 45d09b1e11..9f238a8430 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -472,6 +472,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + if (arg_default_timeout_start_usec <= 0) + arg_default_timeout_start_usec = USEC_INFINITY; + ++ } else if (proc_cmdline_key_streq(key, "systemd.cpu_affinity")) { ++ ++ if (proc_cmdline_value_missing(key, value)) ++ return 0; ++ ++ r = parse_cpu_set(value, &arg_cpu_affinity); ++ if (r < 0) ++ log_warning_errno(r, "Failed to parse CPU affinity mask '%s', ignoring: %m", value); ++ + } else if (proc_cmdline_key_streq(key, "systemd.watchdog_device")) { + + if (proc_cmdline_value_missing(key, value)) diff --git a/SOURCES/0371-udev-rules-make-tape-changers-also-apprear-in-dev-ta.patch b/SOURCES/0371-udev-rules-make-tape-changers-also-apprear-in-dev-ta.patch new file mode 100644 index 0000000..e267fe5 --- /dev/null +++ b/SOURCES/0371-udev-rules-make-tape-changers-also-apprear-in-dev-ta.patch @@ -0,0 +1,57 @@ +From f60e89ea4c38c11a9d0c1e642c0a78faa32aca56 Mon Sep 17 00:00:00 2001 +From: Joerg Steffens +Date: Tue, 21 Nov 2017 12:21:49 +0100 +Subject: [PATCH] udev-rules: make tape-changers also apprear in + /dev/tape/by-path/ + +It is important to be able to access tape changer ("Medium Changers") by +persistant name. +While tape devices can be accessed via /dev/tape/by-id/ and +/dev/tape/by-path/, tape-changers could only be accessed by +/dev/tape/by-id/. +However, in some cases, especially when accessing Amazon Webservice +Storage Gateway VTLs (or accessing iSCSI VTLs in general?) this does not +work, as all tape devices and the tape changer have the same ENV{ID_SERIAL}. +The results is, that only the last device is available in +/dev/tape/by-id/, as the former devices have been overwritten. + +As this behavior is hard to change without breaking consistentcy, +this additional device in /dev/tape/by-path/ can be used to access the medium changes. +The tape devices can also be accessed by this path. + +The content of the directory will now look like: + + # SCSI tape device, rewind (unchanged) + /dev/tape/by-path/$env{ID_PATH} -> ../../st* + + # SCSI tape device, no-rewind (unchanged) + /dev/tape/by-path/$env{ID_PATH}-nst -> ../../nst* + + # SCSI tape changer device (newly added) + /dev/tape/by-path/$env{ID_PATH}-changer -> ../../sg* + +Tape devices and tape changer have different ID_PATHs. +SCSI tape changer get the suffix "-changer" +to make them better distinguishable from tape devices. + +(cherry picked from commit 7f8ddf96a25162f06bd94a684cf700c128d18142) + +Resolves: #1820112 +--- + rules/60-persistent-storage-tape.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rules/60-persistent-storage-tape.rules b/rules/60-persistent-storage-tape.rules +index b604864ee8..0575f308df 100644 +--- a/rules/60-persistent-storage-tape.rules ++++ b/rules/60-persistent-storage-tape.rules +@@ -9,6 +9,9 @@ ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_t + SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --whitelisted -d $devnode", \ + SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL}" + ++SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{builtin}="path_id", \ ++ SYMLINK+="tape/by-path/$env{ID_PATH}-changer" ++ + SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end" + + KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394" diff --git a/SOURCES/0372-man-be-clearer-that-.timer-time-expressions-need-to-.patch b/SOURCES/0372-man-be-clearer-that-.timer-time-expressions-need-to-.patch new file mode 100644 index 0000000..8e72683 --- /dev/null +++ b/SOURCES/0372-man-be-clearer-that-.timer-time-expressions-need-to-.patch @@ -0,0 +1,75 @@ +From b8af9fd65b697e9bb77a32d1a6a70367814aaed5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Apr 2019 17:30:45 +0200 +Subject: [PATCH] man: be clearer that .timer time expressions need to be reset + to override them + +let's be clearer about the overriding concept for OnCalendar= settings. + +Prompted by this thread: + +https://lists.freedesktop.org/archives/systemd-devel/2019-March/042351.html +(cherry picked from commit 58031d99c6320855b86f4890baa9165597e3d841) + +Resolves: #1816908 +--- + man/systemd.timer.xml | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml +index 44b257c745..ebc1df89f1 100644 +--- a/man/systemd.timer.xml ++++ b/man/systemd.timer.xml +@@ -125,12 +125,12 @@ + to when the unit the timer is activating was last + deactivated. + +- Multiple directives may be combined of the same and of +- different types. For example, by combining +- OnBootSec= and +- OnUnitActiveSec=, it is possible to define +- a timer that elapses in regular intervals and activates a +- specific service each time. ++ Multiple directives may be combined of the same and of different types, in which case the timer ++ unit will trigger whenever any of the specified timer expressions elapse. For example, by combining ++ OnBootSec= and OnUnitActiveSec=, it is possible to define a ++ timer that elapses in regular intervals and activates a specific service each time. Moreover, both ++ monotonic time expressions and OnCalendar= calendar expressions may be combined in ++ the same timer unit. + + The arguments to the directives are time spans + configured in seconds. Example: "OnBootSec=50" means 50s after +@@ -145,13 +145,12 @@ + and the configured unit is started. This is not the case for + timers defined in the other directives. + +- These are monotonic timers, independent of wall-clock +- time and timezones. If the computer is temporarily suspended, +- the monotonic clock stops too. ++ These are monotonic timers, independent of wall-clock time and timezones. If the computer is ++ temporarily suspended, the monotonic clock pauses, too. + +- If the empty string is assigned to any of these options, +- the list of timers is reset, and all prior assignments will +- have no effect. ++ If the empty string is assigned to any of these options, the list of timers is reset (both ++ monotonic timers and OnCalendar= timers, see below), and all prior assignments ++ will have no effect. + + Note that timers do not necessarily expire at the + precise time configured with these settings, as they are +@@ -175,7 +174,13 @@ + the AccuracySec= setting + below. + +- May be specified more than once. ++ May be specified more than once, in which case the timer unit will trigger whenever any of the ++ specified expressions elapse. Moreover calendar timers and monotonic timers (see above) may be ++ combined within the same timer unit. ++ ++ If the empty string is assigned to any of these options, the list of timers is reset (both ++ OnCalendar= timers and monotonic timers, see above), and all prior assignments ++ will have no effect. + + + diff --git a/SOURCES/0373-Add-support-for-opening-files-for-appending.patch b/SOURCES/0373-Add-support-for-opening-files-for-appending.patch new file mode 100644 index 0000000..fbfa0e8 --- /dev/null +++ b/SOURCES/0373-Add-support-for-opening-files-for-appending.patch @@ -0,0 +1,312 @@ +From 2808e53f785e9ca7fdab286678e784b661b4c185 Mon Sep 17 00:00:00 2001 +From: Zsolt Dollenstein +Date: Tue, 3 Jul 2018 12:22:29 -0700 +Subject: [PATCH] Add support for opening files for appending + +Addresses part of #8983 + +(cherry picked from commit 566b7d23eb747e9c5a74e5647693077b52395fc5) + +Resolves: #1809175 +--- + man/systemd.exec.xml | 16 ++++++---- + src/core/dbus-execute.c | 30 ++++++++++++++----- + src/core/execute.c | 20 ++++++++++--- + src/core/execute.h | 1 + + src/core/load-fragment.c | 11 +++++++ + src/core/main.c | 4 +-- + src/test/test-execute.c | 10 +++++++ + test/meson.build | 2 ++ + .../exec-standardoutput-append.service | 13 ++++++++ + .../exec-standardoutput-file.service | 13 ++++++++ + 10 files changed, 101 insertions(+), 19 deletions(-) + create mode 100644 test/test-execute/exec-standardoutput-append.service + create mode 100644 test/test-execute/exec-standardoutput-file.service + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index bdaed68162..e2a5ede968 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -1792,8 +1792,8 @@ SystemCallErrorNumber=EPERM + of , , , , + , , , + , , +- , or +- . ++ , , ++ or. + + duplicates the file descriptor of standard input for standard output. + +@@ -1824,11 +1824,17 @@ SystemCallErrorNumber=EPERM + + The option may be used to connect a specific file + system object to standard output. The semantics are similar to the same option of +- StandardInput=, see above. If standard input and output are directed to the same file path, +- it is opened only once, for reading as well as writing and duplicated. This is particular useful when the +- specified path refers to an AF_UNIX socket in the file system, as in that case only a ++ StandardInput=, see above. If path refers to a regular file ++ on the filesystem, it is opened (created if it doesn't exist yet) for writing at the beginning of the file, ++ but without truncating it. ++ If standard input and output are directed to the same file path, it is opened only once, for reading as well ++ as writing and duplicated. This is particularly useful when the specified path refers to an ++ AF_UNIX socket in the file system, as in that case only a + single stream connection is created for both input and output. + ++ is similar to above, but it opens the file in append mode. ++ + connects standard output to a socket acquired via socket activation. The + semantics are similar to the same option of StandardInput=, see above. + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index e7c0b893d1..f9527e56b2 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1772,7 +1772,10 @@ int bus_exec_context_set_transient_property( + + return 1; + +- } else if (STR_IN_SET(name, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) { ++ } else if (STR_IN_SET(name, ++ "StandardInputFile", ++ "StandardOutputFile", "StandardOutputFileToCreate", "StandardOutputFileToAppend", ++ "StandardErrorFile", "StandardErrorFileToCreate", "StandardErrorFileToAppend")) { + const char *s; + + r = sd_bus_message_read(message, "s", &s); +@@ -1796,23 +1799,34 @@ int bus_exec_context_set_transient_property( + c->std_input = EXEC_INPUT_FILE; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s); + +- } else if (streq(name, "StandardOutputFile")) { ++ } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend")) { + r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s)); + if (r < 0) + return r; + +- c->std_output = EXEC_OUTPUT_FILE; +- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); +- ++ if (streq(name, "StandardOutputFile")) { ++ c->std_output = EXEC_OUTPUT_FILE; ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); ++ } else { ++ assert(streq(name, "StandardOutputFileToAppend")); ++ c->std_output = EXEC_OUTPUT_FILE_APPEND; ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); ++ } + } else { +- assert(streq(name, "StandardErrorFile")); ++ assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend")); + + r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s)); + if (r < 0) + return r; + +- c->std_error = EXEC_OUTPUT_FILE; +- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s); ++ if (streq(name, "StandardErrorFile")) { ++ c->std_error = EXEC_OUTPUT_FILE; ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); ++ } else { ++ assert(streq(name, "StandardErrorFileToAppend")); ++ c->std_error = EXEC_OUTPUT_FILE_APPEND; ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); ++ } + } + } + +diff --git a/src/core/execute.c b/src/core/execute.c +index f012023224..3c54ac1110 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -89,6 +89,7 @@ + #include "strv.h" + #include "syslog-util.h" + #include "terminal-util.h" ++#include "umask-util.h" + #include "unit.h" + #include "user-util.h" + #include "util.h" +@@ -675,9 +676,10 @@ static int setup_output( + (void) fd_nonblock(named_iofds[fileno], false); + return dup2(named_iofds[fileno], fileno) < 0 ? -errno : fileno; + +- case EXEC_OUTPUT_FILE: { ++ case EXEC_OUTPUT_FILE: ++ case EXEC_OUTPUT_FILE_APPEND: { + bool rw; +- int fd; ++ int fd, flags; + + assert(context->stdio_file[fileno]); + +@@ -687,11 +689,16 @@ static int setup_output( + if (rw) + return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno; + +- fd = acquire_path(context->stdio_file[fileno], O_WRONLY, 0666 & ~context->umask); ++ flags = O_WRONLY; ++ if (o == EXEC_OUTPUT_FILE_APPEND) ++ flags |= O_APPEND; ++ ++ fd = acquire_path(context->stdio_file[fileno], flags, 0666 & ~context->umask); ++ + if (fd < 0) + return fd; + +- return move_fd(fd, fileno, false); ++ return move_fd(fd, fileno, 0); + } + + default: +@@ -4168,8 +4175,12 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { + fprintf(f, "%sStandardInputFile: %s\n", prefix, c->stdio_file[STDIN_FILENO]); + if (c->std_output == EXEC_OUTPUT_FILE) + fprintf(f, "%sStandardOutputFile: %s\n", prefix, c->stdio_file[STDOUT_FILENO]); ++ if (c->std_output == EXEC_OUTPUT_FILE_APPEND) ++ fprintf(f, "%sStandardOutputFileToAppend: %s\n", prefix, c->stdio_file[STDOUT_FILENO]); + if (c->std_error == EXEC_OUTPUT_FILE) + fprintf(f, "%sStandardErrorFile: %s\n", prefix, c->stdio_file[STDERR_FILENO]); ++ if (c->std_error == EXEC_OUTPUT_FILE_APPEND) ++ fprintf(f, "%sStandardErrorFileToAppend: %s\n", prefix, c->stdio_file[STDERR_FILENO]); + + if (c->tty_path) + fprintf(f, +@@ -5111,6 +5122,7 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { + [EXEC_OUTPUT_SOCKET] = "socket", + [EXEC_OUTPUT_NAMED_FD] = "fd", + [EXEC_OUTPUT_FILE] = "file", ++ [EXEC_OUTPUT_FILE_APPEND] = "append", + }; + + DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); +diff --git a/src/core/execute.h b/src/core/execute.h +index 2266355962..86c1cee84c 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -57,6 +57,7 @@ typedef enum ExecOutput { + EXEC_OUTPUT_SOCKET, + EXEC_OUTPUT_NAMED_FD, + EXEC_OUTPUT_FILE, ++ EXEC_OUTPUT_FILE_APPEND, + _EXEC_OUTPUT_MAX, + _EXEC_OUTPUT_INVALID = -1 + } ExecOutput; +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 2082166afb..9b2724307d 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1016,6 +1016,17 @@ int config_parse_exec_output( + + eo = EXEC_OUTPUT_FILE; + ++ } else if ((n = startswith(rvalue, "append:"))) { ++ ++ r = unit_full_printf(u, n, &resolved); ++ if (r < 0) ++ return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n); ++ ++ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE | PATH_CHECK_FATAL, unit, filename, line, lvalue); ++ if (r < 0) ++ return -ENOEXEC; ++ ++ eo = EXEC_OUTPUT_FILE_APPEND; + } else { + eo = exec_output_from_string(rvalue); + if (eo < 0) { +diff --git a/src/core/main.c b/src/core/main.c +index 9f238a8430..25536054b3 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -620,8 +620,8 @@ static int config_parse_output_restricted( + return 0; + } + +- if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE)) { +- log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file: are not supported as defaults, ignoring: %s", rvalue); ++ if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND)) { ++ log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file:, append: are not supported as defaults, ignoring: %s", rvalue); + return 0; + } + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 637ffe96bb..0f8dc883b1 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -651,6 +651,14 @@ static void test_exec_standardinput(Manager *m) { + test(m, "exec-standardinput-file.service", 0, CLD_EXITED); + } + ++static void test_exec_standardoutput(Manager *m) { ++ test(m, "exec-standardoutput-file.service", 0, CLD_EXITED); ++} ++ ++static void test_exec_standardoutput_append(Manager *m) { ++ test(m, "exec-standardoutput-append.service", 0, CLD_EXITED); ++} ++ + static int run_tests(UnitFileScope scope, const test_function_t *tests) { + const test_function_t *test = NULL; + _cleanup_(manager_freep) Manager *m = NULL; +@@ -698,6 +706,8 @@ int main(int argc, char *argv[]) { + test_exec_restrictnamespaces, + test_exec_runtimedirectory, + test_exec_standardinput, ++ test_exec_standardoutput, ++ test_exec_standardoutput_append, + test_exec_supplementarygroups, + test_exec_systemcallerrornumber, + test_exec_systemcallfilter, +diff --git a/test/meson.build b/test/meson.build +index fb9f2cdb9b..4d1c51048c 100644 +--- a/test/meson.build ++++ b/test/meson.build +@@ -115,6 +115,8 @@ test_data_files = ''' + test-execute/exec-specifier@.service + test-execute/exec-standardinput-data.service + test-execute/exec-standardinput-file.service ++ test-execute/exec-standardoutput-file.service ++ test-execute/exec-standardoutput-append.service + test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service + test-execute/exec-supplementarygroups-multiple-groups-withgid.service + test-execute/exec-supplementarygroups-multiple-groups-withuid.service +diff --git a/test/test-execute/exec-standardoutput-append.service b/test/test-execute/exec-standardoutput-append.service +new file mode 100644 +index 0000000000..8983bb056b +--- /dev/null ++++ b/test/test-execute/exec-standardoutput-append.service +@@ -0,0 +1,13 @@ ++[Unit] ++Description=Test for StandardOutput=append: ++ ++[Service] ++ExecStartPre=sh -c 'printf "hello\n" > /tmp/test-exec-standardoutput-output' ++ExecStartPre=sh -c 'printf "hello\nhello\n" > /tmp/test-exec-standardoutput-expected' ++StandardInput=data ++StandardInputText=hello ++StandardOutput=append:/tmp/test-exec-standardoutput-output ++StandardError=null ++ExecStart=cat ++ExecStart=cmp /tmp/test-exec-standardoutput-output /tmp/test-exec-standardoutput-expected ++Type=oneshot +diff --git a/test/test-execute/exec-standardoutput-file.service b/test/test-execute/exec-standardoutput-file.service +new file mode 100644 +index 0000000000..71e2604b94 +--- /dev/null ++++ b/test/test-execute/exec-standardoutput-file.service +@@ -0,0 +1,13 @@ ++[Unit] ++Description=Test for StandardOutput=file: ++ ++[Service] ++ExecStartPre=sh -c 'printf "nooo\nhello\n" > /tmp/test-exec-standardoutput-output' ++ExecStartPre=sh -c 'printf "hello\nello\n" > /tmp/test-exec-standardoutput-expected' ++StandardInput=data ++StandardInputText=hello ++StandardOutput=file:/tmp/test-exec-standardoutput-output ++StandardError=null ++ExecStart=cat ++ExecStart=cmp /tmp/test-exec-standardoutput-expected /tmp/test-exec-standardoutput-output ++Type=oneshot diff --git a/SOURCES/0374-nspawn-move-payload-to-sub-cgroup-first-then-sync-cg.patch b/SOURCES/0374-nspawn-move-payload-to-sub-cgroup-first-then-sync-cg.patch new file mode 100644 index 0000000..52971de --- /dev/null +++ b/SOURCES/0374-nspawn-move-payload-to-sub-cgroup-first-then-sync-cg.patch @@ -0,0 +1,36 @@ +From 8ee1465520ad49892a0a378626ef93abc03f4d4e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 5 Mar 2019 18:57:53 +0100 +Subject: [PATCH] nspawn: move payload to sub-cgroup first, then sync cgroup + trees + +if we sync the legacy and unified trees before moving to the right +subcgroup then ultimately the cgroup paths in the hierarchies will be +out-of-sync... Hence, let's move the payload first, and sync then. + +Addresses: https://github.com/systemd/systemd/pull/9762#issuecomment-441187979 +(cherry picked from commit 27da7ef0d09e00eae821f3ef26e1a666fe7aa087) + +Resolves: #1837094 +--- + src/nspawn/nspawn.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 08255b5724..8cb7591f0e 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -3960,11 +3960,11 @@ static int run(int master, + } else if (arg_slice || arg_property) + log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect."); + +- r = sync_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift); ++ r = create_subcgroup(*pid, arg_keep_unit, arg_unified_cgroup_hierarchy); + if (r < 0) + return r; + +- r = create_subcgroup(*pid, arg_keep_unit, arg_unified_cgroup_hierarchy); ++ r = sync_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift); + if (r < 0) + return r; + diff --git a/SOURCES/0375-nspawn-chown-the-legacy-hierarchy-when-it-s-used-in-.patch b/SOURCES/0375-nspawn-chown-the-legacy-hierarchy-when-it-s-used-in-.patch new file mode 100644 index 0000000..1914ad5 --- /dev/null +++ b/SOURCES/0375-nspawn-chown-the-legacy-hierarchy-when-it-s-used-in-.patch @@ -0,0 +1,31 @@ +From f4a34d97bd7e1564a51f590df591cb31a1a3f333 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 17 Sep 2018 07:12:38 +0000 +Subject: [PATCH] nspawn: chown() the legacy hierarchy when it's used in a + container + +This is a follow-up to 720f0a2f3c928cc9379501a52146be9fbb4d9be2. + +Closes https://github.com/systemd/systemd/issues/10026 +Closes https://github.com/systemd/systemd/issues/9563 + +(cherry picked from commit 89f180201cd8c0f3ce5cb6e8dd7e2b3cbcf71527) + +Resolves: 1837094 +--- + src/nspawn/nspawn-cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c +index d8a39a6959..a231622e29 100644 +--- a/src/nspawn/nspawn-cgroup.c ++++ b/src/nspawn/nspawn-cgroup.c +@@ -55,7 +55,7 @@ int chown_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift) { + if (r < 0) + return log_error_errno(r, "Failed to chown() cgroup %s: %m", fs); + +- if (unified_requested == CGROUP_UNIFIED_SYSTEMD) { ++ if (unified_requested == CGROUP_UNIFIED_SYSTEMD || (unified_requested == CGROUP_UNIFIED_NONE && cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0)) { + _cleanup_free_ char *lfs = NULL; + /* Always propagate access rights from unified to legacy controller */ + diff --git a/SOURCES/0376-core-move-unit_status_emit_starting_stopping_reloadi.patch b/SOURCES/0376-core-move-unit_status_emit_starting_stopping_reloadi.patch new file mode 100644 index 0000000..2badda5 --- /dev/null +++ b/SOURCES/0376-core-move-unit_status_emit_starting_stopping_reloadi.patch @@ -0,0 +1,354 @@ +From 883dfbff6e3e9763d21f9d029a824c63e016cfd9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 19:57:43 +0100 +Subject: [PATCH] core: move unit_status_emit_starting_stopping_reloading() and + related calls to job.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This call is only used by job.c and very specific to job handling. +Moreover the very similar logic of job_emit_status_message() is already +in job.c. + +Hence, let's clean this up, and move both sets of functions to job.c, +and rename them a bit so that they express precisely what they do: + +1. unit_status_emit_starting_stopping_reloading() → + job_emit_begin_status_message() +2. job_emit_status_message() → job_emit_done_status_message() + +The first call is after all what we call when we begin with the +execution of a job, and the second call what we call when we are done +wiht it. + +Just some moving and renaming, not other changes, and hence no change in +behaviour. + +(cherry picked from commit 33a3fdd9781329379f74e11a7a2707816aad8c61) + +Related: #1737283 +--- + src/core/job.c | 119 +++++++++++++++++++++++++++++++++++++++++------- + src/core/unit.c | 86 ---------------------------------- + src/core/unit.h | 1 - + 3 files changed, 103 insertions(+), 103 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 769ed6d603..561ea14682 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -507,6 +507,93 @@ static void job_change_type(Job *j, JobType newtype) { + j->type = newtype; + } + ++_pure_ static const char* job_get_begin_status_message_format(Unit *u, JobType t) { ++ const char *format; ++ const UnitStatusMessageFormats *format_table; ++ ++ assert(u); ++ assert(IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD)); ++ ++ if (t != JOB_RELOAD) { ++ format_table = &UNIT_VTABLE(u)->status_message_formats; ++ if (format_table) { ++ format = format_table->starting_stopping[t == JOB_STOP]; ++ if (format) ++ return format; ++ } ++ } ++ ++ /* Return generic strings */ ++ if (t == JOB_START) ++ return "Starting %s."; ++ else if (t == JOB_STOP) ++ return "Stopping %s."; ++ else ++ return "Reloading %s."; ++} ++ ++static void job_print_begin_status_message(Unit *u, JobType t) { ++ const char *format; ++ ++ assert(u); ++ ++ /* Reload status messages have traditionally not been printed to console. */ ++ if (!IN_SET(t, JOB_START, JOB_STOP)) ++ return; ++ ++ format = job_get_begin_status_message_format(u, t); ++ ++ DISABLE_WARNING_FORMAT_NONLITERAL; ++ unit_status_printf(u, "", format); ++ REENABLE_WARNING; ++} ++ ++static void job_log_begin_status_message(Unit *u, JobType t) { ++ const char *format, *mid; ++ char buf[LINE_MAX]; ++ ++ assert(u); ++ ++ if (!IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD)) ++ return; ++ ++ if (log_on_console()) ++ return; ++ ++ /* We log status messages for all units and all operations. */ ++ ++ format = job_get_begin_status_message_format(u, t); ++ ++ DISABLE_WARNING_FORMAT_NONLITERAL; ++ (void) snprintf(buf, sizeof buf, format, unit_description(u)); ++ REENABLE_WARNING; ++ ++ mid = t == JOB_START ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTING_STR : ++ t == JOB_STOP ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPING_STR : ++ "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADING_STR; ++ ++ /* Note that we deliberately use LOG_MESSAGE() instead of ++ * LOG_UNIT_MESSAGE() here, since this is supposed to mimic ++ * closely what is written to screen using the status output, ++ * which is supposed the highest level, friendliest output ++ * possible, which means we should avoid the low-level unit ++ * name. */ ++ log_struct(LOG_INFO, ++ LOG_MESSAGE("%s", buf), ++ LOG_UNIT_ID(u), ++ LOG_UNIT_INVOCATION_ID(u), ++ mid); ++} ++ ++static void job_emit_begin_status_message(Unit *u, JobType t) { ++ assert(u); ++ assert(t >= 0); ++ assert(t < _JOB_TYPE_MAX); ++ ++ job_log_begin_status_message(u, t); ++ job_print_begin_status_message(u, t); ++} ++ + static int job_perform_on_unit(Job **j) { + uint32_t id; + Manager *m; +@@ -552,7 +639,7 @@ static int job_perform_on_unit(Job **j) { + * actually did something. */ + *j = manager_get_job(m, id); + if (*j && r > 0) +- unit_status_emit_starting_stopping_reloading(u, t); ++ job_emit_begin_status_message(u, t); + + return r; + } +@@ -638,7 +725,7 @@ int job_run_and_invalidate(Job *j) { + return r; + } + +-_pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) { ++_pure_ static const char *job_get_done_status_message_format(Unit *u, JobType t, JobResult result) { + + static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = { + [JOB_DONE] = "Started %s.", +@@ -699,7 +786,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR + + static const struct { + const char *color, *word; +-} job_print_status_messages [_JOB_RESULT_MAX] = { ++} job_print_done_status_messages[_JOB_RESULT_MAX] = { + [JOB_DONE] = { ANSI_OK_COLOR, " OK " }, + [JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " }, + [JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" }, +@@ -711,7 +798,7 @@ static const struct { + [JOB_ONCE] = { ANSI_HIGHLIGHT_RED, " ONCE " }, + }; + +-static void job_print_status_message(Unit *u, JobType t, JobResult result) { ++static void job_print_done_status_message(Unit *u, JobType t, JobResult result) { + const char *format; + const char *status; + +@@ -723,19 +810,19 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) { + if (t == JOB_RELOAD) + return; + +- if (!job_print_status_messages[result].word) ++ if (!job_print_done_status_messages[result].word) + return; + +- format = job_get_status_message_format(u, t, result); ++ format = job_get_done_status_message_format(u, t, result); + if (!format) + return; + + if (log_get_show_color()) +- status = strjoina(job_print_status_messages[result].color, +- job_print_status_messages[result].word, ++ status = strjoina(job_print_done_status_messages[result].color, ++ job_print_done_status_messages[result].word, + ANSI_NORMAL); + else +- status = job_print_status_messages[result].word; ++ status = job_print_done_status_messages[result].word; + + if (result != JOB_DONE) + manager_flip_auto_status(u->manager, true); +@@ -752,7 +839,7 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) { + } + } + +-static void job_log_status_message(Unit *u, JobType t, JobResult result) { ++static void job_log_done_status_message(Unit *u, uint32_t job_id, JobType t, JobResult result) { + const char *format, *mid; + char buf[LINE_MAX]; + static const int job_result_log_level[_JOB_RESULT_MAX] = { +@@ -775,10 +862,10 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { + + /* Skip printing if output goes to the console, and job_print_status_message() + will actually print something to the console. */ +- if (log_on_console() && job_print_status_messages[result].word) ++ if (log_on_console() && job_print_done_status_messages[result].word) + return; + +- format = job_get_status_message_format(u, t, result); ++ format = job_get_done_status_message_format(u, t, result); + if (!format) + return; + +@@ -827,15 +914,15 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { + mid); + } + +-static void job_emit_status_message(Unit *u, JobType t, JobResult result) { ++static void job_emit_done_status_message(Unit *u, uint32_t job_id, JobType t, JobResult result) { + assert(u); + + /* No message if the job did not actually do anything due to failed condition. */ + if (t == JOB_START && result == JOB_DONE && !u->condition_result) + return; + +- job_log_status_message(u, t, result); +- job_print_status_message(u, t, result); ++ job_log_done_status_message(u, job_id, t, result); ++ job_print_done_status_message(u, t, result); + } + + static void job_fail_dependencies(Unit *u, UnitDependency d) { +@@ -890,7 +977,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr + + /* If this job did nothing to respective unit we don't log the status message */ + if (!already) +- job_emit_status_message(u, t, result); ++ job_emit_done_status_message(u, j->id, t, result); + + /* Patch restart jobs so that they become normal start jobs */ + if (result == JOB_DONE && t == JOB_RESTART) { +diff --git a/src/core/unit.c b/src/core/unit.c +index 40f138d25c..f5e251123d 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1624,92 +1624,6 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg + REENABLE_WARNING; + } + +-_pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) { +- const char *format; +- const UnitStatusMessageFormats *format_table; +- +- assert(u); +- assert(IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD)); +- +- if (t != JOB_RELOAD) { +- format_table = &UNIT_VTABLE(u)->status_message_formats; +- if (format_table) { +- format = format_table->starting_stopping[t == JOB_STOP]; +- if (format) +- return format; +- } +- } +- +- /* Return generic strings */ +- if (t == JOB_START) +- return "Starting %s."; +- else if (t == JOB_STOP) +- return "Stopping %s."; +- else +- return "Reloading %s."; +-} +- +-static void unit_status_print_starting_stopping(Unit *u, JobType t) { +- const char *format; +- +- assert(u); +- +- /* Reload status messages have traditionally not been printed to console. */ +- if (!IN_SET(t, JOB_START, JOB_STOP)) +- return; +- +- format = unit_get_status_message_format(u, t); +- +- DISABLE_WARNING_FORMAT_NONLITERAL; +- unit_status_printf(u, "", format); +- REENABLE_WARNING; +-} +- +-static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { +- const char *format, *mid; +- char buf[LINE_MAX]; +- +- assert(u); +- +- if (!IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD)) +- return; +- +- if (log_on_console()) +- return; +- +- /* We log status messages for all units and all operations. */ +- +- format = unit_get_status_message_format(u, t); +- +- DISABLE_WARNING_FORMAT_NONLITERAL; +- (void) snprintf(buf, sizeof buf, format, unit_description(u)); +- REENABLE_WARNING; +- +- mid = t == JOB_START ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTING_STR : +- t == JOB_STOP ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPING_STR : +- "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADING_STR; +- +- /* Note that we deliberately use LOG_MESSAGE() instead of +- * LOG_UNIT_MESSAGE() here, since this is supposed to mimic +- * closely what is written to screen using the status output, +- * which is supposed the highest level, friendliest output +- * possible, which means we should avoid the low-level unit +- * name. */ +- log_struct(LOG_INFO, +- LOG_MESSAGE("%s", buf), +- LOG_UNIT_ID(u), +- LOG_UNIT_INVOCATION_ID(u), +- mid); +-} +- +-void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) { +- assert(u); +- assert(t >= 0); +- assert(t < _JOB_TYPE_MAX); +- +- unit_status_log_starting_stopping_reloading(u, t); +- unit_status_print_starting_stopping(u, t); +-} + + int unit_start_limit_test(Unit *u) { + assert(u); +diff --git a/src/core/unit.h b/src/core/unit.h +index 595ee88d43..4d9539790a 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -699,7 +699,6 @@ int unit_coldplug(Unit *u); + void unit_catchup(Unit *u); + + void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0); +-void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t); + + bool unit_need_daemon_reload(Unit *u); + diff --git a/SOURCES/0377-job-when-a-job-was-skipped-due-to-a-failed-condition.patch b/SOURCES/0377-job-when-a-job-was-skipped-due-to-a-failed-condition.patch new file mode 100644 index 0000000..c7f1a68 --- /dev/null +++ b/SOURCES/0377-job-when-a-job-was-skipped-due-to-a-failed-condition.patch @@ -0,0 +1,63 @@ +From 9c543783dbe560f4dafa4c2f276e03a4bce0389e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 14 Nov 2018 11:08:16 +0100 +Subject: [PATCH] job: when a job was skipped due to a failed condition, log + about it + +Previously we'd neither show console status output nor log output. Let's +fix that, and still log something. + +(cherry picked from commit 9a80f2f4533883d272e6a436512aa7e88cedc549) + +Related: #1737283 +--- + src/core/job.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 561ea14682..b9eee91cf3 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -810,6 +810,10 @@ static void job_print_done_status_message(Unit *u, JobType t, JobResult result) + if (t == JOB_RELOAD) + return; + ++ /* No message if the job did not actually do anything due to failed condition. */ ++ if (t == JOB_START && result == JOB_DONE && !u->condition_result) ++ return; ++ + if (!job_print_done_status_messages[result].word) + return; + +@@ -865,6 +869,20 @@ static void job_log_done_status_message(Unit *u, uint32_t job_id, JobType t, Job + if (log_on_console() && job_print_done_status_messages[result].word) + return; + ++ /* Show condition check message if the job did not actually do anything due to failed condition. */ ++ if (t == JOB_START && result == JOB_DONE && !u->condition_result) { ++ log_struct(LOG_INFO, ++ "MESSAGE=Condition check resulted in %s being skipped.", unit_description(u), ++ "JOB_ID=%" PRIu32, job_id, ++ "JOB_TYPE=%s", job_type_to_string(t), ++ "JOB_RESULT=%s", job_result_to_string(result), ++ LOG_UNIT_ID(u), ++ LOG_UNIT_INVOCATION_ID(u), ++ "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTED_STR); ++ ++ return; ++ } ++ + format = job_get_done_status_message_format(u, t, result); + if (!format) + return; +@@ -917,10 +935,6 @@ static void job_log_done_status_message(Unit *u, uint32_t job_id, JobType t, Job + static void job_emit_done_status_message(Unit *u, uint32_t job_id, JobType t, JobResult result) { + assert(u); + +- /* No message if the job did not actually do anything due to failed condition. */ +- if (t == JOB_START && result == JOB_DONE && !u->condition_result) +- return; +- + job_log_done_status_message(u, job_id, t, result); + job_print_done_status_message(u, t, result); + } diff --git a/SOURCES/0378-core-split-out-all-logic-that-updates-a-Job-on-a-uni.patch b/SOURCES/0378-core-split-out-all-logic-that-updates-a-Job-on-a-uni.patch new file mode 100644 index 0000000..eb29a28 --- /dev/null +++ b/SOURCES/0378-core-split-out-all-logic-that-updates-a-Job-on-a-uni.patch @@ -0,0 +1,169 @@ +From 81c3f90d41c973a18e157c1106926711815adc0e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 10 Dec 2018 20:56:57 +0100 +Subject: [PATCH] core: split out all logic that updates a Job on a unit's + unit_notify() invocation + +Just some refactoring, no change in behaviour. + +(cherry picked from commit 16c74914d233ec93012d77e5f93cf90e42939669) + +Related: #1737283 +--- + src/core/unit.c | 136 +++++++++++++++++++++++++----------------------- + 1 file changed, 71 insertions(+), 65 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index f5e251123d..a4865c1da5 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2225,6 +2225,73 @@ static void unit_update_on_console(Unit *u) { + manager_unref_console(u->manager); + } + ++static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) { ++ bool unexpected = false; ++ ++ assert(j); ++ ++ if (j->state == JOB_WAITING) ++ ++ /* So we reached a different state for this job. Let's see if we can run it now if it failed previously ++ * due to EAGAIN. */ ++ job_add_to_run_queue(j); ++ ++ /* Let's check whether the unit's new state constitutes a finished job, or maybe contradicts a running job and ++ * hence needs to invalidate jobs. */ ++ ++ switch (j->type) { ++ ++ case JOB_START: ++ case JOB_VERIFY_ACTIVE: ++ ++ if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) ++ job_finish_and_invalidate(j, JOB_DONE, true, false); ++ else if (j->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { ++ unexpected = true; ++ ++ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) ++ job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); ++ } ++ ++ break; ++ ++ case JOB_RELOAD: ++ case JOB_RELOAD_OR_START: ++ case JOB_TRY_RELOAD: ++ ++ if (j->state == JOB_RUNNING) { ++ if (ns == UNIT_ACTIVE) ++ job_finish_and_invalidate(j, (flags & UNIT_NOTIFY_RELOAD_FAILURE) ? JOB_FAILED : JOB_DONE, true, false); ++ else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING)) { ++ unexpected = true; ++ ++ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) ++ job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); ++ } ++ } ++ ++ break; ++ ++ case JOB_STOP: ++ case JOB_RESTART: ++ case JOB_TRY_RESTART: ++ ++ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) ++ job_finish_and_invalidate(j, JOB_DONE, true, false); ++ else if (j->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { ++ unexpected = true; ++ job_finish_and_invalidate(j, JOB_FAILED, true, false); ++ } ++ ++ break; ++ ++ default: ++ assert_not_reached("Job type unknown"); ++ } ++ ++ return unexpected; ++} ++ + void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags) { + bool unexpected; + Manager *m; +@@ -2265,71 +2332,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + + unit_update_on_console(u); + +- if (u->job) { +- unexpected = false; +- +- if (u->job->state == JOB_WAITING) +- +- /* So we reached a different state for this +- * job. Let's see if we can run it now if it +- * failed previously due to EAGAIN. */ +- job_add_to_run_queue(u->job); +- +- /* Let's check whether this state change constitutes a +- * finished job, or maybe contradicts a running job and +- * hence needs to invalidate jobs. */ +- +- switch (u->job->type) { +- +- case JOB_START: +- case JOB_VERIFY_ACTIVE: +- +- if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) +- job_finish_and_invalidate(u->job, JOB_DONE, true, false); +- else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { +- unexpected = true; +- +- if (UNIT_IS_INACTIVE_OR_FAILED(ns)) +- job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); +- } +- +- break; +- +- case JOB_RELOAD: +- case JOB_RELOAD_OR_START: +- case JOB_TRY_RELOAD: +- +- if (u->job->state == JOB_RUNNING) { +- if (ns == UNIT_ACTIVE) +- job_finish_and_invalidate(u->job, (flags & UNIT_NOTIFY_RELOAD_FAILURE) ? JOB_FAILED : JOB_DONE, true, false); +- else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING)) { +- unexpected = true; +- +- if (UNIT_IS_INACTIVE_OR_FAILED(ns)) +- job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); +- } +- } +- +- break; +- +- case JOB_STOP: +- case JOB_RESTART: +- case JOB_TRY_RESTART: +- +- if (UNIT_IS_INACTIVE_OR_FAILED(ns)) +- job_finish_and_invalidate(u->job, JOB_DONE, true, false); +- else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { +- unexpected = true; +- job_finish_and_invalidate(u->job, JOB_FAILED, true, false); +- } +- +- break; +- +- default: +- assert_not_reached("Job type unknown"); +- } +- +- } else ++ /* Let's propagate state changes to the job */ ++ if (u->job) ++ unexpected = unit_process_job(u->job, ns, flags); ++ else + unexpected = true; + + if (!MANAGER_IS_RELOADING(m)) { diff --git a/SOURCES/0379-core-make-log-messages-about-units-entering-a-failed.patch b/SOURCES/0379-core-make-log-messages-about-units-entering-a-failed.patch new file mode 100644 index 0000000..ff88dd4 --- /dev/null +++ b/SOURCES/0379-core-make-log-messages-about-units-entering-a-failed.patch @@ -0,0 +1,200 @@ +From d5245b46716cf53ce4d95966ea99499cf7aa209a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 21:25:22 +0100 +Subject: [PATCH] core: make log messages about units entering a 'failed' state + recognizable + +Let's make this recognizable, and carry result information in a +structure fashion. + +(cherry picked from commit 7c047d7443347c109daf67023a01c118b5f361eb) + +Related: #1737283 +--- + catalog/systemd.catalog.in | 7 +++++++ + src/core/automount.c | 2 +- + src/core/mount.c | 2 +- + src/core/path.c | 2 +- + src/core/scope.c | 2 +- + src/core/service.c | 2 +- + src/core/socket.c | 2 +- + src/core/swap.c | 2 +- + src/core/timer.c | 2 +- + src/core/unit.c | 12 ++++++++++++ + src/core/unit.h | 2 ++ + src/systemd/sd-messages.h | 4 ++++ + 12 files changed, 33 insertions(+), 8 deletions(-) + +diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in +index 49a45890f6..54a0f46921 100644 +--- a/catalog/systemd.catalog.in ++++ b/catalog/systemd.catalog.in +@@ -344,6 +344,13 @@ Support: %SUPPORT_URL% + + The unit @UNIT@ completed and consumed the indicated resources. + ++-- d9b373ed55a64feb8242e02dbe79a49c ++Subject: Unit failed ++Defined-By: systemd ++Support: %SUPPORT_URL% ++ ++The unit @UNIT@ has entered the 'failed' state with result '@UNIT_RESULT@'. ++ + -- 50876a9db00f4c40bde1a2ad381c3a1b + Subject: The system is configured in a way that might cause problems + Defined-By: systemd +diff --git a/src/core/automount.c b/src/core/automount.c +index 1b96a52c00..c78562c549 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -315,7 +315,7 @@ static void automount_enter_dead(Automount *a, AutomountResult f) { + a->result = f; + + if (a->result != AUTOMOUNT_SUCCESS) +- log_unit_warning(UNIT(a), "Failed with result '%s'.", automount_result_to_string(a->result)); ++ unit_log_failure(UNIT(a), automount_result_to_string(a->result)); + + automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD); + } +diff --git a/src/core/mount.c b/src/core/mount.c +index 5878814b1b..3cd0e479e9 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -797,7 +797,7 @@ static void mount_enter_dead(Mount *m, MountResult f) { + m->result = f; + + if (m->result != MOUNT_SUCCESS) +- log_unit_warning(UNIT(m), "Failed with result '%s'.", mount_result_to_string(m->result)); ++ unit_log_failure(UNIT(m), mount_result_to_string(m->result)); + + mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); + +diff --git a/src/core/path.c b/src/core/path.c +index 5ef178a46b..f8b69e7804 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -449,7 +449,7 @@ static void path_enter_dead(Path *p, PathResult f) { + p->result = f; + + if (p->result != PATH_SUCCESS) +- log_unit_warning(UNIT(p), "Failed with result '%s'.", path_result_to_string(p->result)); ++ unit_log_failure(UNIT(p), path_result_to_string(p->result)); + + path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); + } +diff --git a/src/core/scope.c b/src/core/scope.c +index 751556fecf..79ecfd992f 100644 +--- a/src/core/scope.c ++++ b/src/core/scope.c +@@ -240,7 +240,7 @@ static void scope_enter_dead(Scope *s, ScopeResult f) { + s->result = f; + + if (s->result != SCOPE_SUCCESS) +- log_unit_warning(UNIT(s), "Failed with result '%s'.", scope_result_to_string(s->result)); ++ unit_log_failure(UNIT(s), scope_result_to_string(s->result)); + + scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD); + } +diff --git a/src/core/service.c b/src/core/service.c +index 5035dcacac..efceb0614c 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1680,7 +1680,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) + s->result = f; + + if (s->result != SERVICE_SUCCESS) +- log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result)); ++ unit_log_failure(UNIT(s), service_result_to_string(s->result)); + + if (allow_restart && service_shall_restart(s)) + s->will_auto_restart = true; +diff --git a/src/core/socket.c b/src/core/socket.c +index b034549634..160f11765c 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1991,7 +1991,7 @@ static void socket_enter_dead(Socket *s, SocketResult f) { + s->result = f; + + if (s->result != SOCKET_SUCCESS) +- log_unit_warning(UNIT(s), "Failed with result '%s'.", socket_result_to_string(s->result)); ++ unit_log_failure(UNIT(s), socket_result_to_string(s->result)); + + socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); + +diff --git a/src/core/swap.c b/src/core/swap.c +index 66a62d8a37..b5926d8644 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -657,7 +657,7 @@ static void swap_enter_dead(Swap *s, SwapResult f) { + s->result = f; + + if (s->result != SWAP_SUCCESS) +- log_unit_warning(UNIT(s), "Failed with result '%s'.", swap_result_to_string(s->result)); ++ unit_log_failure(UNIT(s), swap_result_to_string(s->result)); + + swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); + +diff --git a/src/core/timer.c b/src/core/timer.c +index db202971d3..6ac310cbe0 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -288,7 +288,7 @@ static void timer_enter_dead(Timer *t, TimerResult f) { + t->result = f; + + if (t->result != TIMER_SUCCESS) +- log_unit_warning(UNIT(t), "Failed with result '%s'.", timer_result_to_string(t->result)); ++ unit_log_failure(UNIT(t), timer_result_to_string(t->result)); + + timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD); + } +diff --git a/src/core/unit.c b/src/core/unit.c +index a4865c1da5..f55bddc00f 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5462,6 +5462,18 @@ int unit_pid_attachable(Unit *u, pid_t pid, sd_bus_error *error) { + return 0; + } + ++void unit_log_failure(Unit *u, const char *result) { ++ assert(u); ++ assert(result); ++ ++ log_struct(LOG_WARNING, ++ "MESSAGE_ID=" SD_MESSAGE_UNIT_FAILURE_RESULT_STR, ++ LOG_UNIT_ID(u), ++ LOG_UNIT_INVOCATION_ID(u), ++ LOG_UNIT_MESSAGE(u, "Failed with result '%s'.", result), ++ "UNIT_RESULT=%s", result); ++} ++ + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index 4d9539790a..9d226fb3e0 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -804,6 +804,8 @@ const char *unit_label_path(Unit *u); + + int unit_pid_attachable(Unit *unit, pid_t pid, sd_bus_error *error); + ++void unit_log_failure(Unit *u, const char *result); ++ + /* Macros which append UNIT= or USER_UNIT= to the message */ + + #define log_unit_full(unit, level, error, ...) \ +diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h +index 2adfe16062..846b28fc2b 100644 +--- a/src/systemd/sd-messages.h ++++ b/src/systemd/sd-messages.h +@@ -106,6 +106,10 @@ _SD_BEGIN_DECLARATIONS; + #define SD_MESSAGE_UNIT_RESOURCES SD_ID128_MAKE(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) + #define SD_MESSAGE_UNIT_RESOURCES_STR SD_ID128_MAKE_STR(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) + ++#define SD_MESSAGE_UNIT_FAILURE_RESULT SD_ID128_MAKE(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) ++#define SD_MESSAGE_UNIT_FAILURE_RESULT_STR \ ++ SD_ID128_MAKE_STR(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) ++ + #define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) + #define SD_MESSAGE_SPAWN_FAILED_STR SD_ID128_MAKE_STR(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) + diff --git a/SOURCES/0380-core-log-a-recognizable-message-when-a-unit-succeeds.patch b/SOURCES/0380-core-log-a-recognizable-message-when-a-unit-succeeds.patch new file mode 100644 index 0000000..a526810 --- /dev/null +++ b/SOURCES/0380-core-log-a-recognizable-message-when-a-unit-succeeds.patch @@ -0,0 +1,210 @@ +From 40c2b0a20ff133f2050642dc7230424ddcb2987b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 13 Nov 2018 23:28:09 +0100 +Subject: [PATCH] core: log a recognizable message when a unit succeeds, too + +We already are doing it on failure, let's do it on success, too. + +Fixes: #10265 +(cherry picked from commit 523ee2d41471bfb738f52d59de9b469301842644) + +Related: #1737283 +--- + catalog/systemd.catalog.in | 7 +++++++ + src/core/automount.c | 4 +++- + src/core/mount.c | 4 +++- + src/core/path.c | 4 +++- + src/core/scope.c | 4 +++- + src/core/service.c | 4 +++- + src/core/socket.c | 4 +++- + src/core/swap.c | 4 +++- + src/core/timer.c | 4 +++- + src/core/unit.c | 10 ++++++++++ + src/core/unit.h | 1 + + src/systemd/sd-messages.h | 2 ++ + 12 files changed, 44 insertions(+), 8 deletions(-) + +diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in +index 54a0f46921..2492ad2028 100644 +--- a/catalog/systemd.catalog.in ++++ b/catalog/systemd.catalog.in +@@ -344,6 +344,13 @@ Support: %SUPPORT_URL% + + The unit @UNIT@ completed and consumed the indicated resources. + ++-- 7ad2d189f7e94e70a38c781354912448 ++Subject: Unit succeeded ++Defined-By: systemd ++Support: %SUPPORT_URL% ++ ++The unit @UNIT@ has successfully entered the 'dead' state. ++ + -- d9b373ed55a64feb8242e02dbe79a49c + Subject: Unit failed + Defined-By: systemd +diff --git a/src/core/automount.c b/src/core/automount.c +index c78562c549..b1a155d8d4 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -314,7 +314,9 @@ static void automount_enter_dead(Automount *a, AutomountResult f) { + if (a->result == AUTOMOUNT_SUCCESS) + a->result = f; + +- if (a->result != AUTOMOUNT_SUCCESS) ++ if (a->result == AUTOMOUNT_SUCCESS) ++ unit_log_success(UNIT(a)); ++ else + unit_log_failure(UNIT(a), automount_result_to_string(a->result)); + + automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD); +diff --git a/src/core/mount.c b/src/core/mount.c +index 3cd0e479e9..30aaf5ae55 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -796,7 +796,9 @@ static void mount_enter_dead(Mount *m, MountResult f) { + if (m->result == MOUNT_SUCCESS) + m->result = f; + +- if (m->result != MOUNT_SUCCESS) ++ if (m->result == MOUNT_SUCCESS) ++ unit_log_success(UNIT(m)); ++ else + unit_log_failure(UNIT(m), mount_result_to_string(m->result)); + + mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); +diff --git a/src/core/path.c b/src/core/path.c +index f8b69e7804..dda4a3036b 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -448,7 +448,9 @@ static void path_enter_dead(Path *p, PathResult f) { + if (p->result == PATH_SUCCESS) + p->result = f; + +- if (p->result != PATH_SUCCESS) ++ if (p->result == PATH_SUCCESS) ++ unit_log_success(UNIT(p)); ++ else + unit_log_failure(UNIT(p), path_result_to_string(p->result)); + + path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); +diff --git a/src/core/scope.c b/src/core/scope.c +index 79ecfd992f..a1a5363244 100644 +--- a/src/core/scope.c ++++ b/src/core/scope.c +@@ -239,7 +239,9 @@ static void scope_enter_dead(Scope *s, ScopeResult f) { + if (s->result == SCOPE_SUCCESS) + s->result = f; + +- if (s->result != SCOPE_SUCCESS) ++ if (s->result == SCOPE_SUCCESS) ++ unit_log_success(UNIT(s)); ++ else + unit_log_failure(UNIT(s), scope_result_to_string(s->result)); + + scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD); +diff --git a/src/core/service.c b/src/core/service.c +index efceb0614c..2c31e70ef6 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1679,7 +1679,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) + if (s->result == SERVICE_SUCCESS) + s->result = f; + +- if (s->result != SERVICE_SUCCESS) ++ if (s->result == SERVICE_SUCCESS) ++ unit_log_success(UNIT(s)); ++ else + unit_log_failure(UNIT(s), service_result_to_string(s->result)); + + if (allow_restart && service_shall_restart(s)) +diff --git a/src/core/socket.c b/src/core/socket.c +index 160f11765c..7c6d3dfad1 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1990,7 +1990,9 @@ static void socket_enter_dead(Socket *s, SocketResult f) { + if (s->result == SOCKET_SUCCESS) + s->result = f; + +- if (s->result != SOCKET_SUCCESS) ++ if (s->result == SOCKET_SUCCESS) ++ unit_log_success(UNIT(s)); ++ else + unit_log_failure(UNIT(s), socket_result_to_string(s->result)); + + socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); +diff --git a/src/core/swap.c b/src/core/swap.c +index b5926d8644..a8f127f660 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -656,7 +656,9 @@ static void swap_enter_dead(Swap *s, SwapResult f) { + if (s->result == SWAP_SUCCESS) + s->result = f; + +- if (s->result != SWAP_SUCCESS) ++ if (s->result == SWAP_SUCCESS) ++ unit_log_success(UNIT(s)); ++ else + unit_log_failure(UNIT(s), swap_result_to_string(s->result)); + + swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); +diff --git a/src/core/timer.c b/src/core/timer.c +index 6ac310cbe0..2876d54a59 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -287,7 +287,9 @@ static void timer_enter_dead(Timer *t, TimerResult f) { + if (t->result == TIMER_SUCCESS) + t->result = f; + +- if (t->result != TIMER_SUCCESS) ++ if (t->result == TIMER_SUCCESS) ++ unit_log_success(UNIT(t)); ++ else + unit_log_failure(UNIT(t), timer_result_to_string(t->result)); + + timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD); +diff --git a/src/core/unit.c b/src/core/unit.c +index f55bddc00f..ccb0106719 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5462,6 +5462,16 @@ int unit_pid_attachable(Unit *u, pid_t pid, sd_bus_error *error) { + return 0; + } + ++void unit_log_success(Unit *u) { ++ assert(u); ++ ++ log_struct(LOG_INFO, ++ "MESSAGE_ID=" SD_MESSAGE_UNIT_SUCCESS_STR, ++ LOG_UNIT_ID(u), ++ LOG_UNIT_INVOCATION_ID(u), ++ LOG_UNIT_MESSAGE(u, "Succeeded.")); ++} ++ + void unit_log_failure(Unit *u, const char *result) { + assert(u); + assert(result); +diff --git a/src/core/unit.h b/src/core/unit.h +index 9d226fb3e0..4ae1b38624 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -804,6 +804,7 @@ const char *unit_label_path(Unit *u); + + int unit_pid_attachable(Unit *unit, pid_t pid, sd_bus_error *error); + ++void unit_log_success(Unit *u); + void unit_log_failure(Unit *u, const char *result); + + /* Macros which append UNIT= or USER_UNIT= to the message */ +diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h +index 846b28fc2b..e7ef81b597 100644 +--- a/src/systemd/sd-messages.h ++++ b/src/systemd/sd-messages.h +@@ -106,6 +106,8 @@ _SD_BEGIN_DECLARATIONS; + #define SD_MESSAGE_UNIT_RESOURCES SD_ID128_MAKE(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) + #define SD_MESSAGE_UNIT_RESOURCES_STR SD_ID128_MAKE_STR(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) + ++#define SD_MESSAGE_UNIT_SUCCESS SD_ID128_MAKE(7a,d2,d1,89,f7,e9,4e,70,a3,8c,78,13,54,91,24,48) ++#define SD_MESSAGE_UNIT_SUCCESS_STR SD_ID128_MAKE_STR(7a,d2,d1,89,f7,e9,4e,70,a3,8c,78,13,54,91,24,48) + #define SD_MESSAGE_UNIT_FAILURE_RESULT SD_ID128_MAKE(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) + #define SD_MESSAGE_UNIT_FAILURE_RESULT_STR \ + SD_ID128_MAKE_STR(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) diff --git a/SOURCES/0381-tests-always-use-the-right-vtable-wrapper-calls.patch b/SOURCES/0381-tests-always-use-the-right-vtable-wrapper-calls.patch new file mode 100644 index 0000000..d10b974 --- /dev/null +++ b/SOURCES/0381-tests-always-use-the-right-vtable-wrapper-calls.patch @@ -0,0 +1,113 @@ +From 9a6fa8659e7c6b18c95754e6fa9417f03b6341df Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Nov 2018 14:48:28 +0100 +Subject: [PATCH] tests: always use the right vtable wrapper calls + +Prompted by https://github.com/systemd/systemd/pull/10836#discussion_r234598868 + +(cherry picked from commit bd7989a3d90e5d97e09f1eef33d09b2469a79f4d) + +Related: #1737283 +--- + src/test/test-execute.c | 2 +- + src/test/test-path.c | 18 +++++++++--------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 0f8dc883b1..d88de52d2a 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -129,7 +129,7 @@ static void test(Manager *m, const char *unit_name, int status_expected, int cod + assert_se(unit_name); + + assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + check(m, unit, status_expected, code_expected); + } + +diff --git a/src/test/test-path.c b/src/test/test-path.c +index 209eb2e366..3a1469ae02 100644 +--- a/src/test/test-path.c ++++ b/src/test/test-path.c +@@ -106,7 +106,7 @@ static void check_stop_unlink(Manager *m, Unit *unit, const char *test_path, con + } + } + +- assert_se(UNIT_VTABLE(unit)->stop(unit) >= 0); ++ assert_se(unit_stop(unit) >= 0); + (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL); + } + +@@ -117,7 +117,7 @@ static void test_path_exists(Manager *m) { + assert_se(m); + + assert_se(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + assert_se(touch(test_path) >= 0); + +@@ -130,7 +130,7 @@ static void test_path_existsglob(Manager *m) { + + assert_se(m); + assert_se(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + assert_se(touch(test_path) >= 0); + +@@ -147,7 +147,7 @@ static void test_path_changed(Manager *m) { + assert_se(touch(test_path) >= 0); + + assert_se(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + f = fopen(test_path, "w"); + assert_se(f); +@@ -166,7 +166,7 @@ static void test_path_modified(Manager *m) { + assert_se(touch(test_path) >= 0); + + assert_se(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + f = fopen(test_path, "w"); + assert_se(f); +@@ -182,7 +182,7 @@ static void test_path_unit(Manager *m) { + assert_se(m); + + assert_se(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + assert_se(touch(test_path) >= 0); + +@@ -198,7 +198,7 @@ static void test_path_directorynotempty(Manager *m) { + assert_se(access(test_path, F_OK) < 0); + + assert_se(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + /* MakeDirectory default to no */ + assert_se(access(test_path, F_OK) < 0); +@@ -219,7 +219,7 @@ static void test_path_makedirectory_directorymode(Manager *m) { + assert_se(access(test_path, F_OK) < 0); + + assert_se(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, &unit) >= 0); +- assert_se(UNIT_VTABLE(unit)->start(unit) >= 0); ++ assert_se(unit_start(unit) >= 0); + + /* Check if the directory has been created */ + assert_se(access(test_path, F_OK) >= 0); +@@ -230,7 +230,7 @@ static void test_path_makedirectory_directorymode(Manager *m) { + assert_se((s.st_mode & S_IRWXG) == 0040); + assert_se((s.st_mode & S_IRWXO) == 0004); + +- assert_se(UNIT_VTABLE(unit)->stop(unit) >= 0); ++ assert_se(unit_stop(unit) >= 0); + (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL); + } + diff --git a/SOURCES/0382-test-execute-allow-filtering-test-cases-by-pattern.patch b/SOURCES/0382-test-execute-allow-filtering-test-cases-by-pattern.patch new file mode 100644 index 0000000..da50009 --- /dev/null +++ b/SOURCES/0382-test-execute-allow-filtering-test-cases-by-pattern.patch @@ -0,0 +1,153 @@ +From 9beae637a919326ddc072c4dd53cb66e80273c8f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 15 Mar 2019 13:42:55 +0100 +Subject: [PATCH] test-execute: allow filtering test cases by pattern + +When debugging failure in one of the cases, it's annoying to have to wade +through the output from all the other cases. Let's allow picking select +cases. + +(cherry picked from commit 9efb96315ae502dabeb94ab35816ea8955563b7a) + +Related: #1737283 +--- + src/test/test-execute.c | 104 ++++++++++++++++++++++------------------ + 1 file changed, 58 insertions(+), 46 deletions(-) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index d88de52d2a..d077674efc 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -659,8 +659,15 @@ static void test_exec_standardoutput_append(Manager *m) { + test(m, "exec-standardoutput-append.service", 0, CLD_EXITED); + } + +-static int run_tests(UnitFileScope scope, const test_function_t *tests) { +- const test_function_t *test = NULL; ++typedef struct test_entry { ++ test_function_t f; ++ const char *name; ++} test_entry; ++ ++#define entry(x) {x, #x} ++ ++static int run_tests(UnitFileScope scope, const test_entry tests[], char **patterns) { ++ const test_entry *test = NULL; + _cleanup_(manager_freep) Manager *m = NULL; + int r; + +@@ -674,55 +681,60 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) { + assert_se(r >= 0); + assert_se(manager_startup(m, NULL, NULL) >= 0); + +- for (test = tests; test && *test; test++) +- (*test)(m); ++ for (test = tests; test && test->f; test++) ++ if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE)) ++ test->f(m); ++ else ++ log_info("Skipping %s because it does not match any pattern.", test->name); + + return 0; + } + ++ + int main(int argc, char *argv[]) { + _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; +- static const test_function_t user_tests[] = { +- test_exec_basic, +- test_exec_ambientcapabilities, +- test_exec_bindpaths, +- test_exec_capabilityboundingset, +- test_exec_cpuaffinity, +- test_exec_environment, +- test_exec_environmentfile, +- test_exec_group, +- test_exec_ignoresigpipe, +- test_exec_inaccessiblepaths, +- test_exec_ioschedulingclass, +- test_exec_oomscoreadjust, +- test_exec_passenvironment, +- test_exec_personality, +- test_exec_privatedevices, +- test_exec_privatenetwork, +- test_exec_privatetmp, +- test_exec_protectkernelmodules, +- test_exec_readonlypaths, +- test_exec_readwritepaths, +- test_exec_restrictnamespaces, +- test_exec_runtimedirectory, +- test_exec_standardinput, +- test_exec_standardoutput, +- test_exec_standardoutput_append, +- test_exec_supplementarygroups, +- test_exec_systemcallerrornumber, +- test_exec_systemcallfilter, +- test_exec_temporaryfilesystem, +- test_exec_umask, +- test_exec_unsetenvironment, +- test_exec_user, +- test_exec_workingdirectory, +- NULL, ++ _cleanup_free_ char *test_execute_path = NULL; ++ static const test_entry user_tests[] = { ++ entry(test_exec_basic), ++ entry(test_exec_ambientcapabilities), ++ entry(test_exec_bindpaths), ++ entry(test_exec_capabilityboundingset), ++ entry(test_exec_cpuaffinity), ++ entry(test_exec_environment), ++ entry(test_exec_environmentfile), ++ entry(test_exec_group), ++ entry(test_exec_ignoresigpipe), ++ entry(test_exec_inaccessiblepaths), ++ entry(test_exec_ioschedulingclass), ++ entry(test_exec_oomscoreadjust), ++ entry(test_exec_passenvironment), ++ entry(test_exec_personality), ++ entry(test_exec_privatedevices), ++ entry(test_exec_privatenetwork), ++ entry(test_exec_privatetmp), ++ entry(test_exec_protectkernelmodules), ++ entry(test_exec_readonlypaths), ++ entry(test_exec_readwritepaths), ++ entry(test_exec_restrictnamespaces), ++ entry(test_exec_runtimedirectory), ++ entry(test_exec_standardinput), ++ entry(test_exec_standardoutput), ++ entry(test_exec_standardoutput_append), ++ entry(test_exec_supplementarygroups), ++ entry(test_exec_systemcallerrornumber), ++ entry(test_exec_systemcallfilter), ++ entry(test_exec_temporaryfilesystem), ++ entry(test_exec_umask), ++ entry(test_exec_unsetenvironment), ++ entry(test_exec_user), ++ entry(test_exec_workingdirectory), ++ {}, + }; +- static const test_function_t system_tests[] = { +- test_exec_dynamicuser, +- test_exec_specifier, +- test_exec_systemcallfilter_system, +- NULL, ++ static const test_entry system_tests[] = { ++ entry(test_exec_dynamicuser), ++ entry(test_exec_specifier), ++ entry(test_exec_systemcallfilter_system), ++ {}, + }; + int r; + +@@ -759,9 +771,9 @@ int main(int argc, char *argv[]) { + assert_se(unsetenv("VAR2") == 0); + assert_se(unsetenv("VAR3") == 0); + +- r = run_tests(UNIT_FILE_USER, user_tests); ++ r = run_tests(UNIT_FILE_USER, user_tests, argv + 1); + if (r != 0) + return r; + +- return run_tests(UNIT_FILE_SYSTEM, system_tests); ++ return run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1); + } diff --git a/SOURCES/0383-test-execute-provide-custom-failure-message.patch b/SOURCES/0383-test-execute-provide-custom-failure-message.patch new file mode 100644 index 0000000..3299943 --- /dev/null +++ b/SOURCES/0383-test-execute-provide-custom-failure-message.patch @@ -0,0 +1,568 @@ +From ad8f0b480799aa7e312dacbcb0c01a3a9e6aa6db Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 26 Mar 2019 11:38:55 +0100 +Subject: [PATCH] test-execute: provide custom failure message + +test_exec_ambientcapabilities: exec-ambientcapabilities-nobody.service: exit status 0, expected 1 + +Sometimes we get just the last line, for example from the failure summary, +so make it as useful as possible. + +(cherry picked from commit 6aed6a11577b108b9a39f26aeae5e45d98f20c90) + +Related: #1737283 +--- + src/test/test-execute.c | 236 +++++++++++++++++++++------------------- + 1 file changed, 123 insertions(+), 113 deletions(-) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index d077674efc..e42d0d30a8 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -30,7 +30,7 @@ + + typedef void (*test_function_t)(Manager *m); + +-static void check(Manager *m, Unit *unit, int status_expected, int code_expected) { ++static void check(const char *func, Manager *m, Unit *unit, int status_expected, int code_expected) { + Service *service = NULL; + usec_t ts; + usec_t timeout = 2 * USEC_PER_MINUTE; +@@ -56,8 +56,18 @@ static void check(Manager *m, Unit *unit, int status_expected, int code_expected + } + } + exec_status_dump(&service->main_exec_status, stdout, "\t"); +- assert_se(service->main_exec_status.status == status_expected); +- assert_se(service->main_exec_status.code == code_expected); ++ if (service->main_exec_status.status != status_expected) { ++ log_error("%s: %s: exit status %d, expected %d", ++ func, unit->id, ++ service->main_exec_status.status, status_expected); ++ abort(); ++ } ++ if (service->main_exec_status.code != code_expected) { ++ log_error("%s: %s: exit code %d, expected %d", ++ func, unit->id, ++ service->main_exec_status.code, code_expected); ++ abort(); ++ } + } + + static bool check_nobody_user_and_group(void) { +@@ -123,21 +133,21 @@ static bool is_inaccessible_available(void) { + return true; + } + +-static void test(Manager *m, const char *unit_name, int status_expected, int code_expected) { ++static void test(const char *func, Manager *m, const char *unit_name, int status_expected, int code_expected) { + Unit *unit; + + assert_se(unit_name); + + assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0); + assert_se(unit_start(unit) >= 0); +- check(m, unit, status_expected, code_expected); ++ check(func, m, unit, status_expected, code_expected); + } + + static void test_exec_bindpaths(Manager *m) { + assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0); + assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0); + +- test(m, "exec-bindpaths.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-bindpaths.service", 0, CLD_EXITED); + + (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL); + (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL); +@@ -154,8 +164,8 @@ static void test_exec_cpuaffinity(Manager *m) { + return; + } + +- test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED); +- test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-cpuaffinity1.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-cpuaffinity2.service", 0, CLD_EXITED); + + if (!CPU_ISSET_S(1, c.allocated, c.set) || + !CPU_ISSET_S(2, c.allocated, c.set)) { +@@ -163,52 +173,52 @@ static void test_exec_cpuaffinity(Manager *m) { + return; + } + +- test(m, "exec-cpuaffinity3.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-cpuaffinity3.service", 0, CLD_EXITED); + } + + static void test_exec_workingdirectory(Manager *m) { + assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0); + +- test(m, "exec-workingdirectory.service", 0, CLD_EXITED); +- test(m, "exec-workingdirectory-trailing-dot.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-workingdirectory.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-workingdirectory-trailing-dot.service", 0, CLD_EXITED); + + (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT|REMOVE_PHYSICAL); + } + + static void test_exec_personality(Manager *m) { + #if defined(__x86_64__) +- test(m, "exec-personality-x86-64.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-x86-64.service", 0, CLD_EXITED); + + #elif defined(__s390__) +- test(m, "exec-personality-s390.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-s390.service", 0, CLD_EXITED); + + #elif defined(__powerpc64__) + # if __BYTE_ORDER == __BIG_ENDIAN +- test(m, "exec-personality-ppc64.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-ppc64.service", 0, CLD_EXITED); + # else +- test(m, "exec-personality-ppc64le.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-ppc64le.service", 0, CLD_EXITED); + # endif + + #elif defined(__aarch64__) +- test(m, "exec-personality-aarch64.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-aarch64.service", 0, CLD_EXITED); + + #elif defined(__i386__) +- test(m, "exec-personality-x86.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-personality-x86.service", 0, CLD_EXITED); + #else + log_notice("Unknown personality, skipping %s", __func__); + #endif + } + + static void test_exec_ignoresigpipe(Manager *m) { +- test(m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED); +- test(m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED); ++ test(__func__, m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED); + } + + static void test_exec_privatetmp(Manager *m) { + assert_se(touch("/tmp/test-exec_privatetmp") >= 0); + +- test(m, "exec-privatetmp-yes.service", 0, CLD_EXITED); +- test(m, "exec-privatetmp-no.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatetmp-yes.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatetmp-no.service", 0, CLD_EXITED); + + unlink("/tmp/test-exec_privatetmp"); + } +@@ -225,9 +235,9 @@ static void test_exec_privatedevices(Manager *m) { + return; + } + +- test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED); +- test(m, "exec-privatedevices-no.service", 0, CLD_EXITED); +- test(m, "exec-privatedevices-disabled-by-prefix.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-yes.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-no.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-disabled-by-prefix.service", 0, CLD_EXITED); + + /* We use capsh to test if the capabilities are + * properly set, so be sure that it exists */ +@@ -237,10 +247,10 @@ static void test_exec_privatedevices(Manager *m) { + return; + } + +- test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED); +- test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED); +- test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED); +- test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED); + } + + static void test_exec_protectkernelmodules(Manager *m) { +@@ -261,23 +271,23 @@ static void test_exec_protectkernelmodules(Manager *m) { + return; + } + +- test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED); +- test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED); +- test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED); + } + + static void test_exec_readonlypaths(Manager *m) { + +- test(m, "exec-readonlypaths-simple.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-readonlypaths-simple.service", 0, CLD_EXITED); + + if (path_is_read_only_fs("/var") > 0) { + log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__); + return; + } + +- test(m, "exec-readonlypaths.service", 0, CLD_EXITED); +- test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED); +- test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-readonlypaths.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED); + } + + static void test_exec_readwritepaths(Manager *m) { +@@ -287,7 +297,7 @@ static void test_exec_readwritepaths(Manager *m) { + return; + } + +- test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED); + } + + static void test_exec_inaccessiblepaths(Manager *m) { +@@ -297,22 +307,22 @@ static void test_exec_inaccessiblepaths(Manager *m) { + return; + } + +- test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED); + + if (path_is_read_only_fs("/") > 0) { + log_notice("Root directory is readonly, skipping remaining tests in %s", __func__); + return; + } + +- test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED); + } + + static void test_exec_temporaryfilesystem(Manager *m) { + +- test(m, "exec-temporaryfilesystem-options.service", 0, CLD_EXITED); +- test(m, "exec-temporaryfilesystem-ro.service", 0, CLD_EXITED); +- test(m, "exec-temporaryfilesystem-rw.service", 0, CLD_EXITED); +- test(m, "exec-temporaryfilesystem-usr.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-temporaryfilesystem-options.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-temporaryfilesystem-ro.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-temporaryfilesystem-rw.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-temporaryfilesystem-usr.service", 0, CLD_EXITED); + } + + static void test_exec_systemcallfilter(Manager *m) { +@@ -324,10 +334,10 @@ static void test_exec_systemcallfilter(Manager *m) { + return; + } + +- test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED); +- test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED); +- test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED); +- test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED); ++ test(__func__, m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED); ++ test(__func__, m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED); + + r = find_binary("python3", NULL); + if (r < 0) { +@@ -335,8 +345,8 @@ static void test_exec_systemcallfilter(Manager *m) { + return; + } + +- test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED); +- test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED); + #endif + } + +@@ -355,8 +365,8 @@ static void test_exec_systemcallerrornumber(Manager *m) { + return; + } + +- test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED); +- test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED); ++ test(__func__, m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED); ++ test(__func__, m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED); + #endif + } + +@@ -367,13 +377,13 @@ static void test_exec_restrictnamespaces(Manager *m) { + return; + } + +- test(m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED); +- test(m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED); +- test(m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED); +- test(m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED); +- test(m, "exec-restrictnamespaces-merge-and.service", 0, CLD_EXITED); +- test(m, "exec-restrictnamespaces-merge-or.service", 0, CLD_EXITED); +- test(m, "exec-restrictnamespaces-merge-all.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-merge-and.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-merge-or.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-restrictnamespaces-merge-all.service", 0, CLD_EXITED); + #endif + } + +@@ -384,7 +394,7 @@ static void test_exec_systemcallfilter_system(Manager *m) { + return; + } + +- test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED); + + if (!check_nobody_user_and_group()) { + log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__); +@@ -396,12 +406,12 @@ static void test_exec_systemcallfilter_system(Manager *m) { + return; + } + +- test(m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); + #endif + } + + static void test_exec_user(Manager *m) { +- test(m, "exec-user.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-user.service", 0, CLD_EXITED); + + if (!check_nobody_user_and_group()) { + log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__); +@@ -413,11 +423,11 @@ static void test_exec_user(Manager *m) { + return; + } + +- test(m, "exec-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); + } + + static void test_exec_group(Manager *m) { +- test(m, "exec-group.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-group.service", 0, CLD_EXITED); + + if (!check_nobody_user_and_group()) { + log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__); +@@ -429,31 +439,31 @@ static void test_exec_group(Manager *m) { + return; + } + +- test(m, "exec-group-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-group-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED); + } + + static void test_exec_supplementarygroups(Manager *m) { +- test(m, "exec-supplementarygroups.service", 0, CLD_EXITED); +- test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED); +- test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED); +- test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED); +- test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED); +- test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED); + } + + static void test_exec_dynamicuser(Manager *m) { +- test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED); +- test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED); +- test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED); +- test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED); + + (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL); + (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL); + (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL); + (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL); + +- test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED); +- test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED); + + (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL); + (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL); +@@ -462,9 +472,9 @@ static void test_exec_dynamicuser(Manager *m) { + } + + static void test_exec_environment(Manager *m) { +- test(m, "exec-environment.service", 0, CLD_EXITED); +- test(m, "exec-environment-multiple.service", 0, CLD_EXITED); +- test(m, "exec-environment-empty.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-environment.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-environment-multiple.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-environment-empty.service", 0, CLD_EXITED); + } + + static void test_exec_environmentfile(Manager *m) { +@@ -484,7 +494,7 @@ static void test_exec_environmentfile(Manager *m) { + r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE); + assert_se(r == 0); + +- test(m, "exec-environmentfile.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-environmentfile.service", 0, CLD_EXITED); + + (void) unlink("/tmp/test-exec_environmentfile.conf"); + } +@@ -506,26 +516,26 @@ static void test_exec_passenvironment(Manager *m) { + assert_se(setenv("VAR3", "$word 5 6", 1) == 0); + assert_se(setenv("VAR4", "new\nline", 1) == 0); + assert_se(setenv("VAR5", "passwordwithbackslashes", 1) == 0); +- test(m, "exec-passenvironment.service", 0, CLD_EXITED); +- test(m, "exec-passenvironment-repeated.service", 0, CLD_EXITED); +- test(m, "exec-passenvironment-empty.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-passenvironment.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-passenvironment-repeated.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-passenvironment-empty.service", 0, CLD_EXITED); + assert_se(unsetenv("VAR1") == 0); + assert_se(unsetenv("VAR2") == 0); + assert_se(unsetenv("VAR3") == 0); + assert_se(unsetenv("VAR4") == 0); + assert_se(unsetenv("VAR5") == 0); +- test(m, "exec-passenvironment-absent.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-passenvironment-absent.service", 0, CLD_EXITED); + } + + static void test_exec_umask(Manager *m) { +- test(m, "exec-umask-default.service", 0, CLD_EXITED); +- test(m, "exec-umask-0177.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-umask-default.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-umask-0177.service", 0, CLD_EXITED); + } + + static void test_exec_runtimedirectory(Manager *m) { +- test(m, "exec-runtimedirectory.service", 0, CLD_EXITED); +- test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED); +- test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-runtimedirectory.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED); + + if (!check_nobody_user_and_group()) { + log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__); +@@ -537,7 +547,7 @@ static void test_exec_runtimedirectory(Manager *m) { + return; + } + +- test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED); + } + + static void test_exec_capabilityboundingset(Manager *m) { +@@ -556,14 +566,14 @@ static void test_exec_capabilityboundingset(Manager *m) { + return; + } + +- test(m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED); +- test(m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED); +- test(m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED); +- test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED); + } + + static void test_exec_basic(Manager *m) { +- test(m, "exec-basic.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-basic.service", 0, CLD_EXITED); + } + + static void test_exec_ambientcapabilities(Manager *m) { +@@ -585,8 +595,8 @@ static void test_exec_ambientcapabilities(Manager *m) { + return; + } + +- test(m, "exec-ambientcapabilities.service", 0, CLD_EXITED); +- test(m, "exec-ambientcapabilities-merge.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ambientcapabilities.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ambientcapabilities-merge.service", 0, CLD_EXITED); + + if (!check_nobody_user_and_group()) { + log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__); +@@ -598,8 +608,8 @@ static void test_exec_ambientcapabilities(Manager *m) { + return; + } + +- test(m, "exec-ambientcapabilities-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); +- test(m, "exec-ambientcapabilities-merge-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ambientcapabilities-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ambientcapabilities-merge-" NOBODY_USER_NAME ".service", 0, CLD_EXITED); + } + + static void test_exec_privatenetwork(Manager *m) { +@@ -611,52 +621,52 @@ static void test_exec_privatenetwork(Manager *m) { + return; + } + +- test(m, "exec-privatenetwork-yes.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-privatenetwork-yes.service", 0, CLD_EXITED); + } + + static void test_exec_oomscoreadjust(Manager *m) { +- test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED); + + if (detect_container() > 0) { + log_notice("Testing in container, skipping remaining tests in %s", __func__); + return; + } +- test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED); + } + + static void test_exec_ioschedulingclass(Manager *m) { +- test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED); +- test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED); +- test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED); + + if (detect_container() > 0) { + log_notice("Testing in container, skipping remaining tests in %s", __func__); + return; + } +- test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED); + } + + static void test_exec_unsetenvironment(Manager *m) { +- test(m, "exec-unsetenvironment.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-unsetenvironment.service", 0, CLD_EXITED); + } + + static void test_exec_specifier(Manager *m) { +- test(m, "exec-specifier.service", 0, CLD_EXITED); +- test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED); +- test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-specifier.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-specifier@foo-bar.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-specifier-interpolation.service", 0, CLD_EXITED); + } + + static void test_exec_standardinput(Manager *m) { +- test(m, "exec-standardinput-data.service", 0, CLD_EXITED); +- test(m, "exec-standardinput-file.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-standardinput-data.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-standardinput-file.service", 0, CLD_EXITED); + } + + static void test_exec_standardoutput(Manager *m) { +- test(m, "exec-standardoutput-file.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-standardoutput-file.service", 0, CLD_EXITED); + } + + static void test_exec_standardoutput_append(Manager *m) { +- test(m, "exec-standardoutput-append.service", 0, CLD_EXITED); ++ test(__func__, m, "exec-standardoutput-append.service", 0, CLD_EXITED); + } + + typedef struct test_entry { diff --git a/SOURCES/0384-core-ExecCondition-for-services.patch b/SOURCES/0384-core-ExecCondition-for-services.patch new file mode 100644 index 0000000..1d1e10f --- /dev/null +++ b/SOURCES/0384-core-ExecCondition-for-services.patch @@ -0,0 +1,738 @@ +From ab9c835796a27f0fbaee75a90f0311ec456941d8 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Fri, 28 Jun 2019 17:02:30 -0700 +Subject: [PATCH] core: ExecCondition= for services + +Closes #10596 + +(cherry picked from commit 31cd5f63ce86a0784c4ef869c4d323a11ff14adc) + +Resolves: #1737283 +--- + TODO | 2 - + catalog/systemd.catalog.in | 7 ++ + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.service.xml | 20 ++++ + src/basic/unit-def.c | 1 + + src/basic/unit-def.h | 1 + + src/core/dbus-service.c | 1 + + src/core/job.c | 3 +- + src/core/job.h | 2 +- + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/service.c | 93 ++++++++++++++++--- + src/core/service.h | 2 + + src/core/unit.c | 25 ++++- + src/core/unit.h | 4 + + src/shared/bus-unit-util.c | 2 +- + src/systemd/sd-messages.h | 2 + + src/test/test-execute.c | 50 +++++++++- + test/fuzz/fuzz-unit-file/directives.service | 1 + + test/meson.build | 2 + + .../exec-condition-failed.service | 11 +++ + test/test-execute/exec-condition-skip.service | 15 +++ + 21 files changed, 222 insertions(+), 24 deletions(-) + create mode 100644 test/test-execute/exec-condition-failed.service + create mode 100644 test/test-execute/exec-condition-skip.service + +diff --git a/TODO b/TODO +index ff1008accf..8f78000089 100644 +--- a/TODO ++++ b/TODO +@@ -626,8 +626,6 @@ Features: + + * merge unit_kill_common() and unit_kill_context() + +-* introduce ExecCondition= in services +- + * EFI: + - honor language efi variables for default language selection (if there are any?) + - honor timezone efi variables for default timezone selection (if there are any?) +diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in +index 2492ad2028..dc44414f9d 100644 +--- a/catalog/systemd.catalog.in ++++ b/catalog/systemd.catalog.in +@@ -358,6 +358,13 @@ Support: %SUPPORT_URL% + + The unit @UNIT@ has entered the 'failed' state with result '@UNIT_RESULT@'. + ++-- 0e4284a0caca4bfc81c0bb6786972673 ++Subject: Unit skipped ++Defined-By: systemd ++Support: %SUPPORT_URL% ++ ++The unit @UNIT@ was skipped and has entered the 'dead' state with result '@UNIT_RESULT@'. ++ + -- 50876a9db00f4c40bde1a2ad381c3a1b + Subject: The system is configured in a way that might cause problems + Defined-By: systemd +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 0b2ad66dcb..23fe84e4d1 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -267,6 +267,7 @@ Most service unit settings are available for transient units. + + ``` + ✓ PIDFile= ++✓ ExecCondition= + ✓ ExecStartPre= + ✓ ExecStart= + ✓ ExecStartPost= +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 315b80e704..54586d1948 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -414,6 +414,26 @@ + + + ++ ++ ExecCondition= ++ Optional commands that are executed before the command(s) in ExecStartPre=. ++ Syntax is the same as for ExecStart=, except that multiple command lines are allowed and the ++ commands are executed one after the other, serially. ++ ++ The behavior is like an ExecStartPre= and condition check hybrid: when an ++ ExecCondition= command exits with exit code 1 through 254 (inclusive), the remaining ++ commands are skipped and the unit is not marked as failed. However, if an ++ ExecCondition= command exits with 255 or abnormally (e.g. timeout, killed by a ++ signal, etc.), the unit will be considered failed (and remaining commands will be skipped). Exit code of 0 or ++ those matching SuccessExitStatus= will continue execution to the next command(s). ++ ++ The same recommendations about not running long-running processes in ExecStartPre= ++ also applies to ExecCondition=. ExecCondition= will also run the commands ++ in ExecStopPost=, as part of stopping the service, in the case of any non-zero or abnormal ++ exits, like the ones described above. ++ ++ ++ + + ExecReload= + Commands to execute to trigger a configuration +diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c +index ac6a9b37e8..46593f6e65 100644 +--- a/src/basic/unit-def.c ++++ b/src/basic/unit-def.c +@@ -162,6 +162,7 @@ DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState); + + static const char* const service_state_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = "dead", ++ [SERVICE_CONDITION] = "condition", + [SERVICE_START_PRE] = "start-pre", + [SERVICE_START] = "start", + [SERVICE_START_POST] = "start-post", +diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h +index d7e2d74669..db397a31ed 100644 +--- a/src/basic/unit-def.h ++++ b/src/basic/unit-def.h +@@ -101,6 +101,7 @@ typedef enum ScopeState { + + typedef enum ServiceState { + SERVICE_DEAD, ++ SERVICE_CONDITION, + SERVICE_START_PRE, + SERVICE_START, + SERVICE_START_POST, +diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c +index 1b4c98c7d2..5f768a77c8 100644 +--- a/src/core/dbus-service.c ++++ b/src/core/dbus-service.c +@@ -127,6 +127,7 @@ const sd_bus_vtable bus_service_vtable[] = { + SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned, offsetof(Service, n_restarts), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), ++ BUS_EXEC_COMMAND_LIST_VTABLE("ExecCondition", offsetof(Service, exec_command[SERVICE_EXEC_CONDITION]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), + BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), + BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), + BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), +diff --git a/src/core/job.c b/src/core/job.c +index b9eee91cf3..870ec0a387 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -870,7 +870,8 @@ static void job_log_done_status_message(Unit *u, uint32_t job_id, JobType t, Job + return; + + /* Show condition check message if the job did not actually do anything due to failed condition. */ +- if (t == JOB_START && result == JOB_DONE && !u->condition_result) { ++ if ((t == JOB_START && result == JOB_DONE && !u->condition_result) || ++ (t == JOB_START && result == JOB_SKIPPED)) { + log_struct(LOG_INFO, + "MESSAGE=Condition check resulted in %s being skipped.", unit_description(u), + "JOB_ID=%" PRIu32, job_id, +diff --git a/src/core/job.h b/src/core/job.h +index 2f5f3f3989..189fea20ca 100644 +--- a/src/core/job.h ++++ b/src/core/job.h +@@ -85,7 +85,7 @@ enum JobResult { + JOB_TIMEOUT, /* Job timeout elapsed */ + JOB_FAILED, /* Job failed */ + JOB_DEPENDENCY, /* A required dependency job did not result in JOB_DONE */ +- JOB_SKIPPED, /* Negative result of JOB_VERIFY_ACTIVE */ ++ JOB_SKIPPED, /* Negative result of JOB_VERIFY_ACTIVE or skip due to ExecCondition= */ + JOB_INVALID, /* JOB_RELOAD of inactive unit */ + JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */ + JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */ +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 161c5a2c82..8883818ff2 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -291,6 +291,7 @@ Unit.AssertNull, config_parse_unit_condition_null, 0, + Unit.CollectMode, config_parse_collect_mode, 0, offsetof(Unit, collect_mode) + m4_dnl + Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) ++Service.ExecCondition, config_parse_exec, SERVICE_EXEC_CONDITION, offsetof(Service, exec_command) + Service.ExecStartPre, config_parse_exec, SERVICE_EXEC_START_PRE, offsetof(Service, exec_command) + Service.ExecStart, config_parse_exec, SERVICE_EXEC_START, offsetof(Service, exec_command) + Service.ExecStartPost, config_parse_exec, SERVICE_EXEC_START_POST, offsetof(Service, exec_command) +diff --git a/src/core/service.c b/src/core/service.c +index 2c31e70ef6..92be4280f6 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -41,6 +41,7 @@ + + static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = UNIT_INACTIVE, ++ [SERVICE_CONDITION] = UNIT_ACTIVATING, + [SERVICE_START_PRE] = UNIT_ACTIVATING, + [SERVICE_START] = UNIT_ACTIVATING, + [SERVICE_START_POST] = UNIT_ACTIVATING, +@@ -62,6 +63,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { + * consider idle jobs active as soon as we start working on them */ + static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = UNIT_INACTIVE, ++ [SERVICE_CONDITION] = UNIT_ACTIVE, + [SERVICE_START_PRE] = UNIT_ACTIVE, + [SERVICE_START] = UNIT_ACTIVE, + [SERVICE_START_POST] = UNIT_ACTIVE, +@@ -1024,7 +1026,7 @@ static void service_set_state(Service *s, ServiceState state) { + service_unwatch_pid_file(s); + + if (!IN_SET(state, +- SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, ++ SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, + SERVICE_RUNNING, + SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, +@@ -1042,7 +1044,7 @@ static void service_set_state(Service *s, ServiceState state) { + } + + if (!IN_SET(state, +- SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, ++ SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, + SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { +@@ -1057,7 +1059,7 @@ static void service_set_state(Service *s, ServiceState state) { + } + + if (!IN_SET(state, +- SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, ++ SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, + SERVICE_RUNNING, SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) && +@@ -1080,7 +1082,8 @@ static void service_set_state(Service *s, ServiceState state) { + + unit_notify(UNIT(s), table[old_state], table[state], + (s->reload_result == SERVICE_SUCCESS ? 0 : UNIT_NOTIFY_RELOAD_FAILURE) | +- (s->will_auto_restart ? UNIT_NOTIFY_WILL_AUTO_RESTART : 0)); ++ (s->will_auto_restart ? UNIT_NOTIFY_WILL_AUTO_RESTART : 0) | ++ (s->result == SERVICE_SKIP_CONDITION ? UNIT_NOTIFY_SKIP_CONDITION : 0)); + } + + static usec_t service_coldplug_timeout(Service *s) { +@@ -1088,6 +1091,7 @@ static usec_t service_coldplug_timeout(Service *s) { + + switch (s->deserialized_state) { + ++ case SERVICE_CONDITION: + case SERVICE_START_PRE: + case SERVICE_START: + case SERVICE_START_POST: +@@ -1143,7 +1147,7 @@ static int service_coldplug(Unit *u) { + if (s->control_pid > 0 && + pid_is_unwaited(s->control_pid) && + IN_SET(s->deserialized_state, +- SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, ++ SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, + SERVICE_RELOAD, + SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { +@@ -1667,6 +1671,7 @@ static bool service_will_restart(Unit *u) { + } + + static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) { ++ ServiceState end_state; + int r; + + assert(s); +@@ -1679,10 +1684,16 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) + if (s->result == SERVICE_SUCCESS) + s->result = f; + +- if (s->result == SERVICE_SUCCESS) ++ if (s->result == SERVICE_SUCCESS) { + unit_log_success(UNIT(s)); +- else ++ end_state = SERVICE_DEAD; ++ } else if (s->result == SERVICE_SKIP_CONDITION) { ++ unit_log_skip(UNIT(s), service_result_to_string(s->result)); ++ end_state = SERVICE_DEAD; ++ } else { + unit_log_failure(UNIT(s), service_result_to_string(s->result)); ++ end_state = SERVICE_FAILED; ++ } + + if (allow_restart && service_shall_restart(s)) + s->will_auto_restart = true; +@@ -1691,7 +1702,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) + * SERVICE_FAILED/SERVICE_DEAD before entering into SERVICE_AUTO_RESTART. */ + s->n_keep_fd_store ++; + +- service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD); ++ service_set_state(s, end_state); + + if (s->will_auto_restart) { + s->will_auto_restart = false; +@@ -2110,6 +2121,40 @@ fail: + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); + } + ++static void service_enter_condition(Service *s) { ++ int r; ++ ++ assert(s); ++ ++ service_unwatch_control_pid(s); ++ ++ s->control_command = s->exec_command[SERVICE_EXEC_CONDITION]; ++ if (s->control_command) { ++ ++ unit_warn_leftover_processes(UNIT(s)); ++ ++ s->control_command_id = SERVICE_EXEC_CONDITION; ++ ++ r = service_spawn(s, ++ s->control_command, ++ s->timeout_start_usec, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_APPLY_TTY_STDIN, ++ &s->control_pid); ++ ++ if (r < 0) ++ goto fail; ++ ++ service_set_state(s, SERVICE_CONDITION); ++ } else ++ service_enter_start_pre(s); ++ ++ return; ++ ++fail: ++ log_unit_warning_errno(UNIT(s), r, "Failed to run 'exec-condition' task: %m"); ++ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); ++} ++ + static void service_enter_restart(Service *s) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; +@@ -2222,7 +2267,7 @@ static void service_run_next_control(Service *s) { + s->control_command = s->control_command->command_next; + service_unwatch_control_pid(s); + +- if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) ++ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) + timeout = s->timeout_start_usec; + else + timeout = s->timeout_stop_usec; +@@ -2231,7 +2276,7 @@ static void service_run_next_control(Service *s) { + s->control_command, + timeout, + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL| +- (IN_SET(s->control_command_id, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)| ++ (IN_SET(s->control_command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)| + (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0), + &s->control_pid); + if (r < 0) +@@ -2242,7 +2287,7 @@ static void service_run_next_control(Service *s) { + fail: + log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m"); + +- if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP)) ++ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP)) + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); + else if (s->state == SERVICE_STOP_POST) + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); +@@ -2296,7 +2341,7 @@ static int service_start(Unit *u) { + return -EAGAIN; + + /* Already on it! */ +- if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST)) ++ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST)) + return 0; + + /* A service that will be restarted must be stopped first to +@@ -2344,7 +2389,9 @@ static int service_start(Unit *u) { + s->flush_n_restarts = false; + } + +- service_enter_start_pre(s); ++ u->reset_accounting = true; ++ ++ service_enter_condition(s); + return 1; + } + +@@ -2370,7 +2417,7 @@ static int service_stop(Unit *u) { + + /* If there's already something running we go directly into + * kill mode. */ +- if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD)) { ++ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD)) { + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS); + return 0; + } +@@ -3303,6 +3350,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + } else if (s->control_pid == pid) { + s->control_pid = 0; + ++ /* ExecCondition= calls that exit with (0, 254] should invoke skip-like behavior instead of failing */ ++ if (f == SERVICE_FAILURE_EXIT_CODE && s->state == SERVICE_CONDITION && status < 255) ++ f = SERVICE_SKIP_CONDITION; ++ + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + +@@ -3338,6 +3389,13 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + + switch (s->state) { + ++ case SERVICE_CONDITION: ++ if (f == SERVICE_SUCCESS) ++ service_enter_start_pre(s); ++ else ++ service_enter_signal(s, SERVICE_STOP_SIGTERM, f); ++ break; ++ + case SERVICE_START_PRE: + if (f == SERVICE_SUCCESS) + service_enter_start(s); +@@ -3462,9 +3520,10 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us + + switch (s->state) { + ++ case SERVICE_CONDITION: + case SERVICE_START_PRE: + case SERVICE_START: +- log_unit_warning(UNIT(s), "%s operation timed out. Terminating.", s->state == SERVICE_START ? "Start" : "Start-pre"); ++ log_unit_warning(UNIT(s), "%s operation timed out. Terminating.", service_state_to_string(s->state)); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + +@@ -3975,6 +4034,7 @@ static bool service_needs_console(Unit *u) { + return false; + + return IN_SET(s->state, ++ SERVICE_CONDITION, + SERVICE_START_PRE, + SERVICE_START, + SERVICE_START_POST, +@@ -4014,6 +4074,7 @@ static const char* const service_type_table[_SERVICE_TYPE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType); + + static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = { ++ [SERVICE_EXEC_CONDITION] = "ExecCondition", + [SERVICE_EXEC_START_PRE] = "ExecStartPre", + [SERVICE_EXEC_START] = "ExecStart", + [SERVICE_EXEC_START_POST] = "ExecStartPost", +@@ -4043,6 +4104,7 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = { + [SERVICE_FAILURE_CORE_DUMP] = "core-dump", + [SERVICE_FAILURE_WATCHDOG] = "watchdog", + [SERVICE_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [SERVICE_SKIP_CONDITION] = "exec-condition", + }; + + DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult); +@@ -4118,6 +4180,7 @@ const UnitVTable service_vtable = { + .finished_start_job = { + [JOB_DONE] = "Started %s.", + [JOB_FAILED] = "Failed to start %s.", ++ [JOB_SKIPPED] = "Skipped %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Stopped %s.", +diff --git a/src/core/service.h b/src/core/service.h +index 1206e3cdda..62b78cadf1 100644 +--- a/src/core/service.h ++++ b/src/core/service.h +@@ -36,6 +36,7 @@ typedef enum ServiceType { + } ServiceType; + + typedef enum ServiceExecCommand { ++ SERVICE_EXEC_CONDITION, + SERVICE_EXEC_START_PRE, + SERVICE_EXEC_START, + SERVICE_EXEC_START_POST, +@@ -67,6 +68,7 @@ typedef enum ServiceResult { + SERVICE_FAILURE_CORE_DUMP, + SERVICE_FAILURE_WATCHDOG, + SERVICE_FAILURE_START_LIMIT_HIT, ++ SERVICE_SKIP_CONDITION, + _SERVICE_RESULT_MAX, + _SERVICE_RESULT_INVALID = -1 + } ServiceResult; +diff --git a/src/core/unit.c b/src/core/unit.c +index ccb0106719..61799bf9e3 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2227,6 +2227,7 @@ static void unit_update_on_console(Unit *u) { + + static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) { + bool unexpected = false; ++ JobResult result; + + assert(j); + +@@ -2249,8 +2250,16 @@ static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) + else if (j->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { + unexpected = true; + +- if (UNIT_IS_INACTIVE_OR_FAILED(ns)) +- job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false); ++ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) { ++ if (ns == UNIT_FAILED) ++ result = JOB_FAILED; ++ else if (FLAGS_SET(flags, UNIT_NOTIFY_SKIP_CONDITION)) ++ result = JOB_SKIPPED; ++ else ++ result = JOB_DONE; ++ ++ job_finish_and_invalidate(j, result, true, false); ++ } + } + + break; +@@ -5484,6 +5493,18 @@ void unit_log_failure(Unit *u, const char *result) { + "UNIT_RESULT=%s", result); + } + ++void unit_log_skip(Unit *u, const char *result) { ++ assert(u); ++ assert(result); ++ ++ log_struct(LOG_INFO, ++ "MESSAGE_ID=" SD_MESSAGE_UNIT_SKIPPED_STR, ++ LOG_UNIT_ID(u), ++ LOG_UNIT_INVOCATION_ID(u), ++ LOG_UNIT_MESSAGE(u, "Skipped due to '%s'.", result), ++ "UNIT_RESULT=%s", result); ++} ++ + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index 4ae1b38624..39179f5fd4 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -658,6 +658,7 @@ int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t cont + typedef enum UnitNotifyFlags { + UNIT_NOTIFY_RELOAD_FAILURE = 1 << 0, + UNIT_NOTIFY_WILL_AUTO_RESTART = 1 << 1, ++ UNIT_NOTIFY_SKIP_CONDITION = 1 << 2, + } UnitNotifyFlags; + + void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags); +@@ -806,6 +807,9 @@ int unit_pid_attachable(Unit *unit, pid_t pid, sd_bus_error *error); + + void unit_log_success(Unit *u); + void unit_log_failure(Unit *u, const char *result); ++/* unit_log_skip is for cases like ExecCondition= where a unit is considered "done" ++ * after some execution, rather than succeeded or failed. */ ++void unit_log_skip(Unit *u, const char *result); + + /* Macros which append UNIT= or USER_UNIT= to the message */ + +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 8f3b463c6b..e0b2cfb170 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -1334,7 +1334,7 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con + return bus_append_safe_atou(m, field, eq); + + if (STR_IN_SET(field, +- "ExecStartPre", "ExecStart", "ExecStartPost", ++ "ExecCondition", "ExecStartPre", "ExecStart", "ExecStartPost", + "ExecReload", "ExecStop", "ExecStopPost")) + + return bus_append_exec_command(m, field, eq); +diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h +index e7ef81b597..bdd4fd3974 100644 +--- a/src/systemd/sd-messages.h ++++ b/src/systemd/sd-messages.h +@@ -111,6 +111,8 @@ _SD_BEGIN_DECLARATIONS; + #define SD_MESSAGE_UNIT_FAILURE_RESULT SD_ID128_MAKE(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) + #define SD_MESSAGE_UNIT_FAILURE_RESULT_STR \ + SD_ID128_MAKE_STR(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) ++#define SD_MESSAGE_UNIT_SKIPPED SD_ID128_MAKE(0e,42,84,a0,ca,ca,4b,fc,81,c0,bb,67,86,97,26,73) ++#define SD_MESSAGE_UNIT_SKIPPED_STR SD_ID128_MAKE_STR(0e,42,84,a0,ca,ca,4b,fc,81,c0,bb,67,86,97,26,73) + + #define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) + #define SD_MESSAGE_SPAWN_FAILED_STR SD_ID128_MAKE_STR(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index e42d0d30a8..882e866ea9 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -30,7 +30,7 @@ + + typedef void (*test_function_t)(Manager *m); + +-static void check(const char *func, Manager *m, Unit *unit, int status_expected, int code_expected) { ++static void wait_for_service_finish(Manager *m, Unit *unit) { + Service *service = NULL; + usec_t ts; + usec_t timeout = 2 * USEC_PER_MINUTE; +@@ -55,6 +55,17 @@ static void check(const char *func, Manager *m, Unit *unit, int status_expected, + exit(EXIT_FAILURE); + } + } ++} ++ ++static void check_main_result(const char *func, Manager *m, Unit *unit, int status_expected, int code_expected) { ++ Service *service = NULL; ++ ++ assert_se(m); ++ assert_se(unit); ++ ++ wait_for_service_finish(m, unit); ++ ++ service = SERVICE(unit); + exec_status_dump(&service->main_exec_status, stdout, "\t"); + if (service->main_exec_status.status != status_expected) { + log_error("%s: %s: exit status %d, expected %d", +@@ -70,6 +81,25 @@ static void check(const char *func, Manager *m, Unit *unit, int status_expected, + } + } + ++static void check_service_result(const char *func, Manager *m, Unit *unit, ServiceResult result_expected) { ++ Service *service = NULL; ++ ++ assert_se(m); ++ assert_se(unit); ++ ++ wait_for_service_finish(m, unit); ++ ++ service = SERVICE(unit); ++ ++ if (service->result != result_expected) { ++ log_error("%s: %s: service end result %s, expected %s", ++ func, unit->id, ++ service_result_to_string(service->result), ++ service_result_to_string(result_expected)); ++ abort(); ++ } ++} ++ + static bool check_nobody_user_and_group(void) { + static int cache = -1; + struct passwd *p; +@@ -140,7 +170,17 @@ static void test(const char *func, Manager *m, const char *unit_name, int status + + assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0); + assert_se(unit_start(unit) >= 0); +- check(func, m, unit, status_expected, code_expected); ++ check_main_result(func, m, unit, status_expected, code_expected); ++} ++ ++static void test_service(const char *func, Manager *m, const char *unit_name, ServiceResult result_expected) { ++ Unit *unit; ++ ++ assert_se(unit_name); ++ ++ assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0); ++ assert_se(unit_start(unit) >= 0); ++ check_service_result(func, m, unit, result_expected); + } + + static void test_exec_bindpaths(Manager *m) { +@@ -669,6 +709,11 @@ static void test_exec_standardoutput_append(Manager *m) { + test(__func__, m, "exec-standardoutput-append.service", 0, CLD_EXITED); + } + ++static void test_exec_condition(Manager *m) { ++ test_service(__func__, m, "exec-condition-failed.service", SERVICE_FAILURE_EXIT_CODE); ++ test_service(__func__, m, "exec-condition-skip.service", SERVICE_SKIP_CONDITION); ++} ++ + typedef struct test_entry { + test_function_t f; + const char *name; +@@ -709,6 +754,7 @@ int main(int argc, char *argv[]) { + entry(test_exec_ambientcapabilities), + entry(test_exec_bindpaths), + entry(test_exec_capabilityboundingset), ++ entry(test_exec_condition), + entry(test_exec_cpuaffinity), + entry(test_exec_environment), + entry(test_exec_environmentfile), +diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +index eab1820e20..9d0530df72 100644 +--- a/test/fuzz/fuzz-unit-file/directives.service ++++ b/test/fuzz/fuzz-unit-file/directives.service +@@ -83,6 +83,7 @@ DirectoryNotEmpty= + Documentation= + DynamicUser= + ExecReload= ++ExecCondition= + ExecStart= + ExecStartPost= + ExecStartPre= +diff --git a/test/meson.build b/test/meson.build +index 4d1c51048c..070731c4a9 100644 +--- a/test/meson.build ++++ b/test/meson.build +@@ -42,6 +42,8 @@ test_data_files = ''' + test-execute/exec-capabilityboundingset-merge.service + test-execute/exec-capabilityboundingset-reset.service + test-execute/exec-capabilityboundingset-simple.service ++ test-execute/exec-condition-failed.service ++ test-execute/exec-condition-skip.service + test-execute/exec-cpuaffinity1.service + test-execute/exec-cpuaffinity2.service + test-execute/exec-cpuaffinity3.service +diff --git a/test/test-execute/exec-condition-failed.service b/test/test-execute/exec-condition-failed.service +new file mode 100644 +index 0000000000..4a406dc17f +--- /dev/null ++++ b/test/test-execute/exec-condition-failed.service +@@ -0,0 +1,11 @@ ++[Unit] ++Description=Test for exec condition that fails the unit ++ ++[Service] ++Type=oneshot ++ ++# exit 255 will fail the unit ++ExecCondition=/bin/sh -c 'exit 255' ++ ++# This should not get run ++ExecStart=/bin/sh -c 'true' +diff --git a/test/test-execute/exec-condition-skip.service b/test/test-execute/exec-condition-skip.service +new file mode 100644 +index 0000000000..9450e8442a +--- /dev/null ++++ b/test/test-execute/exec-condition-skip.service +@@ -0,0 +1,15 @@ ++[Unit] ++Description=Test for exec condition that triggers skipping ++ ++[Service] ++Type=oneshot ++ ++# exit codes [1, 254] will result in skipping the rest of execution ++ExecCondition=/bin/sh -c 'exit 0' ++ExecCondition=/bin/sh -c 'exit 254' ++ ++# This would normally fail the unit but will not get run due to the skip above ++ExecCondition=/bin/sh -c 'exit 255' ++ ++# This should not get run ++ExecStart=/bin/sh -c 'true' diff --git a/SOURCES/0385-Drop-support-for-lz4-1.3.0.patch b/SOURCES/0385-Drop-support-for-lz4-1.3.0.patch new file mode 100644 index 0000000..0f14b3d --- /dev/null +++ b/SOURCES/0385-Drop-support-for-lz4-1.3.0.patch @@ -0,0 +1,75 @@ +From 09c96d5ef3f2b0bc4e5f1cf69e9b66248e325509 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 29 Oct 2018 18:32:51 +0100 +Subject: [PATCH] Drop support for lz4 < 1.3.0 + +lz4-r130 was released on May 29th, 2015. Let's drop the work-around for older +versions. In particular, we won't test any new code against those ancient +releases, so we shouldn't pretend they are supported. + +(cherry picked from commit e0a1d4b049e6991919a0eacd5d96f7f39dc6ddd1) +Resolves: #1843871 +--- + README | 2 +- + meson.build | 1 + + src/journal/compress.c | 4 ---- + src/journal/test-compress.c | 4 ---- + 4 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/README b/README +index 7d06e04800..859152fbde 100644 +--- a/README ++++ b/README +@@ -148,7 +148,7 @@ REQUIREMENTS: + libacl (optional) + libselinux (optional) + liblzma (optional) +- liblz4 >= 119 (optional) ++ liblz4 >= 1.3.0 / 130 (optional) + libgcrypt (optional) + libqrencode (optional) + libmicrohttpd (optional) +diff --git a/meson.build b/meson.build +index 70811c29cf..c8ae1e15bd 100644 +--- a/meson.build ++++ b/meson.build +@@ -1076,6 +1076,7 @@ conf.set10('HAVE_XZ', have) + want_lz4 = get_option('lz4') + if want_lz4 != 'false' and not fuzzer_build + liblz4 = dependency('liblz4', ++ version : '>= 1.3.0', + required : want_lz4 == 'true') + have = liblz4.found() + else +diff --git a/src/journal/compress.c b/src/journal/compress.c +index 6baf15c8ff..a4a5e63840 100644 +--- a/src/journal/compress.c ++++ b/src/journal/compress.c +@@ -95,11 +95,7 @@ int compress_blob_lz4(const void *src, uint64_t src_size, + if (src_size < 9) + return -ENOBUFS; + +-#if LZ4_VERSION_NUMBER >= 10700 + r = LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8); +-#else +- r = LZ4_compress_limitedOutput(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8); +-#endif + if (r <= 0) + return -ENOBUFS; + +diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c +index 791c6fdffb..eb3dc3eb6b 100644 +--- a/src/journal/test-compress.c ++++ b/src/journal/test-compress.c +@@ -207,11 +207,7 @@ static void test_lz4_decompress_partial(void) { + memset(huge, 'x', HUGE_SIZE); + memcpy(huge, "HUGE=", 5); + +-#if LZ4_VERSION_NUMBER >= 10700 + r = LZ4_compress_default(huge, buf, HUGE_SIZE, buf_size); +-#else +- r = LZ4_compress_limitedOutput(huge, buf, HUGE_SIZE, buf_size); +-#endif + assert_se(r >= 0); + compressed = r; + log_info("Compressed %i → %zu", HUGE_SIZE, compressed); diff --git a/SOURCES/0386-test-compress-add-test-for-short-decompress_startswi.patch b/SOURCES/0386-test-compress-add-test-for-short-decompress_startswi.patch new file mode 100644 index 0000000..2931a78 --- /dev/null +++ b/SOURCES/0386-test-compress-add-test-for-short-decompress_startswi.patch @@ -0,0 +1,72 @@ +From fc1e6209f622ff96c24259a50d98ca6f57a55426 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 29 Oct 2018 22:21:28 +0100 +Subject: [PATCH] test-compress: add test for short decompress_startswith calls + +I thought this might fail with lz4 < 1.8.3, but it seems that because of +greedy_realloc, we always use a buffer that is large enough, and it always +passes. + +(cherry picked from commit ba17efce44e6a1e139c1671205e9a6ed3824af1b) +Resolves: #1843871 +--- + src/journal/test-compress.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c +index eb3dc3eb6b..65cd3fbfeb 100644 +--- a/src/journal/test-compress.c ++++ b/src/journal/test-compress.c +@@ -131,6 +131,32 @@ static void test_decompress_startswith(int compression, + assert_se(r > 0); + } + ++static void test_decompress_startswith_short(int compression, ++ compress_blob_t compress, ++ decompress_sw_t decompress_sw) { ++ ++#define TEXT "HUGE=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ++ ++ char buf[1024]; ++ size_t i, csize; ++ int r; ++ ++ log_info("/* %s with %s */", __func__, object_compressed_to_string(compression)); ++ ++ r = compress(TEXT, sizeof TEXT, buf, sizeof buf, &csize); ++ assert_se(r == 0); ++ ++ for (i = 1; i < strlen(TEXT); i++) { ++ size_t alloc_size = i; ++ _cleanup_free_ void *buf2 = NULL; ++ ++ assert_se(buf2 = malloc(i)); ++ ++ assert_se(decompress_sw(buf, csize, &buf2, &alloc_size, TEXT, i, TEXT[i]) == 1); ++ assert_se(decompress_sw(buf, csize, &buf2, &alloc_size, TEXT, i, 'y') == 0); ++ } ++} ++ + static void test_compress_stream(int compression, + const char* cat, + compress_stream_t compress, +@@ -271,6 +297,9 @@ int main(int argc, char *argv[]) { + + test_compress_stream(OBJECT_COMPRESSED_XZ, "xzcat", + compress_stream_xz, decompress_stream_xz, srcfile); ++ ++ test_decompress_startswith_short(OBJECT_COMPRESSED_XZ, compress_blob_xz, decompress_startswith_xz); ++ + #else + log_info("/* XZ test skipped */"); + #endif +@@ -295,6 +324,9 @@ int main(int argc, char *argv[]) { + compress_stream_lz4, decompress_stream_lz4, srcfile); + + test_lz4_decompress_partial(); ++ ++ test_decompress_startswith_short(OBJECT_COMPRESSED_LZ4, compress_blob_lz4, decompress_startswith_lz4); ++ + #else + log_info("/* LZ4 test skipped */"); + #endif diff --git a/SOURCES/0387-journal-adapt-for-new-improved-LZ4_decompress_safe_p.patch b/SOURCES/0387-journal-adapt-for-new-improved-LZ4_decompress_safe_p.patch new file mode 100644 index 0000000..2b61c2c --- /dev/null +++ b/SOURCES/0387-journal-adapt-for-new-improved-LZ4_decompress_safe_p.patch @@ -0,0 +1,180 @@ +From 696d56fc75e72f47e4d3232a2140fac10b6b44de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 29 Oct 2018 14:55:33 +0100 +Subject: [PATCH] journal: adapt for new improved LZ4_decompress_safe_partial() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With lz4 1.8.3, this function can now decompress partial results into a smaller +buffer. The release news don't say anything interesting, but the test case that +was previously failing now works OK. + +Fixes #10259. + +A test is added. It shows that with *older* lz4, a partial decompression can +occur with the returned size smaller then the requested number of bytes _and_ +smaller then the size of the compressed data: + +(lz4-libs-1.8.2-1.fc29.x86_64) +Compressed 4194304 → 16464 +Decompressed → 4194304 +Decompressed partial 12/4194304 → 4194304 +Decompressed partial 1/1 → -2 (bad) +Decompressed partial 2/2 → -2 (bad) +Decompressed partial 3/3 → -2 (bad) +Decompressed partial 4/4 → -2 (bad) +Decompressed partial 5/5 → -2 (bad) +Decompressed partial 6/6 → 6 (good) +Decompressed partial 7/7 → 6 (good) +Decompressed partial 8/8 → 6 (good) +Decompressed partial 9/9 → 6 (good) +Decompressed partial 10/10 → 6 (good) +Decompressed partial 11/11 → 6 (good) +Decompressed partial 12/12 → 6 (good) +Decompressed partial 13/13 → 6 (good) +Decompressed partial 14/14 → 6 (good) +Decompressed partial 15/15 → 6 (good) +Decompressed partial 16/16 → 6 (good) +Decompressed partial 17/17 → 6 (good) +Decompressed partial 18/18 → -16459 (bad) + +(lz4-libs-1.8.3-1.fc29.x86_64) +Compressed 4194304 → 16464 +Decompressed → 4194304 +Decompressed partial 12/4194304 → 12 +Decompressed partial 1/1 → 1 (good) +Decompressed partial 2/2 → 2 (good) +Decompressed partial 3/3 → 3 (good) +Decompressed partial 4/4 → 4 (good) +... + +If we got such a short "successful" decompression in decompress_startswith() as +implemented before this patch, we could be confused and return a false negative +result. But it turns out that this only occurs with small output buffer +sizes. We use greedy_realloc() to manager the buffer, so it is always at least +64 bytes. I couldn't hit a case where decompress_startswith() would actually +return a bogus result. But since the lack of proof is not conclusive, the code +for *older* lz4 is changed too, just to be safe. We cannot rule out that on a +different architecture or with some unlucky compressed string we could hit this +corner case. + +The fallback code is guarded by a version check. The check uses a function not +the compile-time define, because there was no soversion bump in lz4 or new +symbols, and we could be compiled against a newer lz4 and linked at runtime +with an older one. (This happens routinely e.g. when somebody upgrades a subset +of distro packages.) + +(cherry picked from commit e41ef6fd0027d3619dc1cf062100b2d224d0ee7e) +Resolves: #1843871 +--- + src/journal/compress.c | 39 ++++++++++++++++++++++++------------- + src/journal/test-compress.c | 21 ++++++++++---------- + 2 files changed, 37 insertions(+), 23 deletions(-) + +diff --git a/src/journal/compress.c b/src/journal/compress.c +index a4a5e63840..e95ce2bcaa 100644 +--- a/src/journal/compress.c ++++ b/src/journal/compress.c +@@ -290,7 +290,6 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size, + * prefix */ + + int r; +- size_t size; + + assert(src); + assert(src_size > 0); +@@ -307,23 +306,37 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size, + + r = LZ4_decompress_safe_partial((char*)src + 8, *buffer, src_size - 8, + prefix_len + 1, *buffer_size); +- if (r >= 0) +- size = (unsigned) r; +- else { +- /* lz4 always tries to decode full "sequence", so in +- * pathological cases might need to decompress the +- * full field. */ ++ /* One lz4 < 1.8.3, we might get "failure" (r < 0), or "success" where ++ * just a part of the buffer is decompressed. But if we get a smaller ++ * amount of bytes than requested, we don't know whether there isn't enough ++ * data to fill the requested size or whether we just got a partial answer. ++ */ ++ if (r < 0 || (size_t) r < prefix_len + 1) { ++ size_t size; ++ ++ if (LZ4_versionNumber() >= 10803) ++ /* We trust that the newer lz4 decompresses the number of bytes we ++ * requested if available in the compressed string. */ ++ return 0; ++ ++ if (r > 0) ++ /* Compare what we have first, in case of mismatch we can ++ * shortcut the full comparison. */ ++ if (memcmp(*buffer, prefix, r) != 0) ++ return 0; ++ ++ /* Before version 1.8.3, lz4 always tries to decode full a "sequence", ++ * so in pathological cases might need to decompress the full field. */ + r = decompress_blob_lz4(src, src_size, buffer, buffer_size, &size, 0); + if (r < 0) + return r; +- } + +- if (size >= prefix_len + 1) +- return memcmp(*buffer, prefix, prefix_len) == 0 && +- ((const uint8_t*) *buffer)[prefix_len] == extra; +- else +- return 0; ++ if (size < prefix_len + 1) ++ return 0; ++ } + ++ return memcmp(*buffer, prefix, prefix_len) == 0 && ++ ((const uint8_t*) *buffer)[prefix_len] == extra; + #else + return -EPROTONOSUPPORT; + #endif +diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c +index 65cd3fbfeb..f60c4ae3d7 100644 +--- a/src/journal/test-compress.c ++++ b/src/journal/test-compress.c +@@ -223,13 +223,13 @@ static void test_compress_stream(int compression, + + #if HAVE_LZ4 + static void test_lz4_decompress_partial(void) { +- char buf[20000]; ++ char buf[20000], buf2[100]; + size_t buf_size = sizeof(buf), compressed; + int r; + _cleanup_free_ char *huge = NULL; + + #define HUGE_SIZE (4096*1024) +- huge = malloc(HUGE_SIZE); ++ assert_se(huge = malloc(HUGE_SIZE)); + memset(huge, 'x', HUGE_SIZE); + memcpy(huge, "HUGE=", 5); + +@@ -248,14 +248,15 @@ static void test_lz4_decompress_partial(void) { + assert_se(r >= 0); + log_info("Decompressed partial %i/%i → %i", 12, HUGE_SIZE, r); + +- /* We expect this to fail, because that's how current lz4 works. If this +- * call succeeds, then lz4 has been fixed, and we need to change our code. +- */ +- r = LZ4_decompress_safe_partial(buf, huge, +- compressed, +- 12, HUGE_SIZE-1); +- assert_se(r < 0); +- log_info("Decompressed partial %i/%i → %i", 12, HUGE_SIZE-1, r); ++ for (size_t size = 1; size < sizeof(buf2); size++) { ++ /* This failed in older lz4s but works in newer ones. */ ++ r = LZ4_decompress_safe_partial(buf, buf2, compressed, size, size); ++ log_info("Decompressed partial %zu/%zu → %i (%s)", size, size, r, ++ r < 0 ? "bad" : "good"); ++ if (r >= 0 && LZ4_versionNumber() >= 10803) ++ /* lz4 <= 1.8.2 should fail that test, let's only check for newer ones */ ++ assert_se(memcmp(buf2, huge, r) == 0); ++ } + } + #endif + diff --git a/SOURCES/0388-fuzz-compress-add-fuzzer-for-compression-and-decompr.patch b/SOURCES/0388-fuzz-compress-add-fuzzer-for-compression-and-decompr.patch new file mode 100644 index 0000000..cccc17a --- /dev/null +++ b/SOURCES/0388-fuzz-compress-add-fuzzer-for-compression-and-decompr.patch @@ -0,0 +1,118 @@ +From 242273e1afd456e86ebc48d7d601cb28297f8efb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 30 Oct 2018 09:02:26 +0100 +Subject: [PATCH] fuzz-compress: add fuzzer for compression and decompression + +(cherry picked from commit 029427043b2e0523a21f54374f872b23cf744350) +Resolves: #1843871 +--- + src/fuzz/fuzz-compress.c | 80 ++++++++++++++++++++++++++++++++++++++++ + src/fuzz/meson.build | 7 +++- + 2 files changed, 86 insertions(+), 1 deletion(-) + create mode 100644 src/fuzz/fuzz-compress.c + +diff --git a/src/fuzz/fuzz-compress.c b/src/fuzz/fuzz-compress.c +new file mode 100644 +index 0000000000..9c5dfc92c0 +--- /dev/null ++++ b/src/fuzz/fuzz-compress.c +@@ -0,0 +1,80 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++ ++#include "alloc-util.h" ++#include "compress.h" ++#include "fuzz.h" ++ ++static int compress(int alg, ++ const void *src, uint64_t src_size, ++ void *dst, size_t dst_alloc_size, size_t *dst_size) { ++ ++ if (alg == OBJECT_COMPRESSED_LZ4) ++ return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size); ++ if (alg == OBJECT_COMPRESSED_XZ) ++ return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size); ++ return -EOPNOTSUPP; ++} ++ ++typedef struct header { ++ uint32_t alg:2; /* We have only two compression algorithms so far, but we might add ++ * more in the future. Let's make this a bit wider so our fuzzer ++ * cases remain stable in the future. */ ++ uint32_t sw_len; ++ uint32_t sw_alloc; ++ uint32_t reserved[3]; /* Extra space to keep fuzz cases stable in case we need to ++ * add stuff in the future. */ ++ uint8_t data[]; ++} header; ++ ++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ++ _cleanup_free_ void *buf = NULL, *buf2 = NULL; ++ int r; ++ ++ if (size < offsetof(header, data) + 1) ++ return 0; ++ ++ const header *h = (struct header*) data; ++ const size_t data_len = size - offsetof(header, data); ++ ++ int alg = h->alg; ++ ++ /* We don't want to fill the logs with messages about parse errors. ++ * Disable most logging if not running standalone */ ++ if (!getenv("SYSTEMD_LOG_LEVEL")) ++ log_set_max_level(LOG_CRIT); ++ ++ log_info("Using compression %s, data size=%zu", ++ object_compressed_to_string(alg) ?: "(none)", ++ data_len); ++ ++ buf = malloc(MAX(size, 128u)); /* Make the buffer a bit larger for very small data */ ++ if (!buf) { ++ log_oom(); ++ return 0; ++ } ++ ++ size_t csize; ++ r = compress(alg, h->data, data_len, buf, size, &csize); ++ if (r < 0) { ++ log_error_errno(r, "Compression failed: %m"); ++ return 0; ++ } ++ ++ log_debug("Compressed %zu bytes to → %zu bytes", data_len, csize); ++ ++ size_t sw_alloc = MAX(h->sw_alloc, 1u); ++ buf2 = malloc(sw_alloc); ++ if (!buf) { ++ log_oom(); ++ return 0; ++ } ++ ++ size_t sw_len = MIN(data_len - 1, h->sw_len); ++ ++ r = decompress_startswith(alg, buf, csize, &buf2, &sw_alloc, h->data, sw_len, h->data[sw_len]); ++ assert_se(r > 0); ++ ++ return 0; ++} +diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build +index 5315d2771c..b8d5979d3c 100644 +--- a/src/fuzz/meson.build ++++ b/src/fuzz/meson.build +@@ -73,8 +73,13 @@ fuzzers += [ + [libsystemd_journal_remote, + libshared], + []], ++ + [['src/fuzz/fuzz-fido-id-desc.c', + 'src/udev/fido_id/fido_id_desc.c'], + [], +- []] ++ []], ++ ++ [['src/fuzz/fuzz-compress.c'], ++ [libshared], ++ []], + ] diff --git a/SOURCES/0389-seccomp-fix-__NR__sysctl-usage.patch b/SOURCES/0389-seccomp-fix-__NR__sysctl-usage.patch new file mode 100644 index 0000000..7d67d8f --- /dev/null +++ b/SOURCES/0389-seccomp-fix-__NR__sysctl-usage.patch @@ -0,0 +1,35 @@ +From 65a066aae68744e889c114cee56dff5b48d872df Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Thu, 4 Jun 2020 16:55:52 +0200 +Subject: [PATCH] seccomp: fix __NR__sysctl usage + +Loosely based on +https://github.com/systemd/systemd/pull/14032 and +https://github.com/systemd/systemd/pull/14268. + +Related: #1843871 +--- + src/test/test-seccomp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 4021a06e0e..009a2e1922 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -237,14 +237,14 @@ static void test_protect_sysctl(void) { + assert_se(pid >= 0); + + if (pid == 0) { +-#if __NR__sysctl > 0 ++#if defined __NR__sysctl && __NR__sysctl >= 0 + assert_se(syscall(__NR__sysctl, NULL) < 0); + assert_se(errno == EFAULT); + #endif + + assert_se(seccomp_protect_sysctl() >= 0); + +-#if __NR__sysctl > 0 ++#if defined __NR__sysctl && __NR__sysctl >= 0 + assert_se(syscall(__NR__sysctl, 0, 0, 0) < 0); + assert_se(errno == EPERM); + #endif diff --git a/SOURCES/0390-tmpfiles-fix-crash-with-NULL-in-arg_root-and-other-f.patch b/SOURCES/0390-tmpfiles-fix-crash-with-NULL-in-arg_root-and-other-f.patch new file mode 100644 index 0000000..8ae24a5 --- /dev/null +++ b/SOURCES/0390-tmpfiles-fix-crash-with-NULL-in-arg_root-and-other-f.patch @@ -0,0 +1,174 @@ +From 3569b29eb8b082229dd97b8aae60bbe4d2f96ef5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 19 Dec 2018 23:05:48 +0100 +Subject: [PATCH] tmpfiles: fix crash with NULL in arg_root and other fixes and + tests + +The function to replacement paths into the configuration file list was borked. +Apart from the crash with empty root prefix, it would incorrectly handle the +case where root *was* set, and the replacement file was supposed to override +an existing file. + +prefix_root is used instead of path_join because prefix_root removes duplicate +slashes (when --root=dir/ is used). + +A test is added. + +Fixes #11124. + +(cherry picked from commit 082bb1c59bd4300bcdc08488c94109680cfadf57) + +Resolves: #1836024 +--- + src/basic/conf-files.c | 21 ++++++++----- + src/test/test-conf-files.c | 61 +++++++++++++++++++++++++++++++++++++- + 2 files changed, 73 insertions(+), 9 deletions(-) + +diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c +index d6ef0e941e..5ca83091c9 100644 +--- a/src/basic/conf-files.c ++++ b/src/basic/conf-files.c +@@ -204,14 +204,17 @@ int conf_files_insert(char ***strv, const char *root, char **dirs, const char *p + if (c == 0) { + char **dir; + +- /* Oh, we found our spot and it already contains something. */ ++ /* Oh, there already is an entry with a matching name (the last component). */ ++ + STRV_FOREACH(dir, dirs) { ++ _cleanup_free_ char *rdir = NULL; + char *p1, *p2; + +- p1 = path_startswith((*strv)[i], root); +- if (p1) +- /* Skip "/" in *dir, because p1 is without "/" too */ +- p1 = path_startswith(p1, *dir + 1); ++ rdir = prefix_root(root, *dir); ++ if (!rdir) ++ return -ENOMEM; ++ ++ p1 = path_startswith((*strv)[i], rdir); + if (p1) + /* Existing entry with higher priority + * or same priority, no need to do anything. */ +@@ -220,7 +223,8 @@ int conf_files_insert(char ***strv, const char *root, char **dirs, const char *p + p2 = path_startswith(path, *dir); + if (p2) { + /* Our new entry has higher priority */ +- t = path_join(root, path, NULL); ++ ++ t = prefix_root(root, path); + if (!t) + return log_oom(); + +@@ -236,7 +240,8 @@ int conf_files_insert(char ***strv, const char *root, char **dirs, const char *p + /* … we are not there yet, let's continue */ + } + +- t = path_join(root, path, NULL); ++ /* The new file has lower priority than all the existing entries */ ++ t = prefix_root(root, path); + if (!t) + return log_oom(); + +@@ -322,7 +327,7 @@ int conf_files_list_with_replacement( + if (r < 0) + return log_error_errno(r, "Failed to extend config file list: %m"); + +- p = path_join(root, replacement, NULL); ++ p = prefix_root(root, replacement); + if (!p) + return log_oom(); + } +diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c +index 2ec2dfc261..5789767161 100644 +--- a/src/test/test-conf-files.c ++++ b/src/test/test-conf-files.c +@@ -13,6 +13,7 @@ + #include "macro.h" + #include "mkdir.h" + #include "parse-util.h" ++#include "path-util.h" + #include "rm-rf.h" + #include "string-util.h" + #include "strv.h" +@@ -42,7 +43,7 @@ static void test_conf_files_list(bool use_root) { + _cleanup_strv_free_ char **found_files = NULL, **found_files2 = NULL; + const char *root_dir, *search_1, *search_2, *expect_a, *expect_b, *expect_c, *mask; + +- log_debug("/* %s */", __func__); ++ log_debug("/* %s(%s) */", __func__, yes_no(use_root)); + + setup_test_dir(tmp_dir, + "/dir1/a.conf", +@@ -92,6 +93,60 @@ static void test_conf_files_list(bool use_root) { + assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0); + } + ++static void test_conf_files_insert(const char *root) { ++ _cleanup_strv_free_ char **s = NULL; ++ ++ log_info("/* %s root=%s */", __func__, strempty(root)); ++ ++ char **dirs = STRV_MAKE("/dir1", "/dir2", "/dir3"); ++ ++ _cleanup_free_ const char ++ *foo1 = prefix_root(root, "/dir1/foo.conf"), ++ *foo2 = prefix_root(root, "/dir2/foo.conf"), ++ *bar2 = prefix_root(root, "/dir2/bar.conf"), ++ *zzz3 = prefix_root(root, "/dir3/zzz.conf"), ++ *whatever = prefix_root(root, "/whatever.conf"); ++ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(foo2))); ++ ++ /* The same file again, https://github.com/systemd/systemd/issues/11124 */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(foo2))); ++ ++ /* Lower priority → new entry is ignored */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir3/foo.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(foo2))); ++ ++ /* Higher priority → new entry replaces */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir1/foo.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(foo1))); ++ ++ /* Earlier basename */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir2/bar.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(bar2, foo1))); ++ ++ /* Later basename */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir3/zzz.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); ++ ++ /* All lower priority → all ignored */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir3/zzz.conf") == 0); ++ assert_se(conf_files_insert(&s, root, dirs, "/dir2/bar.conf") == 0); ++ assert_se(conf_files_insert(&s, root, dirs, "/dir3/bar.conf") == 0); ++ assert_se(conf_files_insert(&s, root, dirs, "/dir2/foo.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); ++ ++ /* Two entries that don't match any of the directories, but match basename */ ++ assert_se(conf_files_insert(&s, root, dirs, "/dir4/zzz.conf") == 0); ++ assert_se(conf_files_insert(&s, root, dirs, "/zzz.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, zzz3))); ++ ++ /* An entry that doesn't match any of the directories, no match at all */ ++ assert_se(conf_files_insert(&s, root, dirs, "/whatever.conf") == 0); ++ assert_se(strv_equal(s, STRV_MAKE(bar2, foo1, whatever, zzz3))); ++} ++ + int main(int argc, char **argv) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); +@@ -99,5 +154,9 @@ int main(int argc, char **argv) { + + test_conf_files_list(false); + test_conf_files_list(true); ++ test_conf_files_insert(NULL); ++ test_conf_files_insert("/root"); ++ test_conf_files_insert("/root/"); ++ + return 0; + } diff --git a/SOURCES/0391-sulogin-shell-Use-force-if-SYSTEMD_SULOGIN_FORCE-set.patch b/SOURCES/0391-sulogin-shell-Use-force-if-SYSTEMD_SULOGIN_FORCE-set.patch new file mode 100644 index 0000000..31783e0 --- /dev/null +++ b/SOURCES/0391-sulogin-shell-Use-force-if-SYSTEMD_SULOGIN_FORCE-set.patch @@ -0,0 +1,85 @@ +From d8ae33a302f01601e9e98b4aca3516e93c634a54 Mon Sep 17 00:00:00 2001 +From: Andreas Henriksson +Date: Sun, 14 Oct 2018 14:53:09 +0200 +Subject: [PATCH] sulogin-shell: Use force if SYSTEMD_SULOGIN_FORCE set + +When the root account is locked sulogin will either inform you of +this and not allow you in or if --force is used it will hand +you passwordless root (if using a recent enough version of util-linux). + +Not being allowed a shell is ofcourse inconvenient, but at the same +time handing out passwordless root unconditionally is probably not +a good idea everywhere. + +This patch thus allows to control which behaviour you want by +setting the SYSTEMD_SULOGIN_FORCE environment variable to true +or false to control the behaviour, eg. via adding this to +'systemctl edit rescue.service' (or emergency.service): + +[Service] +Environment=SYSTEMD_SULOGIN_FORCE=1 + +Distributions who used locked root accounts and want the passwordless +behaviour could thus simply drop in the override file in +/etc/systemd/system/rescue.service.d/override.conf + +Fixes: #7115 +Addresses: https://bugs.debian.org/802211 +(cherry picked from commit 33eb44fe4a8d7971b5614bc4c2d90f8d91cce66c) + +Resolves: #1625929 +--- + doc/ENVIRONMENT.md | 6 ++++++ + src/sulogin-shell/sulogin-shell.c | 11 ++++++++++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 1e648be640..39a36a52cc 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -101,3 +101,9 @@ systemd-timedated: + NTP client services. If set, `timedatectl set-ntp on` enables and starts the + first existing unit listed in the environment variable, and + `timedatectl set-ntp off` disables and stops all listed units. ++ ++systemd-sulogin-shell: ++ ++* `$SYSTEMD_SULOGIN_FORCE=1` — This skips asking for the root password if the ++ root password is not available (such as when the root account is locked). ++ See `sulogin(8)` for more details. +diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c +index 5db3592d6f..a1ea2333de 100644 +--- a/src/sulogin-shell/sulogin-shell.c ++++ b/src/sulogin-shell/sulogin-shell.c +@@ -9,6 +9,7 @@ + #include "bus-util.h" + #include "bus-error.h" + #include "def.h" ++#include "env-util.h" + #include "log.h" + #include "process-util.h" + #include "sd-bus.h" +@@ -89,7 +90,11 @@ static void print_mode(const char* mode) { + } + + int main(int argc, char *argv[]) { +- static const char* const sulogin_cmdline[] = {SULOGIN, NULL}; ++ const char* sulogin_cmdline[] = { ++ SULOGIN, ++ NULL, /* --force */ ++ NULL ++ }; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + +@@ -99,6 +104,10 @@ int main(int argc, char *argv[]) { + + print_mode(argc > 1 ? argv[1] : ""); + ++ if (getenv_bool("SYSTEMD_SULOGIN_FORCE") > 0) ++ /* allows passwordless logins if root account is locked. */ ++ sulogin_cmdline[1] = "--force"; ++ + (void) fork_wait(sulogin_cmdline); + + r = bus_connect_system_systemd(&bus); diff --git a/SOURCES/0392-resolvconf-fixes-for-the-compatibility-interface.patch b/SOURCES/0392-resolvconf-fixes-for-the-compatibility-interface.patch new file mode 100644 index 0000000..636b585 --- /dev/null +++ b/SOURCES/0392-resolvconf-fixes-for-the-compatibility-interface.patch @@ -0,0 +1,62 @@ +From 9b7aa39e7db5a6446d3c034741e64cda1a9dd200 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Mon, 25 Jun 2018 18:07:48 -0700 +Subject: [PATCH] resolvconf: fixes for the compatibility interface + +Also use compat_main() when called as `resolvconf`, since the interface +is closer to that of `systemd-resolve`. + +Use a heap allocated string to set arg_ifname, since a stack allocated +one would be lost after the function returns. (This last one broke the +case where an interface name was suffixed with a dot, such as in +`resolvconf -a tap0.dhcp`.) + +Tested: + $ build/resolvconf -a nonexistent.abc +Date: Tue, 17 Mar 2020 10:49:44 +0100 +Subject: [PATCH] mount: don't add Requires for tmp.mount + +This is a follow-up to #1619292. + +rhel-only +Resolves: #1748840 +--- + src/core/mount.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 30aaf5ae55..2746372db2 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -305,7 +305,7 @@ static int mount_add_mount_dependencies(Mount *m) { + if (r < 0) + return r; + +- if (UNIT(m)->fragment_path) { ++ if (UNIT(m)->fragment_path && !streq(UNIT(m)->id, "tmp.mount")) { + /* If we have fragment configuration, then make this dependency required */ + r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true, UNIT_DEPENDENCY_PATH); + if (r < 0) diff --git a/SOURCES/0394-core-coldplug-possible-nop_job.patch b/SOURCES/0394-core-coldplug-possible-nop_job.patch new file mode 100644 index 0000000..f133544 --- /dev/null +++ b/SOURCES/0394-core-coldplug-possible-nop_job.patch @@ -0,0 +1,55 @@ +From 4a1405998671caaaad5b24d4cef309c05175b1c1 Mon Sep 17 00:00:00 2001 +From: ypf791 +Date: Fri, 19 Jul 2019 18:28:04 +0800 +Subject: [PATCH] core: coldplug possible nop_job + +When a unit in a state INACTIVE or DEACTIVATING, JobType JOB_TRY_RESTART or +JOB_TRY_RELOAD will be collapsed to JOB_NOP. And use u->nop_job instead +of u->job. + +If a JOB_NOP job is going on with a waiting state, a parallel daemon-reload +just install it during deserialization. Without a coldplug, the job will +not be in m->run_queue, which results in a hung try-restart or +try-reload process. + +Reproduce: + + run systemctl try-restart test.servcie (inactive) repeatly in a terminal. + run systemctl daemon-reload repeatly in other terminals. + +After successful reproduce, systemctl list-jobs will list the hang job. + +Upsteam: +systemd/systemd#13124 + +(cherry picked from commit b49e14d5f3081dfcd363d8199a14c0924ae9152f) + +Resolves: #1829798 +--- + src/core/unit.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 61799bf9e3..f57260727f 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3696,6 +3696,7 @@ int unit_add_node_dependency(Unit *u, const char *what, bool wants, UnitDependen + int unit_coldplug(Unit *u) { + int r = 0, q; + char **i; ++ Job *uj; + + assert(u); + +@@ -3718,8 +3719,9 @@ int unit_coldplug(Unit *u) { + r = q; + } + +- if (u->job) { +- q = job_coldplug(u->job); ++ uj = u->job ?: u->nop_job; ++ if (uj) { ++ q = job_coldplug(uj); + if (q < 0 && r >= 0) + r = q; + } diff --git a/SOURCES/0395-core-add-IODeviceLatencyTargetSec.patch b/SOURCES/0395-core-add-IODeviceLatencyTargetSec.patch new file mode 100644 index 0000000..974a1d9 --- /dev/null +++ b/SOURCES/0395-core-add-IODeviceLatencyTargetSec.patch @@ -0,0 +1,584 @@ +From 2240e7955d64260e94dd52a3ab9855d267c2af89 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 13 Jun 2018 14:16:35 -0700 +Subject: [PATCH] core: add IODeviceLatencyTargetSec + +This adds support for the following proposed latency based IO control +mechanism. + + https://lkml.org/lkml/2018/6/5/428 + +(cherry picked from commit 6ae4283cb14c4e4a895f4bbba703804e4128c86c) + +Resolves: #1831519 +--- + man/systemd.resource-control.xml | 29 +++++-- + src/core/cgroup.c | 56 +++++++++++-- + src/core/cgroup.h | 9 +++ + src/core/dbus-cgroup.c | 111 ++++++++++++++++++++++++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/load-fragment.c | 72 +++++++++++++++++ + src/core/load-fragment.h | 1 + + src/shared/bus-unit-util.c | 31 +++++++ + src/systemctl/systemctl.c | 22 +++++ + 9 files changed, 320 insertions(+), 12 deletions(-) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 4329742e94..b0064bf98f 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -417,11 +417,11 @@ + + Set the per-device overall block I/O weight for the executed processes, if the unified control group + hierarchy is used on the system. Takes a space-separated pair of a file path and a weight value to specify +- the device specific weight value, between 1 and 10000. (Example: "/dev/sda 1000"). The file path may be +- specified as path to a block device node or as any other file, in which case the backing block device of the +- file system of the file is determined. This controls the io.weight control group +- attribute, which defaults to 100. Use this option multiple times to set weights for multiple devices. For +- details about this control group attribute, see /dev/sda 1000). The file ++ path may be specified as path to a block device node or as any other file, in which case the backing block ++ device of the file system of the file is determined. This controls the io.weight control ++ group attribute, which defaults to 100. Use this option multiple times to set weights for multiple devices. ++ For details about this control group attribute, see cgroup-v2.txt. + + Implies IOAccounting=true. +@@ -482,6 +482,25 @@ + + + ++ ++ IODeviceLatencyTargetSec=device target ++ ++ ++ Set the per-device average target I/O latency for the executed processes, if the unified control group ++ hierarchy is used on the system. Takes a file path and a timespan separated by a space to specify ++ the device specific latency target. (Example: "/dev/sda 25ms"). The file path may be specified ++ as path to a block device node or as any other file, in which case the backing block device of the file ++ system of the file is determined. This controls the io.latency control group ++ attribute. Use this option multiple times to set latency target for multiple devices. For details about this ++ control group attribute, see cgroup-v2.txt. ++ ++ Implies IOAccounting=true. ++ ++ These settings are supported only if the unified control group hierarchy is used. ++ ++ ++ + + IPAccounting= + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 9e4c3c7dac..ad8219bd79 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -114,6 +114,15 @@ void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight + free(w); + } + ++void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLatency *l) { ++ assert(c); ++ assert(l); ++ ++ LIST_REMOVE(device_latencies, c->io_device_latencies, l); ++ free(l->path); ++ free(l); ++} ++ + void cgroup_context_free_io_device_limit(CGroupContext *c, CGroupIODeviceLimit *l) { + assert(c); + assert(l); +@@ -147,6 +156,9 @@ void cgroup_context_done(CGroupContext *c) { + while (c->io_device_weights) + cgroup_context_free_io_device_weight(c, c->io_device_weights); + ++ while (c->io_device_latencies) ++ cgroup_context_free_io_device_latency(c, c->io_device_latencies); ++ + while (c->io_device_limits) + cgroup_context_free_io_device_limit(c, c->io_device_limits); + +@@ -171,6 +183,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + _cleanup_free_ char *cpuset_mems = NULL; + CGroupIODeviceLimit *il; + CGroupIODeviceWeight *iw; ++ CGroupIODeviceLatency *l; + CGroupBlockIODeviceBandwidth *b; + CGroupBlockIODeviceWeight *w; + CGroupDeviceAllow *a; +@@ -256,11 +269,18 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + + LIST_FOREACH(device_weights, iw, c->io_device_weights) + fprintf(f, +- "%sIODeviceWeight=%s %" PRIu64, ++ "%sIODeviceWeight=%s %" PRIu64 "\n", + prefix, + iw->path, + iw->weight); + ++ LIST_FOREACH(device_latencies, l, c->io_device_latencies) ++ fprintf(f, ++ "%sIODeviceLatencyTargetSec=%s %s\n", ++ prefix, ++ l->path, ++ format_timespan(u, sizeof(u), l->target_usec, 1)); ++ + LIST_FOREACH(device_limits, il, c->io_device_limits) { + char buf[FORMAT_BYTES_MAX]; + CGroupIOLimitType type; +@@ -573,6 +593,7 @@ static bool cgroup_context_has_io_config(CGroupContext *c) { + c->io_weight != CGROUP_WEIGHT_INVALID || + c->startup_io_weight != CGROUP_WEIGHT_INVALID || + c->io_device_weights || ++ c->io_device_latencies || + c->io_device_limits; + } + +@@ -646,6 +667,26 @@ static void cgroup_apply_blkio_device_weight(Unit *u, const char *dev_path, uint + "Failed to set blkio.weight_device: %m"); + } + ++static void cgroup_apply_io_device_latency(Unit *u, const char *dev_path, usec_t target) { ++ char buf[DECIMAL_STR_MAX(dev_t)*2+2+7+DECIMAL_STR_MAX(uint64_t)+1]; ++ dev_t dev; ++ int r; ++ ++ r = lookup_block_device(dev_path, &dev); ++ if (r < 0) ++ return; ++ ++ if (target != USEC_INFINITY) ++ xsprintf(buf, "%u:%u target=%" PRIu64 "\n", major(dev), minor(dev), target); ++ else ++ xsprintf(buf, "%u:%u target=max\n", major(dev), minor(dev)); ++ ++ r = cg_set_attribute("io", u->cgroup_path, "io.latency", buf); ++ if (r < 0) ++ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to set io.latency on cgroup %s: %m", u->cgroup_path); ++} ++ + static void cgroup_apply_io_device_limit(Unit *u, const char *dev_path, uint64_t *limits) { + char limit_bufs[_CGROUP_IO_LIMIT_TYPE_MAX][DECIMAL_STR_MAX(uint64_t)]; + char buf[DECIMAL_STR_MAX(dev_t)*2+2+(6+DECIMAL_STR_MAX(uint64_t)+1)*4]; +@@ -827,13 +868,11 @@ static void cgroup_context_apply( + if (has_io) { + CGroupIODeviceWeight *w; + +- /* FIXME: no way to reset this list */ + LIST_FOREACH(device_weights, w, c->io_device_weights) + cgroup_apply_io_device_weight(u, w->path, w->weight); + } else if (has_blockio) { + CGroupBlockIODeviceWeight *w; + +- /* FIXME: no way to reset this list */ + LIST_FOREACH(device_weights, w, c->blockio_device_weights) { + weight = cgroup_weight_blkio_to_io(w->weight); + +@@ -843,9 +882,15 @@ static void cgroup_context_apply( + cgroup_apply_io_device_weight(u, w->path, weight); + } + } ++ ++ if (has_io) { ++ CGroupIODeviceLatency *l; ++ ++ LIST_FOREACH(device_latencies, l, c->io_device_latencies) ++ cgroup_apply_io_device_latency(u, l->path, l->target_usec); ++ } + } + +- /* Apply limits and free ones without config. */ + if (has_io) { + CGroupIODeviceLimit *l; + +@@ -902,7 +947,6 @@ static void cgroup_context_apply( + if (has_io) { + CGroupIODeviceWeight *w; + +- /* FIXME: no way to reset this list */ + LIST_FOREACH(device_weights, w, c->io_device_weights) { + weight = cgroup_weight_io_to_blkio(w->weight); + +@@ -914,13 +958,11 @@ static void cgroup_context_apply( + } else if (has_blockio) { + CGroupBlockIODeviceWeight *w; + +- /* FIXME: no way to reset this list */ + LIST_FOREACH(device_weights, w, c->blockio_device_weights) + cgroup_apply_blkio_device_weight(u, w->path, w->weight); + } + } + +- /* Apply limits and free ones without config. */ + if (has_io) { + CGroupIODeviceLimit *l; + +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index da10575394..f7365b4c46 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -13,6 +13,7 @@ typedef struct CGroupContext CGroupContext; + typedef struct CGroupDeviceAllow CGroupDeviceAllow; + typedef struct CGroupIODeviceWeight CGroupIODeviceWeight; + typedef struct CGroupIODeviceLimit CGroupIODeviceLimit; ++typedef struct CGroupIODeviceLatency CGroupIODeviceLatency; + typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight; + typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth; + +@@ -52,6 +53,12 @@ struct CGroupIODeviceLimit { + uint64_t limits[_CGROUP_IO_LIMIT_TYPE_MAX]; + }; + ++struct CGroupIODeviceLatency { ++ LIST_FIELDS(CGroupIODeviceLatency, device_latencies); ++ char *path; ++ usec_t target_usec; ++}; ++ + struct CGroupBlockIODeviceWeight { + LIST_FIELDS(CGroupBlockIODeviceWeight, device_weights); + char *path; +@@ -85,6 +92,7 @@ struct CGroupContext { + uint64_t startup_io_weight; + LIST_HEAD(CGroupIODeviceWeight, io_device_weights); + LIST_HEAD(CGroupIODeviceLimit, io_device_limits); ++ LIST_HEAD(CGroupIODeviceLatency, io_device_latencies); + + uint64_t memory_low; + uint64_t memory_high; +@@ -137,6 +145,7 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c); + void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a); + void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight *w); + void cgroup_context_free_io_device_limit(CGroupContext *c, CGroupIODeviceLimit *l); ++void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLatency *l); + void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); + void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); + +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 30d4e83932..a1d3014d61 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -140,6 +140,36 @@ static int property_get_io_device_limits( + return sd_bus_message_close_container(reply); + } + ++static int property_get_io_device_latency( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ CGroupContext *c = userdata; ++ CGroupIODeviceLatency *l; ++ int r; ++ ++ assert(bus); ++ assert(reply); ++ assert(c); ++ ++ r = sd_bus_message_open_container(reply, 'a', "(st)"); ++ if (r < 0) ++ return r; ++ ++ LIST_FOREACH(device_latencies, l, c->io_device_latencies) { ++ r = sd_bus_message_append(reply, "(st)", l->path, l->target_usec); ++ if (r < 0) ++ return r; ++ } ++ ++ return sd_bus_message_close_container(reply); ++} ++ + static int property_get_blockio_device_weight( + sd_bus *bus, + const char *path, +@@ -314,6 +344,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0), + SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0), + SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0), ++ SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency, 0, 0), + SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0), + SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0), + SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0), +@@ -898,6 +929,86 @@ int bus_cgroup_set_property( + + return 1; + ++ } else if (streq(name, "IODeviceLatencyTargetUSec")) { ++ const char *path; ++ uint64_t target; ++ unsigned n = 0; ++ ++ r = sd_bus_message_enter_container(message, 'a', "(st)"); ++ if (r < 0) ++ return r; ++ ++ while ((r = sd_bus_message_read(message, "(st)", &path, &target)) > 0) { ++ ++ if (!path_is_normalized(path)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path); ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ CGroupIODeviceLatency *a = NULL, *b; ++ ++ LIST_FOREACH(device_latencies, b, c->io_device_latencies) { ++ if (path_equal(b->path, path)) { ++ a = b; ++ break; ++ } ++ } ++ ++ if (!a) { ++ a = new0(CGroupIODeviceLatency, 1); ++ if (!a) ++ return -ENOMEM; ++ ++ a->path = strdup(path); ++ if (!a->path) { ++ free(a); ++ return -ENOMEM; ++ } ++ LIST_PREPEND(device_latencies, c->io_device_latencies, a); ++ } ++ ++ a->target_usec = target; ++ } ++ ++ n++; ++ } ++ ++ r = sd_bus_message_exit_container(message); ++ if (r < 0) ++ return r; ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ _cleanup_free_ char *buf = NULL; ++ _cleanup_fclose_ FILE *f = NULL; ++ char ts[FORMAT_TIMESPAN_MAX]; ++ CGroupIODeviceLatency *a; ++ size_t size = 0; ++ ++ if (n == 0) { ++ while (c->io_device_latencies) ++ cgroup_context_free_io_device_latency(c, c->io_device_latencies); ++ } ++ ++ unit_invalidate_cgroup(u, CGROUP_MASK_IO); ++ ++ f = open_memstream(&buf, &size); ++ if (!f) ++ return -ENOMEM; ++ ++ (void) __fsetlocking(f, FSETLOCKING_BYCALLER); ++ ++ fputs("IODeviceLatencyTargetSec=\n", f); ++ LIST_FOREACH(device_latencies, a, c->io_device_latencies) ++ fprintf(f, "IODeviceLatencyTargetSec=%s %s\n", ++ a->path, format_timespan(ts, sizeof(ts), a->target_usec, 1)); ++ ++ r = fflush_and_check(f); ++ if (r < 0) ++ return r; ++ unit_write_setting(u, flags, name, buf); ++ } ++ ++ return 1; ++ + } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) { + const char *path; + bool read = true; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 8883818ff2..23879c001f 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -185,6 +185,7 @@ $1.IOReadBandwidthMax, config_parse_io_limit, 0, + $1.IOWriteBandwidthMax, config_parse_io_limit, 0, offsetof($1, cgroup_context) + $1.IOReadIOPSMax, config_parse_io_limit, 0, offsetof($1, cgroup_context) + $1.IOWriteIOPSMax, config_parse_io_limit, 0, offsetof($1, cgroup_context) ++$1.IODeviceLatencyTargetSec, config_parse_io_device_latency, 0, offsetof($1, cgroup_context) + $1.BlockIOAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.blockio_accounting) + $1.BlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context.blockio_weight) + $1.StartupBlockIOWeight, config_parse_blockio_weight, 0, offsetof($1, cgroup_context.startup_blockio_weight) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 9b2724307d..1e22013b75 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3383,6 +3383,77 @@ int config_parse_io_device_weight( + return 0; + } + ++int config_parse_io_device_latency( ++ const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *section, ++ unsigned section_line, ++ const char *lvalue, ++ int ltype, ++ const char *rvalue, ++ void *data, ++ void *userdata) { ++ ++ _cleanup_free_ char *path = NULL, *resolved = NULL; ++ CGroupIODeviceLatency *l; ++ CGroupContext *c = data; ++ const char *p = rvalue; ++ usec_t usec; ++ int r; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ ++ if (isempty(rvalue)) { ++ while (c->io_device_latencies) ++ cgroup_context_free_io_device_latency(c, c->io_device_latencies); ++ ++ return 0; ++ } ++ ++ r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES); ++ if (r == -ENOMEM) ++ return log_oom(); ++ if (r < 0) { ++ log_syntax(unit, LOG_WARNING, filename, line, r, ++ "Invalid syntax, ignoring: %s", rvalue); ++ return 0; ++ } ++ if (r == 0 || isempty(p)) { ++ log_syntax(unit, LOG_WARNING, filename, line, 0, ++ "Failed to extract device path and latency from '%s', ignoring.", rvalue); ++ return 0; ++ } ++ ++ r = unit_full_printf(userdata, path, &resolved); ++ if (r < 0) { ++ log_syntax(unit, LOG_WARNING, filename, line, r, ++ "Failed to resolve unit specifiers in '%s', ignoring: %m", path); ++ return 0; ++ } ++ ++ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue); ++ if (r < 0) ++ return 0; ++ ++ if (parse_sec(p, &usec) < 0) { ++ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse timer value, ignoring: %s", p); ++ return 0; ++ } ++ ++ l = new0(CGroupIODeviceLatency, 1); ++ if (!l) ++ return log_oom(); ++ ++ l->path = TAKE_PTR(resolved); ++ l->target_usec = usec; ++ ++ LIST_PREPEND(device_latencies, c->io_device_latencies, l); ++ return 0; ++} ++ + int config_parse_io_limit( + const char *unit, + const char *filename, +@@ -4572,6 +4643,7 @@ void unit_dump_config_items(FILE *f) { + { config_parse_device_policy, "POLICY" }, + { config_parse_io_limit, "LIMIT" }, + { config_parse_io_device_weight, "DEVICEWEIGHT" }, ++ { config_parse_io_device_latency, "DEVICELATENCY" }, + { config_parse_blockio_bandwidth, "BANDWIDTH" }, + { config_parse_blockio_weight, "WEIGHT" }, + { config_parse_blockio_device_weight, "DEVICEWEIGHT" }, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index 424fa478a7..65a94d53cc 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -68,6 +68,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max); + CONFIG_PARSER_PROTOTYPE(config_parse_delegate); + CONFIG_PARSER_PROTOTYPE(config_parse_device_policy); + CONFIG_PARSER_PROTOTYPE(config_parse_device_allow); ++CONFIG_PARSER_PROTOTYPE(config_parse_io_device_latency); + CONFIG_PARSER_PROTOTYPE(config_parse_io_device_weight); + CONFIG_PARSER_PROTOTYPE(config_parse_io_limit); + CONFIG_PARSER_PROTOTYPE(config_parse_blockio_weight); +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index e0b2cfb170..3c1ecf2027 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -566,6 +566,37 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + ++ if (streq(field, "IODeviceLatencyTargetSec")) { ++ const char *field_usec = "IODeviceLatencyTargetUSec"; ++ ++ if (isempty(eq)) ++ r = sd_bus_message_append(m, "(sv)", field_usec, "a(st)", USEC_INFINITY); ++ else { ++ const char *path, *target, *e; ++ usec_t usec; ++ ++ e = strchr(eq, ' '); ++ if (!e) { ++ log_error("Failed to parse %s value %s.", field, eq); ++ return -EINVAL; ++ } ++ ++ path = strndupa(eq, e - eq); ++ target = e+1; ++ ++ r = parse_sec(target, &usec); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse %s value %s: %m", field, target); ++ ++ r = sd_bus_message_append(m, "(sv)", field_usec, "a(st)", 1, path, usec); ++ } ++ ++ if (r < 0) ++ return bus_log_create_error(r); ++ ++ return 1; ++ } ++ + if (STR_IN_SET(field, "IPAddressAllow", "IPAddressDeny")) { + unsigned char prefixlen; + union in_addr_union prefix = {}; +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index a3074bc5e3..559e49f104 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -4875,6 +4875,28 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool + + return 1; + ++ } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && ++ streq(name, "IODeviceLatencyTargetUSec")) { ++ char ts[FORMAT_TIMESPAN_MAX]; ++ const char *path; ++ uint64_t target; ++ ++ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)"); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ while ((r = sd_bus_message_read(m, "(st)", &path, &target)) > 0) ++ print_prop(name, "%s %s", strna(path), ++ format_timespan(ts, sizeof(ts), target, 1)); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ r = sd_bus_message_exit_container(m); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ return 1; ++ + } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) { + _cleanup_free_ char *h = NULL; + const void *p; diff --git a/SOURCES/0396-time-util-Introduce-parse_sec_def_infinity.patch b/SOURCES/0396-time-util-Introduce-parse_sec_def_infinity.patch new file mode 100644 index 0000000..8af140b --- /dev/null +++ b/SOURCES/0396-time-util-Introduce-parse_sec_def_infinity.patch @@ -0,0 +1,122 @@ +From 9692477a59c47b5fb6bd6d4702302859296db070 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Wed, 23 Jan 2019 19:48:54 -0800 +Subject: [PATCH] time-util: Introduce parse_sec_def_infinity + +This works like parse_sec() but defaults to USEC_INFINITY when passed an +empty string or only whitespace. + +Also introduce config_parse_sec_def_infinity, which can be used to parse +config options using this function. + +This is useful for time options that use "infinity" for default and that +can be reset by unsetting them. + +Introduce a test case to ensure it works as expected. + +(cherry picked from commit 7b61ce3c44ef5908e817009ce4f9d2a7a37722be) + +Related: #1770379 +--- + src/basic/time-util.c | 9 +++++++++ + src/basic/time-util.h | 1 + + src/shared/conf-parser.c | 1 + + src/shared/conf-parser.h | 1 + + src/test/test-time-util.c | 21 +++++++++++++++++++++ + 5 files changed, 33 insertions(+) + +diff --git a/src/basic/time-util.c b/src/basic/time-util.c +index fe201c398d..c36e462193 100644 +--- a/src/basic/time-util.c ++++ b/src/basic/time-util.c +@@ -1072,6 +1072,15 @@ int parse_sec_fix_0(const char *t, usec_t *usec) { + return parse_sec(t, usec); + } + ++int parse_sec_def_infinity(const char *t, usec_t *ret) { ++ t += strspn(t, WHITESPACE); ++ if (isempty(t)) { ++ *ret = USEC_INFINITY; ++ return 0; ++ } ++ return parse_sec(t, ret); ++} ++ + int parse_nsec(const char *t, nsec_t *nsec) { + static const struct { + const char *suffix; +diff --git a/src/basic/time-util.h b/src/basic/time-util.h +index 344f2dc52e..f5c9ea6327 100644 +--- a/src/basic/time-util.h ++++ b/src/basic/time-util.h +@@ -116,6 +116,7 @@ int parse_timestamp(const char *t, usec_t *usec); + + int parse_sec(const char *t, usec_t *usec); + int parse_sec_fix_0(const char *t, usec_t *usec); ++int parse_sec_def_infinity(const char *t, usec_t *usec); + int parse_time(const char *t, usec_t *usec, usec_t default_unit); + int parse_nsec(const char *t, nsec_t *nsec); + +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index 2d62fdf05d..246b7431e4 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -509,6 +509,7 @@ DEFINE_PARSER(unsigned, unsigned, safe_atou); + DEFINE_PARSER(double, double, safe_atod); + DEFINE_PARSER(nsec, nsec_t, parse_nsec); + DEFINE_PARSER(sec, usec_t, parse_sec); ++DEFINE_PARSER(sec_def_infinity, usec_t, parse_sec_def_infinity); + DEFINE_PARSER(mode, mode_t, parse_mode); + + int config_parse_iec_size(const char* unit, +diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h +index 16f042d894..a0a5c89c27 100644 +--- a/src/shared/conf-parser.h ++++ b/src/shared/conf-parser.h +@@ -127,6 +127,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_string); + CONFIG_PARSER_PROTOTYPE(config_parse_path); + CONFIG_PARSER_PROTOTYPE(config_parse_strv); + CONFIG_PARSER_PROTOTYPE(config_parse_sec); ++CONFIG_PARSER_PROTOTYPE(config_parse_sec_def_infinity); + CONFIG_PARSER_PROTOTYPE(config_parse_nsec); + CONFIG_PARSER_PROTOTYPE(config_parse_mode); + CONFIG_PARSER_PROTOTYPE(config_parse_warn_compat); +diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c +index 87de8d172c..354a01dd1a 100644 +--- a/src/test/test-time-util.c ++++ b/src/test/test-time-util.c +@@ -61,6 +61,26 @@ static void test_parse_sec_fix_0(void) { + assert_se(u == USEC_INFINITY); + } + ++static void test_parse_sec_def_infinity(void) { ++ usec_t u; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(parse_sec_def_infinity("5s", &u) >= 0); ++ assert_se(u == 5 * USEC_PER_SEC); ++ assert_se(parse_sec_def_infinity("", &u) >= 0); ++ assert_se(u == USEC_INFINITY); ++ assert_se(parse_sec_def_infinity(" ", &u) >= 0); ++ assert_se(u == USEC_INFINITY); ++ assert_se(parse_sec_def_infinity("0s", &u) >= 0); ++ assert_se(u == 0); ++ assert_se(parse_sec_def_infinity("0", &u) >= 0); ++ assert_se(u == 0); ++ assert_se(parse_sec_def_infinity(" 0", &u) >= 0); ++ assert_se(u == 0); ++ assert_se(parse_sec_def_infinity("-5s", &u) < 0); ++} ++ + static void test_parse_time(void) { + usec_t u; + +@@ -420,6 +440,7 @@ int main(int argc, char *argv[]) { + + test_parse_sec(); + test_parse_sec_fix_0(); ++ test_parse_sec_def_infinity(); + test_parse_time(); + test_parse_nsec(); + test_format_timespan(1); diff --git a/SOURCES/0397-cgroup-use-structured-initialization.patch b/SOURCES/0397-cgroup-use-structured-initialization.patch new file mode 100644 index 0000000..7b9e695 --- /dev/null +++ b/SOURCES/0397-cgroup-use-structured-initialization.patch @@ -0,0 +1,63 @@ +From f7b462bacb3c0ed1f7bbe63193e9e349aafd21d3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 20 Nov 2018 19:45:02 +0100 +Subject: [PATCH] cgroup: use structured initialization + +(cherry picked from commit de8a711a5849f9239c93aefa5554a62986dfce42) + +Related: #1770379 +--- + src/core/cgroup.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index ad8219bd79..7aa7db9261 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -71,29 +71,30 @@ static void cgroup_compat_warn(void) { + void cgroup_context_init(CGroupContext *c) { + assert(c); + +- /* Initialize everything to the kernel defaults, assuming the +- * structure is preinitialized to 0 */ ++ /* Initialize everything to the kernel defaults. */ + +- c->cpu_weight = CGROUP_WEIGHT_INVALID; +- c->startup_cpu_weight = CGROUP_WEIGHT_INVALID; +- c->cpu_quota_per_sec_usec = USEC_INFINITY; ++ *c = (CGroupContext) { ++ .cpu_weight = CGROUP_WEIGHT_INVALID, ++ .startup_cpu_weight = CGROUP_WEIGHT_INVALID, ++ .cpu_quota_per_sec_usec = USEC_INFINITY, + +- c->cpu_shares = CGROUP_CPU_SHARES_INVALID; +- c->startup_cpu_shares = CGROUP_CPU_SHARES_INVALID; ++ .cpu_shares = CGROUP_CPU_SHARES_INVALID, ++ .startup_cpu_shares = CGROUP_CPU_SHARES_INVALID, + +- c->memory_high = CGROUP_LIMIT_MAX; +- c->memory_max = CGROUP_LIMIT_MAX; +- c->memory_swap_max = CGROUP_LIMIT_MAX; ++ .memory_high = CGROUP_LIMIT_MAX, ++ .memory_max = CGROUP_LIMIT_MAX, ++ .memory_swap_max = CGROUP_LIMIT_MAX, + +- c->memory_limit = CGROUP_LIMIT_MAX; ++ .memory_limit = CGROUP_LIMIT_MAX, + +- c->io_weight = CGROUP_WEIGHT_INVALID; +- c->startup_io_weight = CGROUP_WEIGHT_INVALID; ++ .io_weight = CGROUP_WEIGHT_INVALID, ++ .startup_io_weight = CGROUP_WEIGHT_INVALID, + +- c->blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID; +- c->startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID; ++ .blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID, ++ .startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID, + +- c->tasks_max = (uint64_t) -1; ++ .tasks_max = CGROUP_LIMIT_MAX, ++ }; + } + + void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) { diff --git a/SOURCES/0398-core-add-CPUQuotaPeriodSec.patch b/SOURCES/0398-core-add-CPUQuotaPeriodSec.patch new file mode 100644 index 0000000..b411152 --- /dev/null +++ b/SOURCES/0398-core-add-CPUQuotaPeriodSec.patch @@ -0,0 +1,403 @@ +From 11df25536319a4c0f3276c2218054243d9ee213c Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Fri, 2 Nov 2018 09:21:57 -0700 +Subject: [PATCH] core: add CPUQuotaPeriodSec= + +This new setting allows configuration of CFS period on the CPU cgroup, instead +of using a hardcoded default of 100ms. + +Tested: +- Legacy cgroup + Unified cgroup +- systemctl set-property +- systemctl show +- Confirmed that the cgroup settings (such as cpu.cfs_period_ns) were set + appropriately, including updating the CPU quota (cpu.cfs_quota_ns) when + CPUQuotaPeriodSec= is updated. +- Checked that clamping works properly when either period or (quota * period) + are below the resolution of 1ms, or if period is above the max of 1s. + +(cherry picked from commit 10f28641115733c61754342d5dcbe70b083bea4b) + +Resolves: #1770379 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.resource-control.xml | 19 +++++++++ + src/core/cgroup.c | 61 ++++++++++++++++++++++----- + src/core/cgroup.h | 3 ++ + src/core/dbus-cgroup.c | 23 ++++++++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/load-fragment.c | 1 + + src/shared/bus-unit-util.c | 14 ++++++ + src/test/meson.build | 5 +++ + src/test/test-cgroup-cpu.c | 38 +++++++++++++++++ + 10 files changed, 155 insertions(+), 11 deletions(-) + create mode 100644 src/test/test-cgroup-cpu.c + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 23fe84e4d1..0d2d3e9065 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -218,6 +218,7 @@ All cgroup/resource control settings are available for transient units + ✓ CPUShares= + ✓ StartupCPUShares= + ✓ CPUQuota= ++✓ CPUQuotaPeriodSec= + ✓ AllowedCPUs= + ✓ AllowedMemoryNodes= + ✓ MemoryAccounting= +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index b0064bf98f..cfe19a6574 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -231,6 +231,25 @@ + + + ++ ++ CPUQuotaPeriodSec= ++ ++ ++ Assign the duration over which the CPU time quota specified by CPUQuota= is measured. ++ Takes a time duration value in seconds, with an optional suffix such as "ms" for milliseconds (or "s" for seconds.) ++ The default setting is 100ms. The period is clamped to the range supported by the kernel, which is [1ms, 1000ms]. ++ Additionally, the period is adjusted up so that the quota interval is also at least 1ms. ++ Setting CPUQuotaPeriodSec= to an empty value resets it to the default. ++ ++ This controls the second field of cpu.max attribute on the unified control group hierarchy ++ and cpu.cfs_period_us on legacy. For details about these control group attributes, see ++ cgroup-v2.txt and ++ sched-design-CFS.txt. ++ ++ Example: CPUQuotaPeriodSec=10ms to request that the CPU quota is measured in periods of 10ms. ++ ++ ++ + + MemoryAccounting= + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 7aa7db9261..45fd64a394 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -23,7 +23,7 @@ + #include "string-util.h" + #include "virt.h" + +-#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC) ++#define CGROUP_CPU_QUOTA_DEFAULT_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC) + + bool manager_owns_root_cgroup(Manager *m) { + assert(m); +@@ -77,6 +77,7 @@ void cgroup_context_init(CGroupContext *c) { + .cpu_weight = CGROUP_WEIGHT_INVALID, + .startup_cpu_weight = CGROUP_WEIGHT_INVALID, + .cpu_quota_per_sec_usec = USEC_INFINITY, ++ .cpu_quota_period_usec = USEC_INFINITY, + + .cpu_shares = CGROUP_CPU_SHARES_INVALID, + .startup_cpu_shares = CGROUP_CPU_SHARES_INVALID, +@@ -190,6 +191,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + CGroupDeviceAllow *a; + IPAddressAccessItem *iaai; + char u[FORMAT_TIMESPAN_MAX]; ++ char v[FORMAT_TIMESPAN_MAX]; + + assert(c); + assert(f); +@@ -211,6 +213,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sCPUShares=%" PRIu64 "\n" + "%sStartupCPUShares=%" PRIu64 "\n" + "%sCPUQuotaPerSecSec=%s\n" ++ "%sCPUQuotaPeriodSec=%s\n" + "%sAllowedCPUs=%s\n" + "%sAllowedMemoryNodes=%s\n" + "%sIOWeight=%" PRIu64 "\n" +@@ -236,6 +239,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + prefix, c->cpu_shares, + prefix, c->startup_cpu_shares, + prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1), ++ prefix, format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1), + prefix, cpuset_cpus, + prefix, cpuset_mems, + prefix, c->io_weight, +@@ -515,7 +519,40 @@ static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state) + return CGROUP_CPU_SHARES_DEFAULT; + } + +-static void cgroup_apply_unified_cpu_config(Unit *u, uint64_t weight, uint64_t quota) { ++usec_t cgroup_cpu_adjust_period(usec_t period, usec_t quota, usec_t resolution, usec_t max_period) { ++ /* kernel uses a minimum resolution of 1ms, so both period and (quota * period) ++ * need to be higher than that boundary. quota is specified in USecPerSec. ++ * Additionally, period must be at most max_period. */ ++ assert(quota > 0); ++ ++ return MIN(MAX3(period, resolution, resolution * USEC_PER_SEC / quota), max_period); ++} ++ ++static usec_t cgroup_cpu_adjust_period_and_log(Unit *u, usec_t period, usec_t quota) { ++ usec_t new_period; ++ ++ if (quota == USEC_INFINITY) ++ /* Always use default period for infinity quota. */ ++ return CGROUP_CPU_QUOTA_DEFAULT_PERIOD_USEC; ++ ++ if (period == USEC_INFINITY) ++ /* Default period was requested. */ ++ period = CGROUP_CPU_QUOTA_DEFAULT_PERIOD_USEC; ++ ++ /* Clamp to interval [1ms, 1s] */ ++ new_period = cgroup_cpu_adjust_period(period, quota, USEC_PER_MSEC, USEC_PER_SEC); ++ ++ if (new_period != period) { ++ char v[FORMAT_TIMESPAN_MAX]; ++ log_unit_full(u, LOG_WARNING, 0, ++ "Clamping CPU interval for cpu.max: period is now %s", ++ format_timespan(v, sizeof(v), new_period, 1)); ++ } ++ ++ return new_period; ++} ++ ++static void cgroup_apply_unified_cpu_config(Unit *u, uint64_t weight, uint64_t quota, usec_t period) { + char buf[MAX(DECIMAL_STR_MAX(uint64_t) + 1, (DECIMAL_STR_MAX(usec_t) + 1) * 2)]; + int r; + +@@ -525,11 +562,12 @@ static void cgroup_apply_unified_cpu_config(Unit *u, uint64_t weight, uint64_t q + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set cpu.weight: %m"); + ++ period = cgroup_cpu_adjust_period_and_log(u, period, quota); + if (quota != USEC_INFINITY) + xsprintf(buf, USEC_FMT " " USEC_FMT "\n", +- quota * CGROUP_CPU_QUOTA_PERIOD_USEC / USEC_PER_SEC, CGROUP_CPU_QUOTA_PERIOD_USEC); ++ MAX(quota * period / USEC_PER_SEC, USEC_PER_MSEC), period); + else +- xsprintf(buf, "max " USEC_FMT "\n", CGROUP_CPU_QUOTA_PERIOD_USEC); ++ xsprintf(buf, "max " USEC_FMT "\n", period); + + r = cg_set_attribute("cpu", u->cgroup_path, "cpu.max", buf); + +@@ -538,7 +576,7 @@ static void cgroup_apply_unified_cpu_config(Unit *u, uint64_t weight, uint64_t q + "Failed to set cpu.max: %m"); + } + +-static void cgroup_apply_legacy_cpu_config(Unit *u, uint64_t shares, uint64_t quota) { ++static void cgroup_apply_legacy_cpu_config(Unit *u, uint64_t shares, uint64_t quota, usec_t period) { + char buf[MAX(DECIMAL_STR_MAX(uint64_t), DECIMAL_STR_MAX(usec_t)) + 1]; + int r; + +@@ -548,20 +586,21 @@ static void cgroup_apply_legacy_cpu_config(Unit *u, uint64_t shares, uint64_t qu + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set cpu.shares: %m"); + +- xsprintf(buf, USEC_FMT "\n", CGROUP_CPU_QUOTA_PERIOD_USEC); ++ period = cgroup_cpu_adjust_period_and_log(u, period, quota); ++ ++ xsprintf(buf, USEC_FMT "\n", period); + r = cg_set_attribute("cpu", u->cgroup_path, "cpu.cfs_period_us", buf); + if (r < 0) + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set cpu.cfs_period_us: %m"); + + if (quota != USEC_INFINITY) { +- xsprintf(buf, USEC_FMT "\n", quota * CGROUP_CPU_QUOTA_PERIOD_USEC / USEC_PER_SEC); +- r = cg_set_attribute("cpu", u->cgroup_path, "cpu.cfs_quota_us", buf); +- } else ++ xsprintf(buf, USEC_FMT "\n", MAX(quota * period / USEC_PER_SEC, USEC_PER_MSEC)); + r = cg_set_attribute("cpu", u->cgroup_path, "cpu.cfs_quota_us", "-1"); + if (r < 0) + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set cpu.cfs_quota_us: %m"); ++ } + } + + static uint64_t cgroup_cpu_shares_to_weight(uint64_t shares) { +@@ -815,7 +854,7 @@ static void cgroup_context_apply( + } else + weight = CGROUP_WEIGHT_DEFAULT; + +- cgroup_apply_unified_cpu_config(u, weight, c->cpu_quota_per_sec_usec); ++ cgroup_apply_unified_cpu_config(u, weight, c->cpu_quota_per_sec_usec, c->cpu_quota_period_usec); + } else { + uint64_t shares; + +@@ -831,7 +870,7 @@ static void cgroup_context_apply( + else + shares = CGROUP_CPU_SHARES_DEFAULT; + +- cgroup_apply_legacy_cpu_config(u, shares, c->cpu_quota_per_sec_usec); ++ cgroup_apply_legacy_cpu_config(u, shares, c->cpu_quota_per_sec_usec, c->cpu_quota_period_usec); + } + } + +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index f7365b4c46..2ba57d3ded 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -84,6 +84,7 @@ struct CGroupContext { + uint64_t cpu_weight; + uint64_t startup_cpu_weight; + usec_t cpu_quota_per_sec_usec; ++ usec_t cpu_quota_period_usec; + + CPUSet cpuset_cpus; + CPUSet cpuset_mems; +@@ -136,6 +137,8 @@ typedef enum CGroupIPAccountingMetric { + typedef struct Unit Unit; + typedef struct Manager Manager; + ++usec_t cgroup_cpu_adjust_period(usec_t period, usec_t quota, usec_t resolution, usec_t max_period); ++ + void cgroup_context_init(CGroupContext *c); + void cgroup_context_done(CGroupContext *c); + void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix); +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index a1d3014d61..c8b918e45d 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -334,6 +334,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0), + SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0), + SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0), ++ SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_period_usec), 0), + SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus), 0), + SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0), + SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0), +@@ -725,6 +726,28 @@ int bus_cgroup_set_property( + + return 1; + ++ } else if (streq(name, "CPUQuotaPeriodUSec")) { ++ uint64_t u64; ++ ++ r = sd_bus_message_read(message, "t", &u64); ++ if (r < 0) ++ return r; ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ c->cpu_quota_period_usec = u64; ++ unit_invalidate_cgroup(u, CGROUP_MASK_CPU); ++ if (c->cpu_quota_period_usec == USEC_INFINITY) ++ unit_write_setting(u, flags, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec="); ++ else { ++ char v[FORMAT_TIMESPAN_MAX]; ++ unit_write_settingf(u, flags, "CPUQuotaPeriodSec", ++ "CPUQuotaPeriodSec=%s", ++ format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1)); ++ } ++ } ++ ++ return 1; ++ + } else if (STR_IN_SET(name, "AllowedCPUs", "AllowedMemoryNodes")) { + const void *a; + size_t n; +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 23879c001f..4defa82ac1 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -169,6 +169,7 @@ $1.StartupCPUWeight, config_parse_cg_weight, 0, + $1.CPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.cpu_shares) + $1.StartupCPUShares, config_parse_cpu_shares, 0, offsetof($1, cgroup_context.startup_cpu_shares) + $1.CPUQuota, config_parse_cpu_quota, 0, offsetof($1, cgroup_context) ++$1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 1e22013b75..762b106007 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -55,6 +55,7 @@ + #include "unit-name.h" + #include "unit-printf.h" + #include "user-util.h" ++#include "time-util.h" + #include "web-util.h" + + static int supported_socket_protocol_from_string(const char *s) { +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 3c1ecf2027..ec45d6f86d 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -480,6 +480,20 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + ++ if (streq(field, "CPUQuotaPeriodSec")) { ++ usec_t u = USEC_INFINITY; ++ ++ r = parse_sec_def_infinity(eq, &u); ++ if (r < 0) ++ return log_error_errno(r, "CPU quota period '%s' invalid.", eq); ++ ++ r = sd_bus_message_append(m, "(sv)", "CPUQuotaPeriodUSec", "t", u); ++ if (r < 0) ++ return bus_log_create_error(r); ++ ++ return 1; ++ } ++ + if (streq(field, "DeviceAllow")) { + + if (isempty(eq)) +diff --git a/src/test/meson.build b/src/test/meson.build +index ead000e30c..22264d034c 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -513,6 +513,11 @@ tests += [ + [], + '', 'manual'], + ++ [['src/test/test-cgroup-cpu.c'], ++ [libcore, ++ libshared], ++ []], ++ + [['src/test/test-cgroup-mask.c', + 'src/test/test-helper.c'], + [libcore, +diff --git a/src/test/test-cgroup-cpu.c b/src/test/test-cgroup-cpu.c +new file mode 100644 +index 0000000000..a445acc955 +--- /dev/null ++++ b/src/test/test-cgroup-cpu.c +@@ -0,0 +1,38 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "cgroup.h" ++#include "log.h" ++ ++static void test_cgroup_cpu_adjust_period(void) { ++ log_info("/* %s */", __func__); ++ ++ /* Period 1ms, quota 40% -> Period 2.5ms */ ++ assert_se(2500 == cgroup_cpu_adjust_period(USEC_PER_MSEC, 400 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 10ms, quota 10% -> keep. */ ++ assert_se(10 * USEC_PER_MSEC == cgroup_cpu_adjust_period(10 * USEC_PER_MSEC, 100 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 1ms, quota 1000% -> keep. */ ++ assert_se(USEC_PER_MSEC == cgroup_cpu_adjust_period(USEC_PER_MSEC, 10000 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 100ms, quota 30% -> keep. */ ++ assert_se(100 * USEC_PER_MSEC == cgroup_cpu_adjust_period(100 * USEC_PER_MSEC, 300 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 5s, quota 40% -> adjust to 1s. */ ++ assert_se(USEC_PER_SEC == cgroup_cpu_adjust_period(5 * USEC_PER_SEC, 400 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 2s, quota 250% -> adjust to 1s. */ ++ assert_se(USEC_PER_SEC == cgroup_cpu_adjust_period(2 * USEC_PER_SEC, 2500 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 10us, quota 5,000,000% -> adjust to 1ms. */ ++ assert_se(USEC_PER_MSEC == cgroup_cpu_adjust_period(10, 50000000 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 10ms, quota 50,000% -> keep. */ ++ assert_se(10 * USEC_PER_MSEC == cgroup_cpu_adjust_period(10 * USEC_PER_MSEC, 500000 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 10ms, quota 1% -> adjust to 100ms. */ ++ assert_se(100 * USEC_PER_MSEC == cgroup_cpu_adjust_period(10 * USEC_PER_MSEC, 10 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 10ms, quota .001% -> adjust to 1s. */ ++ assert_se(1 * USEC_PER_SEC == cgroup_cpu_adjust_period(10 * USEC_PER_MSEC, 10, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 0ms, quota 200% -> adjust to 1ms. */ ++ assert_se(1 * USEC_PER_MSEC == cgroup_cpu_adjust_period(0, 2 * USEC_PER_SEC, USEC_PER_MSEC, USEC_PER_SEC)); ++ /* Period 0ms, quota 40% -> adjust to 2.5ms. */ ++ assert_se(2500 == cgroup_cpu_adjust_period(0, 400 * USEC_PER_MSEC, USEC_PER_MSEC, USEC_PER_SEC)); ++} ++ ++int main(int argc, char *argv[]) { ++ test_cgroup_cpu_adjust_period(); ++ return 0; ++} diff --git a/SOURCES/0399-core-downgrade-CPUQuotaPeriodSec-clamping-logs-to-de.patch b/SOURCES/0399-core-downgrade-CPUQuotaPeriodSec-clamping-logs-to-de.patch new file mode 100644 index 0000000..e584cb5 --- /dev/null +++ b/SOURCES/0399-core-downgrade-CPUQuotaPeriodSec-clamping-logs-to-de.patch @@ -0,0 +1,66 @@ +From 9d58db234dc9f22a4f551b1b06bd9fc60d085f4d Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Wed, 23 Jan 2019 20:19:44 -0800 +Subject: [PATCH] core: downgrade CPUQuotaPeriodSec= clamping logs to debug + +After the first warning log, further messages are downgraded to LOG_DEBUG. + +(cherry picked from commit 527ede0c638b47b62a87900438a8a09dea42889e) + +Related: #1770379 +--- + src/core/cgroup.c | 3 ++- + src/core/dbus-cgroup.c | 2 ++ + src/core/unit.h | 3 +++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 45fd64a394..f8b351a65d 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -544,9 +544,10 @@ static usec_t cgroup_cpu_adjust_period_and_log(Unit *u, usec_t period, usec_t qu + + if (new_period != period) { + char v[FORMAT_TIMESPAN_MAX]; +- log_unit_full(u, LOG_WARNING, 0, ++ log_unit_full(u, u->warned_clamping_cpu_quota_period ? LOG_DEBUG : LOG_WARNING, 0, + "Clamping CPU interval for cpu.max: period is now %s", + format_timespan(v, sizeof(v), new_period, 1)); ++ u->warned_clamping_cpu_quota_period = true; + } + + return new_period; +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index c8b918e45d..4555b33b1f 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -712,6 +712,7 @@ int bus_cgroup_set_property( + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->cpu_quota_per_sec_usec = u64; ++ u->warned_clamping_cpu_quota_period = false; + unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + + if (c->cpu_quota_per_sec_usec == USEC_INFINITY) +@@ -735,6 +736,7 @@ int bus_cgroup_set_property( + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->cpu_quota_period_usec = u64; ++ u->warned_clamping_cpu_quota_period = false; + unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (c->cpu_quota_period_usec == USEC_INFINITY) + unit_write_setting(u, flags, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec="); +diff --git a/src/core/unit.h b/src/core/unit.h +index 39179f5fd4..b40ff9b961 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -356,6 +356,9 @@ typedef struct Unit { + bool exported_log_rate_limit_interval:1; + bool exported_log_rate_limit_burst:1; + ++ /* Whether we warned about clamping the CPU quota period */ ++ bool warned_clamping_cpu_quota_period:1; ++ + /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If + * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */ + int last_section_private:2; diff --git a/SOURCES/0400-sd-bus-avoid-magic-number-in-SASL-length-calculation.patch b/SOURCES/0400-sd-bus-avoid-magic-number-in-SASL-length-calculation.patch new file mode 100644 index 0000000..f0bf8b7 --- /dev/null +++ b/SOURCES/0400-sd-bus-avoid-magic-number-in-SASL-length-calculation.patch @@ -0,0 +1,41 @@ +From d524f9f9089b71d83e991ed42d25a4616ec575a2 Mon Sep 17 00:00:00 2001 +From: David Rheinsberg +Date: Thu, 14 Mar 2019 13:26:50 +0100 +Subject: [PATCH] sd-bus: avoid magic number in SASL length calculation + +Lets avoid magic numbers and use a constant `strlen()` instead. + +Signed-off-by: David Rheinsberg +(cherry picked from commit 3cacdab925c40a5d9b7cf3f67719201bbaa17f67) + +Related: #1838081 +--- + src/libsystemd/sd-bus/bus-socket.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 4a72795d2b..1c8b331b48 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -390,7 +390,9 @@ static int bus_socket_auth_verify_server(sd_bus *b) { + + if (line_begins(line, l, "AUTH ANONYMOUS")) { + +- r = verify_anonymous_token(b, line + 14, l - 14); ++ r = verify_anonymous_token(b, ++ line + strlen("AUTH ANONYMOUS"), ++ l - strlen("AUTH ANONYMOUS")); + if (r < 0) + return r; + if (r == 0) +@@ -402,7 +404,9 @@ static int bus_socket_auth_verify_server(sd_bus *b) { + + } else if (line_begins(line, l, "AUTH EXTERNAL")) { + +- r = verify_external_token(b, line + 13, l - 13); ++ r = verify_external_token(b, ++ line + strlen("AUTH EXTERNAL"), ++ l - strlen("AUTH EXTERNAL")); + if (r < 0) + return r; + if (r == 0) diff --git a/SOURCES/0401-sd-bus-fix-SASL-reply-to-empty-AUTH.patch b/SOURCES/0401-sd-bus-fix-SASL-reply-to-empty-AUTH.patch new file mode 100644 index 0000000..636fad0 --- /dev/null +++ b/SOURCES/0401-sd-bus-fix-SASL-reply-to-empty-AUTH.patch @@ -0,0 +1,55 @@ +From badb16c481cf592a1761ad20dd0a84614d2bbd5b Mon Sep 17 00:00:00 2001 +From: David Rheinsberg +Date: Thu, 14 Mar 2019 13:33:28 +0100 +Subject: [PATCH] sd-bus: fix SASL reply to empty AUTH + +The correct way to reply to "AUTH " without any payload is to +send "DATA" rather than "OK". The "DATA" reply triggers the client to +respond with the requested payload. + +In fact, adding the data as hex-encoded argument like +"AUTH " is an optimization that skips the "DATA" +roundtrip. The standard way to perform an authentication is to send the +"DATA" line. + +This commit fixes sd-bus to properly send the "DATA" line. Surprisingly +no existing implementation depends on this, as they all pass the data +directly as argument to "AUTH". This will not work if we want to pass +an empty argument, though. + +Signed-off-by: David Rheinsberg +(cherry picked from commit 2010873b4b49b223e0cc07d28205b09c693ef005) + +Related: #1838081 +--- + src/libsystemd/sd-bus/bus-socket.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 1c8b331b48..e505d43c6b 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -399,7 +399,10 @@ static int bus_socket_auth_verify_server(sd_bus *b) { + r = bus_socket_auth_write(b, "REJECTED\r\n"); + else { + b->auth = BUS_AUTH_ANONYMOUS; +- r = bus_socket_auth_write_ok(b); ++ if (l <= strlen("AUTH ANONYMOUS")) ++ r = bus_socket_auth_write(b, "DATA\r\n"); ++ else ++ r = bus_socket_auth_write_ok(b); + } + + } else if (line_begins(line, l, "AUTH EXTERNAL")) { +@@ -413,7 +416,10 @@ static int bus_socket_auth_verify_server(sd_bus *b) { + r = bus_socket_auth_write(b, "REJECTED\r\n"); + else { + b->auth = BUS_AUTH_EXTERNAL; +- r = bus_socket_auth_write_ok(b); ++ if (l <= strlen("AUTH EXTERNAL")) ++ r = bus_socket_auth_write(b, "DATA\r\n"); ++ else ++ r = bus_socket_auth_write_ok(b); + } + + } else if (line_begins(line, l, "AUTH")) diff --git a/SOURCES/0402-sd-bus-skip-sending-formatted-UIDs-via-SASL.patch b/SOURCES/0402-sd-bus-skip-sending-formatted-UIDs-via-SASL.patch new file mode 100644 index 0000000..063be89 --- /dev/null +++ b/SOURCES/0402-sd-bus-skip-sending-formatted-UIDs-via-SASL.patch @@ -0,0 +1,210 @@ +From ccdb8883c6ff0e72d5e221768af0718e25cbf177 Mon Sep 17 00:00:00 2001 +From: David Rheinsberg +Date: Thu, 14 Mar 2019 13:34:13 +0100 +Subject: [PATCH] sd-bus: skip sending formatted UIDs via SASL + +The dbus external authentication takes as optional argument the UID the +sender wants to authenticate as. This uid is purely optional. The +AF_UNIX socket already conveys the same information through the +auxiliary socket data, so we really don't have to provide that +information. + +Unfortunately, there is no way to send empty arguments, since they are +interpreted as "missing argument", which has a different meaning. The +SASL negotiation thus changes from: + + AUTH EXTERNAL + NEGOTIATE_UNIX_FD (optional) + BEGIN + +to: + + AUTH EXTERNAL + DATA + NEGOTIATE_UNIX_FD (optional) + BEGIN + +And thus the replies we expect as a client change from: + + OK + AGREE_UNIX_FD (optional) + +to: + + DATA + OK + AGREE_UNIX_FD (optional) + +Since the old sd-bus server implementation used the wrong reply for +"AUTH" requests that do not carry the arguments inlined, we decided to +make sd-bus clients accept this as well. Hence, sd-bus now allows +"OK \r\n" replies instead of "DATA\r\n" replies. + +Signed-off-by: David Rheinsberg +(cherry picked from commit 1ed4723d38cd0d1423c8fe650f90fa86007ddf55) + +Resolves: #1838081 +--- + src/libsystemd/sd-bus/bus-socket.c | 106 +++++++++++++++++------------ + 1 file changed, 64 insertions(+), 42 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index e505d43c6b..8813dd5efd 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -162,17 +162,25 @@ static int bus_socket_write_auth(sd_bus *b) { + } + + static int bus_socket_auth_verify_client(sd_bus *b) { +- char *e, *f, *start; ++ char *d, *e, *f, *start; + sd_id128_t peer; + unsigned i; + int r; + + assert(b); + +- /* We expect two response lines: "OK" and possibly +- * "AGREE_UNIX_FD" */ ++ /* ++ * We expect three response lines: ++ * "DATA\r\n" ++ * "OK \r\n" ++ * "AGREE_UNIX_FD\r\n" (optional) ++ */ + +- e = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2); ++ d = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2); ++ if (!d) ++ return 0; ++ ++ e = memmem(d + 2, b->rbuffer_size - (d - (char*) b->rbuffer) - 2, "\r\n", 2); + if (!e) + return 0; + +@@ -187,13 +195,30 @@ static int bus_socket_auth_verify_client(sd_bus *b) { + start = e + 2; + } + +- /* Nice! We got all the lines we need. First check the OK +- * line */ ++ /* Nice! We got all the lines we need. First check the DATA line. */ ++ ++ if (d - (char*) b->rbuffer == 4) { ++ if (memcmp(b->rbuffer, "DATA", 4)) ++ return -EPERM; ++ } else if (d - (char*) b->rbuffer == 3 + 32) { ++ /* ++ * Old versions of the server-side implementation of `sd-bus` replied with "OK " to ++ * "AUTH" requests from a client, even if the "AUTH" line did not contain inlined ++ * arguments. Therefore, we also accept "OK " here, even though it is technically the ++ * wrong reply. We ignore the "" parameter, though, since it has no real value. ++ */ ++ if (memcmp(b->rbuffer, "OK ", 3)) ++ return -EPERM; ++ } else { ++ return -EPERM; ++ } ++ ++ /* Now check the OK line. */ + +- if (e - (char*) b->rbuffer != 3 + 32) ++ if (e - d != 2 + 3 + 32) + return -EPERM; + +- if (memcmp(b->rbuffer, "OK ", 3)) ++ if (memcmp(d + 2, "OK ", 3)) + return -EPERM; + + b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL; +@@ -201,8 +226,8 @@ static int bus_socket_auth_verify_client(sd_bus *b) { + for (i = 0; i < 32; i += 2) { + int x, y; + +- x = unhexchar(((char*) b->rbuffer)[3 + i]); +- y = unhexchar(((char*) b->rbuffer)[3 + i + 1]); ++ x = unhexchar(d[2 + 3 + i]); ++ y = unhexchar(d[2 + 3 + i + 1]); + + if (x < 0 || y < 0) + return -EINVAL; +@@ -216,7 +241,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) { + + b->server_id = peer; + +- /* And possibly check the second line, too */ ++ /* And possibly check the third line, too */ + + if (f) + b->can_fds = +@@ -616,42 +641,39 @@ static void bus_get_peercred(sd_bus *b) { + } + + static int bus_socket_start_auth_client(sd_bus *b) { +- size_t l; +- const char *auth_suffix, *auth_prefix; ++ static const char sasl_auth_anonymous[] = { ++ /* ++ * We use an arbitrary trace-string for the ANONYMOUS authentication. It can be used by the ++ * message broker to aid debugging of clients. We fully anonymize the connection and use a ++ * static default. ++ */ ++ "\0AUTH ANONYMOUS\r\n" ++ /* HEX a n o n y m o u s */ ++ "DATA 616e6f6e796d6f7573\r\n" ++ }; ++ static const char sasl_auth_external[] = { ++ "\0AUTH EXTERNAL\r\n" ++ "DATA\r\n" ++ }; ++ static const char sasl_negotiate_unix_fd[] = { ++ "NEGOTIATE_UNIX_FD\r\n" ++ }; ++ static const char sasl_begin[] = { ++ "BEGIN\r\n" ++ }; ++ size_t i = 0; + + assert(b); + +- if (b->anonymous_auth) { +- auth_prefix = "\0AUTH ANONYMOUS "; +- +- /* For ANONYMOUS auth we send some arbitrary "trace" string */ +- l = 9; +- b->auth_buffer = hexmem("anonymous", l); +- } else { +- char text[DECIMAL_STR_MAX(uid_t) + 1]; +- +- auth_prefix = "\0AUTH EXTERNAL "; +- +- xsprintf(text, UID_FMT, geteuid()); +- +- l = strlen(text); +- b->auth_buffer = hexmem(text, l); +- } +- +- if (!b->auth_buffer) +- return -ENOMEM; ++ if (b->anonymous_auth) ++ b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_anonymous, sizeof(sasl_auth_anonymous) - 1); ++ else ++ b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_external, sizeof(sasl_auth_external) - 1); + + if (b->accept_fd) +- auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n"; +- else +- auth_suffix = "\r\nBEGIN\r\n"; +- +- b->auth_iovec[0].iov_base = (void*) auth_prefix; +- b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1); +- b->auth_iovec[1].iov_base = (void*) b->auth_buffer; +- b->auth_iovec[1].iov_len = l * 2; +- b->auth_iovec[2].iov_base = (void*) auth_suffix; +- b->auth_iovec[2].iov_len = strlen(auth_suffix); ++ b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_negotiate_unix_fd); ++ ++ b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_begin); + + return bus_socket_write_auth(b); + } diff --git a/SOURCES/0403-core-add-MemoryMin.patch b/SOURCES/0403-core-add-MemoryMin.patch new file mode 100644 index 0000000..eadeaed --- /dev/null +++ b/SOURCES/0403-core-add-MemoryMin.patch @@ -0,0 +1,231 @@ +From 04f21709ff081a5f1a2b5ca746582a9c5c03db7f Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Fri, 8 Jun 2018 17:33:14 -0700 +Subject: [PATCH] core: add MemoryMin + +The kernel added support for a new cgroup memory controller knob memory.min in +bf8d5d52ffe8 ("memcg: introduce memory.min") which was merged during v4.18 +merge window. + +Add MemoryMin to support memory.min. + +(cherry picked from commit 484226357789991de0b3363beb69258be06b4c92) + +Resolves: #1763435 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.resource-control.xml | 21 +++++++++++++++++++++ + src/core/cgroup.c | 5 ++++- + src/core/cgroup.h | 1 + + src/core/dbus-cgroup.c | 7 +++++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/load-fragment.c | 4 +++- + src/shared/bus-unit-util.c | 2 +- + src/systemctl/systemctl.c | 11 +++++++++-- + 9 files changed, 48 insertions(+), 5 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 0d2d3e9065..93865c0333 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -222,6 +222,7 @@ All cgroup/resource control settings are available for transient units + ✓ AllowedCPUs= + ✓ AllowedMemoryNodes= + ✓ MemoryAccounting= ++✓ MemoryMin= + ✓ MemoryLow= + ✓ MemoryHigh= + ✓ MemoryMax= +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index cfe19a6574..63a0c87565 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -265,6 +265,27 @@ + + + ++ ++ MemoryMin=bytes ++ ++ ++ Specify the memory usage protection of the executed processes in this unit. If the memory usages of ++ this unit and all its ancestors are below their minimum boundaries, this unit's memory won't be reclaimed. ++ ++ 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. This controls the memory.min control group attribute. For details about this ++ control group attribute, see cgroup-v2.txt. ++ ++ Implies MemoryAccounting=true. ++ ++ This setting is supported only if the unified control group hierarchy is used and disables ++ MemoryLimit=. ++ ++ ++ + + MemoryLow=bytes + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f8b351a65d..9d09c65453 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -220,6 +220,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sStartupIOWeight=%" PRIu64 "\n" + "%sBlockIOWeight=%" PRIu64 "\n" + "%sStartupBlockIOWeight=%" PRIu64 "\n" ++ "%sMemoryMin=%" PRIu64 "\n" + "%sMemoryLow=%" PRIu64 "\n" + "%sMemoryHigh=%" PRIu64 "\n" + "%sMemoryMax=%" PRIu64 "\n" +@@ -246,6 +247,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + prefix, c->startup_io_weight, + prefix, c->blockio_weight, + prefix, c->startup_blockio_weight, ++ prefix, c->memory_min, + prefix, c->memory_low, + prefix, c->memory_high, + prefix, c->memory_max, +@@ -777,7 +779,7 @@ static void cgroup_apply_blkio_device_limit(Unit *u, const char *dev_path, uint6 + } + + static bool cgroup_context_has_unified_memory_config(CGroupContext *c) { +- return c->memory_low > 0 || c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || c->memory_swap_max != CGROUP_LIMIT_MAX; ++ return c->memory_min > 0 || c->memory_low > 0 || c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || c->memory_swap_max != CGROUP_LIMIT_MAX; + } + + static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) { +@@ -1035,6 +1037,7 @@ static void cgroup_context_apply( + log_cgroup_compat(u, "Applying MemoryLimit %" PRIu64 " as MemoryMax", max); + } + ++ cgroup_apply_unified_memory_limit(u, "memory.min", c->memory_min); + cgroup_apply_unified_memory_limit(u, "memory.low", c->memory_low); + cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high); + cgroup_apply_unified_memory_limit(u, "memory.max", max); +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 2ba57d3ded..5e1be87b20 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -95,6 +95,7 @@ struct CGroupContext { + LIST_HEAD(CGroupIODeviceLimit, io_device_limits); + LIST_HEAD(CGroupIODeviceLatency, io_device_latencies); + ++ uint64_t memory_min; + uint64_t memory_low; + uint64_t memory_high; + uint64_t memory_max; +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 4555b33b1f..6ce5984a02 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -353,6 +353,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0), + SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0), + SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0), ++ SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0), + SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0), + SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0), + SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0), +@@ -661,6 +662,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryAccounting")) + return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error); + ++ if (streq(name, "MemoryMin")) ++ return bus_cgroup_set_memory(u, name, &c->memory_min, message, flags, error); ++ + if (streq(name, "MemoryLow")) + return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); + +@@ -676,6 +680,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLimit")) + return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); + ++ if (streq(name, "MemoryMinScale")) ++ return bus_cgroup_set_memory_scale(u, name, &c->memory_min, message, flags, error); ++ + if (streq(name, "MemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 4defa82ac1..1c6e539f30 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -171,6 +171,7 @@ $1.StartupCPUShares, config_parse_cpu_shares, 0, + $1.CPUQuota, config_parse_cpu_quota, 0, offsetof($1, cgroup_context) + $1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) ++$1.MemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryMax, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 762b106007..d43b0f08f9 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3096,7 +3096,9 @@ int config_parse_memory_limit( + } + } + +- if (streq(lvalue, "MemoryLow")) ++ if (streq(lvalue, "MemoryMin")) ++ c->memory_min = bytes; ++ else if (streq(lvalue, "MemoryLow")) + c->memory_low = bytes; + else if (streq(lvalue, "MemoryHigh")) + c->memory_high = bytes; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index ec45d6f86d..203c068d02 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -429,7 +429,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { ++ if (STR_IN_SET(field, "MemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { + + if (isempty(eq) || streq(eq, "infinity")) { + r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX); +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 559e49f104..35ad20f510 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3905,6 +3905,7 @@ typedef struct UnitStatusInfo { + + /* CGroup */ + uint64_t memory_current; ++ uint64_t memory_min; + uint64_t memory_low; + uint64_t memory_high; + uint64_t memory_max; +@@ -4284,12 +4285,17 @@ static void print_status_info( + + printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current)); + +- if (i->memory_low > 0 || i->memory_high != CGROUP_LIMIT_MAX || +- i->memory_max != CGROUP_LIMIT_MAX || i->memory_swap_max != CGROUP_LIMIT_MAX || ++ if (i->memory_min > 0 || i->memory_low > 0 || ++ i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX || ++ i->memory_swap_max != CGROUP_LIMIT_MAX || + i->memory_limit != CGROUP_LIMIT_MAX) { + const char *prefix = ""; + + printf(" ("); ++ if (i->memory_min > 0) { ++ printf("%smin: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_min)); ++ prefix = " "; ++ } + if (i->memory_low > 0) { + printf("%slow: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_low)); + prefix = " "; +@@ -5022,6 +5028,7 @@ static int show_one( + { "Where", "s", NULL, offsetof(UnitStatusInfo, where) }, + { "What", "s", NULL, offsetof(UnitStatusInfo, what) }, + { "MemoryCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_current) }, ++ { "MemoryMin", "t", NULL, offsetof(UnitStatusInfo, memory_min) }, + { "MemoryLow", "t", NULL, offsetof(UnitStatusInfo, memory_low) }, + { "MemoryHigh", "t", NULL, offsetof(UnitStatusInfo, memory_high) }, + { "MemoryMax", "t", NULL, offsetof(UnitStatusInfo, memory_max) }, diff --git a/SOURCES/0404-core-introduce-cgroup_add_device_allow.patch b/SOURCES/0404-core-introduce-cgroup_add_device_allow.patch new file mode 100644 index 0000000..351e10a --- /dev/null +++ b/SOURCES/0404-core-introduce-cgroup_add_device_allow.patch @@ -0,0 +1,98 @@ +From d8024b3de8ce376cdea48ffa59a44b050f215470 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 6 Aug 2018 13:42:14 +0900 +Subject: [PATCH] core: introduce cgroup_add_device_allow() + +(cherry picked from commit fd870bac25c2dd36affaed0251b5a7023f635306) + +Related: #1763435 +--- + src/core/cgroup.c | 29 +++++++++++++++++++++++++++++ + src/core/cgroup.h | 2 ++ + src/core/load-fragment.c | 13 +------------ + 3 files changed, 32 insertions(+), 12 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 9d09c65453..a17b38f914 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -341,6 +341,35 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + } + } + ++int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode) { ++ _cleanup_free_ CGroupDeviceAllow *a = NULL; ++ _cleanup_free_ char *d = NULL; ++ ++ assert(c); ++ assert(dev); ++ assert(isempty(mode) || in_charset(mode, "rwm")); ++ ++ a = new(CGroupDeviceAllow, 1); ++ if (!a) ++ return -ENOMEM; ++ ++ d = strdup(dev); ++ if (!d) ++ return -ENOMEM; ++ ++ *a = (CGroupDeviceAllow) { ++ .path = TAKE_PTR(d), ++ .r = isempty(mode) || !!strchr(mode, 'r'), ++ .w = isempty(mode) || !!strchr(mode, 'w'), ++ .m = isempty(mode) || !!strchr(mode, 'm'), ++ }; ++ ++ LIST_PREPEND(device_allow, c->device_allow, a); ++ TAKE_PTR(a); ++ ++ return 0; ++} ++ + static int lookup_block_device(const char *p, dev_t *ret) { + struct stat st; + int r; +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 5e1be87b20..8102b442b8 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -153,6 +153,8 @@ void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLaten + void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); + void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); + ++int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode); ++ + CGroupMask unit_get_own_mask(Unit *u); + CGroupMask unit_get_delegate_mask(Unit *u); + CGroupMask unit_get_members_mask(Unit *u); +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index d43b0f08f9..89a3457acc 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3250,7 +3250,6 @@ int config_parse_device_allow( + + _cleanup_free_ char *path = NULL, *resolved = NULL; + CGroupContext *c = data; +- CGroupDeviceAllow *a; + const char *p = rvalue; + int r; + +@@ -3299,17 +3298,7 @@ int config_parse_device_allow( + return 0; + } + +- a = new0(CGroupDeviceAllow, 1); +- if (!a) +- return log_oom(); +- +- a->path = TAKE_PTR(resolved); +- a->r = isempty(p) || !!strchr(p, 'r'); +- a->w = isempty(p) || !!strchr(p, 'w'); +- a->m = isempty(p) || !!strchr(p, 'm'); +- +- LIST_PREPEND(device_allow, c->device_allow, a); +- return 0; ++ return cgroup_add_device_allow(c, resolved, p); + } + + int config_parse_io_device_weight( diff --git a/SOURCES/0405-test-remove-support-for-suffix-in-get_testdata_dir.patch b/SOURCES/0405-test-remove-support-for-suffix-in-get_testdata_dir.patch new file mode 100644 index 0000000..811da17 --- /dev/null +++ b/SOURCES/0405-test-remove-support-for-suffix-in-get_testdata_dir.patch @@ -0,0 +1,302 @@ +From e73aa709bff2eb5c4649ed7c7055f29ca42f52aa Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 11 Sep 2018 23:15:09 -0700 +Subject: [PATCH] test: remove support for suffix in get_testdata_dir() + +Instead, use path_join() in callers wherever needed. + +(cherry picked from commit 55890a40c3ec0c061c04d1395a38c26313132d12) + +Related: #1763435 +--- + src/resolve/test-dns-packet.c | 5 ++++- + src/shared/tests.c | 4 +--- + src/shared/tests.h | 2 +- + src/test/test-bpf.c | 2 +- + src/test/test-cgroup-mask.c | 2 +- + src/test/test-engine.c | 2 +- + src/test/test-execute.c | 3 ++- + src/test/test-journal-importer.c | 10 ++++++++-- + src/test/test-path.c | 5 ++++- + src/test/test-sched-prio.c | 2 +- + src/test/test-umount.c | 18 ++++++++++++++---- + src/test/test-watch-pid.c | 2 +- + 12 files changed, 39 insertions(+), 18 deletions(-) + +diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c +index 905f000dc2..0dac05e7be 100644 +--- a/src/resolve/test-dns-packet.c ++++ b/src/resolve/test-dns-packet.c +@@ -12,6 +12,7 @@ + #include "macro.h" + #include "resolved-dns-packet.h" + #include "resolved-dns-rr.h" ++#include "path-util.h" + #include "string-util.h" + #include "strv.h" + #include "tests.h" +@@ -92,6 +93,7 @@ static void test_packet_from_file(const char* filename, bool canonical) { + + int main(int argc, char **argv) { + int i, N; ++ _cleanup_free_ char *pkts_glob = NULL; + _cleanup_globfree_ glob_t g = {}; + char **fnames; + +@@ -101,7 +103,8 @@ int main(int argc, char **argv) { + N = argc - 1; + fnames = argv + 1; + } else { +- assert_se(glob(get_testdata_dir("/test-resolve/*.pkts"), GLOB_NOSORT, NULL, &g) == 0); ++ pkts_glob = path_join(NULL, get_testdata_dir(), "test-resolve/*.pkts"); ++ assert_se(glob(pkts_glob, GLOB_NOSORT, NULL, &g) == 0); + N = g.gl_pathc; + fnames = g.gl_pathv; + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index c77eb00924..100b62b9b0 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -37,7 +37,7 @@ bool test_is_running_from_builddir(char **exedir) { + return r; + } + +-const char* get_testdata_dir(const char *suffix) { ++const char* get_testdata_dir(void) { + const char *env; + /* convenience: caller does not need to free result */ + static char testdir[PATH_MAX]; +@@ -61,14 +61,12 @@ const char* get_testdata_dir(const char *suffix) { + /* Try relative path, according to the install-test layout */ + assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", exedir) > 0); + +- /* test this without the suffix, as it may contain a glob */ + if (access(testdir, F_OK) < 0) { + fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr); + exit(EXIT_FAILURE); + } + } + +- strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1); + return testdir; + } + +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 7f45c32d32..3d696d02fd 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -3,5 +3,5 @@ + + char* setup_fake_runtime_dir(void); + bool test_is_running_from_builddir(char **exedir); +-const char* get_testdata_dir(const char *suffix); ++const char* get_testdata_dir(void); + void test_setup_logging(int level); +diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c +index 4d89bd46d3..6f4a22a1cc 100644 +--- a/src/test/test-bpf.c ++++ b/src/test/test-bpf.c +@@ -38,7 +38,7 @@ int main(int argc, char *argv[]) { + return EXIT_TEST_SKIP; + } + +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p); +diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c +index 93c3f5d856..ed2d810dd6 100644 +--- a/src/test/test-cgroup-mask.c ++++ b/src/test/test-cgroup-mask.c +@@ -26,7 +26,7 @@ static int test_cgroup_mask(void) { + } + + /* Prepare the manager. */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (IN_SET(r, -EPERM, -EACCES)) { +diff --git a/src/test/test-engine.c b/src/test/test-engine.c +index d072a15cb1..0f3e244dc1 100644 +--- a/src/test/test-engine.c ++++ b/src/test/test-engine.c +@@ -29,7 +29,7 @@ int main(int argc, char *argv[]) { + } + + /* prepare the test */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (MANAGER_SKIP_TEST(r)) { +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 882e866ea9..294f8fe7dd 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -815,7 +815,8 @@ int main(int argc, char *argv[]) { + } + + assert_se(runtime_dir = setup_fake_runtime_dir()); +- assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0); ++ test_execute_path = path_join(NULL, get_testdata_dir(), "test-execute"); ++ assert_se(set_unit_path(test_execute_path) >= 0); + + /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test + * cases, otherwise (and if they are present in the environment), +diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c +index 56bf6a1296..8f09d5ad2f 100644 +--- a/src/test/test-journal-importer.c ++++ b/src/test/test-journal-importer.c +@@ -4,8 +4,10 @@ + #include + #include + ++#include "alloc-util.h" + #include "log.h" + #include "journal-importer.h" ++#include "path-util.h" + #include "string-util.h" + #include "tests.h" + +@@ -20,9 +22,11 @@ static void assert_iovec_entry(const struct iovec *iovec, const char* content) { + + static void test_basic_parsing(void) { + _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; ++ _cleanup_free_ char *journal_data_path = NULL; + int r; + +- imp.fd = open(get_testdata_dir("/journal-data/journal-1.txt"), O_RDONLY|O_CLOEXEC); ++ journal_data_path = path_join(NULL, get_testdata_dir(), "journal-data/journal-1.txt"); ++ imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); + assert_se(imp.fd >= 0); + + do +@@ -49,9 +53,11 @@ static void test_basic_parsing(void) { + + static void test_bad_input(void) { + _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; ++ _cleanup_free_ char *journal_data_path = NULL; + int r; + +- imp.fd = open(get_testdata_dir("/journal-data/journal-2.txt"), O_RDONLY|O_CLOEXEC); ++ journal_data_path = path_join(NULL, get_testdata_dir(), "journal-data/journal-2.txt"); ++ imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); + assert_se(imp.fd >= 0); + + do +diff --git a/src/test/test-path.c b/src/test/test-path.c +index 3a1469ae02..faae142696 100644 +--- a/src/test/test-path.c ++++ b/src/test/test-path.c +@@ -12,6 +12,7 @@ + #include "macro.h" + #include "manager.h" + #include "mkdir.h" ++#include "path-util.h" + #include "rm-rf.h" + #include "string-util.h" + #include "strv.h" +@@ -247,6 +248,7 @@ int main(int argc, char *argv[]) { + }; + + _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; ++ _cleanup_free_ char *test_path = NULL; + const test_function_t *test = NULL; + Manager *m = NULL; + +@@ -255,7 +257,8 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + +- assert_se(set_unit_path(get_testdata_dir("/test-path")) >= 0); ++ test_path = path_join(NULL, get_testdata_dir(), "test-path"); ++ assert_se(set_unit_path(test_path) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + for (test = tests; test && *test; test++) { +diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c +index c986284155..60012e47d2 100644 +--- a/src/test/test-sched-prio.c ++++ b/src/test/test-sched-prio.c +@@ -26,7 +26,7 @@ int main(int argc, char *argv[]) { + } + + /* prepare the test */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (MANAGER_SKIP_TEST(r)) { +diff --git a/src/test/test-umount.c b/src/test/test-umount.c +index 770d1a73c8..c068f7a0f0 100644 +--- a/src/test/test-umount.c ++++ b/src/test/test-umount.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include "alloc-util.h" + #include "log.h" ++#include "path-util.h" + #include "string-util.h" + #include "tests.h" + #include "umount.h" +@@ -8,10 +10,14 @@ + + static void test_mount_points_list(const char *fname) { + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); ++ _cleanup_free_ char *testdata_fname = NULL; + MountPoint *m; + + log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo"); + ++ if (fname) ++ fname = testdata_fname = path_join(NULL, get_testdata_dir(), fname); ++ + LIST_HEAD_INIT(mp_list_head); + assert_se(mount_points_list_get(fname, &mp_list_head) >= 0); + +@@ -26,10 +32,14 @@ static void test_mount_points_list(const char *fname) { + + static void test_swap_list(const char *fname) { + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); ++ _cleanup_free_ char *testdata_fname = NULL; + MountPoint *m; + + log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/swaps"); + ++ if (fname) ++ fname = testdata_fname = path_join(NULL, get_testdata_dir(), fname); ++ + LIST_HEAD_INIT(mp_list_head); + assert_se(swap_list_get(fname, &mp_list_head) >= 0); + +@@ -48,10 +58,10 @@ int main(int argc, char **argv) { + log_open(); + + test_mount_points_list(NULL); +- test_mount_points_list(get_testdata_dir("/test-umount/empty.mountinfo")); +- test_mount_points_list(get_testdata_dir("/test-umount/garbled.mountinfo")); +- test_mount_points_list(get_testdata_dir("/test-umount/rhbug-1554943.mountinfo")); ++ test_mount_points_list("/test-umount/empty.mountinfo"); ++ test_mount_points_list("/test-umount/garbled.mountinfo"); ++ test_mount_points_list("/test-umount/rhbug-1554943.mountinfo"); + + test_swap_list(NULL); +- test_swap_list(get_testdata_dir("/test-umount/example.swaps")); ++ test_swap_list("/test-umount/example.swaps"); + } +diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c +index 8c70175aed..d6e2886dde 100644 +--- a/src/test/test-watch-pid.c ++++ b/src/test/test-watch-pid.c +@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { + return EXIT_TEST_SKIP; + } + +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + assert_se(manager_new(UNIT_FILE_USER, true, &m) >= 0); diff --git a/SOURCES/0406-cgroup-Implement-default-propagation-of-MemoryLow-wi.patch b/SOURCES/0406-cgroup-Implement-default-propagation-of-MemoryLow-wi.patch new file mode 100644 index 0000000..cbd2d37 --- /dev/null +++ b/SOURCES/0406-cgroup-Implement-default-propagation-of-MemoryLow-wi.patch @@ -0,0 +1,695 @@ +From f45cb6d6a2c247c7594d9965cbb745303adb61d6 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Thu, 28 Mar 2019 12:50:50 +0000 +Subject: [PATCH] cgroup: Implement default propagation of MemoryLow with + DefaultMemoryLow + +In cgroup v2 we have protection tunables -- currently MemoryLow and +MemoryMin (there will be more in future for other resources, too). The +design of these protection tunables requires not only intermediate +cgroups to propagate protections, but also the units at the leaf of that +resource's operation to accept it (by setting MemoryLow or MemoryMin). + +This makes sense from an low-level API design perspective, but it's a +good idea to also have a higher-level abstraction that can, by default, +propagate these resources to children recursively. In this patch, this +happens by having descendants set memory.low to N if their ancestor has +DefaultMemoryLow=N -- assuming they don't set a separate MemoryLow +value. + +Any affected unit can opt out of this propagation by manually setting +`MemoryLow` to some value in its unit configuration. A unit can also +stop further propagation by setting `DefaultMemoryLow=` with no +argument. This removes further propagation in the subtree, but has no +effect on the unit itself (for that, use `MemoryLow=0`). + +Our use case in production is simplifying the configuration of machines +which heavily rely on memory protection tunables, but currently require +tweaking a huge number of unit files to make that a reality. This +directive makes that significantly less fragile, and decreases the risk +of misconfiguration. + +After this patch is merged, I will implement DefaultMemoryMin= using the +same principles. + +(cherry picked from commit c52db42b78f6fbeb7792cc4eca27e2767a48b6ca) + +Related: #1763435 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.resource-control.xml | 4 + + src/core/cgroup.c | 58 +++++++++-- + src/core/cgroup.h | 6 ++ + src/core/dbus-cgroup.c | 7 ++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/load-fragment.c | 13 ++- + src/shared/bus-unit-util.c | 2 +- + src/shared/bus-util.c | 2 +- + src/systemctl/systemctl.c | 3 + + src/test/meson.build | 6 ++ + src/test/test-cgroup-unit-default.c | 145 ++++++++++++++++++++++++++ + test/dml-discard-empty.service | 7 ++ + test/dml-discard-set-ml.service | 8 ++ + test/dml-discard.slice | 5 + + test/dml-override-empty.service | 7 ++ + test/dml-override.slice | 5 + + test/dml-passthrough-empty.service | 7 ++ + test/dml-passthrough-set-dml.service | 8 ++ + test/dml-passthrough-set-ml.service | 8 ++ + test/dml-passthrough.slice | 5 + + test/dml.slice | 5 + + test/meson.build | 10 ++ + 23 files changed, 310 insertions(+), 13 deletions(-) + create mode 100644 src/test/test-cgroup-unit-default.c + create mode 100644 test/dml-discard-empty.service + create mode 100644 test/dml-discard-set-ml.service + create mode 100644 test/dml-discard.slice + create mode 100644 test/dml-override-empty.service + create mode 100644 test/dml-override.slice + create mode 100644 test/dml-passthrough-empty.service + create mode 100644 test/dml-passthrough-set-dml.service + create mode 100644 test/dml-passthrough-set-ml.service + create mode 100644 test/dml-passthrough.slice + create mode 100644 test/dml.slice + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 93865c0333..5a8fa0727e 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -223,6 +223,7 @@ All cgroup/resource control settings are available for transient units + ✓ AllowedMemoryNodes= + ✓ MemoryAccounting= + ✓ MemoryMin= ++✓ DefaultMemoryLow= + ✓ MemoryLow= + ✓ MemoryHigh= + ✓ MemoryMax= +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 63a0c87565..27f16001dd 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -305,6 +305,10 @@ + + This setting is supported only if the unified control group hierarchy is used and disables + MemoryLimit=. ++ ++ Units may can have their children use a default memory.low value by specifying ++ DefaultMemoryLow=, which has the same usage as MemoryLow=. This setting ++ does not affect memory.low in the unit itself. + + + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index a17b38f914..f804bf4727 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -220,6 +220,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sStartupIOWeight=%" PRIu64 "\n" + "%sBlockIOWeight=%" PRIu64 "\n" + "%sStartupBlockIOWeight=%" PRIu64 "\n" ++ "%sDefaultMemoryLow=%" PRIu64 "\n" + "%sMemoryMin=%" PRIu64 "\n" + "%sMemoryLow=%" PRIu64 "\n" + "%sMemoryHigh=%" PRIu64 "\n" +@@ -247,6 +248,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + prefix, c->startup_io_weight, + prefix, c->blockio_weight, + prefix, c->startup_blockio_weight, ++ prefix, c->default_memory_low, + prefix, c->memory_min, + prefix, c->memory_low, + prefix, c->memory_high, +@@ -370,6 +372,32 @@ int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode) + return 0; + } + ++uint64_t unit_get_ancestor_memory_low(Unit *u) { ++ CGroupContext *c; ++ ++ /* 1. Is MemoryLow set in this unit? If so, use that. ++ * 2. Is DefaultMemoryLow set in any ancestor? If so, use that. ++ * 3. Otherwise, return CGROUP_LIMIT_MIN. */ ++ ++ assert(u); ++ ++ c = unit_get_cgroup_context(u); ++ ++ if (c->memory_low_set) ++ return c->memory_low; ++ ++ while (UNIT_ISSET(u->slice)) { ++ u = UNIT_DEREF(u->slice); ++ c = unit_get_cgroup_context(u); ++ ++ if (c->default_memory_low_set) ++ return c->default_memory_low; ++ } ++ ++ /* We've reached the root, but nobody had DefaultMemoryLow set, so set it to the kernel default. */ ++ return CGROUP_LIMIT_MIN; ++} ++ + static int lookup_block_device(const char *p, dev_t *ret) { + struct stat st; + int r; +@@ -807,8 +835,17 @@ static void cgroup_apply_blkio_device_limit(Unit *u, const char *dev_path, uint6 + "Failed to set blkio.throttle.write_bps_device: %m"); + } + +-static bool cgroup_context_has_unified_memory_config(CGroupContext *c) { +- return c->memory_min > 0 || c->memory_low > 0 || c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || c->memory_swap_max != CGROUP_LIMIT_MAX; ++static bool unit_has_unified_memory_config(Unit *u) { ++ CGroupContext *c; ++ ++ assert(u); ++ ++ c = unit_get_cgroup_context(u); ++ assert(c); ++ ++ return c->memory_min > 0 || unit_get_ancestor_memory_low(u) > 0 || ++ c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || ++ c->memory_swap_max != CGROUP_LIMIT_MAX; + } + + static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) { +@@ -1056,7 +1093,7 @@ static void cgroup_context_apply( + if (cg_all_unified() > 0) { + uint64_t max, swap_max = CGROUP_LIMIT_MAX; + +- if (cgroup_context_has_unified_memory_config(c)) { ++ if (unit_has_unified_memory_config(u)) { + max = c->memory_max; + swap_max = c->memory_swap_max; + } else { +@@ -1067,7 +1104,7 @@ static void cgroup_context_apply( + } + + cgroup_apply_unified_memory_limit(u, "memory.min", c->memory_min); +- cgroup_apply_unified_memory_limit(u, "memory.low", c->memory_low); ++ cgroup_apply_unified_memory_limit(u, "memory.low", unit_get_ancestor_memory_low(u)); + cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high); + cgroup_apply_unified_memory_limit(u, "memory.max", max); + cgroup_apply_unified_memory_limit(u, "memory.swap.max", swap_max); +@@ -1075,7 +1112,7 @@ static void cgroup_context_apply( + char buf[DECIMAL_STR_MAX(uint64_t) + 1]; + uint64_t val; + +- if (cgroup_context_has_unified_memory_config(c)) { ++ if (unit_has_unified_memory_config(u)) { + val = c->memory_max; + log_cgroup_compat(u, "Applying MemoryMax %" PRIi64 " as MemoryLimit", val); + } else +@@ -1204,8 +1241,13 @@ static void cgroup_context_apply( + cgroup_apply_firewall(u); + } + +-CGroupMask cgroup_context_get_mask(CGroupContext *c) { ++static CGroupMask unit_get_cgroup_mask(Unit *u) { + CGroupMask mask = 0; ++ CGroupContext *c; ++ ++ assert(u); ++ ++ c = unit_get_cgroup_context(u); + + /* Figure out which controllers we need */ + +@@ -1223,7 +1265,7 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) { + + if (c->memory_accounting || + c->memory_limit != CGROUP_LIMIT_MAX || +- cgroup_context_has_unified_memory_config(c)) ++ unit_has_unified_memory_config(u)) + mask |= CGROUP_MASK_MEMORY; + + if (c->device_allow || +@@ -1246,7 +1288,7 @@ CGroupMask unit_get_own_mask(Unit *u) { + if (!c) + return 0; + +- return cgroup_context_get_mask(c) | unit_get_delegate_mask(u); ++ return unit_get_cgroup_mask(u) | unit_get_delegate_mask(u); + } + + CGroupMask unit_get_delegate_mask(Unit *u) { +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 8102b442b8..a263d6a169 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -95,12 +95,16 @@ struct CGroupContext { + LIST_HEAD(CGroupIODeviceLimit, io_device_limits); + LIST_HEAD(CGroupIODeviceLatency, io_device_latencies); + ++ uint64_t default_memory_low; + uint64_t memory_min; + uint64_t memory_low; + uint64_t memory_high; + uint64_t memory_max; + uint64_t memory_swap_max; + ++ bool default_memory_low_set; ++ bool memory_low_set; ++ + LIST_HEAD(IPAddressAccessItem, ip_address_allow); + LIST_HEAD(IPAddressAccessItem, ip_address_deny); + +@@ -191,6 +195,8 @@ Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup); + Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid); + Unit* manager_get_unit_by_pid(Manager *m, pid_t pid); + ++uint64_t unit_get_ancestor_memory_low(Unit *u); ++ + int unit_search_main_pid(Unit *u, pid_t *ret); + int unit_watch_all_pids(Unit *u); + +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 6ce5984a02..2115d43b0c 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -353,6 +353,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0), + SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0), + SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0), ++ SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0), + SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0), + SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0), + SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0), +@@ -668,6 +669,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLow")) + return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); + ++ if (streq(name, "DefaultMemoryLow")) ++ return bus_cgroup_set_memory(u, name, &c->default_memory_low, message, flags, error); ++ + if (streq(name, "MemoryHigh")) + return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); + +@@ -686,6 +690,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); + ++ if (streq(name, "DefaultMemoryLowScale")) ++ return bus_cgroup_set_memory_scale(u, name, &c->default_memory_low, message, flags, error); ++ + if (streq(name, "MemoryHighScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error); + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 1c6e539f30..43cc78fdea 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -172,6 +172,7 @@ $1.CPUQuota, config_parse_cpu_quota, 0, + $1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) + $1.MemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context) ++$1.DefaultMemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryMax, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 89a3457acc..20faed02ad 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3096,11 +3096,18 @@ int config_parse_memory_limit( + } + } + +- if (streq(lvalue, "MemoryMin")) ++ if (streq(lvalue, "DefaultMemoryLow")) { ++ c->default_memory_low_set = true; ++ if (isempty(rvalue)) ++ c->default_memory_low = CGROUP_LIMIT_MIN; ++ else ++ c->default_memory_low = bytes; ++ } else if (streq(lvalue, "MemoryMin")) + c->memory_min = bytes; +- else if (streq(lvalue, "MemoryLow")) ++ else if (streq(lvalue, "MemoryLow")) { + c->memory_low = bytes; +- else if (streq(lvalue, "MemoryHigh")) ++ c->memory_low_set = true; ++ } else if (streq(lvalue, "MemoryHigh")) + c->memory_high = bytes; + else if (streq(lvalue, "MemoryMax")) + c->memory_max = bytes; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 203c068d02..f88730a85d 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -429,7 +429,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- if (STR_IN_SET(field, "MemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { ++ if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { + + if (isempty(eq) || streq(eq, "infinity")) { + r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX); +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index 5ed68429be..0ba2712deb 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -774,7 +774,7 @@ int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all + + print_property(name, "%s", "[not set]"); + +- else if ((STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || ++ else if ((STR_IN_SET(name, "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || + (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) || + (startswith(name, "Limit") && u == (uint64_t) -1) || + (startswith(name, "DefaultLimit") && u == (uint64_t) -1)) +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 35ad20f510..763ca0c6b7 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3918,6 +3918,8 @@ typedef struct UnitStatusInfo { + uint64_t ip_ingress_bytes; + uint64_t ip_egress_bytes; + ++ uint64_t default_memory_low; ++ + LIST_HEAD(ExecStatusInfo, exec); + } UnitStatusInfo; + +@@ -5028,6 +5030,7 @@ static int show_one( + { "Where", "s", NULL, offsetof(UnitStatusInfo, where) }, + { "What", "s", NULL, offsetof(UnitStatusInfo, what) }, + { "MemoryCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_current) }, ++ { "DefaultMemoryLow", "t", NULL, offsetof(UnitStatusInfo, default_memory_low) }, + { "MemoryMin", "t", NULL, offsetof(UnitStatusInfo, memory_min) }, + { "MemoryLow", "t", NULL, offsetof(UnitStatusInfo, memory_low) }, + { "MemoryHigh", "t", NULL, offsetof(UnitStatusInfo, memory_high) }, +diff --git a/src/test/meson.build b/src/test/meson.build +index 22264d034c..7b310d4ec7 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -518,6 +518,12 @@ tests += [ + libshared], + []], + ++ [['src/test/test-cgroup-unit-default.c', ++ 'src/test/test-helper.c'], ++ [libcore, ++ libshared], ++ []], ++ + [['src/test/test-cgroup-mask.c', + 'src/test/test-helper.c'], + [libcore, +diff --git a/src/test/test-cgroup-unit-default.c b/src/test/test-cgroup-unit-default.c +new file mode 100644 +index 0000000000..54f7d50c45 +--- /dev/null ++++ b/src/test/test-cgroup-unit-default.c +@@ -0,0 +1,145 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include ++ ++#include "cgroup.h" ++#include "manager.h" ++#include "rm-rf.h" ++#include "test-helper.h" ++#include "tests.h" ++#include "unit.h" ++ ++static int test_default_memory_low(void) { ++ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; ++ _cleanup_(manager_freep) Manager *m = NULL; ++ Unit *root, *dml, ++ *dml_passthrough, *dml_passthrough_empty, *dml_passthrough_set_dml, *dml_passthrough_set_ml, ++ *dml_override, *dml_override_empty, ++ *dml_discard, *dml_discard_empty, *dml_discard_set_ml; ++ uint64_t dml_tree_default; ++ int r; ++ ++ r = enter_cgroup_subroot(); ++ if (r == -ENOMEDIUM) ++ return EXIT_TEST_SKIP; ++ ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); ++ assert_se(runtime_dir = setup_fake_runtime_dir()); ++ r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); ++ if (IN_SET(r, -EPERM, -EACCES)) { ++ log_error_errno(r, "manager_new: %m"); ++ return EXIT_TEST_SKIP; ++ } ++ ++ assert_se(r >= 0); ++ assert_se(manager_startup(m, NULL, NULL) >= 0); ++ ++ /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this: ++ * ++ * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only ++ * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with ++ * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which ++ * should have the value of 25, as it has MemoryLow explicitly set. ++ * ++ * ┌───────────┐ ++ * │ dml.slice │ ++ * └─────┬─────┘ ++ * MemoryLow=100 ++ * ┌───────────┴───────────┐ ++ * │ dml-passthrough.slice │ ++ * └───────────┬───────────┘ ++ * ┌───────────────────────────────────┼───────────────────────────────────┐ ++ * no new settings DefaultMemoryLow=15 MemoryLow=25 ++ * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐ ++ * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │ ++ * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘ ++ * ++ * 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also ++ * end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50. ++ * ++ * ┌───────────┐ ++ * │ dml.slice │ ++ * └─────┬─────┘ ++ * DefaultMemoryLow=10 ++ * ┌─────────┴──────────┐ ++ * │ dml-override.slice │ ++ * └─────────┬──────────┘ ++ * no new settings ++ * ┌─────────────┴──────────────┐ ++ * │ dml-override-empty.service │ ++ * └────────────────────────────┘ ++ * ++ * 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such, ++ * dml-discard-empty.service should end up with a value of 0. ++ * dml-discard-explicit-ml.service sets MemoryLow=70, and as such should have that override the ++ * reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50. ++ * ++ * ┌───────────┐ ++ * │ dml.slice │ ++ * └─────┬─────┘ ++ * DefaultMemoryLow= ++ * ┌─────────┴─────────┐ ++ * │ dml-discard.slice │ ++ * └─────────┬─────────┘ ++ * ┌──────────────┴───────────────┐ ++ * no new settings MemoryLow=15 ++ * ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐ ++ * │ dml-discard-empty.service │ │ dml-discard-set-ml.service │ ++ * └───────────────────────────┘ └────────────────────────────┘ ++ */ ++ assert_se(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml) >= 0); ++ ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough.slice", NULL, &dml_passthrough) >= 0); ++ assert_se(UNIT_DEREF(dml_passthrough->slice) == dml); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-empty.service", NULL, &dml_passthrough_empty) >= 0); ++ assert_se(UNIT_DEREF(dml_passthrough_empty->slice) == dml_passthrough); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-dml.service", NULL, &dml_passthrough_set_dml) >= 0); ++ assert_se(UNIT_DEREF(dml_passthrough_set_dml->slice) == dml_passthrough); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-ml.service", NULL, &dml_passthrough_set_ml) >= 0); ++ assert_se(UNIT_DEREF(dml_passthrough_set_ml->slice) == dml_passthrough); ++ ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-override.slice", NULL, &dml_override) >= 0); ++ assert_se(UNIT_DEREF(dml_override->slice) == dml); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-override-empty.service", NULL, &dml_override_empty) >= 0); ++ assert_se(UNIT_DEREF(dml_override_empty->slice) == dml_override); ++ ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard.slice", NULL, &dml_discard) >= 0); ++ assert_se(UNIT_DEREF(dml_discard->slice) == dml); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-empty.service", NULL, &dml_discard_empty) >= 0); ++ assert_se(UNIT_DEREF(dml_discard_empty->slice) == dml_discard); ++ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-set-ml.service", NULL, &dml_discard_set_ml) >= 0); ++ assert_se(UNIT_DEREF(dml_discard_set_ml->slice) == dml_discard); ++ ++ root = UNIT_DEREF(dml->slice); ++ assert_se(!UNIT_ISSET(root->slice)); ++ ++ assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN); ++ ++ assert_se(unit_get_ancestor_memory_low(dml) == CGROUP_LIMIT_MIN); ++ dml_tree_default = unit_get_cgroup_context(dml)->default_memory_low; ++ assert_se(dml_tree_default == 50); ++ ++ assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100); ++ assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default); ++ assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50); ++ assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 25); ++ ++ assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default); ++ assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10); ++ ++ assert_se(unit_get_ancestor_memory_low(dml_discard) == dml_tree_default); ++ assert_se(unit_get_ancestor_memory_low(dml_discard_empty) == CGROUP_LIMIT_MIN); ++ assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml) == 15); ++ ++ return 0; ++} ++ ++int main(int argc, char* argv[]) { ++ int rc = EXIT_SUCCESS; ++ ++ test_setup_logging(LOG_DEBUG); ++ ++ TEST_REQ_RUNNING_SYSTEMD(rc = test_default_memory_low()); ++ ++ return rc; ++} +diff --git a/test/dml-discard-empty.service b/test/dml-discard-empty.service +new file mode 100644 +index 0000000000..75228f6470 +--- /dev/null ++++ b/test/dml-discard-empty.service +@@ -0,0 +1,7 @@ ++[Unit] ++Description=DML discard empty service ++ ++[Service] ++Slice=dml-discard.slice ++Type=oneshot ++ExecStart=/bin/true +diff --git a/test/dml-discard-set-ml.service b/test/dml-discard-set-ml.service +new file mode 100644 +index 0000000000..591c99270c +--- /dev/null ++++ b/test/dml-discard-set-ml.service +@@ -0,0 +1,8 @@ ++[Unit] ++Description=DML discard set ml service ++ ++[Service] ++Slice=dml-discard.slice ++Type=oneshot ++ExecStart=/bin/true ++MemoryLow=15 +diff --git a/test/dml-discard.slice b/test/dml-discard.slice +new file mode 100644 +index 0000000000..e26d86846c +--- /dev/null ++++ b/test/dml-discard.slice +@@ -0,0 +1,5 @@ ++[Unit] ++Description=DML discard slice ++ ++[Slice] ++DefaultMemoryLow= +diff --git a/test/dml-override-empty.service b/test/dml-override-empty.service +new file mode 100644 +index 0000000000..142c98720c +--- /dev/null ++++ b/test/dml-override-empty.service +@@ -0,0 +1,7 @@ ++[Unit] ++Description=DML override empty service ++ ++[Service] ++Slice=dml-override.slice ++Type=oneshot ++ExecStart=/bin/true +diff --git a/test/dml-override.slice b/test/dml-override.slice +new file mode 100644 +index 0000000000..feb6773e39 +--- /dev/null ++++ b/test/dml-override.slice +@@ -0,0 +1,5 @@ ++[Unit] ++Description=DML override slice ++ ++[Slice] ++DefaultMemoryLow=10 +diff --git a/test/dml-passthrough-empty.service b/test/dml-passthrough-empty.service +new file mode 100644 +index 0000000000..34832de491 +--- /dev/null ++++ b/test/dml-passthrough-empty.service +@@ -0,0 +1,7 @@ ++[Unit] ++Description=DML passthrough empty service ++ ++[Service] ++Slice=dml-passthrough.slice ++Type=oneshot ++ExecStart=/bin/true +diff --git a/test/dml-passthrough-set-dml.service b/test/dml-passthrough-set-dml.service +new file mode 100644 +index 0000000000..5bdf4ed4b7 +--- /dev/null ++++ b/test/dml-passthrough-set-dml.service +@@ -0,0 +1,8 @@ ++[Unit] ++Description=DML passthrough set DML service ++ ++[Service] ++Slice=dml-passthrough.slice ++Type=oneshot ++ExecStart=/bin/true ++DefaultMemoryLow=15 +diff --git a/test/dml-passthrough-set-ml.service b/test/dml-passthrough-set-ml.service +new file mode 100644 +index 0000000000..2abd591389 +--- /dev/null ++++ b/test/dml-passthrough-set-ml.service +@@ -0,0 +1,8 @@ ++[Unit] ++Description=DML passthrough set ML service ++ ++[Service] ++Slice=dml-passthrough.slice ++Type=oneshot ++ExecStart=/bin/true ++MemoryLow=25 +diff --git a/test/dml-passthrough.slice b/test/dml-passthrough.slice +new file mode 100644 +index 0000000000..1b1a848edb +--- /dev/null ++++ b/test/dml-passthrough.slice +@@ -0,0 +1,5 @@ ++[Unit] ++Description=DML passthrough slice ++ ++[Slice] ++MemoryLow=100 +diff --git a/test/dml.slice b/test/dml.slice +new file mode 100644 +index 0000000000..84e333ef04 +--- /dev/null ++++ b/test/dml.slice +@@ -0,0 +1,5 @@ ++[Unit] ++Description=DML slice ++ ++[Slice] ++DefaultMemoryLow=50 +diff --git a/test/meson.build b/test/meson.build +index 070731c4a9..52e4fa2e3c 100644 +--- a/test/meson.build ++++ b/test/meson.build +@@ -7,6 +7,16 @@ test_data_files = ''' + c.service + d.service + daughter.service ++ dml.slice ++ dml-passthrough.slice ++ dml-passthrough-empty.service ++ dml-passthrough-set-dml.service ++ dml-passthrough-set-ml.service ++ dml-override.slice ++ dml-override-empty.service ++ dml-discard.slice ++ dml-discard-empty.service ++ dml-discard-set-ml.service + e.service + end.service + f.service diff --git a/SOURCES/0407-cgroup-Create-UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP.patch b/SOURCES/0407-cgroup-Create-UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP.patch new file mode 100644 index 0000000..5c43842 --- /dev/null +++ b/SOURCES/0407-cgroup-Create-UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP.patch @@ -0,0 +1,80 @@ +From a016ef4ab29ed62da547db008866624f75ed6407 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Tue, 16 Apr 2019 18:14:09 +0100 +Subject: [PATCH] cgroup: Create UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP + +This is in preparation for creating unit_get_ancestor_memory_min. + +(cherry picked from commit 6264b85e92aeddb74b8d8808a08c9eae8390a6a5) + +Related: #1763435 +--- + src/core/cgroup.c | 55 ++++++++++++++++++++++++++--------------------- + 1 file changed, 30 insertions(+), 25 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f804bf4727..46a89ff5e1 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -372,31 +372,36 @@ int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode) + return 0; + } + +-uint64_t unit_get_ancestor_memory_low(Unit *u) { +- CGroupContext *c; +- +- /* 1. Is MemoryLow set in this unit? If so, use that. +- * 2. Is DefaultMemoryLow set in any ancestor? If so, use that. +- * 3. Otherwise, return CGROUP_LIMIT_MIN. */ +- +- assert(u); +- +- c = unit_get_cgroup_context(u); +- +- if (c->memory_low_set) +- return c->memory_low; +- +- while (UNIT_ISSET(u->slice)) { +- u = UNIT_DEREF(u->slice); +- c = unit_get_cgroup_context(u); +- +- if (c->default_memory_low_set) +- return c->default_memory_low; +- } +- +- /* We've reached the root, but nobody had DefaultMemoryLow set, so set it to the kernel default. */ +- return CGROUP_LIMIT_MIN; +-} ++#define UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(entry) \ ++ uint64_t unit_get_ancestor_##entry(Unit *u) { \ ++ CGroupContext *c; \ ++ \ ++ /* 1. Is entry set in this unit? If so, use that. \ ++ * 2. Is the default for this entry set in any \ ++ * ancestor? If so, use that. \ ++ * 3. Otherwise, return CGROUP_LIMIT_MIN. */ \ ++ \ ++ assert(u); \ ++ \ ++ c = unit_get_cgroup_context(u); \ ++ \ ++ if (c->entry##_set) \ ++ return c->entry; \ ++ \ ++ while (UNIT_ISSET(u->slice)) { \ ++ u = UNIT_DEREF(u->slice); \ ++ c = unit_get_cgroup_context(u); \ ++ \ ++ if (c->default_##entry##_set) \ ++ return c->default_##entry; \ ++ } \ ++ \ ++ /* We've reached the root, but nobody had default for \ ++ * this entry set, so set it to the kernel default. */ \ ++ return CGROUP_LIMIT_MIN; \ ++} ++ ++UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_low); + + static int lookup_block_device(const char *p, dev_t *ret) { + struct stat st; diff --git a/SOURCES/0408-unit-Add-DefaultMemoryMin.patch b/SOURCES/0408-unit-Add-DefaultMemoryMin.patch new file mode 100644 index 0000000..bdbac28 --- /dev/null +++ b/SOURCES/0408-unit-Add-DefaultMemoryMin.patch @@ -0,0 +1,141 @@ +From 69dbbc29f26569fd09f0109e6fbebde98c0c8567 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Tue, 16 Apr 2019 18:44:05 +0100 +Subject: [PATCH] unit: Add DefaultMemoryMin + +(cherry picked from commit 7ad5439e0663e39e36619957fa37eefe8026bcab) + +Related: #1763435 +--- + src/core/cgroup.c | 3 +++ + src/core/cgroup.h | 4 ++++ + src/core/dbus-cgroup.c | 6 ++++++ + src/core/load-fragment.c | 11 +++++++++-- + src/systemctl/systemctl.c | 2 ++ + 5 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 46a89ff5e1..d40f9cbc2a 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -220,6 +220,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + "%sStartupIOWeight=%" PRIu64 "\n" + "%sBlockIOWeight=%" PRIu64 "\n" + "%sStartupBlockIOWeight=%" PRIu64 "\n" ++ "%sDefaultMemoryMin=%" PRIu64 "\n" + "%sDefaultMemoryLow=%" PRIu64 "\n" + "%sMemoryMin=%" PRIu64 "\n" + "%sMemoryLow=%" PRIu64 "\n" +@@ -248,6 +249,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { + prefix, c->startup_io_weight, + prefix, c->blockio_weight, + prefix, c->startup_blockio_weight, ++ prefix, c->default_memory_min, + prefix, c->default_memory_low, + prefix, c->memory_min, + prefix, c->memory_low, +@@ -402,6 +404,7 @@ int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode) + } + + UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_low); ++UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_min); + + static int lookup_block_device(const char *p, dev_t *ret) { + struct stat st; +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index a263d6a169..976224336d 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -95,6 +95,7 @@ struct CGroupContext { + LIST_HEAD(CGroupIODeviceLimit, io_device_limits); + LIST_HEAD(CGroupIODeviceLatency, io_device_latencies); + ++ uint64_t default_memory_min; + uint64_t default_memory_low; + uint64_t memory_min; + uint64_t memory_low; +@@ -102,7 +103,9 @@ struct CGroupContext { + uint64_t memory_max; + uint64_t memory_swap_max; + ++ bool default_memory_min_set; + bool default_memory_low_set; ++ bool memory_min_set; + bool memory_low_set; + + LIST_HEAD(IPAddressAccessItem, ip_address_allow); +@@ -195,6 +198,7 @@ Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup); + Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid); + Unit* manager_get_unit_by_pid(Manager *m, pid_t pid); + ++uint64_t unit_get_ancestor_memory_min(Unit *u); + uint64_t unit_get_ancestor_memory_low(Unit *u); + + int unit_search_main_pid(Unit *u, pid_t *ret); +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 2115d43b0c..e1278c317a 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -669,6 +669,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLow")) + return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); + ++ if (streq(name, "DefaultMemoryMin")) ++ return bus_cgroup_set_memory(u, name, &c->default_memory_min, message, flags, error); ++ + if (streq(name, "DefaultMemoryLow")) + return bus_cgroup_set_memory(u, name, &c->default_memory_low, message, flags, error); + +@@ -690,6 +693,9 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); + ++ if (streq(name, "DefaultMemoryMinScale")) ++ return bus_cgroup_set_memory_scale(u, name, &c->default_memory_min, message, flags, error); ++ + if (streq(name, "DefaultMemoryLowScale")) + return bus_cgroup_set_memory_scale(u, name, &c->default_memory_low, message, flags, error); + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 20faed02ad..3b8ee6b124 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3102,9 +3102,16 @@ int config_parse_memory_limit( + c->default_memory_low = CGROUP_LIMIT_MIN; + else + c->default_memory_low = bytes; +- } else if (streq(lvalue, "MemoryMin")) ++ } else if (streq(lvalue, "DefaultMemoryMin")) { ++ c->default_memory_min_set = true; ++ if (isempty(rvalue)) ++ c->default_memory_min = CGROUP_LIMIT_MIN; ++ else ++ c->default_memory_min = bytes; ++ } else if (streq(lvalue, "MemoryMin")) { + c->memory_min = bytes; +- else if (streq(lvalue, "MemoryLow")) { ++ c->memory_min_set = true; ++ } else if (streq(lvalue, "MemoryLow")) { + c->memory_low = bytes; + c->memory_low_set = true; + } else if (streq(lvalue, "MemoryHigh")) +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 763ca0c6b7..e0db97e339 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3918,6 +3918,7 @@ typedef struct UnitStatusInfo { + uint64_t ip_ingress_bytes; + uint64_t ip_egress_bytes; + ++ uint64_t default_memory_min; + uint64_t default_memory_low; + + LIST_HEAD(ExecStatusInfo, exec); +@@ -5030,6 +5031,7 @@ static int show_one( + { "Where", "s", NULL, offsetof(UnitStatusInfo, where) }, + { "What", "s", NULL, offsetof(UnitStatusInfo, what) }, + { "MemoryCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_current) }, ++ { "DefaultMemoryMin", "t", NULL, offsetof(UnitStatusInfo, default_memory_min) }, + { "DefaultMemoryLow", "t", NULL, offsetof(UnitStatusInfo, default_memory_low) }, + { "MemoryMin", "t", NULL, offsetof(UnitStatusInfo, memory_min) }, + { "MemoryLow", "t", NULL, offsetof(UnitStatusInfo, memory_low) }, diff --git a/SOURCES/0409-cgroup-Polish-hierarchically-aware-protection-docs-a.patch b/SOURCES/0409-cgroup-Polish-hierarchically-aware-protection-docs-a.patch new file mode 100644 index 0000000..d2399a0 --- /dev/null +++ b/SOURCES/0409-cgroup-Polish-hierarchically-aware-protection-docs-a.patch @@ -0,0 +1,56 @@ +From 556375ae1d8d0b460d691888f2fb7ea520fe9a6b Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Tue, 30 Apr 2019 14:22:04 -0400 +Subject: [PATCH] cgroup: Polish hierarchically aware protection docs a bit + +I missed adding a section in `systemd.resource-control` about +DefaultMemoryMin in #12332. + +Also, add a NEWS entry going over the general concept. + +(cherry picked from commit acdb4b5236f38bbefbcc4a47fdbb9cd558b4b5c5) + +Related: #1763435 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.resource-control.xml | 8 ++++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 5a8fa0727e..1a4e79190a 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -222,6 +222,7 @@ All cgroup/resource control settings are available for transient units + ✓ AllowedCPUs= + ✓ AllowedMemoryNodes= + ✓ MemoryAccounting= ++✓ DefaultMemoryMin= + ✓ MemoryMin= + ✓ DefaultMemoryLow= + ✓ MemoryLow= +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index 27f16001dd..d3bff29169 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -283,6 +283,10 @@ + + This setting is supported only if the unified control group hierarchy is used and disables + MemoryLimit=. ++ ++ Units may have their children use a default memory.min value by specifying ++ DefaultMemoryMin=, which has the same semantics as MemoryMin=. This setting ++ does not affect memory.min in the unit itself. + + + +@@ -306,8 +310,8 @@ + This setting is supported only if the unified control group hierarchy is used and disables + MemoryLimit=. + +- Units may can have their children use a default memory.low value by specifying +- DefaultMemoryLow=, which has the same usage as MemoryLow=. This setting ++ Units may have their children use a default memory.low value by specifying ++ DefaultMemoryLow=, which has the same semantics as MemoryLow=. This setting + does not affect memory.low in the unit itself. + + diff --git a/SOURCES/0410-cgroup-Readd-some-plumbing-for-DefaultMemoryMin.patch b/SOURCES/0410-cgroup-Readd-some-plumbing-for-DefaultMemoryMin.patch new file mode 100644 index 0000000..13f3fec --- /dev/null +++ b/SOURCES/0410-cgroup-Readd-some-plumbing-for-DefaultMemoryMin.patch @@ -0,0 +1,68 @@ +From dbdba4f2998313949e7c5f5a47f4ef938e759a86 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Fri, 3 May 2019 08:19:05 -0400 +Subject: [PATCH] cgroup: Readd some plumbing for DefaultMemoryMin + +Somehow these got lost in the previous PR, rendering DefaultMemoryMin +not very useful. + +(cherry picked from commit 7e7223b3d57c950b399352a92e1d817f7c463602) + +Related: #1763435 +--- + src/core/dbus-cgroup.c | 1 + + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/shared/bus-unit-util.c | 2 +- + src/shared/bus-util.c | 2 +- + 4 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index e1278c317a..e34ff3a016 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -354,6 +354,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { + SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0), + SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0), + SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0), ++ SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0), + SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0), + SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0), + SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0), +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 43cc78fdea..6d21b2e433 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -172,6 +172,7 @@ $1.CPUQuota, config_parse_cpu_quota, 0, + $1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec) + $1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting) + $1.MemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context) ++$1.DefaultMemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.DefaultMemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context) + $1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context) +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index f88730a85d..77788f0fe2 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -429,7 +429,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { ++ if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) { + + if (isempty(eq) || streq(eq, "infinity")) { + r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX); +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index 0ba2712deb..ff0e800347 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -774,7 +774,7 @@ int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all + + print_property(name, "%s", "[not set]"); + +- else if ((STR_IN_SET(name, "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || ++ else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || + (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) || + (startswith(name, "Limit") && u == (uint64_t) -1) || + (startswith(name, "DefaultLimit") && u == (uint64_t) -1)) diff --git a/SOURCES/0411-cgroup-Support-0-value-for-memory-protection-directi.patch b/SOURCES/0411-cgroup-Support-0-value-for-memory-protection-directi.patch new file mode 100644 index 0000000..5e1e1f2 --- /dev/null +++ b/SOURCES/0411-cgroup-Support-0-value-for-memory-protection-directi.patch @@ -0,0 +1,86 @@ +From 614b43fcad3a16dfde5ad606b43c3aa1adacc30a Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Fri, 3 May 2019 08:32:41 -0400 +Subject: [PATCH] cgroup: Support 0-value for memory protection directives + +These make sense to be explicitly set at 0 (which has a different effect +than the default, since it can affect processing of `DefaultMemoryXXX`). + +Without this, it's not easily possible to relinquish memory protection +for a subtree, which is not great. + +(cherry picked from commit 22bf131be278b95a4a204514d37a4344cf6365c6) + +Related: #1763435 +--- + src/core/dbus-cgroup.c | 17 +++++++++-------- + src/core/load-fragment.c | 2 +- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index e34ff3a016..39778a8dd4 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -606,6 +606,7 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_O + BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID); + BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID); + BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1); ++BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0); + BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0); + BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale, 1); + #pragma GCC diagnostic pop +@@ -665,16 +666,16 @@ int bus_cgroup_set_property( + return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error); + + if (streq(name, "MemoryMin")) +- return bus_cgroup_set_memory(u, name, &c->memory_min, message, flags, error); ++ return bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error); + + if (streq(name, "MemoryLow")) +- return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error); ++ return bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error); + + if (streq(name, "DefaultMemoryMin")) +- return bus_cgroup_set_memory(u, name, &c->default_memory_min, message, flags, error); ++ return bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error); + + if (streq(name, "DefaultMemoryLow")) +- return bus_cgroup_set_memory(u, name, &c->default_memory_low, message, flags, error); ++ return bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error); + + if (streq(name, "MemoryHigh")) + return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); +@@ -689,16 +690,16 @@ int bus_cgroup_set_property( + return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); + + if (streq(name, "MemoryMinScale")) +- return bus_cgroup_set_memory_scale(u, name, &c->memory_min, message, flags, error); ++ return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error); + + if (streq(name, "MemoryLowScale")) +- return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error); ++ return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error); + + if (streq(name, "DefaultMemoryMinScale")) +- return bus_cgroup_set_memory_scale(u, name, &c->default_memory_min, message, flags, error); ++ return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error); + + if (streq(name, "DefaultMemoryLowScale")) +- return bus_cgroup_set_memory_scale(u, name, &c->default_memory_low, message, flags, error); ++ return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error); + + if (streq(name, "MemoryHighScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error); +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 3b8ee6b124..33fdb82754 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -3090,7 +3090,7 @@ int config_parse_memory_limit( + bytes = physical_memory_scale(r, 100U); + + if (bytes >= UINT64_MAX || +- (bytes <= 0 && !streq(lvalue, "MemorySwapMax"))) { ++ (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue); + return 0; + } diff --git a/SOURCES/0412-cgroup-Test-that-it-s-possible-to-set-memory-protect.patch b/SOURCES/0412-cgroup-Test-that-it-s-possible-to-set-memory-protect.patch new file mode 100644 index 0000000..bb8f9c9 --- /dev/null +++ b/SOURCES/0412-cgroup-Test-that-it-s-possible-to-set-memory-protect.patch @@ -0,0 +1,58 @@ +From ef4157dab3d267c33ec2a06ae9bb5e4c87f785a6 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Fri, 3 May 2019 08:40:11 -0400 +Subject: [PATCH] cgroup: Test that it's possible to set memory protection to 0 + again + +The previous commit fixes this up, and this should prevent it +regressing. + +(cherry picked from commit 465ace74d9820824968ab5e82c81e42c2f1894b0) + +Related: #1763435 +--- + src/test/test-cgroup-unit-default.c | 6 +++--- + test/dml-passthrough-set-ml.service | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/test/test-cgroup-unit-default.c b/src/test/test-cgroup-unit-default.c +index 54f7d50c45..1938609cee 100644 +--- a/src/test/test-cgroup-unit-default.c ++++ b/src/test/test-cgroup-unit-default.c +@@ -39,7 +39,7 @@ static int test_default_memory_low(void) { + * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only + * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with + * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which +- * should have the value of 25, as it has MemoryLow explicitly set. ++ * should have the value of 0, as it has MemoryLow explicitly set. + * + * ┌───────────┐ + * │ dml.slice │ +@@ -49,7 +49,7 @@ static int test_default_memory_low(void) { + * │ dml-passthrough.slice │ + * └───────────┬───────────┘ + * ┌───────────────────────────────────┼───────────────────────────────────┐ +- * no new settings DefaultMemoryLow=15 MemoryLow=25 ++ * no new settings DefaultMemoryLow=15 MemoryLow=0 + * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐ + * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │ + * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘ +@@ -122,7 +122,7 @@ static int test_default_memory_low(void) { + assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100); + assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default); + assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50); +- assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 25); ++ assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0); + + assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default); + assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10); +diff --git a/test/dml-passthrough-set-ml.service b/test/dml-passthrough-set-ml.service +index 2abd591389..2e568b5deb 100644 +--- a/test/dml-passthrough-set-ml.service ++++ b/test/dml-passthrough-set-ml.service +@@ -5,4 +5,4 @@ Description=DML passthrough set ML service + Slice=dml-passthrough.slice + Type=oneshot + ExecStart=/bin/true +-MemoryLow=25 ++MemoryLow=0 diff --git a/SOURCES/0413-cgroup-Check-ancestor-memory-min-for-unified-memory-.patch b/SOURCES/0413-cgroup-Check-ancestor-memory-min-for-unified-memory-.patch new file mode 100644 index 0000000..7761e7f --- /dev/null +++ b/SOURCES/0413-cgroup-Check-ancestor-memory-min-for-unified-memory-.patch @@ -0,0 +1,28 @@ +From 49c990010f48b429b52f73f54d70d529f0d2c7fe Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Mon, 30 Sep 2019 18:24:26 +0100 +Subject: [PATCH] cgroup: Check ancestor memory min for unified memory config + +Otherwise we might not enable it when we should, ie. DefaultMemoryMin is +set in a parent, but not MemoryMin in the current unit. + +(cherry picked from commit 7c9d2b79935d413389a603918a711df75acd3f48) + +Related: #1763435 +--- + src/core/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index d40f9cbc2a..4299923754 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -851,7 +851,7 @@ static bool unit_has_unified_memory_config(Unit *u) { + c = unit_get_cgroup_context(u); + assert(c); + +- return c->memory_min > 0 || unit_get_ancestor_memory_low(u) > 0 || ++ return unit_get_ancestor_memory_min(u) > 0 || unit_get_ancestor_memory_low(u) > 0 || + c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || + c->memory_swap_max != CGROUP_LIMIT_MAX; + } diff --git a/SOURCES/0414-cgroup-Respect-DefaultMemoryMin-when-setting-memory..patch b/SOURCES/0414-cgroup-Respect-DefaultMemoryMin-when-setting-memory..patch new file mode 100644 index 0000000..4ded71a --- /dev/null +++ b/SOURCES/0414-cgroup-Respect-DefaultMemoryMin-when-setting-memory..patch @@ -0,0 +1,31 @@ +From 9c04746fb35b32b592fe14cab43782db9e0dee5c Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Mon, 30 Sep 2019 18:25:09 +0100 +Subject: [PATCH] cgroup: Respect DefaultMemoryMin when setting memory.min + +This is an oversight from https://github.com/systemd/systemd/pull/12332. + +Sadly the tests didn't catch it since it requires a real cgroup +hierarchy to see, and it wasn't seen in prod since we're only currently +using DefaultMemoryLow, not DefaultMemoryMin. :-( + +(cherry picked from commit 64fe532e90b3e99bf7821ded8a1107c239099e40) + +Related: #1763435 +--- + src/core/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 4299923754..7a9857adad 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1111,7 +1111,7 @@ static void cgroup_context_apply( + log_cgroup_compat(u, "Applying MemoryLimit %" PRIu64 " as MemoryMax", max); + } + +- cgroup_apply_unified_memory_limit(u, "memory.min", c->memory_min); ++ cgroup_apply_unified_memory_limit(u, "memory.min", unit_get_ancestor_memory_min(u)); + cgroup_apply_unified_memory_limit(u, "memory.low", unit_get_ancestor_memory_low(u)); + cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high); + cgroup_apply_unified_memory_limit(u, "memory.max", max); diff --git a/SOURCES/0415-cgroup-Mark-memory-protections-as-explicitly-set-in-.patch b/SOURCES/0415-cgroup-Mark-memory-protections-as-explicitly-set-in-.patch new file mode 100644 index 0000000..c38a93e --- /dev/null +++ b/SOURCES/0415-cgroup-Mark-memory-protections-as-explicitly-set-in-.patch @@ -0,0 +1,108 @@ +From 4e7a3af028dfe6b5a4a85c31d670df73c08a0719 Mon Sep 17 00:00:00 2001 +From: Chris Down +Date: Mon, 30 Sep 2019 18:36:13 +0100 +Subject: [PATCH] cgroup: Mark memory protections as explicitly set in + transient units + +A later version of the DefaultMemory{Low,Min} patch changed these to +require explicitly setting memory_foo_set, but we only set that in +load-fragment, not dbus-cgroup. + +Without these, we may fall back to either DefaultMemoryFoo or +CGROUP_LIMIT_MIN when we really shouldn't. + +(cherry picked from commit 184e989d7da4648bd36511ffa28a9f2b469589d1) + +Related: #1763435 +--- + src/core/dbus-cgroup.c | 64 +++++++++++++++++++++++++++++++----------- + 1 file changed, 48 insertions(+), 16 deletions(-) + +diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c +index 39778a8dd4..de85a4851b 100644 +--- a/src/core/dbus-cgroup.c ++++ b/src/core/dbus-cgroup.c +@@ -665,17 +665,33 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryAccounting")) + return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error); + +- if (streq(name, "MemoryMin")) +- return bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error); ++ if (streq(name, "MemoryMin")) { ++ r = bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error); ++ if (r > 0) ++ c->memory_min_set = true; ++ return r; ++ } + +- if (streq(name, "MemoryLow")) +- return bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error); ++ if (streq(name, "MemoryLow")) { ++ r = bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error); ++ if (r > 0) ++ c->memory_low_set = true; ++ return r; ++ } + +- if (streq(name, "DefaultMemoryMin")) +- return bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error); ++ if (streq(name, "DefaultMemoryMin")) { ++ r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error); ++ if (r > 0) ++ c->default_memory_min_set = true; ++ return r; ++ } + +- if (streq(name, "DefaultMemoryLow")) +- return bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error); ++ if (streq(name, "DefaultMemoryLow")) { ++ r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error); ++ if (r > 0) ++ c->default_memory_low_set = true; ++ return r; ++ } + + if (streq(name, "MemoryHigh")) + return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error); +@@ -689,17 +705,33 @@ int bus_cgroup_set_property( + if (streq(name, "MemoryLimit")) + return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); + +- if (streq(name, "MemoryMinScale")) +- return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error); ++ if (streq(name, "MemoryMinScale")) { ++ r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error); ++ if (r > 0) ++ c->memory_min_set = true; ++ return r; ++ } + +- if (streq(name, "MemoryLowScale")) +- return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error); ++ if (streq(name, "MemoryLowScale")) { ++ r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error); ++ if (r > 0) ++ c->memory_low_set = true; ++ return r; ++ } + +- if (streq(name, "DefaultMemoryMinScale")) +- return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error); ++ if (streq(name, "DefaultMemoryMinScale")) { ++ r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error); ++ if (r > 0) ++ c->default_memory_min_set = true; ++ return r; ++ } + +- if (streq(name, "DefaultMemoryLowScale")) +- return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error); ++ if (streq(name, "DefaultMemoryLowScale")) { ++ r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error); ++ if (r > 0) ++ c->default_memory_low_set = true; ++ return r; ++ } + + if (streq(name, "MemoryHighScale")) + return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error); diff --git a/SOURCES/0416-meson-allow-setting-the-version-string-during-config.patch b/SOURCES/0416-meson-allow-setting-the-version-string-during-config.patch new file mode 100644 index 0000000..9e082d2 --- /dev/null +++ b/SOURCES/0416-meson-allow-setting-the-version-string-during-config.patch @@ -0,0 +1,86 @@ +From 0065f2bf838dd0c24ec7be41439b4c0ba650029c Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 19 Feb 2020 15:36:13 +0100 +Subject: [PATCH] meson: allow setting the version string during configuration + +Very loosely based on upstream commits e1ca734edd17a90a325d5b566a4ea96e66c206e5 +and 681bd2c524ed71ac04045c90884ba8d55eee7b66. + +Resolves: #1804252 +--- + meson.build | 15 +++++++++++---- + meson_options.txt | 3 +++ + src/udev/udev-ctrl.c | 5 ++++- + 3 files changed, 18 insertions(+), 5 deletions(-) + +diff --git a/meson.build b/meson.build +index c8ae1e15bd..0ba3f924ea 100644 +--- a/meson.build ++++ b/meson.build +@@ -15,17 +15,24 @@ project('systemd', 'c', + libsystemd_version = '0.23.0' + libudev_version = '1.6.11' + ++dist_version = get_option('version-tag') ++if dist_version == '' ++ dist_version = meson.project_version() ++else ++ dist_version = meson.project_version() + ' (' + dist_version + ')' ++endif ++ + # We need the same data in two different formats, ugh! + # Also, for hysterical reasons, we use different variable + # names, sometimes. Not all variables are included in every + # set. Ugh, ugh, ugh! + conf = configuration_data() +-conf.set_quoted('PACKAGE_STRING', meson.project_name() + ' ' + meson.project_version()) +-conf.set_quoted('PACKAGE_VERSION', meson.project_version()) ++conf.set_quoted('PACKAGE_STRING', meson.project_name() + ' ' + dist_version) ++conf.set_quoted('PACKAGE_VERSION', dist_version) + + substs = configuration_data() + substs.set('PACKAGE_URL', 'https://www.freedesktop.org/wiki/Software/systemd') +-substs.set('PACKAGE_VERSION', meson.project_version()) ++substs.set('PACKAGE_VERSION', dist_version) + + ##################################################################### + +@@ -2871,7 +2878,7 @@ run_target( + ############################################################ + + status = [ +- '@0@ @1@'.format(meson.project_name(), meson.project_version()), ++ '@0@ @1@'.format(meson.project_name(), dist_version), + + 'split /usr: @0@'.format(split_usr), + 'split bin-sbin: @0@'.format(split_bin), +diff --git a/meson_options.txt b/meson_options.txt +index 563b11f0a2..0996891177 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -1,6 +1,9 @@ + # -*- mode: meson -*- + # SPDX-License-Identifier: LGPL-2.1+ + ++option('version-tag', type : 'string', ++ description : 'override the version string') ++ + option('split-usr', type : 'combo', choices : ['auto', 'true', 'false'], + description : '''/bin, /sbin aren't symlinks into /usr''') + option('split-bin', type : 'combo', choices : ['auto', 'true', 'false'], +diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c +index efe7297f04..5382ce0d26 100644 +--- a/src/udev/udev-ctrl.c ++++ b/src/udev/udev-ctrl.c +@@ -239,7 +239,10 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int + int err = 0; + + memzero(&ctrl_msg_wire, sizeof(struct udev_ctrl_msg_wire)); +- strcpy(ctrl_msg_wire.version, "udev-" PACKAGE_VERSION); ++ /* jsynacek: As PACKAGE_VERSION is populated from the spec file with %{version}-%{release}, ++ * it might not fit entirely into the version field. */ ++ strncpy(ctrl_msg_wire.version, "udev-" PACKAGE_VERSION, 16-5); ++ ctrl_msg_wire.version[15] = '\0'; + ctrl_msg_wire.magic = UDEV_CTRL_MAGIC; + ctrl_msg_wire.type = type; + diff --git a/SOURCES/0417-core-don-t-consider-SERVICE_SKIP_CONDITION-for-abnor.patch b/SOURCES/0417-core-don-t-consider-SERVICE_SKIP_CONDITION-for-abnor.patch new file mode 100644 index 0000000..3ef1273 --- /dev/null +++ b/SOURCES/0417-core-don-t-consider-SERVICE_SKIP_CONDITION-for-abnor.patch @@ -0,0 +1,170 @@ +From 41346615264e01c6ff6118e09cf3ac4b4c71e89d Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Wed, 10 Jun 2020 01:18:00 -0700 +Subject: [PATCH] core: don't consider SERVICE_SKIP_CONDITION for abnormal or + failure restarts + +Fixes: #16115 +(cherry picked from commit bb9244781c6fc7608f7cac910269f8987b8adc01) + +Related: #1737283 +--- + src/core/service.c | 4 +-- + test/TEST-51-ISSUE-16115/Makefile | 1 + + test/TEST-51-ISSUE-16115/repro-1.service | 9 +++++ + test/TEST-51-ISSUE-16115/repro-2.service | 9 +++++ + test/TEST-51-ISSUE-16115/test.sh | 46 ++++++++++++++++++++++++ + test/TEST-51-ISSUE-16115/testsuite.sh | 19 ++++++++++ + test/test-functions | 2 +- + 7 files changed, 87 insertions(+), 3 deletions(-) + create mode 120000 test/TEST-51-ISSUE-16115/Makefile + create mode 100644 test/TEST-51-ISSUE-16115/repro-1.service + create mode 100644 test/TEST-51-ISSUE-16115/repro-2.service + create mode 100755 test/TEST-51-ISSUE-16115/test.sh + create mode 100755 test/TEST-51-ISSUE-16115/testsuite.sh + +diff --git a/src/core/service.c b/src/core/service.c +index 92be4280f6..1d98ee37fd 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1637,10 +1637,10 @@ static bool service_shall_restart(Service *s) { + return s->result == SERVICE_SUCCESS; + + case SERVICE_RESTART_ON_FAILURE: +- return s->result != SERVICE_SUCCESS; ++ return !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_SKIP_CONDITION); + + case SERVICE_RESTART_ON_ABNORMAL: +- return !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE); ++ return !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE, SERVICE_SKIP_CONDITION); + + case SERVICE_RESTART_ON_WATCHDOG: + return s->result == SERVICE_FAILURE_WATCHDOG; +diff --git a/test/TEST-51-ISSUE-16115/Makefile b/test/TEST-51-ISSUE-16115/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-51-ISSUE-16115/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-51-ISSUE-16115/repro-1.service b/test/TEST-51-ISSUE-16115/repro-1.service +new file mode 100644 +index 0000000000..96ecabe234 +--- /dev/null ++++ b/test/TEST-51-ISSUE-16115/repro-1.service +@@ -0,0 +1,9 @@ ++[Unit] ++Description=Issue 16115 Repro with on-abnormal ++ ++[Service] ++Type=simple ++Restart=on-abnormal ++ExecCondition=/bin/false ++ExecStart=sleep 100 ++RestartSec=1 +diff --git a/test/TEST-51-ISSUE-16115/repro-2.service b/test/TEST-51-ISSUE-16115/repro-2.service +new file mode 100644 +index 0000000000..6015ad8080 +--- /dev/null ++++ b/test/TEST-51-ISSUE-16115/repro-2.service +@@ -0,0 +1,9 @@ ++[Unit] ++Description=Issue 16115 Repro with on-failure ++ ++[Service] ++Type=simple ++Restart=on-failure ++ExecCondition=/bin/false ++ExecStart=sleep 100 ++RestartSec=1 +diff --git a/test/TEST-51-ISSUE-16115/test.sh b/test/TEST-51-ISSUE-16115/test.sh +new file mode 100755 +index 0000000000..09ac96ffce +--- /dev/null ++++ b/test/TEST-51-ISSUE-16115/test.sh +@@ -0,0 +1,46 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Test ExecCondition= does not restart on abnormal or failure" ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < /testok ++ ++exit 0 +diff --git a/test/test-functions b/test/test-functions +index 7c4230b078..4d7832b1fb 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0418-selinux-do-preprocessor-check-only-in-selinux-access.patch b/SOURCES/0418-selinux-do-preprocessor-check-only-in-selinux-access.patch new file mode 100644 index 0000000..d6b7c1a --- /dev/null +++ b/SOURCES/0418-selinux-do-preprocessor-check-only-in-selinux-access.patch @@ -0,0 +1,39 @@ +From 7301b170b266225f091e95ff52b3a95ff9776d13 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 3 Apr 2020 09:13:59 +0200 +Subject: [PATCH] selinux: do preprocessor check only in selinux-access.c + +This has the advantage that mac_selinux_access_check() can be used as a +function in all contexts. For example, parameters passed to it won't be +reported as unused if the "function" call is replaced with 0 on SELinux +disabled builds. + +(cherry picked from commit 08deac6e3e9119aeb966375f94695e4aa14ffb1c) + +Related: #1830861 +--- + src/core/selinux-access.h | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h +index 59f2e60c77..46a657a4b4 100644 +--- a/src/core/selinux-access.h ++++ b/src/core/selinux-access.h +@@ -12,17 +12,8 @@ + + int mac_selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error); + +-#if HAVE_SELINUX +- + #define mac_selinux_access_check(message, permission, error) \ + mac_selinux_generic_access_check((message), NULL, (permission), (error)) + + #define mac_selinux_unit_access_check(unit, message, permission, error) \ + mac_selinux_generic_access_check((message), unit_label_path(unit), (permission), (error)) +- +-#else +- +-#define mac_selinux_access_check(message, permission, error) 0 +-#define mac_selinux_unit_access_check(unit, message, permission, error) 0 +- +-#endif diff --git a/SOURCES/0419-basic-cgroup-util-introduce-cg_get_keyed_attribute_f.patch b/SOURCES/0419-basic-cgroup-util-introduce-cg_get_keyed_attribute_f.patch new file mode 100644 index 0000000..adcc7a4 --- /dev/null +++ b/SOURCES/0419-basic-cgroup-util-introduce-cg_get_keyed_attribute_f.patch @@ -0,0 +1,144 @@ +From 5aefc153b25b42a80942e5c367ce143817551870 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Wed, 29 Apr 2020 17:40:22 +0200 +Subject: [PATCH] basic/cgroup-util: introduce cg_get_keyed_attribute_full() + +Callers of cg_get_keyed_attribute_full() can now specify via the flag whether the +missing keyes in cgroup attribute file are OK or not. Also the wrappers for both +strict and graceful version are provided. + +(cherry picked from commit 25a1f04c682260bb9b96e25bdf33665d6172db98) + +Related: #1830861 +--- + src/basic/cgroup-util.c | 13 ++++++++++--- + src/basic/cgroup-util.h | 24 +++++++++++++++++++++++- + src/test/test-cgroup-util.c | 20 ++++++++++++++++++++ + 3 files changed, 53 insertions(+), 4 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 92bc1f2543..4c0b73850d 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -2021,12 +2021,13 @@ int cg_get_attribute(const char *controller, const char *path, const char *attri + return read_one_line_file(p, ret); + } + +-int cg_get_keyed_attribute( ++int cg_get_keyed_attribute_full( + const char *controller, + const char *path, + const char *attribute, + char **keys, +- char **ret_values) { ++ char **ret_values, ++ CGroupKeyMode mode) { + + _cleanup_free_ char *filename = NULL, *contents = NULL; + const char *p; +@@ -2086,7 +2087,10 @@ int cg_get_keyed_attribute( + p += strspn(p, NEWLINE); + } + +- r = -ENXIO; ++ if (mode & CG_KEY_MODE_GRACEFUL) ++ goto done; ++ else ++ r = -ENXIO; + + fail: + for (i = 0; i < n; i++) +@@ -2096,6 +2100,9 @@ fail: + + done: + memcpy(ret_values, v, sizeof(char*) * n); ++ if (mode & CG_KEY_MODE_GRACEFUL) ++ return n_done; ++ + return 0; + + } +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index b414600dca..0673f4b4ce 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -167,9 +167,31 @@ int cg_attach(const char *controller, const char *path, pid_t pid); + int cg_attach_fallback(const char *controller, const char *path, pid_t pid); + int cg_create_and_attach(const char *controller, const char *path, pid_t pid); + ++typedef enum { ++ CG_KEY_MODE_GRACEFUL = 1 << 0, ++} CGroupKeyMode; ++ + int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); + int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret); +-int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char **keys, char **values); ++int cg_get_keyed_attribute_full(const char *controller, const char *path, const char *attribute, char **keys, char **values, CGroupKeyMode mode); ++ ++static inline int cg_get_keyed_attribute( ++ const char *controller, ++ const char *path, ++ const char *attribute, ++ char **keys, ++ char **ret_values) { ++ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, 0); ++} ++ ++static inline int cg_get_keyed_attribute_graceful( ++ const char *controller, ++ const char *path, ++ const char *attribute, ++ char **keys, ++ char **ret_values) { ++ return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, CG_KEY_MODE_GRACEFUL); ++} + + int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid); + +diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c +index d49356315e..60d7bb19cb 100644 +--- a/src/test/test-cgroup-util.c ++++ b/src/test/test-cgroup-util.c +@@ -421,22 +421,42 @@ static void test_cg_get_keyed_attribute(void) { + } + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO); ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == 0); + assert_se(val == NULL); + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 0); ++ free(val); ++ ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 1); + log_info("cpu /init.scope cpu.stat [usage_usec] → \"%s\"", val); + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO); ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == 1); ++ assert(vals3[0] && !vals3[1]); ++ free(vals3[0]); + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == -ENXIO); ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == 1); ++ assert(vals3[0] && !vals3[1]); ++ free(vals3[0]); + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", + STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 0); ++ for (i = 0; i < 3; i++) ++ free(vals3[i]); ++ ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", ++ STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 3); + log_info("cpu /init.scope cpu.stat [usage_usec user_usec system_usec] → \"%s\", \"%s\", \"%s\"", + vals3[0], vals3[1], vals3[2]); + + assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", + STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 0); ++ for (i = 0; i < 3; i++) ++ free(vals3a[i]); ++ ++ assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", ++ STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 3); + log_info("cpu /init.scope cpu.stat [system_usec user_usec usage_usec] → \"%s\", \"%s\", \"%s\"", + vals3a[0], vals3a[1], vals3a[2]); + diff --git a/SOURCES/0420-shared-add-generic-logic-for-waiting-for-a-unit-to-e.patch b/SOURCES/0420-shared-add-generic-logic-for-waiting-for-a-unit-to-e.patch new file mode 100644 index 0000000..39ba3d7 --- /dev/null +++ b/SOURCES/0420-shared-add-generic-logic-for-waiting-for-a-unit-to-e.patch @@ -0,0 +1,526 @@ +From 5e422a9cea38bd5c7ce54c7bbac612c04418dc41 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Apr 2019 18:54:59 +0200 +Subject: [PATCH] shared: add generic logic for waiting for a unit to enter + some state + +This is a generic implementation of a client-side logic of waiting until +a unit enters or leaves some state. + +This is a more generic implementation of the WaitContext logic currently +in systemctl.c, and is supposed to replace it (a later commit does +this). It's similar to bus-wait-for-jobs.c and we probably should fold +that one into it later on. + +This code is more powerful and cleaner than the WaitContext logic +however. In addition to waiting for a unit to exit this also allows us +to wait for a unit to leave the "maintainance" state. + +This commit only implements the generic logic, and adds no users of it +yet. + +(cherry picked from commit 3572d3df8f822d4cf1601428401a837f723771cf) + +Related: #1830861 +--- + src/shared/bus-wait-for-units.c | 434 ++++++++++++++++++++++++++++++++ + src/shared/bus-wait-for-units.h | 35 +++ + src/shared/meson.build | 2 + + 3 files changed, 471 insertions(+) + create mode 100644 src/shared/bus-wait-for-units.c + create mode 100644 src/shared/bus-wait-for-units.h + +diff --git a/src/shared/bus-wait-for-units.c b/src/shared/bus-wait-for-units.c +new file mode 100644 +index 0000000000..d07f491e93 +--- /dev/null ++++ b/src/shared/bus-wait-for-units.c +@@ -0,0 +1,434 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "bus-util.h" ++#include "bus-wait-for-units.h" ++#include "hashmap.h" ++#include "string-util.h" ++#include "strv.h" ++#include "unit-def.h" ++ ++typedef struct WaitForItem { ++ BusWaitForUnits *parent; ++ ++ BusWaitForUnitsFlags flags; ++ ++ char *bus_path; ++ ++ sd_bus_slot *slot_get_all; ++ sd_bus_slot *slot_properties_changed; ++ ++ bus_wait_for_units_unit_callback unit_callback; ++ void *userdata; ++ ++ char *active_state; ++ uint32_t job_id; ++ char *clean_result; ++} WaitForItem; ++ ++typedef struct BusWaitForUnits { ++ sd_bus *bus; ++ sd_bus_slot *slot_disconnected; ++ ++ Hashmap *items; ++ ++ bus_wait_for_units_ready_callback ready_callback; ++ void *userdata; ++ ++ WaitForItem *current; ++ ++ BusWaitForUnitsState state; ++ bool has_failed:1; ++} BusWaitForUnits; ++ ++static WaitForItem *wait_for_item_free(WaitForItem *item) { ++ int r; ++ ++ if (!item) ++ return NULL; ++ ++ if (item->parent) { ++ if (FLAGS_SET(item->flags, BUS_WAIT_REFFED) && item->bus_path && item->parent->bus) { ++ r = sd_bus_call_method_async( ++ item->parent->bus, ++ NULL, ++ "org.freedesktop.systemd1", ++ item->bus_path, ++ "org.freedesktop.systemd1.Unit", ++ "Unref", ++ NULL, ++ NULL, ++ NULL); ++ if (r < 0) ++ log_debug_errno(r, "Failed to drop reference to unit %s, ignoring: %m", item->bus_path); ++ } ++ ++ assert_se(hashmap_remove(item->parent->items, item->bus_path) == item); ++ ++ if (item->parent->current == item) ++ item->parent->current = NULL; ++ } ++ ++ sd_bus_slot_unref(item->slot_properties_changed); ++ sd_bus_slot_unref(item->slot_get_all); ++ ++ free(item->bus_path); ++ free(item->active_state); ++ free(item->clean_result); ++ ++ return mfree(item); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(WaitForItem*, wait_for_item_free); ++ ++static void bus_wait_for_units_clear(BusWaitForUnits *d) { ++ WaitForItem *item; ++ ++ assert(d); ++ ++ d->slot_disconnected = sd_bus_slot_unref(d->slot_disconnected); ++ d->bus = sd_bus_unref(d->bus); ++ ++ while ((item = hashmap_first(d->items))) { ++ d->current = item; ++ ++ item->unit_callback(d, item->bus_path, false, item->userdata); ++ wait_for_item_free(item); ++ } ++ ++ d->items = hashmap_free(d->items); ++} ++ ++static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) { ++ BusWaitForUnits *d = userdata; ++ ++ assert(m); ++ assert(d); ++ ++ log_error("Warning! D-Bus connection terminated."); ++ ++ bus_wait_for_units_clear(d); ++ ++ if (d->ready_callback) ++ d->ready_callback(d, false, d->userdata); ++ else /* If no ready callback is specified close the connection so that the event loop exits */ ++ sd_bus_close(sd_bus_message_get_bus(m)); ++ ++ return 0; ++} ++ ++int bus_wait_for_units_new(sd_bus *bus, BusWaitForUnits **ret) { ++ _cleanup_(bus_wait_for_units_freep) BusWaitForUnits *d = NULL; ++ int r; ++ ++ assert(bus); ++ assert(ret); ++ ++ d = new(BusWaitForUnits, 1); ++ if (!d) ++ return -ENOMEM; ++ ++ *d = (BusWaitForUnits) { ++ .state = BUS_WAIT_SUCCESS, ++ .bus = sd_bus_ref(bus), ++ }; ++ ++ r = sd_bus_match_signal_async( ++ bus, ++ &d->slot_disconnected, ++ "org.freedesktop.DBus.Local", ++ NULL, ++ "org.freedesktop.DBus.Local", ++ "Disconnected", ++ match_disconnected, NULL, d); ++ if (r < 0) ++ return r; ++ ++ *ret = TAKE_PTR(d); ++ return 0; ++} ++ ++BusWaitForUnits* bus_wait_for_units_free(BusWaitForUnits *d) { ++ if (!d) ++ return NULL; ++ ++ bus_wait_for_units_clear(d); ++ sd_bus_slot_unref(d->slot_disconnected); ++ sd_bus_unref(d->bus); ++ ++ return mfree(d); ++} ++ ++static bool bus_wait_for_units_is_ready(BusWaitForUnits *d) { ++ assert(d); ++ ++ if (!d->bus) /* Disconnected? */ ++ return true; ++ ++ return hashmap_isempty(d->items); ++} ++ ++void bus_wait_for_units_set_ready_callback(BusWaitForUnits *d, bus_wait_for_units_ready_callback callback, void *userdata) { ++ assert(d); ++ ++ d->ready_callback = callback; ++ d->userdata = userdata; ++} ++ ++static void bus_wait_for_units_check_ready(BusWaitForUnits *d) { ++ assert(d); ++ ++ if (!bus_wait_for_units_is_ready(d)) ++ return; ++ ++ d->state = d->has_failed ? BUS_WAIT_FAILURE : BUS_WAIT_SUCCESS; ++ ++ if (d->ready_callback) ++ d->ready_callback(d, d->state, d->userdata); ++} ++ ++static void wait_for_item_check_ready(WaitForItem *item) { ++ BusWaitForUnits *d; ++ ++ assert(item); ++ assert(d = item->parent); ++ ++ if (FLAGS_SET(item->flags, BUS_WAIT_FOR_MAINTENANCE_END)) { ++ ++ if (item->clean_result && !streq(item->clean_result, "success")) ++ d->has_failed = true; ++ ++ if (!item->active_state || streq(item->active_state, "maintenance")) ++ return; ++ } ++ ++ if (FLAGS_SET(item->flags, BUS_WAIT_NO_JOB) && item->job_id != 0) ++ return; ++ ++ if (FLAGS_SET(item->flags, BUS_WAIT_FOR_INACTIVE)) { ++ ++ if (streq_ptr(item->active_state, "failed")) ++ d->has_failed = true; ++ else if (!streq_ptr(item->active_state, "inactive")) ++ return; ++ } ++ ++ if (item->unit_callback) { ++ d->current = item; ++ item->unit_callback(d, item->bus_path, true, item->userdata); ++ } ++ ++ wait_for_item_free(item); ++ ++ bus_wait_for_units_check_ready(d); ++} ++ ++static int property_map_job( ++ sd_bus *bus, ++ const char *member, ++ sd_bus_message *m, ++ sd_bus_error *error, ++ void *userdata) { ++ ++ WaitForItem *item = userdata; ++ const char *path; ++ uint32_t id; ++ int r; ++ ++ assert(item); ++ ++ r = sd_bus_message_read(m, "(uo)", &id, &path); ++ if (r < 0) ++ return r; ++ ++ item->job_id = id; ++ return 0; ++} ++ ++static int wait_for_item_parse_properties(WaitForItem *item, sd_bus_message *m) { ++ ++ static const struct bus_properties_map map[] = { ++ { "ActiveState", "s", NULL, offsetof(WaitForItem, active_state) }, ++ { "Job", "(uo)", property_map_job, 0 }, ++ { "CleanResult", "s", NULL, offsetof(WaitForItem, clean_result) }, ++ {} ++ }; ++ ++ int r; ++ ++ assert(item); ++ assert(m); ++ ++ r = bus_message_map_all_properties(m, map, BUS_MAP_STRDUP, NULL, item); ++ if (r < 0) ++ return r; ++ ++ wait_for_item_check_ready(item); ++ return 0; ++} ++ ++static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) { ++ WaitForItem *item = userdata; ++ const char *interface; ++ int r; ++ ++ assert(item); ++ ++ r = sd_bus_message_read(m, "s", &interface); ++ if (r < 0) { ++ log_debug_errno(r, "Failed to parse PropertiesChanged signal: %m"); ++ return 0; ++ } ++ ++ if (!streq(interface, "org.freedesktop.systemd1.Unit")) ++ return 0; ++ ++ r = wait_for_item_parse_properties(item, m); ++ if (r < 0) ++ log_debug_errno(r, "Failed to process PropertiesChanged signal: %m"); ++ ++ return 0; ++} ++ ++static int on_get_all_properties(sd_bus_message *m, void *userdata, sd_bus_error *error) { ++ WaitForItem *item = userdata; ++ int r; ++ ++ assert(item); ++ ++ if (sd_bus_error_is_set(error)) { ++ BusWaitForUnits *d = item->parent; ++ ++ d->has_failed = true; ++ ++ log_debug_errno(sd_bus_error_get_errno(error), "GetAll() failed for %s: %s", ++ item->bus_path, error->message); ++ ++ d->current = item; ++ item->unit_callback(d, item->bus_path, false, item->userdata); ++ wait_for_item_free(item); ++ ++ bus_wait_for_units_check_ready(d); ++ return 0; ++ } ++ ++ r = wait_for_item_parse_properties(item, m); ++ if (r < 0) ++ log_debug_errno(r, "Failed to process GetAll method reply: %m"); ++ ++ return 0; ++} ++ ++int bus_wait_for_units_add_unit( ++ BusWaitForUnits *d, ++ const char *unit, ++ BusWaitForUnitsFlags flags, ++ bus_wait_for_units_unit_callback callback, ++ void *userdata) { ++ ++ _cleanup_(wait_for_item_freep) WaitForItem *item = NULL; ++ int r; ++ ++ assert(d); ++ assert(unit); ++ ++ assert(flags != 0); ++ ++ r = hashmap_ensure_allocated(&d->items, &string_hash_ops); ++ if (r < 0) ++ return r; ++ ++ item = new(WaitForItem, 1); ++ if (!item) ++ return -ENOMEM; ++ ++ *item = (WaitForItem) { ++ .flags = flags, ++ .bus_path = unit_dbus_path_from_name(unit), ++ .unit_callback = callback, ++ .userdata = userdata, ++ .job_id = UINT32_MAX, ++ }; ++ ++ if (!item->bus_path) ++ return -ENOMEM; ++ ++ if (!FLAGS_SET(item->flags, BUS_WAIT_REFFED)) { ++ r = sd_bus_call_method_async( ++ d->bus, ++ NULL, ++ "org.freedesktop.systemd1", ++ item->bus_path, ++ "org.freedesktop.systemd1.Unit", ++ "Ref", ++ NULL, ++ NULL, ++ NULL); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to add reference to unit %s: %m", unit); ++ ++ ++ item->flags |= BUS_WAIT_REFFED; ++ } ++ ++ r = sd_bus_match_signal_async( ++ d->bus, ++ &item->slot_properties_changed, ++ "org.freedesktop.systemd1", ++ item->bus_path, ++ "org.freedesktop.DBus.Properties", ++ "PropertiesChanged", ++ on_properties_changed, ++ NULL, ++ item); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to request match for PropertiesChanged signal: %m"); ++ ++ r = sd_bus_call_method_async( ++ d->bus, ++ &item->slot_get_all, ++ "org.freedesktop.systemd1", ++ item->bus_path, ++ "org.freedesktop.DBus.Properties", ++ "GetAll", ++ on_get_all_properties, ++ item, ++ "s", FLAGS_SET(item->flags, BUS_WAIT_FOR_MAINTENANCE_END) ? NULL : "org.freedesktop.systemd1.Unit"); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to request properties of unit %s: %m", unit); ++ ++ r = hashmap_put(d->items, item->bus_path, item); ++ if (r < 0) ++ return r; ++ ++ d->state = BUS_WAIT_RUNNING; ++ item->parent = d; ++ TAKE_PTR(item); ++ return 0; ++} ++ ++int bus_wait_for_units_run(BusWaitForUnits *d) { ++ int r; ++ ++ assert(d); ++ ++ while (d->state == BUS_WAIT_RUNNING) { ++ ++ r = sd_bus_process(d->bus, NULL); ++ if (r < 0) ++ return r; ++ if (r > 0) ++ continue; ++ ++ r = sd_bus_wait(d->bus, (uint64_t) -1); ++ if (r < 0) ++ return r; ++ } ++ ++ return d->state; ++} ++ ++BusWaitForUnitsState bus_wait_for_units_state(BusWaitForUnits *d) { ++ assert(d); ++ ++ return d->state; ++} +diff --git a/src/shared/bus-wait-for-units.h b/src/shared/bus-wait-for-units.h +new file mode 100644 +index 0000000000..a20f3d8fd7 +--- /dev/null ++++ b/src/shared/bus-wait-for-units.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++#include "macro.h" ++#include "sd-bus.h" ++ ++typedef struct BusWaitForUnits BusWaitForUnits; ++ ++typedef enum BusWaitForUnitsState { ++ BUS_WAIT_SUCCESS, /* Nothing to wait for anymore and nothing failed */ ++ BUS_WAIT_FAILURE, /* dito, but something failed */ ++ BUS_WAIT_RUNNING, /* Still something to wait for */ ++ _BUS_WAIT_FOR_UNITS_STATE_MAX, ++ _BUS_WAIT_FOR_UNITS_STATE_INVALID = -1, ++} BusWaitForUnitsState; ++ ++typedef enum BusWaitForUnitsFlags { ++ BUS_WAIT_FOR_MAINTENANCE_END = 1 << 0, /* Wait until the unit is no longer in maintenance state */ ++ BUS_WAIT_FOR_INACTIVE = 1 << 1, /* Wait until the unit is back in inactive or dead state */ ++ BUS_WAIT_NO_JOB = 1 << 2, /* Wait until there's no more job pending */ ++ BUS_WAIT_REFFED = 1 << 3, /* The unit is already reffed with RefUnit() */ ++} BusWaitForUnitsFlags; ++ ++typedef void (*bus_wait_for_units_ready_callback)(BusWaitForUnits *d, BusWaitForUnitsState state, void *userdata); ++typedef void (*bus_wait_for_units_unit_callback)(BusWaitForUnits *d, const char *unit_path, bool good, void *userdata); ++ ++int bus_wait_for_units_new(sd_bus *bus, BusWaitForUnits **ret); ++BusWaitForUnits* bus_wait_for_units_free(BusWaitForUnits *d); ++ ++BusWaitForUnitsState bus_wait_for_units_state(BusWaitForUnits *d); ++void bus_wait_for_units_set_ready_callback(BusWaitForUnits *d, bus_wait_for_units_ready_callback callback, void *userdata); ++int bus_wait_for_units_add_unit(BusWaitForUnits *d, const char *unit, BusWaitForUnitsFlags flags, bus_wait_for_units_unit_callback callback, void *userdata); ++int bus_wait_for_units_run(BusWaitForUnits *d); ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForUnits*, bus_wait_for_units_free); +diff --git a/src/shared/meson.build b/src/shared/meson.build +index 54e77e9af6..d0a1bba4c6 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -18,6 +18,8 @@ shared_sources = files(''' + bus-unit-util.h + bus-util.c + bus-util.h ++ bus-wait-for-units.c ++ bus-wait-for-units.h + cgroup-show.c + cgroup-show.h + clean-ipc.c diff --git a/SOURCES/0421-shared-fix-assert-call.patch b/SOURCES/0421-shared-fix-assert-call.patch new file mode 100644 index 0000000..5650d80 --- /dev/null +++ b/SOURCES/0421-shared-fix-assert-call.patch @@ -0,0 +1,27 @@ +From 63b5df7c9fda4f7d44674076da5fc5cef4564f3a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 17 Jul 2019 09:39:39 +0200 +Subject: [PATCH] shared: fix assert call + +Fixup for 3572d3df8f8. Coverity CID#1403013. + +(cherry picked from commit 60b17d6fcd988c9995b7d1476d3aba1c4cbbfddd) + +Related: #1830861 +--- + src/shared/bus-wait-for-units.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/bus-wait-for-units.c b/src/shared/bus-wait-for-units.c +index d07f491e93..de15da1620 100644 +--- a/src/shared/bus-wait-for-units.c ++++ b/src/shared/bus-wait-for-units.c +@@ -190,7 +190,7 @@ static void wait_for_item_check_ready(WaitForItem *item) { + BusWaitForUnits *d; + + assert(item); +- assert(d = item->parent); ++ assert_se(d = item->parent); + + if (FLAGS_SET(item->flags, BUS_WAIT_FOR_MAINTENANCE_END)) { + diff --git a/SOURCES/0422-shared-Don-t-try-calling-NULL-callback-in-bus_wait_f.patch b/SOURCES/0422-shared-Don-t-try-calling-NULL-callback-in-bus_wait_f.patch new file mode 100644 index 0000000..43aaa66 --- /dev/null +++ b/SOURCES/0422-shared-Don-t-try-calling-NULL-callback-in-bus_wait_f.patch @@ -0,0 +1,28 @@ +From e607286e070675498fcd5a7ab73bc3da533f9eea Mon Sep 17 00:00:00 2001 +From: Balint Reczey +Date: Wed, 22 Apr 2020 09:51:53 +0200 +Subject: [PATCH] shared: Don't try calling NULL callback in + bus_wait_for_units_clear + +BugLink: https://bugs.launchpad.net/bugs/1870930 +(cherry picked from commit 9f656373082cb13542b877b4f5cb917ef5ff329c) + +Related: #1830861 +--- + src/shared/bus-wait-for-units.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/shared/bus-wait-for-units.c b/src/shared/bus-wait-for-units.c +index de15da1620..63ba3fd422 100644 +--- a/src/shared/bus-wait-for-units.c ++++ b/src/shared/bus-wait-for-units.c +@@ -91,7 +91,8 @@ static void bus_wait_for_units_clear(BusWaitForUnits *d) { + while ((item = hashmap_first(d->items))) { + d->current = item; + +- item->unit_callback(d, item->bus_path, false, item->userdata); ++ if (item->unit_callback) ++ item->unit_callback(d, item->bus_path, false, item->userdata); + wait_for_item_free(item); + } + diff --git a/SOURCES/0423-shared-add-NULL-callback-check-in-one-more-place.patch b/SOURCES/0423-shared-add-NULL-callback-check-in-one-more-place.patch new file mode 100644 index 0000000..f0d4a5d --- /dev/null +++ b/SOURCES/0423-shared-add-NULL-callback-check-in-one-more-place.patch @@ -0,0 +1,77 @@ +From 48ab0db62ab23307e9f35a862a9c9b33ba3ef261 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 23 Apr 2020 14:53:54 +0200 +Subject: [PATCH] shared: add NULL callback check in one more place + +Follow-up for 9f65637308. + +(cherry picked from commit d3d53e5cd143bf96d1eb0e254f16fa8d458d38ce) + +Related: #1830861 +--- + src/shared/bus-wait-for-units.c | 31 +++++++++++++------------------ + 1 file changed, 13 insertions(+), 18 deletions(-) + +diff --git a/src/shared/bus-wait-for-units.c b/src/shared/bus-wait-for-units.c +index 63ba3fd422..ba97922764 100644 +--- a/src/shared/bus-wait-for-units.c ++++ b/src/shared/bus-wait-for-units.c +@@ -80,6 +80,15 @@ static WaitForItem *wait_for_item_free(WaitForItem *item) { + + DEFINE_TRIVIAL_CLEANUP_FUNC(WaitForItem*, wait_for_item_free); + ++static void call_unit_callback_and_wait(BusWaitForUnits *d, WaitForItem *item, bool good) { ++ d->current = item; ++ ++ if (item->unit_callback) ++ item->unit_callback(d, item->bus_path, good, item->userdata); ++ ++ wait_for_item_free(item); ++} ++ + static void bus_wait_for_units_clear(BusWaitForUnits *d) { + WaitForItem *item; + +@@ -88,13 +97,8 @@ static void bus_wait_for_units_clear(BusWaitForUnits *d) { + d->slot_disconnected = sd_bus_slot_unref(d->slot_disconnected); + d->bus = sd_bus_unref(d->bus); + +- while ((item = hashmap_first(d->items))) { +- d->current = item; +- +- if (item->unit_callback) +- item->unit_callback(d, item->bus_path, false, item->userdata); +- wait_for_item_free(item); +- } ++ while ((item = hashmap_first(d->items))) ++ call_unit_callback_and_wait(d, item, false); + + d->items = hashmap_free(d->items); + } +@@ -213,13 +217,7 @@ static void wait_for_item_check_ready(WaitForItem *item) { + return; + } + +- if (item->unit_callback) { +- d->current = item; +- item->unit_callback(d, item->bus_path, true, item->userdata); +- } +- +- wait_for_item_free(item); +- ++ call_unit_callback_and_wait(d, item, true); + bus_wait_for_units_check_ready(d); + } + +@@ -304,10 +302,7 @@ static int on_get_all_properties(sd_bus_message *m, void *userdata, sd_bus_error + log_debug_errno(sd_bus_error_get_errno(error), "GetAll() failed for %s: %s", + item->bus_path, error->message); + +- d->current = item; +- item->unit_callback(d, item->bus_path, false, item->userdata); +- wait_for_item_free(item); +- ++ call_unit_callback_and_wait(d, item, false); + bus_wait_for_units_check_ready(d); + return 0; + } diff --git a/SOURCES/0424-core-introduce-support-for-cgroup-freezer.patch b/SOURCES/0424-core-introduce-support-for-cgroup-freezer.patch new file mode 100644 index 0000000..58cd2e7 --- /dev/null +++ b/SOURCES/0424-core-introduce-support-for-cgroup-freezer.patch @@ -0,0 +1,1146 @@ +From 046ea98539eb8d7cef93d8062035fa6d9f58efea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Wed, 29 Apr 2020 17:53:43 +0200 +Subject: [PATCH] core: introduce support for cgroup freezer + +With cgroup v2 the cgroup freezer is implemented as a cgroup +attribute called cgroup.freeze. cgroup can be frozen by writing "1" +to the file and kernel will send us a notification through +"cgroup.events" after the operation is finished and processes in the +cgroup entered quiescent state, i.e. they are not scheduled to +run. Writing "0" to the attribute file does the inverse and process +execution is resumed. + +This commit exposes above low-level functionality through systemd's DBus +API. Each unit type must provide specialized implementation for these +methods, otherwise, we return an error. So far only service, scope, and +slice unit types provide the support. It is possible to check if a +given unit has the support using CanFreeze() DBus property. + +Note that DBus API has a synchronous behavior and we dispatch the reply +to freeze/thaw requests only after the kernel has notified us that +requested operation was completed. + +(cherry picked from commit d9e45bc3abb8adf5a1cb20816ba8f2d2aa65b17e) + +Resolves: #1830861 +--- + man/systemctl.xml | 24 +++++ + src/basic/cgroup-util.c | 18 +++- + src/basic/cgroup-util.h | 1 + + src/basic/unit-def.c | 9 ++ + src/basic/unit-def.h | 12 +++ + src/core/cgroup.c | 105 ++++++++++++++++-- + src/core/cgroup.h | 12 +++ + src/core/dbus-manager.c | 50 +++++++++ + src/core/dbus-unit.c | 96 +++++++++++++++++ + src/core/dbus-unit.h | 3 + + src/core/dbus.c | 7 +- + src/core/scope.c | 3 + + src/core/service.c | 3 + + src/core/slice.c | 80 ++++++++++++++ + src/core/unit.c | 123 ++++++++++++++++++++++ + src/core/unit.h | 20 ++++ + src/libsystemd/sd-bus/bus-common-errors.h | 2 + + src/systemctl/systemctl.c | 105 +++++++++++++++++- + 18 files changed, 660 insertions(+), 13 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index d95d3726af..6145486123 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -873,6 +873,30 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago + the signal to send. + + ++ ++ freeze PATTERN ++ ++ ++ Freeze one or more units specified on the ++ command line using cgroup freezer ++ ++ Freezing the unit will cause all processes contained within the cgroup corresponding to the unit ++ to be suspended. Being suspended means that unit's processes won't be scheduled to run on CPU until thawed. ++ Note that this command is supported only on systems that use unified cgroup hierarchy. Unit is automatically ++ thawed just before we execute a job against the unit, e.g. before the unit is stopped. ++ ++ ++ ++ thaw PATTERN ++ ++ ++ Thaw (unfreeze) one or more units specified on the ++ command line. ++ ++ This is the inverse operation to the freeze command and resumes the execution of ++ processes in the unit's cgroup. ++ ++ + + is-active PATTERN + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 4c0b73850d..992b12811a 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -137,6 +137,17 @@ bool cg_ns_supported(void) { + return enabled; + } + ++bool cg_freezer_supported(void) { ++ static thread_local int supported = -1; ++ ++ if (supported >= 0) ++ return supported; ++ ++ supported = cg_all_unified() > 0 && access("/sys/fs/cgroup/init.scope/cgroup.freeze", F_OK) == 0; ++ ++ return supported; ++} ++ + int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) { + _cleanup_free_ char *fs = NULL; + int r; +@@ -2039,7 +2050,8 @@ int cg_get_keyed_attribute_full( + * all keys to retrieve. The 'ret_values' parameter should be passed as string size with the same number of + * entries as 'keys'. On success each entry will be set to the value of the matching key. + * +- * If the attribute file doesn't exist at all returns ENOENT, if any key is not found returns ENXIO. */ ++ * If the attribute file doesn't exist at all returns ENOENT, if any key is not found returns ENXIO. If mode ++ * is set to GG_KEY_MODE_GRACEFUL we ignore missing keys and return those that were parsed successfully. */ + + r = cg_get_path(controller, path, attribute, &filename); + if (r < 0) +@@ -2089,8 +2101,8 @@ int cg_get_keyed_attribute_full( + + if (mode & CG_KEY_MODE_GRACEFUL) + goto done; +- else +- r = -ENXIO; ++ ++ r = -ENXIO; + + fail: + for (i = 0; i < n; i++) +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index 0673f4b4ce..1210b38a83 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -250,6 +250,7 @@ int cg_mask_to_string(CGroupMask mask, char **ret); + int cg_kernel_controllers(Set **controllers); + + bool cg_ns_supported(void); ++bool cg_freezer_supported(void); + + int cg_all_unified(void); + int cg_hybrid_unified(void); +diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c +index 46593f6e65..e79cc73dd3 100644 +--- a/src/basic/unit-def.c ++++ b/src/basic/unit-def.c +@@ -107,6 +107,15 @@ static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { + + DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); + ++static const char* const freezer_state_table[_FREEZER_STATE_MAX] = { ++ [FREEZER_RUNNING] = "running", ++ [FREEZER_FREEZING] = "freezing", ++ [FREEZER_FROZEN] = "frozen", ++ [FREEZER_THAWING] = "thawing", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(freezer_state, FreezerState); ++ + static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = { + [AUTOMOUNT_DEAD] = "dead", + [AUTOMOUNT_WAITING] = "waiting", +diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h +index db397a31ed..8eea379a6d 100644 +--- a/src/basic/unit-def.h ++++ b/src/basic/unit-def.h +@@ -44,6 +44,15 @@ typedef enum UnitActiveState { + _UNIT_ACTIVE_STATE_INVALID = -1 + } UnitActiveState; + ++typedef enum FreezerState { ++ FREEZER_RUNNING, ++ FREEZER_FREEZING, ++ FREEZER_FROZEN, ++ FREEZER_THAWING, ++ _FREEZER_STATE_MAX, ++ _FREEZER_STATE_INVALID = -1 ++} FreezerState; ++ + typedef enum AutomountState { + AUTOMOUNT_DEAD, + AUTOMOUNT_WAITING, +@@ -245,6 +254,9 @@ UnitLoadState unit_load_state_from_string(const char *s) _pure_; + const char *unit_active_state_to_string(UnitActiveState i) _const_; + UnitActiveState unit_active_state_from_string(const char *s) _pure_; + ++const char *freezer_state_to_string(FreezerState i) _const_; ++FreezerState freezer_state_from_string(const char *s) _pure_; ++ + const char* automount_state_to_string(AutomountState i) _const_; + AutomountState automount_state_from_string(const char *s) _pure_; + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 7a9857adad..e7ae9273a6 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2279,6 +2279,51 @@ void unit_add_to_cgroup_empty_queue(Unit *u) { + log_debug_errno(r, "Failed to enable cgroup empty event source: %m"); + } + ++static void unit_remove_from_cgroup_empty_queue(Unit *u) { ++ assert(u); ++ ++ if (!u->in_cgroup_empty_queue) ++ return; ++ ++ LIST_REMOVE(cgroup_empty_queue, u->manager->cgroup_empty_queue, u); ++ u->in_cgroup_empty_queue = false; ++} ++ ++static int unit_check_cgroup_events(Unit *u) { ++ char *values[2] = {}; ++ int r; ++ ++ assert(u); ++ ++ r = cg_get_keyed_attribute_graceful(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events", ++ STRV_MAKE("populated", "frozen"), values); ++ if (r < 0) ++ return r; ++ ++ /* The cgroup.events notifications can be merged together so act as we saw the given state for the ++ * first time. The functions we call to handle given state are idempotent, which makes them ++ * effectively remember the previous state. */ ++ if (values[0]) { ++ if (streq(values[0], "1")) ++ unit_remove_from_cgroup_empty_queue(u); ++ else ++ unit_add_to_cgroup_empty_queue(u); ++ } ++ ++ /* Disregard freezer state changes due to operations not initiated by us */ ++ if (values[1] && IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)) { ++ if (streq(values[1], "0")) ++ unit_thawed(u); ++ else ++ unit_frozen(u); ++ } ++ ++ free(values[0]); ++ free(values[1]); ++ ++ return 0; ++} ++ + static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + Manager *m = userdata; + +@@ -2310,15 +2355,12 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, + /* The watch was just removed */ + continue; + +- u = hashmap_get(m->cgroup_inotify_wd_unit, INT_TO_PTR(e->wd)); +- if (!u) /* Not that inotify might deliver +- * events for a watch even after it +- * was removed, because it was queued +- * before the removal. Let's ignore +- * this here safely. */ +- continue; ++ /* Note that inotify might deliver events for a watch even after it was removed, ++ * because it was queued before the removal. Let's ignore this here safely. */ + +- unit_add_to_cgroup_empty_queue(u); ++ u = hashmap_get(m->cgroup_inotify_wd_unit, INT_TO_PTR(e->wd)); ++ if (u) ++ unit_check_cgroup_events(u); + } + } + } +@@ -2884,6 +2926,46 @@ void manager_invalidate_startup_units(Manager *m) { + unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO); + } + ++int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { ++ _cleanup_free_ char *path = NULL; ++ FreezerState target, kernel = _FREEZER_STATE_INVALID; ++ int r; ++ ++ assert(u); ++ assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW)); ++ ++ if (!u->cgroup_realized) ++ return -EBUSY; ++ ++ target = action == FREEZER_FREEZE ? FREEZER_FROZEN : FREEZER_RUNNING; ++ ++ r = unit_freezer_state_kernel(u, &kernel); ++ if (r < 0) ++ log_unit_debug_errno(u, r, "Failed to obtain cgroup freezer state: %m"); ++ ++ if (target == kernel) { ++ u->freezer_state = target; ++ return 0; ++ } ++ ++ r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.freeze", &path); ++ if (r < 0) ++ return r; ++ ++ log_unit_debug(u, "%s unit.", action == FREEZER_FREEZE ? "Freezing" : "Thawing"); ++ ++ if (action == FREEZER_FREEZE) ++ u->freezer_state = FREEZER_FREEZING; ++ else ++ u->freezer_state = FREEZER_THAWING; ++ ++ r = write_string_file(path, one_zero(action == FREEZER_FREEZE), WRITE_STRING_FILE_DISABLE_BUFFER); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = { + [CGROUP_AUTO] = "auto", + [CGROUP_CLOSED] = "closed", +@@ -2919,3 +3001,10 @@ int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) { + } + + DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy); ++ ++static const char* const freezer_action_table[_FREEZER_ACTION_MAX] = { ++ [FREEZER_FREEZE] = "freeze", ++ [FREEZER_THAW] = "thaw", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(freezer_action, FreezerAction); +diff --git a/src/core/cgroup.h b/src/core/cgroup.h +index 976224336d..36ea77fdc5 100644 +--- a/src/core/cgroup.h ++++ b/src/core/cgroup.h +@@ -33,6 +33,14 @@ typedef enum CGroupDevicePolicy { + _CGROUP_DEVICE_POLICY_INVALID = -1 + } CGroupDevicePolicy; + ++typedef enum FreezerAction { ++ FREEZER_FREEZE, ++ FREEZER_THAW, ++ ++ _FREEZER_ACTION_MAX, ++ _FREEZER_ACTION_INVALID = -1, ++} FreezerAction; ++ + struct CGroupDeviceAllow { + LIST_FIELDS(CGroupDeviceAllow, device_allow); + char *path; +@@ -235,3 +243,7 @@ CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_; + + bool unit_cgroup_delegate(Unit *u); + int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name); ++int unit_cgroup_freezer_action(Unit *u, FreezerAction action); ++ ++const char* freezer_action_to_string(FreezerAction a) _const_; ++FreezerAction freezer_action_from_string(const char *s) _pure_; +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index b3c011b0df..a0777f63d5 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -683,6 +683,54 @@ static int method_unref_unit(sd_bus_message *message, void *userdata, sd_bus_err + return bus_unit_method_unref(message, u, error); + } + ++static int method_freeze_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ Manager *m = userdata; ++ const char *name; ++ Unit *u; ++ int r; ++ ++ assert(message); ++ assert(m); ++ ++ r = sd_bus_message_read(message, "s", &name); ++ if (r < 0) ++ return r; ++ ++ r = bus_load_unit_by_name(m, message, name, &u, error); ++ if (r < 0) ++ return r; ++ ++ r = bus_unit_validate_load_state(u, error); ++ if (r < 0) ++ return r; ++ ++ return bus_unit_method_freeze(message, u, error); ++} ++ ++static int method_thaw_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ Manager *m = userdata; ++ const char *name; ++ Unit *u; ++ int r; ++ ++ assert(message); ++ assert(m); ++ ++ r = sd_bus_message_read(message, "s", &name); ++ if (r < 0) ++ return r; ++ ++ r = bus_load_unit_by_name(m, message, name, &u, error); ++ if (r < 0) ++ return r; ++ ++ r = bus_unit_validate_load_state(u, error); ++ if (r < 0) ++ return r; ++ ++ return bus_unit_method_thaw(message, u, error); ++} ++ + static int reply_unit_info(sd_bus_message *reply, Unit *u) { + _cleanup_free_ char *unit_path = NULL, *job_path = NULL; + Unit *following; +@@ -2500,6 +2548,8 @@ const sd_bus_vtable bus_manager_vtable[] = { + SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("FreezeUnit", "s", NULL, method_freeze_unit, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("ThawUnit", "s", NULL, method_thaw_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("RefUnit", "s", NULL, method_ref_unit, SD_BUS_VTABLE_UNPRIVILEGED), +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index aa15e47754..ce81103e92 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -42,12 +42,14 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode); + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction); + static BUS_DEFINE_PROPERTY_GET(property_get_description, "s", Unit, unit_description); + static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_active_state, unit_active_state_to_string); ++static BUS_DEFINE_PROPERTY_GET2(property_get_freezer_state, "s", Unit, unit_freezer_state, freezer_state_to_string); + static BUS_DEFINE_PROPERTY_GET(property_get_sub_state, "s", Unit, unit_sub_state_to_string); + static BUS_DEFINE_PROPERTY_GET2(property_get_unit_file_state, "s", Unit, unit_get_unit_file_state, unit_file_state_to_string); + static BUS_DEFINE_PROPERTY_GET(property_get_can_reload, "b", Unit, unit_can_reload); + static BUS_DEFINE_PROPERTY_GET(property_get_can_start, "b", Unit, unit_can_start_refuse_manual); + static BUS_DEFINE_PROPERTY_GET(property_get_can_stop, "b", Unit, unit_can_stop_refuse_manual); + static BUS_DEFINE_PROPERTY_GET(property_get_can_isolate, "b", Unit, unit_can_isolate_refuse_manual); ++static BUS_DEFINE_PROPERTY_GET(property_get_can_freeze, "b", Unit, unit_can_freeze); + static BUS_DEFINE_PROPERTY_GET(property_get_need_daemon_reload, "b", Unit, unit_need_daemon_reload); + static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_strv, "as", 0); + +@@ -561,6 +563,79 @@ int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error + return sd_bus_reply_method_return(message, NULL); + } + ++static int bus_unit_method_freezer_generic(sd_bus_message *message, void *userdata, sd_bus_error *error, FreezerAction action) { ++ const char* perm; ++ int (*method)(Unit*); ++ Unit *u = userdata; ++ bool reply_no_delay = false; ++ int r; ++ ++ assert(message); ++ assert(u); ++ assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW)); ++ ++ if (action == FREEZER_FREEZE) { ++ perm = "stop"; ++ method = unit_freeze; ++ } else { ++ perm = "start"; ++ method = unit_thaw; ++ } ++ ++ r = mac_selinux_unit_access_check(u, message, perm, error); ++ if (r < 0) ++ return r; ++ ++ r = bus_verify_manage_units_async_full( ++ u, ++ perm, ++ CAP_SYS_ADMIN, ++ N_("Authentication is required to freeze or thaw the processes of '$(unit)' unit."), ++ true, ++ message, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ ++ ++ r = method(u); ++ if (r == -EOPNOTSUPP) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not support freezing.", u->id); ++ if (r == -EBUSY) ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_BUSY, "Unit has a pending job."); ++ if (r == -EHOSTDOWN) ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_INACTIVE, "Unit is inactive."); ++ if (r == -EALREADY) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Previously requested freezer operation for unit '%s' is still in progress.", u->id); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ reply_no_delay = true; ++ ++ assert(!u->pending_freezer_message); ++ ++ r = sd_bus_message_new_method_return(message, &u->pending_freezer_message); ++ if (r < 0) ++ return r; ++ ++ if (reply_no_delay) { ++ r = bus_unit_send_pending_freezer_message(u); ++ if (r < 0) ++ return r; ++ } ++ ++ return 1; ++} ++ ++int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_THAW); ++} ++ ++int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_FREEZE); ++} ++ + const sd_bus_vtable bus_unit_vtable[] = { + SD_BUS_VTABLE_START(0), + +@@ -592,6 +667,7 @@ const sd_bus_vtable bus_unit_vtable[] = { + SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), ++ SD_BUS_PROPERTY("FreezerState", "s", property_get_freezer_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("SubState", "s", property_get_sub_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -607,6 +683,7 @@ const sd_bus_vtable bus_unit_vtable[] = { + SD_BUS_PROPERTY("CanStop", "b", property_get_can_stop, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("CanFreeze", "b", property_get_can_freeze, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Job", "(uo)", property_get_job, offsetof(Unit, job), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -650,6 +727,8 @@ const sd_bus_vtable bus_unit_vtable[] = { + SD_BUS_METHOD("SetProperties", "ba(sv)", NULL, bus_unit_method_set_properties, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Ref", NULL, NULL, bus_unit_method_ref, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Unref", NULL, NULL, bus_unit_method_unref, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("Freeze", NULL, NULL, bus_unit_method_freeze, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("Thaw", NULL, NULL, bus_unit_method_thaw, SD_BUS_VTABLE_UNPRIVILEGED), + + /* For dependency types we don't support anymore always return an empty array */ + SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN), +@@ -1209,6 +1288,23 @@ void bus_unit_send_change_signal(Unit *u) { + u->sent_dbus_new_signal = true; + } + ++int bus_unit_send_pending_freezer_message(Unit *u) { ++ int r; ++ ++ assert(u); ++ ++ if (!u->pending_freezer_message) ++ return 0; ++ ++ r = sd_bus_send(NULL, u->pending_freezer_message, NULL); ++ if (r < 0) ++ log_warning_errno(r, "Failed to send queued message, ignoring: %m"); ++ ++ u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); ++ ++ return 0; ++} ++ + static int send_removed_signal(sd_bus *bus, void *userdata) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_free_ char *p = NULL; +diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h +index 68eb621836..39aa1bb53c 100644 +--- a/src/core/dbus-unit.h ++++ b/src/core/dbus-unit.h +@@ -11,6 +11,7 @@ extern const sd_bus_vtable bus_unit_vtable[]; + extern const sd_bus_vtable bus_unit_cgroup_vtable[]; + + void bus_unit_send_change_signal(Unit *u); ++int bus_unit_send_pending_freezer_message(Unit *u); + void bus_unit_send_removed_signal(Unit *u); + + int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error); +@@ -23,6 +24,8 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu + int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd_bus_error *error); + int bus_unit_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error); + int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error *error); ++int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error *error); ++int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error); + + int bus_unit_queue_job(sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error); + int bus_unit_validate_load_state(Unit *u, sd_bus_error *error); +diff --git a/src/core/dbus.c b/src/core/dbus.c +index 346a440c5d..b69c11c519 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -1073,10 +1073,15 @@ static void destroy_bus(Manager *m, sd_bus **bus) { + if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus) + j->bus_track = sd_bus_track_unref(j->bus_track); + +- HASHMAP_FOREACH(u, m->units, i) ++ HASHMAP_FOREACH(u, m->units, i) { + if (u->bus_track && sd_bus_track_get_bus(u->bus_track) == *bus) + u->bus_track = sd_bus_track_unref(u->bus_track); + ++ /* Get rid of pending freezer messages on this bus */ ++ if (u->pending_freezer_message && sd_bus_message_get_bus(u->pending_freezer_message) == *bus) ++ u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); ++ } ++ + /* Get rid of queued message on this bus */ + if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus) + m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); +diff --git a/src/core/scope.c b/src/core/scope.c +index a1a5363244..5a595c65a6 100644 +--- a/src/core/scope.c ++++ b/src/core/scope.c +@@ -601,6 +601,9 @@ const UnitVTable scope_vtable = { + + .kill = scope_kill, + ++ .freeze = unit_freeze_vtable_common, ++ .thaw = unit_thaw_vtable_common, ++ + .get_timeout = scope_get_timeout, + + .serialize = scope_serialize, +diff --git a/src/core/service.c b/src/core/service.c +index 1d98ee37fd..89b41f6783 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -4143,6 +4143,9 @@ const UnitVTable service_vtable = { + + .kill = service_kill, + ++ .freeze = unit_freeze_vtable_common, ++ .thaw = unit_thaw_vtable_common, ++ + .serialize = service_serialize, + .deserialize_item = service_deserialize_item, + +diff --git a/src/core/slice.c b/src/core/slice.c +index 58f18a4dad..b5eb2f5c01 100644 +--- a/src/core/slice.c ++++ b/src/core/slice.c +@@ -344,6 +344,82 @@ static void slice_enumerate_perpetual(Manager *m) { + (void) slice_make_perpetual(m, SPECIAL_SYSTEM_SLICE, NULL); + } + ++static bool slice_freezer_action_supported_by_children(Unit *s) { ++ Unit *member; ++ void *v; ++ Iterator i; ++ ++ assert(s); ++ ++ HASHMAP_FOREACH_KEY(v, member, s->dependencies[UNIT_BEFORE], i) { ++ int r; ++ ++ if (UNIT_DEREF(member->slice) != s) ++ continue; ++ ++ if (member->type == UNIT_SLICE) { ++ r = slice_freezer_action_supported_by_children(member); ++ if (!r) ++ return r; ++ } ++ ++ if (!UNIT_VTABLE(member)->freeze) ++ return false; ++ } ++ ++ return true; ++} ++ ++static int slice_freezer_action(Unit *s, FreezerAction action) { ++ Unit *member; ++ void *v; ++ Iterator i; ++ int r; ++ ++ assert(s); ++ assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW)); ++ ++ if (!slice_freezer_action_supported_by_children(s)) ++ return log_unit_warning(s, "Requested freezer operation is not supported by all children of the slice"); ++ ++ HASHMAP_FOREACH_KEY(v, member, s->dependencies[UNIT_BEFORE], i) { ++ if (UNIT_DEREF(member->slice) != s) ++ continue; ++ ++ if (action == FREEZER_FREEZE) ++ r = UNIT_VTABLE(member)->freeze(member); ++ else ++ r = UNIT_VTABLE(member)->thaw(member); ++ ++ if (r < 0) ++ return r; ++ } ++ ++ r = unit_cgroup_freezer_action(s, action); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++static int slice_freeze(Unit *s) { ++ assert(s); ++ ++ return slice_freezer_action(s, FREEZER_FREEZE); ++} ++ ++static int slice_thaw(Unit *s) { ++ assert(s); ++ ++ return slice_freezer_action(s, FREEZER_THAW); ++} ++ ++static bool slice_can_freeze(Unit *s) { ++ assert(s); ++ ++ return slice_freezer_action_supported_by_children(s); ++} ++ + const UnitVTable slice_vtable = { + .object_size = sizeof(Slice), + .cgroup_context_offset = offsetof(Slice, cgroup_context), +@@ -368,6 +444,10 @@ const UnitVTable slice_vtable = { + + .kill = slice_kill, + ++ .freeze = slice_freeze, ++ .thaw = slice_thaw, ++ .can_freeze = slice_can_freeze, ++ + .serialize = slice_serialize, + .deserialize_item = slice_deserialize_item, + +diff --git a/src/core/unit.c b/src/core/unit.c +index f57260727f..29ce6c1fb7 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -583,6 +583,7 @@ void unit_free(Unit *u) { + sd_bus_slot_unref(u->match_bus_slot); + sd_bus_track_unref(u->bus_track); + u->deserialized_refs = strv_free(u->deserialized_refs); ++ u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); + + unit_free_requires_mounts_for(u); + +@@ -685,6 +686,38 @@ void unit_free(Unit *u) { + free(u); + } + ++FreezerState unit_freezer_state(Unit *u) { ++ assert(u); ++ ++ return u->freezer_state; ++} ++ ++int unit_freezer_state_kernel(Unit *u, FreezerState *ret) { ++ char *values[1] = {}; ++ int r; ++ ++ assert(u); ++ ++ r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events", ++ STRV_MAKE("frozen"), values); ++ if (r < 0) ++ return r; ++ ++ r = _FREEZER_STATE_INVALID; ++ ++ if (values[0]) { ++ if (streq(values[0], "0")) ++ r = FREEZER_RUNNING; ++ else if (streq(values[0], "1")) ++ r = FREEZER_FROZEN; ++ } ++ ++ free(values[0]); ++ *ret = r; ++ ++ return 0; ++} ++ + UnitActiveState unit_active_state(Unit *u) { + assert(u); + +@@ -1760,6 +1793,7 @@ int unit_start(Unit *u) { + * before it will start again. */ + + unit_add_to_dbus_queue(u); ++ unit_cgroup_freezer_action(u, FREEZER_THAW); + + return UNIT_VTABLE(u)->start(u); + } +@@ -1812,6 +1846,7 @@ int unit_stop(Unit *u) { + return -EBADR; + + unit_add_to_dbus_queue(u); ++ unit_cgroup_freezer_action(u, FREEZER_THAW); + + return UNIT_VTABLE(u)->stop(u); + } +@@ -1868,6 +1903,8 @@ int unit_reload(Unit *u) { + return 0; + } + ++ unit_cgroup_freezer_action(u, FREEZER_THAW); ++ + return UNIT_VTABLE(u)->reload(u); + } + +@@ -3208,6 +3245,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { + if (!sd_id128_is_null(u->invocation_id)) + unit_serialize_item_format(u, f, "invocation-id", SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id)); + ++ (void) unit_serialize_item_format(u, f, "freezer-state", "%s", freezer_state_to_string(unit_freezer_state(u))); ++ + bus_track_serialize(u->bus_track, f, "ref"); + + for (m = 0; m < _CGROUP_IP_ACCOUNTING_METRIC_MAX; m++) { +@@ -3574,6 +3613,16 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + log_unit_warning_errno(u, r, "Failed to set invocation ID for unit: %m"); + } + ++ continue; ++ } else if (streq(l, "freezer-state")) { ++ FreezerState s; ++ ++ s = freezer_state_from_string(v); ++ if (s < 0) ++ log_unit_debug(u, "Failed to deserialize freezer-state '%s', ignoring.", v); ++ else ++ u->freezer_state = s; ++ + continue; + } + +@@ -5507,6 +5556,80 @@ void unit_log_skip(Unit *u, const char *result) { + "UNIT_RESULT=%s", result); + } + ++bool unit_can_freeze(Unit *u) { ++ assert(u); ++ ++ if (UNIT_VTABLE(u)->can_freeze) ++ return UNIT_VTABLE(u)->can_freeze(u); ++ ++ return UNIT_VTABLE(u)->freeze; ++} ++ ++void unit_frozen(Unit *u) { ++ assert(u); ++ ++ u->freezer_state = FREEZER_FROZEN; ++ ++ bus_unit_send_pending_freezer_message(u); ++} ++ ++void unit_thawed(Unit *u) { ++ assert(u); ++ ++ u->freezer_state = FREEZER_RUNNING; ++ ++ bus_unit_send_pending_freezer_message(u); ++} ++ ++static int unit_freezer_action(Unit *u, FreezerAction action) { ++ UnitActiveState s; ++ int (*method)(Unit*); ++ int r; ++ ++ assert(u); ++ assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW)); ++ ++ method = action == FREEZER_FREEZE ? UNIT_VTABLE(u)->freeze : UNIT_VTABLE(u)->thaw; ++ if (!method || !cg_freezer_supported()) ++ return -EOPNOTSUPP; ++ ++ if (u->job) ++ return -EBUSY; ++ ++ if (u->load_state != UNIT_LOADED) ++ return -EHOSTDOWN; ++ ++ s = unit_active_state(u); ++ if (s != UNIT_ACTIVE) ++ return -EHOSTDOWN; ++ ++ if (IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)) ++ return -EALREADY; ++ ++ r = method(u); ++ if (r <= 0) ++ return r; ++ ++ return 1; ++} ++ ++int unit_freeze(Unit *u) { ++ return unit_freezer_action(u, FREEZER_FREEZE); ++} ++ ++int unit_thaw(Unit *u) { ++ return unit_freezer_action(u, FREEZER_THAW); ++} ++ ++/* Wrappers around low-level cgroup freezer operations common for service and scope units */ ++int unit_freeze_vtable_common(Unit *u) { ++ return unit_cgroup_freezer_action(u, FREEZER_FREEZE); ++} ++ ++int unit_thaw_vtable_common(Unit *u) { ++ return unit_cgroup_freezer_action(u, FREEZER_THAW); ++} ++ + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index b40ff9b961..6e37fd6f5a 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -118,6 +118,9 @@ typedef struct Unit { + UnitLoadState load_state; + Unit *merged_into; + ++ FreezerState freezer_state; ++ sd_bus_message *pending_freezer_message; ++ + char *id; /* One name is special because we use it for identification. Points to an entry in the names set */ + char *instance; + +@@ -456,6 +459,11 @@ typedef struct UnitVTable { + + int (*kill)(Unit *u, KillWho w, int signo, sd_bus_error *error); + ++ /* Freeze the unit */ ++ int (*freeze)(Unit *u); ++ int (*thaw)(Unit *u); ++ bool (*can_freeze)(Unit *u); ++ + bool (*can_reload)(Unit *u); + + /* Write all data that cannot be restored from other sources +@@ -641,6 +649,8 @@ const char *unit_description(Unit *u) _pure_; + bool unit_has_name(Unit *u, const char *name); + + UnitActiveState unit_active_state(Unit *u); ++FreezerState unit_freezer_state(Unit *u); ++int unit_freezer_state_kernel(Unit *u, FreezerState *ret); + + const char* unit_sub_state_to_string(Unit *u); + +@@ -814,6 +824,16 @@ void unit_log_failure(Unit *u, const char *result); + * after some execution, rather than succeeded or failed. */ + void unit_log_skip(Unit *u, const char *result); + ++bool unit_can_freeze(Unit *u); ++int unit_freeze(Unit *u); ++void unit_frozen(Unit *u); ++ ++int unit_thaw(Unit *u); ++void unit_thawed(Unit *u); ++ ++int unit_freeze_vtable_common(Unit *u); ++int unit_thaw_vtable_common(Unit *u); ++ + /* Macros which append UNIT= or USER_UNIT= to the message */ + + #define log_unit_full(unit, level, error, ...) \ +diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h +index 3945c7f6ac..77da78d4d4 100644 +--- a/src/libsystemd/sd-bus/bus-common-errors.h ++++ b/src/libsystemd/sd-bus/bus-common-errors.h +@@ -30,6 +30,8 @@ + #define BUS_ERROR_NO_SUCH_DYNAMIC_USER "org.freedesktop.systemd1.NoSuchDynamicUser" + #define BUS_ERROR_NOT_REFERENCED "org.freedesktop.systemd1.NotReferenced" + #define BUS_ERROR_DISK_FULL "org.freedesktop.systemd1.DiskFull" ++#define BUS_ERROR_UNIT_BUSY "org.freedesktop.systemd1.UnitBusy" ++#define BUS_ERROR_UNIT_INACTIVE "org.freedesktop.systemd1.UnitInactive" + + #define BUS_ERROR_NO_SUCH_MACHINE "org.freedesktop.machine1.NoSuchMachine" + #define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage" +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index e0db97e339..e963f19b0a 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -27,6 +27,7 @@ + #include "bus-message.h" + #include "bus-unit-util.h" + #include "bus-util.h" ++#include "bus-wait-for-units.h" + #include "cgroup-show.h" + #include "cgroup-util.h" + #include "copy.h" +@@ -3728,6 +3729,98 @@ static int kill_unit(int argc, char *argv[], void *userdata) { + + return r; + } ++static int freeze_or_thaw_unit(int argc, char *argv[], void *userdata) { ++ _cleanup_(bus_wait_for_units_freep) BusWaitForUnits *w = NULL; ++ _cleanup_strv_free_ char **names = NULL; ++ int r, ret = EXIT_SUCCESS; ++ char **name; ++ const char *method; ++ sd_bus *bus; ++ ++ r = acquire_bus(BUS_FULL, &bus); ++ if (r < 0) ++ return r; ++ ++ polkit_agent_open_maybe(); ++ ++ r = expand_names(bus, strv_skip(argv, 1), NULL, &names); ++ if (r < 0) ++ return log_error_errno(r, "Failed to expand names: %m"); ++ ++ if (!arg_no_block) { ++ r = bus_wait_for_units_new(bus, &w); ++ if (r < 0) ++ return log_error_errno(r, "Failed to allocate unit waiter: %m"); ++ } ++ ++ if (streq(argv[0], "freeze")) ++ method = "FreezeUnit"; ++ else if (streq(argv[0], "thaw")) ++ method = "ThawUnit"; ++ else ++ assert_not_reached("Unhandled method"); ++ ++ STRV_FOREACH(name, names) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; ++ ++ if (w) { ++ /* If we shall wait for the cleaning to complete, let's add a ref on the unit first */ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "RefUnit", ++ &error, ++ NULL, ++ "s", *name); ++ if (r < 0) { ++ log_error_errno(r, "Failed to add reference to unit %s: %s", *name, bus_error_message(&error, r)); ++ if (ret == EXIT_SUCCESS) ++ ret = r; ++ continue; ++ } ++ } ++ ++ r = sd_bus_message_new_method_call( ++ bus, ++ &m, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ method); ++ if (r < 0) ++ return bus_log_create_error(r); ++ ++ r = sd_bus_message_append(m, "s", *name); ++ if (r < 0) ++ return bus_log_create_error(r); ++ ++ r = sd_bus_call(bus, m, 0, &error, NULL); ++ if (r < 0) { ++ log_error_errno(r, "Failed to %s unit %s: %s", argv[0], *name, bus_error_message(&error, r)); ++ if (ret == EXIT_SUCCESS) { ++ ret = r; ++ continue; ++ } ++ } ++ ++ if (w) { ++ r = bus_wait_for_units_add_unit(w, *name, BUS_WAIT_REFFED|BUS_WAIT_FOR_MAINTENANCE_END, NULL, NULL); ++ if (r < 0) ++ return log_error_errno(r, "Failed to watch unit %s: %m", *name); ++ } ++ } ++ ++ r = bus_wait_for_units_run(w); ++ if (r < 0) ++ return log_error_errno(r, "Failed to wait for units: %m"); ++ if (r == BUS_WAIT_FAILURE) ++ ret = EXIT_FAILURE; ++ ++ return ret; ++} + + typedef struct ExecStatusInfo { + char *name; +@@ -3832,6 +3925,7 @@ typedef struct UnitStatusInfo { + const char *id; + const char *load_state; + const char *active_state; ++ const char *freezer_state; + const char *sub_state; + const char *unit_file_state; + const char *unit_file_preset; +@@ -3949,7 +4043,7 @@ static void print_status_info( + bool *ellipsized) { + + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX]; +- const char *s1, *s2, *active_on, *active_off, *on, *off, *ss; ++ const char *s1, *s2, *active_on, *active_off, *on, *off, *ss, *fs; + _cleanup_free_ char *formatted_path = NULL; + ExecStatusInfo *p; + usec_t timestamp; +@@ -4056,6 +4150,10 @@ static void print_status_info( + printf(" Active: %s%s%s", + active_on, strna(i->active_state), active_off); + ++ fs = !isempty(i->freezer_state) && !streq(i->freezer_state, "running") ? i->freezer_state : NULL; ++ if (fs) ++ printf(" %s(%s)%s", ansi_highlight_yellow(), fs, active_off); ++ + if (!isempty(i->result) && !streq(i->result, "success")) + printf(" (Result: %s)", i->result); + +@@ -4985,6 +5083,7 @@ static int show_one( + { "Id", "s", NULL, offsetof(UnitStatusInfo, id) }, + { "LoadState", "s", NULL, offsetof(UnitStatusInfo, load_state) }, + { "ActiveState", "s", NULL, offsetof(UnitStatusInfo, active_state) }, ++ { "FreezerState", "s", NULL, offsetof(UnitStatusInfo, freezer_state) }, + { "SubState", "s", NULL, offsetof(UnitStatusInfo, sub_state) }, + { "UnitFileState", "s", NULL, offsetof(UnitStatusInfo, unit_file_state) }, + { "UnitFilePreset", "s", NULL, offsetof(UnitStatusInfo, unit_file_preset) }, +@@ -7139,6 +7238,8 @@ static void systemctl_help(void) { + " if supported, otherwise restart\n" + " isolate UNIT Start one unit and stop all others\n" + " kill UNIT... Send signal to processes of a unit\n" ++ " freeze PATTERN... Freeze execution of unit processes\n" ++ " thaw PATTERN... Resume execution of a frozen unit\n" + " is-active PATTERN... Check whether units are active\n" + " is-failed PATTERN... Check whether units are failed\n" + " status [PATTERN...|PID...] Show runtime status of one or more units\n" +@@ -8280,6 +8381,8 @@ static int systemctl_main(int argc, char *argv[]) { + { "condrestart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with RH */ + { "isolate", 2, 2, VERB_ONLINE_ONLY, start_unit }, + { "kill", 2, VERB_ANY, VERB_ONLINE_ONLY, kill_unit }, ++ { "freeze", 2, VERB_ANY, VERB_ONLINE_ONLY, freeze_or_thaw_unit }, ++ { "thaw", 2, VERB_ANY, VERB_ONLINE_ONLY, freeze_or_thaw_unit }, + { "is-active", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active }, + { "check", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active }, /* deprecated alias of is-active */ + { "is-failed", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_failed }, diff --git a/SOURCES/0425-core-cgroup-fix-return-value-of-unit_cgorup_freezer_.patch b/SOURCES/0425-core-cgroup-fix-return-value-of-unit_cgorup_freezer_.patch new file mode 100644 index 0000000..f78f7a7 --- /dev/null +++ b/SOURCES/0425-core-cgroup-fix-return-value-of-unit_cgorup_freezer_.patch @@ -0,0 +1,31 @@ +From abf2fb67dc3d7da8db030ea8b8db73a20acc08a9 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 7 May 2020 17:23:30 +0200 +Subject: [PATCH] core/cgroup: fix return value of unit_cgorup_freezer_action() + +We should return 0 only if current freezer state, as reported by the +kernel, is already the desired state. Otherwise, we would dispatch +return dbus message prematurely in bus_unit_method_freezer_generic(). + +Thanks to Frantisek Sumsal for reporting the issue. + +(cherry picked from commit d910f4c2b2542544d7b187a09605da7a0f220837) + +Related: #1830861 +--- + src/core/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index e7ae9273a6..2d819b8ebb 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2963,7 +2963,7 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { + if (r < 0) + return r; + +- return 0; ++ return 1; + } + + static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = { diff --git a/SOURCES/0426-core-fix-the-return-value-in-order-to-make-sure-we-d.patch b/SOURCES/0426-core-fix-the-return-value-in-order-to-make-sure-we-d.patch new file mode 100644 index 0000000..94cccdd --- /dev/null +++ b/SOURCES/0426-core-fix-the-return-value-in-order-to-make-sure-we-d.patch @@ -0,0 +1,31 @@ +From 4da9dfaec0d7d232d8bfed0d7f65afd65369bc8c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 5 Jun 2020 15:23:12 +0200 +Subject: [PATCH] core: fix the return value in order to make sure we don't + dipatch method return too early + +Actually, it is the same kind of problem as in d910f4c . Basically, we +need to return 1 on success code path in slice_freezer_action(). +Otherwise we dispatch DBus return message too soon. + +Fixes: #16050 +(cherry picked from commit 2884836e3c26fa76718319cdc6d13136bbc1354d) + +Related: #1830861 +--- + src/core/slice.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/slice.c b/src/core/slice.c +index b5eb2f5c01..c10e830917 100644 +--- a/src/core/slice.c ++++ b/src/core/slice.c +@@ -399,7 +399,7 @@ static int slice_freezer_action(Unit *s, FreezerAction action) { + if (r < 0) + return r; + +- return 0; ++ return 1; + } + + static int slice_freeze(Unit *s) { diff --git a/SOURCES/0427-test-add-test-for-cgroup-v2-freezer-support.patch b/SOURCES/0427-test-add-test-for-cgroup-v2-freezer-support.patch new file mode 100644 index 0000000..4d68414 --- /dev/null +++ b/SOURCES/0427-test-add-test-for-cgroup-v2-freezer-support.patch @@ -0,0 +1,397 @@ +From 762959047c1e1a5d4b6a6fe85cfa8a14c622e4da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 3 Apr 2020 09:13:51 +0200 +Subject: [PATCH] test: add test for cgroup v2 freezer support + +(cherry picked from commit d446ae89c0168f17eed7135ac06df3b294b3fcc6) + +Related: #1830861 +--- + ci/travis-centos-rhel8.sh | 2 +- + test/TEST-38-FREEZER/Makefile | 1 + + test/TEST-38-FREEZER/test.sh | 53 ++++++ + test/TEST-38-FREEZER/testsuite.sh | 293 ++++++++++++++++++++++++++++++ + 4 files changed, 348 insertions(+), 1 deletion(-) + create mode 120000 test/TEST-38-FREEZER/Makefile + create mode 100755 test/TEST-38-FREEZER/test.sh + create mode 100755 test/TEST-38-FREEZER/testsuite.sh + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index a1502e15ee..cd0857fd29 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -15,7 +15,7 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" + DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" + DOCKER_RUN="${DOCKER_RUN:-docker run}" + REPO_ROOT="${REPO_ROOT:-$PWD}" +-ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq) ++ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq diffutils) + # RHEL8 options + CONFIGURE_OPTS=( + -Dsysvinit-path=/etc/rc.d/init.d +diff --git a/test/TEST-38-FREEZER/Makefile b/test/TEST-38-FREEZER/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-38-FREEZER/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-38-FREEZER/test.sh b/test/TEST-38-FREEZER/test.sh +new file mode 100755 +index 0000000000..0d00754b5c +--- /dev/null ++++ b/test/TEST-38-FREEZER/test.sh +@@ -0,0 +1,53 @@ ++#!/bin/bash ++set -e ++TEST_DESCRIPTION="test unit freezing and thawing via DBus and systemctl" ++TEST_NO_NSPAWN=1 ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ dracut_install tr cut timeout ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service < $initdir/etc/systemd/system/testsuite-38-sleep.service << EOF ++[Service] ++ExecStart=/bin/sleep 3600 ++EOF ++ ++ cp testsuite.sh $initdir/ ++ setup_testsuite ++ ) ++ setup_nspawn_root ++ ++ ddebug "umount $TESTDIR/root" ++ umount $TESTDIR/root ++} ++ ++ ++do_test "$@" +diff --git a/test/TEST-38-FREEZER/testsuite.sh b/test/TEST-38-FREEZER/testsuite.sh +new file mode 100755 +index 0000000000..6fcadb8f8e +--- /dev/null ++++ b/test/TEST-38-FREEZER/testsuite.sh +@@ -0,0 +1,293 @@ ++#!/usr/bin/env bash ++ ++set -ex ++set -o pipefail ++ ++systemd-analyze log-level debug ++systemd-analyze log-target console ++ ++unit=testsuite-38-sleep.service ++ ++start_test_service() { ++ systemctl daemon-reload ++ systemctl start "${unit}" ++} ++ ++dbus_freeze() { ++ local suffix= ++ suffix="${1##*.}" ++ ++ local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)" ++ local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ "${object_path}" \ ++ org.freedesktop.systemd1.Unit \ ++ Freeze ++} ++ ++dbus_thaw() { ++ local suffix= ++ suffix="${1##*.}" ++ ++ local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)" ++ local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ "${object_path}" \ ++ org.freedesktop.systemd1.Unit \ ++ Thaw ++} ++ ++dbus_freeze_unit() { ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ FreezeUnit \ ++ s \ ++ "$1" ++} ++ ++dbus_thaw_unit() { ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ ThawUnit \ ++ s \ ++ "$1" ++} ++ ++dbus_can_freeze() { ++ local suffix= ++ suffix="${1##*.}" ++ ++ local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)" ++ local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}" ++ ++ busctl get-property \ ++ org.freedesktop.systemd1 \ ++ "${object_path}" \ ++ org.freedesktop.systemd1.Unit \ ++ CanFreeze ++} ++ ++check_freezer_state() { ++ local suffix= ++ suffix="${1##*.}" ++ ++ local name="$(echo ${1%.$suffix} | sed s/-/_2d/g)" ++ local object_path="/org/freedesktop/systemd1/unit/${name}_2e${suffix}" ++ ++ state=$(busctl get-property \ ++ org.freedesktop.systemd1 \ ++ "${object_path}" \ ++ org.freedesktop.systemd1.Unit \ ++ FreezerState | cut -d " " -f2 | tr -d '"') ++ ++ [ "$state" = "$2" ] || { ++ echo "error: unexpected freezer state, expected: $2, actual: $state" >&2 ++ exit 1 ++ } ++} ++ ++check_cgroup_state() { ++ grep -q "frozen $2" /sys/fs/cgroup/system.slice/"$1"/cgroup.events ++} ++ ++test_dbus_api() { ++ echo "Test that DBus API works:" ++ echo -n " - Freeze(): " ++ dbus_freeze "${unit}" ++ check_freezer_state "${unit}" "frozen" ++ check_cgroup_state "$unit" 1 ++ echo "[ OK ]" ++ ++ echo -n " - Thaw(): " ++ dbus_thaw "${unit}" ++ check_freezer_state "${unit}" "running" ++ check_cgroup_state "$unit" 0 ++ echo "[ OK ]" ++ ++ echo -n " - FreezeUnit(): " ++ dbus_freeze_unit "${unit}" ++ check_freezer_state "${unit}" "frozen" ++ check_cgroup_state "$unit" 1 ++ echo "[ OK ]" ++ ++ echo -n " - ThawUnit(): " ++ dbus_thaw_unit "${unit}" ++ check_freezer_state "${unit}" "running" ++ check_cgroup_state "$unit" 0 ++ echo "[ OK ]" ++ ++ echo -n " - CanFreeze(): " ++ output=$(dbus_can_freeze "${unit}") ++ [ "$output" = "b true" ] ++ echo "[ OK ]" ++ ++ echo ++} ++ ++test_jobs() { ++ local pid_before= ++ local pid_after= ++ echo "Test that it is possible to apply jobs on frozen units:" ++ ++ systemctl start "${unit}" ++ dbus_freeze "${unit}" ++ check_freezer_state "${unit}" "frozen" ++ ++ echo -n " - restart: " ++ pid_before=$(systemctl show -p MainPID "${unit}" --value) ++ systemctl restart "${unit}" ++ pid_after=$(systemctl show -p MainPID "${unit}" --value) ++ [ "$pid_before" != "$pid_after" ] && echo "[ OK ]" ++ ++ dbus_freeze "${unit}" ++ check_freezer_state "${unit}" "frozen" ++ ++ echo -n " - stop: " ++ timeout 5s systemctl stop "${unit}" ++ echo "[ OK ]" ++ ++ echo ++} ++ ++test_systemctl() { ++ echo "Test that systemctl freeze/thaw verbs:" ++ ++ systemctl start "$unit" ++ ++ echo -n " - freeze: " ++ systemctl freeze "$unit" ++ check_freezer_state "${unit}" "frozen" ++ check_cgroup_state "$unit" 1 ++ # Freezing already frozen unit should be NOP and return quickly ++ timeout 3s systemctl freeze "$unit" ++ echo "[ OK ]" ++ ++ echo -n " - thaw: " ++ systemctl thaw "$unit" ++ check_freezer_state "${unit}" "running" ++ check_cgroup_state "$unit" 0 ++ # Likewise thawing already running unit shouldn't block ++ timeout 3s systemctl thaw "$unit" ++ echo "[ OK ]" ++ ++ systemctl stop "$unit" ++ ++ echo ++} ++ ++test_systemctl_show() { ++ echo "Test systemctl show integration:" ++ ++ systemctl start "$unit" ++ ++ echo -n " - FreezerState property: " ++ state=$(systemctl show -p FreezerState --value "$unit") ++ [ "$state" = "running" ] ++ systemctl freeze "$unit" ++ state=$(systemctl show -p FreezerState --value "$unit") ++ [ "$state" = "frozen" ] ++ systemctl thaw "$unit" ++ echo "[ OK ]" ++ ++ echo -n " - CanFreeze property: " ++ state=$(systemctl show -p CanFreeze --value "$unit") ++ [ "$state" = "yes" ] ++ echo "[ OK ]" ++ ++ systemctl stop "$unit" ++ echo ++} ++ ++test_recursive() { ++ local slice="bar.slice" ++ local unit="baz.service" ++ ++ systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1 ++ ++ echo "Test recursive freezing:" ++ ++ echo -n " - freeze: " ++ systemctl freeze "$slice" ++ check_freezer_state "${slice}" "frozen" ++ check_freezer_state "${unit}" "frozen" ++ grep -q "frozen 1" /sys/fs/cgroup/"${slice}"/cgroup.events ++ grep -q "frozen 1" /sys/fs/cgroup/"${slice}"/"${unit}"/cgroup.events ++ echo "[ OK ]" ++ ++ echo -n " - thaw: " ++ systemctl thaw "$slice" ++ check_freezer_state "${unit}" "running" ++ check_freezer_state "${slice}" "running" ++ grep -q "frozen 0" /sys/fs/cgroup/"${slice}"/cgroup.events ++ grep -q "frozen 0" /sys/fs/cgroup/"${slice}"/"${unit}"/cgroup.events ++ echo "[ OK ]" ++ ++ systemctl stop "$unit" ++ systemctl stop "$slice" ++ ++ echo ++} ++ ++test_preserve_state() { ++ local slice="bar.slice" ++ local unit="baz.service" ++ ++ systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1 ++ ++ echo "Test that freezer state is preserved when recursive freezing is initiated from outside (e.g. by manager up the tree):" ++ ++ echo -n " - freeze from outside: " ++ echo 1 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ ++ # Our state should not be affected ++ check_freezer_state "${slice}" "running" ++ check_freezer_state "${unit}" "running" ++ ++ # However actual kernel state should be frozen ++ grep -q "frozen 1" /sys/fs/cgroup/"${slice}"/cgroup.events ++ grep -q "frozen 1" /sys/fs/cgroup/"${slice}"/"${unit}"/cgroup.events ++ echo "[ OK ]" ++ ++ echo -n " - thaw from outside: " ++ echo 0 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ check_freezer_state "${unit}" "running" ++ check_freezer_state "${slice}" "running" ++ grep -q "frozen 0" /sys/fs/cgroup/"${slice}"/cgroup.events ++ grep -q "frozen 0" /sys/fs/cgroup/"${slice}"/"${unit}"/cgroup.events ++ echo "[ OK ]" ++ ++ echo -n " - thaw from outside while inner service is frozen: " ++ systemctl freeze "$unit" ++ check_freezer_state "${unit}" "frozen" ++ echo 1 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ echo 0 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ check_freezer_state "${slice}" "running" ++ check_freezer_state "${unit}" "frozen" ++ echo "[ OK ]" ++ ++ systemctl stop "$unit" ++ systemctl stop "$slice" ++ ++ echo ++} ++ ++test -e /sys/fs/cgroup/system.slice/cgroup.freeze && { ++ start_test_service ++ test_dbus_api ++ test_systemctl ++ test_systemctl_show ++ test_jobs ++ test_recursive ++ test_preserve_state ++} ++ ++echo OK > /testok ++exit 0 diff --git a/SOURCES/0428-fix-mis-merge.patch b/SOURCES/0428-fix-mis-merge.patch new file mode 100644 index 0000000..544299a --- /dev/null +++ b/SOURCES/0428-fix-mis-merge.patch @@ -0,0 +1,29 @@ +From 8e1cc941607263a4f8454d0d6d5939aec3be1fcb Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 23 Jun 2020 13:58:21 +0200 +Subject: [PATCH] fix mis-merge + +Resolves: #1848421 +--- + src/core/cgroup.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 2d819b8ebb..e0eb184fd2 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -664,11 +664,13 @@ static void cgroup_apply_legacy_cpu_config(Unit *u, uint64_t shares, uint64_t qu + + if (quota != USEC_INFINITY) { + xsprintf(buf, USEC_FMT "\n", MAX(quota * period / USEC_PER_SEC, USEC_PER_MSEC)); ++ r = cg_set_attribute("cpu", u->cgroup_path, "cpu.cfs_quota_us", buf); ++ } ++ else + r = cg_set_attribute("cpu", u->cgroup_path, "cpu.cfs_quota_us", "-1"); + if (r < 0) + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set cpu.cfs_quota_us: %m"); +- } + } + + static uint64_t cgroup_cpu_shares_to_weight(uint64_t shares) { diff --git a/SOURCES/0429-tests-sleep-a-bit-and-give-kernel-time-to-perform-th.patch b/SOURCES/0429-tests-sleep-a-bit-and-give-kernel-time-to-perform-th.patch new file mode 100644 index 0000000..82805da --- /dev/null +++ b/SOURCES/0429-tests-sleep-a-bit-and-give-kernel-time-to-perform-th.patch @@ -0,0 +1,36 @@ +From 9028873ee3bffe37b50fa7ada123fcf270de4658 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 5 Jun 2020 11:35:01 +0200 +Subject: [PATCH] tests: sleep a bit and give kernel time to perform the action + after manual freeze/thaw + +Fixes: #16050 +(cherry picked from commit a0d79df8e59c6bb6dc0382d71e835dec869a7df4) + +Related: #1848421 +--- + test/TEST-38-FREEZER/testsuite.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/TEST-38-FREEZER/testsuite.sh b/test/TEST-38-FREEZER/testsuite.sh +index 6fcadb8f8e..18b7bd6dce 100755 +--- a/test/TEST-38-FREEZER/testsuite.sh ++++ b/test/TEST-38-FREEZER/testsuite.sh +@@ -246,6 +246,8 @@ test_preserve_state() { + + echo -n " - freeze from outside: " + echo 1 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ # Give kernel some time to freeze the slice ++ sleep 1 + + # Our state should not be affected + check_freezer_state "${slice}" "running" +@@ -258,6 +260,8 @@ test_preserve_state() { + + echo -n " - thaw from outside: " + echo 0 > /sys/fs/cgroup/"${slice}"/cgroup.freeze ++ sleep 1 ++ + check_freezer_state "${unit}" "running" + check_freezer_state "${slice}" "running" + grep -q "frozen 0" /sys/fs/cgroup/"${slice}"/cgroup.events diff --git a/SOURCES/0430-device-make-sure-we-emit-PropertiesChanged-signal-on.patch b/SOURCES/0430-device-make-sure-we-emit-PropertiesChanged-signal-on.patch new file mode 100644 index 0000000..8d202a4 --- /dev/null +++ b/SOURCES/0430-device-make-sure-we-emit-PropertiesChanged-signal-on.patch @@ -0,0 +1,26 @@ +From 91dddaafe0b6fcc9c0a57d2feef599b82ce2a146 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 26 Mar 2020 13:34:20 +0100 +Subject: [PATCH] device: make sure we emit PropertiesChanged signal once we + set sysfs + +(cherry picked from commit 7c4d139485139eae95b17a1d54cb51ae958abd70) + +Related: #1793533 +--- + src/core/device.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/core/device.c b/src/core/device.c +index a2d00a0fbe..21fe3802bd 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -81,6 +81,8 @@ static int device_set_sysfs(Device *d, const char *sysfs) { + } + + d->sysfs = TAKE_PTR(copy); ++ unit_add_to_dbus_queue(UNIT(d)); ++ + return 0; + } + diff --git a/SOURCES/0431-device-don-t-emit-PropetiesChanged-needlessly.patch b/SOURCES/0431-device-don-t-emit-PropetiesChanged-needlessly.patch new file mode 100644 index 0000000..e0986d5 --- /dev/null +++ b/SOURCES/0431-device-don-t-emit-PropetiesChanged-needlessly.patch @@ -0,0 +1,44 @@ +From a4cefc9f8bf24b2fdcc62cc0d2685698814374d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 26 Mar 2020 13:35:11 +0100 +Subject: [PATCH] device: don't emit PropetiesChanged needlessly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Functions called from device_setup_unit() already make sure that unit is +enqueued in case it is a new unit or properties exported on the bus have +changed. + +This should prevent unnecessary DBus wakeups and associated DBus traffic +when device_setup_unit() was called while reparsing /proc/self/mountinfo +due to the mountinfo notifications. Note that we parse +/proc/self/mountinfo quite often on the busy systems (e.g. k8s container +hosts) but majority of the time mounts didn't change, only some mount +got added. Thus we don't need to generate PropertiesChanged for devices +associated with the mounts that didn't change. + +Thanks to Renaud Métrich for debugging the +problem and providing draft version of the patch. + +(cherry picked from commit 2e129d5d6bd6bd8be4b5359e81a880cbf72a44b8) + +Resolves: #1793533 +--- + src/core/device.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/core/device.c b/src/core/device.c +index 21fe3802bd..021c28dfbd 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -549,9 +549,6 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa + if (dev && device_is_bound_by_mounts(DEVICE(u), dev)) + device_upgrade_mount_deps(u); + +- /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */ +- unit_add_to_dbus_queue(u); +- + return 0; + + fail: diff --git a/SOURCES/0432-units-add-generic-boot-complete.target.patch b/SOURCES/0432-units-add-generic-boot-complete.target.patch new file mode 100644 index 0000000..912b230 --- /dev/null +++ b/SOURCES/0432-units-add-generic-boot-complete.target.patch @@ -0,0 +1,46 @@ +From dd573e5fbac858c20628052acfa19401d3e0d135 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 22 Jun 2018 12:52:28 +0200 +Subject: [PATCH] units: add generic boot-complete.target + +(cherry picked from commit 329d20db3cb02d789473b8f7e4a59526fcbf5728) + +Resolves: #1872243 +--- + units/boot-complete.target | 14 ++++++++++++++ + units/meson.build | 1 + + 2 files changed, 15 insertions(+) + create mode 100644 units/boot-complete.target + +diff --git a/units/boot-complete.target b/units/boot-complete.target +new file mode 100644 +index 0000000000..f0b9e57e7c +--- /dev/null ++++ b/units/boot-complete.target +@@ -0,0 +1,14 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++ ++[Unit] ++Description=Boot Completion Check ++Documentation=man:systemd.special(7) ++Requires=sysinit.target ++After=sysinit.target +diff --git a/units/meson.build b/units/meson.build +index e118d81888..a1cd2524dc 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -3,6 +3,7 @@ + units = [ + ['basic.target', ''], + ['bluetooth.target', ''], ++ ['boot-complete.target', ''], + ['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'], + ['cryptsetup.target', 'HAVE_LIBCRYPTSETUP', + 'sysinit.target.wants/'], diff --git a/SOURCES/0433-man-document-new-boot-complete.target-unit.patch b/SOURCES/0433-man-document-new-boot-complete.target-unit.patch new file mode 100644 index 0000000..376958c --- /dev/null +++ b/SOURCES/0433-man-document-new-boot-complete.target-unit.patch @@ -0,0 +1,53 @@ +From 8ad89170001c9aba8849630ddb5da81d9e24a1bc Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 Jun 2018 17:21:34 +0200 +Subject: [PATCH] man: document new "boot-complete.target" unit + +(cherry picked from commit 82ea38258c0f4964c2f3ad3691c6e4554c4f0bb0) + +Related: #1872243 +--- + man/systemd.special.xml | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/man/systemd.special.xml b/man/systemd.special.xml +index fb12805fff..c9d4345016 100644 +--- a/man/systemd.special.xml ++++ b/man/systemd.special.xml +@@ -29,6 +29,7 @@ + cryptsetup-pre.target, + cryptsetup.target, + ctrl-alt-del.target, ++ boot-complete.target, + default.target, + emergency.target, + exit.target, +@@ -646,6 +647,28 @@ + + + ++ ++ boot-complete.target ++ ++ This target is intended as generic synchronization point for services that shall determine or act on ++ whether the boot process completed successfully. Order units that are required to succeed for a boot process ++ to be considered successful before this unit, and add a Requires= dependency from the ++ target unit to them. Order units that shall only run when the boot process is considered successful after the ++ target unit and pull in the target from it, also with Requires=. Note that by default this ++ target unit is not part of the initial boot transaction, but is supposed to be pulled in only if required by ++ units that want to run only on successful boots. ++ ++ See ++ systemd-boot-check-no-failures.service8 ++ for a service that implements a generic system health check and orders itself before ++ boot-complete.target. ++ ++ See ++ systemd-bless-boot.service8 ++ for a service that propagates boot success information to the boot loader, and orders itself after ++ boot-complete.target. ++ ++ + + syslog.socket + diff --git a/SOURCES/0434-core-make-sure-to-restore-the-control-command-id-too.patch b/SOURCES/0434-core-make-sure-to-restore-the-control-command-id-too.patch new file mode 100644 index 0000000..c5bd3e1 --- /dev/null +++ b/SOURCES/0434-core-make-sure-to-restore-the-control-command-id-too.patch @@ -0,0 +1,30 @@ +From 37f2576684d7494c916fd1f13275982f3c43f44f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 22 Apr 2020 20:34:02 +0200 +Subject: [PATCH] core: make sure to restore the control command id, too + +Fixes: #15356 +(cherry picked from commit e9da62b18af647bfa73807e1c7fc3bfa4bb4b2ac) + +Resolves: #1829867 +--- + src/core/service.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 89b41f6783..7cff419e4e 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2703,9 +2703,10 @@ static int service_deserialize_exec_command(Unit *u, const char *key, const char + break; + } + +- if (command && control) ++ if (command && control) { + s->control_command = command; +- else if (command) ++ s->control_command_id = id; ++ } else if (command) + s->main_command = command; + else + log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed."); diff --git a/SOURCES/0435-cgroup-freezer-action-must-be-NOP-when-cgroup-v2-fre.patch b/SOURCES/0435-cgroup-freezer-action-must-be-NOP-when-cgroup-v2-fre.patch new file mode 100644 index 0000000..04c1355 --- /dev/null +++ b/SOURCES/0435-cgroup-freezer-action-must-be-NOP-when-cgroup-v2-fre.patch @@ -0,0 +1,48 @@ +From 45d093a37b6f8c2ceae9bfd090c5265f35413b46 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Tue, 8 Sep 2020 14:51:39 +0200 +Subject: [PATCH] cgroup: freezer action must be NOP when cgroup v2 freezer is + not available + +Low-level cgroup freezer state manipulation is invoked directly from the +job engine when we are about to execute the job in order to make sure +the unit is not frozen and job execution is not blocked because of +that. + +Currently with cgroup v1 we would needlessly do a bunch of work in the +function and even falsely update the freezer state. Don't do any of this +and skip the function silently when v2 freezer is not available. + +Following bug is fixed by this commit, + +$ systemd-run --unit foo.service /bin/sleep infinity +$ systemctl restart foo.service +$ systemctl show -p FreezerState foo.service + +Before (cgroup v1, i.e. full "legacy" mode): +FreezerState=thawing + +After: +FreezerState=running + +(cherry picked from commit 9a1e90aee556b7a30d87553a891a4175ae77ed68) + +Resolves: #1868831 +--- + src/core/cgroup.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index e0eb184fd2..f1ce070f9a 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2936,6 +2936,9 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { + assert(u); + assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW)); + ++ if (!cg_freezer_supported()) ++ return 0; ++ + if (!u->cgroup_realized) + return -EBUSY; + diff --git a/SOURCES/0436-logind-don-t-print-warning-when-user-.service-templa.patch b/SOURCES/0436-logind-don-t-print-warning-when-user-.service-templa.patch new file mode 100644 index 0000000..961f814 --- /dev/null +++ b/SOURCES/0436-logind-don-t-print-warning-when-user-.service-templa.patch @@ -0,0 +1,32 @@ +From 65e96327360ab41d44d5383dcecc82a19fad198c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 22 Feb 2019 15:50:55 +0100 +Subject: [PATCH] logind: don't print warning when user@.service template is + masked + +User instance of systemd is optional feature and if user@.service +template is masked then administrator most likely doesn't want --user +instances of systemd for logged in users. We don't need to be verbose +about it. + +(cherry picked from commit 03b6fa0c5b51b0d39334ff6ba183a3391443bcf6) + +Resolves: #1880270 +--- + src/login/logind-user.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 8c4cd54a29..56b8066f12 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -326,7 +326,8 @@ static int user_start_service(User *u) { + &job); + if (r < 0) + /* we don't fail due to this, let's try to continue */ +- log_error_errno(r, "Failed to start user service, ignoring: %s", bus_error_message(&error, r)); ++ log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_UNIT_MASKED) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to start user service '%s', ignoring: %s", u->service, bus_error_message(&error, r)); + else + u->service_job = job; + diff --git a/SOURCES/0437-build-use-simple-project-version-in-pkgconfig-files.patch b/SOURCES/0437-build-use-simple-project-version-in-pkgconfig-files.patch new file mode 100644 index 0000000..6ea481d --- /dev/null +++ b/SOURCES/0437-build-use-simple-project-version-in-pkgconfig-files.patch @@ -0,0 +1,80 @@ +From a6d76bf2d21e01a2e031e204966d946925ecc3f6 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Mon, 17 Aug 2020 14:29:04 +0200 +Subject: [PATCH] build: use simple project version in pkgconfig files + +Loosely based on commit a67c318df8800ba98d7361308937ed276dc73982. + +Resolves: #1862714 +--- + meson.build | 2 ++ + src/core/systemd.pc.in | 2 +- + src/libsystemd/libsystemd.pc.in | 2 +- + src/libudev/libudev.pc.in | 2 +- + src/udev/udev.pc.in | 2 +- + 5 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/meson.build b/meson.build +index 0ba3f924ea..65c1d0785e 100644 +--- a/meson.build ++++ b/meson.build +@@ -27,12 +27,14 @@ endif + # names, sometimes. Not all variables are included in every + # set. Ugh, ugh, ugh! + conf = configuration_data() ++conf.set_quoted('PROJECT_VERSION', meson.project_version()) + conf.set_quoted('PACKAGE_STRING', meson.project_name() + ' ' + dist_version) + conf.set_quoted('PACKAGE_VERSION', dist_version) + + substs = configuration_data() + substs.set('PACKAGE_URL', 'https://www.freedesktop.org/wiki/Software/systemd') + substs.set('PACKAGE_VERSION', dist_version) ++substs.set('PROJECT_VERSION', meson.project_version()) + + ##################################################################### + +diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in +index 655773ea8a..a350737cf2 100644 +--- a/src/core/systemd.pc.in ++++ b/src/core/systemd.pc.in +@@ -37,4 +37,4 @@ containeruidbasemax=@containeruidbasemax@ + Name: systemd + Description: systemd System and Service Manager + URL: @PACKAGE_URL@ +-Version: @PACKAGE_VERSION@ ++Version: @PROJECT_VERSION@ +diff --git a/src/libsystemd/libsystemd.pc.in b/src/libsystemd/libsystemd.pc.in +index c861905b67..85d6ebf293 100644 +--- a/src/libsystemd/libsystemd.pc.in ++++ b/src/libsystemd/libsystemd.pc.in +@@ -15,6 +15,6 @@ includedir=@includedir@ + Name: systemd + Description: systemd Library + URL: @PACKAGE_URL@ +-Version: @PACKAGE_VERSION@ ++Version: @PROJECT_VERSION@ + Libs: -L${libdir} -lsystemd + Cflags: -I${includedir} +diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in +index 69f5c6463e..40b340362e 100644 +--- a/src/libudev/libudev.pc.in ++++ b/src/libudev/libudev.pc.in +@@ -14,6 +14,6 @@ includedir=@includedir@ + + Name: libudev + Description: Library to access udev device information +-Version: @PACKAGE_VERSION@ ++Version: @PROJECT_VERSION@ + Libs: -L${libdir} -ludev + Cflags: -I${includedir} +diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in +index e384a6f7c9..5acbb2d01a 100644 +--- a/src/udev/udev.pc.in ++++ b/src/udev/udev.pc.in +@@ -1,5 +1,5 @@ + Name: udev + Description: udev +-Version: @PACKAGE_VERSION@ ++Version: @PROJECT_VERSION@ + + udevdir=@udevlibexecdir@ diff --git a/SOURCES/0438-basic-virt-try-the-proc-1-sched-hack-also-for-PID1.patch b/SOURCES/0438-basic-virt-try-the-proc-1-sched-hack-also-for-PID1.patch new file mode 100644 index 0000000..4237fa1 --- /dev/null +++ b/SOURCES/0438-basic-virt-try-the-proc-1-sched-hack-also-for-PID1.patch @@ -0,0 +1,57 @@ +From 2f584bd93d64a75ab11b5a5aa31d0b7145da5a86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 26 Apr 2019 13:37:31 +0200 +Subject: [PATCH] basic/virt: try the /proc/1/sched hack also for PID1 + +If a container manager does not set $container, we could end up +in a strange situation when detect-virt returns container-other when +run as non-pid-1 and none when run as pid-1. + +(cherry picked from commit 342bed02084c4396dd2f1054bd559bfb2699cfcb) +Resolves: #1868877 +--- + src/basic/virt.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index e05b3e6d99..dfa1525219 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -427,7 +427,6 @@ finish: + } + + int detect_container(void) { +- + static const struct { + const char *value; + int id; +@@ -456,9 +455,15 @@ int detect_container(void) { + } + + if (getpid_cached() == 1) { +- /* If we are PID 1 we can just check our own environment variable, and that's authoritative. */ +- ++ /* If we are PID 1 we can just check our own environment variable, and that's authoritative. ++ * We distinguish three cases: ++ * - the variable is not defined → we jump to other checks ++ * - the variable is defined to an empty value → we are not in a container ++ * - anything else → some container, either one of the known ones or "container-other" ++ */ + e = getenv("container"); ++ if (!e) ++ goto check_sched; + if (isempty(e)) { + r = VIRTUALIZATION_NONE; + goto finish; +@@ -486,8 +491,9 @@ int detect_container(void) { + if (r < 0) /* This only works if we have CAP_SYS_PTRACE, hence let's better ignore failures here */ + log_debug_errno(r, "Failed to read $container of PID 1, ignoring: %m"); + +- /* Interestingly /proc/1/sched actually shows the host's PID for what we see as PID 1. Hence, if the PID shown +- * there is not 1, we know we are in a PID namespace. and hence a container. */ ++ /* Interestingly /proc/1/sched actually shows the host's PID for what we see as PID 1. If the PID ++ * shown there is not 1, we know we are in a PID namespace and hence a container. */ ++ check_sched: + r = read_one_line_file("/proc/1/sched", &m); + if (r >= 0) { + const char *t; diff --git a/SOURCES/0439-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch b/SOURCES/0439-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch new file mode 100644 index 0000000..f824c4d --- /dev/null +++ b/SOURCES/0439-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch @@ -0,0 +1,287 @@ +From 8cc497e735104080f6830a8f468b2724ae372990 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Apr 2019 13:11:00 +0200 +Subject: [PATCH] seccomp: rework how the S[UG]ID filter is installed + +If we know that a syscall is undefined on the given architecture, don't +even try to add it. + +Try to install the filter even if some syscalls fail. Also use a helper +function to make the whole a bit less magic. + +This allows the S[UG]ID test to pass on arm64. + +(cherry picked from commit da4dc9a6748797e804b6bc92ad513d509abf581c) + +Resolves: #1860374 +--- + src/shared/seccomp-util.c | 244 +++++++++++++++++++++----------------- + 1 file changed, 138 insertions(+), 106 deletions(-) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index fd46b9f88d..d91fb4e269 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -1750,9 +1750,139 @@ int seccomp_lock_personality(unsigned long personality) { + return 0; + } + ++static int seccomp_restrict_sxid(scmp_filter_ctx seccomp, mode_t m) { ++ /* Checks the mode_t parameter of the following system calls: ++ * ++ * → chmod() + fchmod() + fchmodat() ++ * → open() + creat() + openat() ++ * → mkdir() + mkdirat() ++ * → mknod() + mknodat() ++ * ++ * Returns error if *everything* failed, and 0 otherwise. ++ */ ++ int r = 0; ++ bool any = false; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(chmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for chmod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for fchmod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(fchmodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for fchmodat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdir), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mkdir: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mkdirat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mkdirat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknod), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mknod: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(mknodat), ++ 1, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for mknodat: %m"); ++ else ++ any = true; ++ ++#if SCMP_SYS(open) > 0 ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(open), ++ 2, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for open: %m"); ++ else ++ any = true; ++#endif ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(openat), ++ 2, ++ SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), ++ SCMP_A3(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for openat: %m"); ++ else ++ any = true; ++ ++ r = seccomp_rule_add_exact( ++ seccomp, ++ SCMP_ACT_ERRNO(EPERM), ++ SCMP_SYS(creat), ++ 1, ++ SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add filter for creat: %m"); ++ else ++ any = true; ++ ++ return any ? 0 : r; ++} ++ + int seccomp_restrict_suid_sgid(void) { + uint32_t arch; +- int r; ++ int r, k; + + SECCOMP_FOREACH_LOCAL_ARCH(arch) { + _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; +@@ -1761,114 +1891,16 @@ int seccomp_restrict_suid_sgid(void) { + if (r < 0) + return r; + +- /* Checks the mode_t parameter of the following system calls: +- * +- * → chmod() + fchmod() + fchmodat() +- * → open() + creat() + openat() +- * → mkdir() + mkdirat() +- * → mknod() + mknodat() +- */ +- +- for (unsigned bit = 0; bit < 2; bit ++) { +- /* Block S_ISUID in the first iteration, S_ISGID in the second */ +- mode_t m = bit == 0 ? S_ISUID : S_ISGID; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(chmod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(fchmod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(fchmodat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mkdir), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mkdirat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mknod), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(mknodat), +- 1, +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(open), +- 2, +- SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), +- SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; ++ r = seccomp_restrict_sxid(seccomp, S_ISUID); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add suid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch)); + +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(openat), +- 2, +- SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT), +- SCMP_A3(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; ++ k = seccomp_restrict_sxid(seccomp, S_ISGID); ++ if (k < 0) ++ log_debug_errno(r, "Failed to add sgid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch)); + +- r = seccomp_rule_add_exact( +- seccomp, +- SCMP_ACT_ERRNO(EPERM), +- SCMP_SYS(creat), +- 1, +- SCMP_A1(SCMP_CMP_MASKED_EQ, m, m)); +- if (r < 0) +- break; +- } +- if (r < 0) { +- log_debug_errno(r, "Failed to add suid/sgid rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); ++ if (r < 0 && k < 0) + continue; +- } + + r = seccomp_load(seccomp); + if (IN_SET(r, -EPERM, -EACCES)) diff --git a/SOURCES/0440-vconsole-setup-downgrade-log-message-when-setting-fo.patch b/SOURCES/0440-vconsole-setup-downgrade-log-message-when-setting-fo.patch new file mode 100644 index 0000000..09874a7 --- /dev/null +++ b/SOURCES/0440-vconsole-setup-downgrade-log-message-when-setting-fo.patch @@ -0,0 +1,91 @@ +From 860749038f508617c8fc31b8292b4019b1e621ba Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Thu, 16 Jul 2020 21:22:37 +0200 +Subject: [PATCH] vconsole-setup: downgrade log message when setting font fails + on dummy console + +Since commit 883eb9be985fd86d9cabe967eeeab91cdd396a81, vconsole-setup might be +called again to operate on dummy console where font operations are not +supported but where it's still important to have the correct keymap set [0][1]. + +vconsole-setup is mainly called by udev but can also be run via a dependency of +an early service. Both cases might end up calling vconsole-setup on the dummy +console. + +The first case can happen during early boot even on systems that use (instead +of the dummy console) a "simple" video console driver supporting font +operations (such as vgacon) until a more specific driver (such as i915) takes +the console over. While this is happening vgacon is deactivated and temporarly +replaced by the dummy console [2]. + +There are also other cases where systemd-vconsole-setup might be called on +dummy console especially during (very) early boot. Indeed +systemd-vconsole-setup.service might be pulled in by early interactive services +such as 'dracut-cmdline-ask.service` which is run before udev. + +If that happens on platforms with no grapical HWs (such as embedded ARM) or +with dummy console initially installed until a driver takes over (like Xen and +xen-fbfront) then setting font will fail. + +Therefore this patch downgrades the log message emitted when setting font fails +to LOG_DEBUG and when font operations is not implemented like it's the case for +the dummy console. + +Fixes: #16406. + +[0] https://github.com/systemd/systemd/issues/10826 +[1] https://bugzilla.redhat.com/show_bug.cgi?id=1652473 +[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/vga/vgaarb.c?h=v5.7#n204 + +(cherry picked from commit 0ef1adf51274960358e852d3bc36ae6c288a70d9) + +Resolves: #1889996 +--- + src/vconsole/vconsole-setup.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c +index f162d29220..1b406c0bc5 100644 +--- a/src/vconsole/vconsole-setup.c ++++ b/src/vconsole/vconsole-setup.c +@@ -222,6 +222,7 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) { + _cleanup_free_ struct unipair* unipairs = NULL; + _cleanup_free_ void *fontbuf = NULL; + unsigned i; ++ int log_level; + int r; + + unipairs = new(struct unipair, USHRT_MAX); +@@ -230,11 +231,20 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) { + return; + } + ++ log_level = LOG_WARNING; ++ + /* get metadata of the current font (width, height, count) */ + r = ioctl(src_fd, KDFONTOP, &cfo); +- if (r < 0) +- log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m"); +- else { ++ if (r < 0) { ++ /* We might be called to operate on the dummy console (to setup keymap ++ * mainly) when fbcon deferred takeover is used for example. In such case, ++ * setting font is not supported and is expected to fail. */ ++ if (errno == ENOSYS) ++ log_level = LOG_DEBUG; ++ ++ log_full_errno(log_level, errno, ++ "KD_FONT_OP_GET failed while trying to get the font metadata: %m"); ++ } else { + /* verify parameter sanity first */ + if (cfo.width > 32 || cfo.height > 32 || cfo.charcount > 512) + log_warning("Invalid font metadata - width: %u (max 32), height: %u (max 32), count: %u (max 512)", +@@ -269,7 +279,7 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) { + } + + if (cfo.op != KD_FONT_OP_SET) +- log_warning("Fonts will not be copied to remaining consoles"); ++ log_full(log_level, "Fonts will not be copied to remaining consoles"); + + for (i = 1; i <= 63; i++) { + char ttyname[sizeof("/dev/tty63")]; diff --git a/SOURCES/0441-units-fix-systemd.special-man-page-reference-in-syst.patch b/SOURCES/0441-units-fix-systemd.special-man-page-reference-in-syst.patch new file mode 100644 index 0000000..4d6bd2e --- /dev/null +++ b/SOURCES/0441-units-fix-systemd.special-man-page-reference-in-syst.patch @@ -0,0 +1,26 @@ +From 46fa8ff1a62e3334582a971cc6bbd9b8a16680d5 Mon Sep 17 00:00:00 2001 +From: Michael Biebl +Date: Thu, 7 Mar 2019 12:02:53 +0100 +Subject: [PATCH] units: fix systemd.special man page reference in + system-update-cleanup.service + +(cherry picked from commit faab72d16b310c17be4b908cfe15eca122d16ae4) + +Resolves: #1871827 +--- + units/system-update-cleanup.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/system-update-cleanup.service b/units/system-update-cleanup.service +index 58baab3023..d5eca2546b 100644 +--- a/units/system-update-cleanup.service ++++ b/units/system-update-cleanup.service +@@ -9,7 +9,7 @@ + + [Unit] + Description=Remove the Offline System Updates symlink +-Documentation=man:systemd.special(5) man:systemd.offline-updates(7) ++Documentation=man:systemd.special(7) man:systemd.offline-updates(7) + After=system-update.target + DefaultDependencies=no + Conflicts=shutdown.target diff --git a/SOURCES/0442-units-drop-reference-to-sushell-man-page.patch b/SOURCES/0442-units-drop-reference-to-sushell-man-page.patch new file mode 100644 index 0000000..d998724 --- /dev/null +++ b/SOURCES/0442-units-drop-reference-to-sushell-man-page.patch @@ -0,0 +1,27 @@ +From 5aa59d172189adcbd7f9dedb3b909c6bf9b609f2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 29 Apr 2019 16:10:51 +0200 +Subject: [PATCH] units: drop reference to sushell man page + +sushell was a Fedoraism, and has been removed since. Hence our upstream +unit files shouldn't reference it either. + +(cherry picked from commit 6dc14d73664390682d47d7e5bcbdbb362d04f623) + +Resolves: #1871827 +--- + units/debug-shell.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/units/debug-shell.service.in b/units/debug-shell.service.in +index 1127e68b63..9f3868e106 100644 +--- a/units/debug-shell.service.in ++++ b/units/debug-shell.service.in +@@ -9,7 +9,6 @@ + + [Unit] + Description=Early root shell on @DEBUGTTY@ FOR DEBUGGING ONLY +-Documentation=man:sushell(8) + Documentation=man:systemd-debug-generator(8) + DefaultDependencies=no + IgnoreOnIsolate=yes diff --git a/SOURCES/0443-sd-bus-break-the-loop-in-bus_ensure_running-if-the-b.patch b/SOURCES/0443-sd-bus-break-the-loop-in-bus_ensure_running-if-the-b.patch new file mode 100644 index 0000000..a53c450 --- /dev/null +++ b/SOURCES/0443-sd-bus-break-the-loop-in-bus_ensure_running-if-the-b.patch @@ -0,0 +1,44 @@ +From 6a50c735a3bbf98d06fbfa7815f7bdc14ea96f9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 14 Oct 2020 14:03:13 +0200 +Subject: [PATCH] sd-bus: break the loop in bus_ensure_running() if the bus is + not connecting + +This might fix #17025: +> the call trace is +> bus_ensure_running -> sd_bus_process -> bus_process_internal -> process_closeing --> sd_bus_close +> | +> \-> process_match + +We ended doing callouts to the Disconnected matches from bus_ensure_running() +and shouldn't. bus_ensure_running() should never do callouts. This change +should fix this however: once we notice that the connection is going down we +will now fail instantly with ENOTOCONN instead of calling any callbacks. + +(cherry picked from commit 93a59b1ae5d3bcb0ec1488ebc13d0d1ff4d1729a) + +Resolves: #1885553 +--- + src/libsystemd/sd-bus/sd-bus.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index a3509f7e89..c65e24b2d1 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2059,12 +2059,13 @@ int bus_ensure_running(sd_bus *bus) { + + assert(bus); + +- if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING)) +- return -ENOTCONN; + if (bus->state == BUS_RUNNING) + return 1; + + for (;;) { ++ if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING)) ++ return -ENOTCONN; ++ + r = sd_bus_process(bus, NULL); + if (r < 0) + return r; diff --git a/SOURCES/0444-core-add-new-API-for-enqueing-a-job-with-returning-t.patch b/SOURCES/0444-core-add-new-API-for-enqueing-a-job-with-returning-t.patch new file mode 100644 index 0000000..ccd3ae1 --- /dev/null +++ b/SOURCES/0444-core-add-new-API-for-enqueing-a-job-with-returning-t.patch @@ -0,0 +1,831 @@ +From 7155c010ef8c620295d230c284849636c07b40c0 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 22 Mar 2019 20:57:30 +0100 +Subject: [PATCH] core: add new API for enqueing a job with returning the + transaction data + +(cherry picked from commit 50cbaba4fe5a32850998682699322d012e597e4a) + +Related: #846319 +--- + src/analyze/analyze-verify.c | 2 +- + src/core/automount.c | 4 +- + src/core/dbus-manager.c | 23 +++++- + src/core/dbus-unit.c | 153 +++++++++++++++++++++++++++++++---- + src/core/dbus-unit.h | 8 +- + src/core/dbus.c | 2 +- + src/core/device.c | 2 +- + src/core/emergency-action.c | 5 +- + src/core/main.c | 4 +- + src/core/manager.c | 38 +++++---- + src/core/manager.h | 6 +- + src/core/path.c | 2 +- + src/core/service.c | 2 +- + src/core/socket.c | 4 +- + src/core/timer.c | 2 +- + src/core/transaction.c | 22 ++++- + src/core/transaction.h | 2 +- + src/core/unit.c | 16 ++-- + src/test/test-engine.c | 20 ++--- + 19 files changed, 244 insertions(+), 73 deletions(-) + +diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c +index ed369532d4..1e143511b2 100644 +--- a/src/analyze/analyze-verify.c ++++ b/src/analyze/analyze-verify.c +@@ -205,7 +205,7 @@ static int verify_unit(Unit *u, bool check_man) { + unit_dump(u, stdout, "\t"); + + log_unit_debug(u, "Creating %s/start job", u->id); +- r = manager_add_job(u->manager, JOB_START, u, JOB_REPLACE, &err, NULL); ++ r = manager_add_job(u->manager, JOB_START, u, JOB_REPLACE, NULL, &err, NULL); + if (r < 0) + log_unit_error_errno(u, r, "Failed to create %s/start: %s", u->id, bus_error_message(&err, r)); + +diff --git a/src/core/automount.c b/src/core/automount.c +index b1a155d8d4..76e70f4dac 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -776,7 +776,7 @@ static void automount_enter_running(Automount *a) { + goto fail; + } + +- r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); + goto fail; +@@ -1032,7 +1032,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo + goto fail; + } + +- r = manager_add_job(UNIT(a)->manager, JOB_STOP, trigger, JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(a)->manager, JOB_STOP, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + log_unit_warning(UNIT(a), "Failed to queue umount startup job: %s", bus_error_message(&error, r)); + goto fail; +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index a0777f63d5..0a1d3df42f 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -549,6 +549,26 @@ static int method_reload_or_try_restart_unit(sd_bus_message *message, void *user + return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error); + } + ++static int method_enqueue_unit_job(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ Manager *m = userdata; ++ const char *name; ++ Unit *u; ++ int r; ++ ++ assert(message); ++ assert(m); ++ ++ r = sd_bus_message_read(message, "s", &name); ++ if (r < 0) ++ return r; ++ ++ r = manager_load_unit(m, name, NULL, error, &u); ++ if (r < 0) ++ return r; ++ ++ return bus_unit_method_enqueue_job(message, u, error); ++} ++ + static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Manager *m = userdata; + const char *old_name; +@@ -978,7 +998,7 @@ static int method_start_transient_unit(sd_bus_message *message, void *userdata, + return r; + + /* Finally, start it */ +- return bus_unit_queue_job(message, u, JOB_START, mode, false, error); ++ return bus_unit_queue_job(message, u, JOB_START, mode, 0, error); + } + + static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) { +@@ -2547,6 +2567,7 @@ const sd_bus_vtable bus_manager_vtable[] = { + SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("EnqueueUnitJob", "sss", "uososa(uosos)", method_enqueue_unit_job, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("FreezeUnit", "s", NULL, method_freeze_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ThawUnit", "s", NULL, method_thaw_unit, SD_BUS_VTABLE_UNPRIVILEGED), +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index ce81103e92..549a166abc 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -314,6 +314,14 @@ static int bus_verify_manage_units_async_full( + error); + } + ++static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = { ++ [JOB_START] = N_("Authentication is required to start '$(unit)'."), ++ [JOB_STOP] = N_("Authentication is required to stop '$(unit)'."), ++ [JOB_RELOAD] = N_("Authentication is required to reload '$(unit)'."), ++ [JOB_RESTART] = N_("Authentication is required to restart '$(unit)'."), ++ [JOB_TRY_RESTART] = N_("Authentication is required to restart '$(unit)'."), ++}; ++ + int bus_unit_method_start_generic( + sd_bus_message *message, + Unit *u, +@@ -324,13 +332,6 @@ int bus_unit_method_start_generic( + const char *smode; + JobMode mode; + _cleanup_free_ char *verb = NULL; +- static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = { +- [JOB_START] = N_("Authentication is required to start '$(unit)'."), +- [JOB_STOP] = N_("Authentication is required to stop '$(unit)'."), +- [JOB_RELOAD] = N_("Authentication is required to reload '$(unit)'."), +- [JOB_RESTART] = N_("Authentication is required to restart '$(unit)'."), +- [JOB_TRY_RESTART] = N_("Authentication is required to restart '$(unit)'."), +- }; + int r; + + assert(message); +@@ -372,7 +373,8 @@ int bus_unit_method_start_generic( + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + +- return bus_unit_queue_job(message, u, job_type, mode, reload_if_possible, error); ++ return bus_unit_queue_job(message, u, job_type, mode, ++ reload_if_possible ? BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE : 0, error); + } + + static int method_start(sd_bus_message *message, void *userdata, sd_bus_error *error) { +@@ -403,6 +405,62 @@ static int method_reload_or_try_restart(sd_bus_message *message, void *userdata, + return bus_unit_method_start_generic(message, userdata, JOB_TRY_RESTART, true, error); + } + ++int bus_unit_method_enqueue_job(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ BusUnitQueueFlags flags = BUS_UNIT_QUEUE_VERBOSE_REPLY; ++ const char *jtype, *smode; ++ Unit *u = userdata; ++ JobType type; ++ JobMode mode; ++ int r; ++ ++ assert(message); ++ assert(u); ++ ++ r = sd_bus_message_read(message, "ss", &jtype, &smode); ++ if (r < 0) ++ return r; ++ ++ /* Parse the two magic reload types "reload-or-…" manually */ ++ if (streq(jtype, "reload-or-restart")) { ++ type = JOB_RESTART; ++ flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE; ++ } else if (streq(jtype, "reload-or-try-restart")) { ++ type = JOB_TRY_RESTART; ++ flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE; ++ } else { ++ /* And the rest generically */ ++ type = job_type_from_string(jtype); ++ if (type < 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job type %s invalid", jtype); ++ } ++ ++ mode = job_mode_from_string(smode); ++ if (mode < 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode); ++ ++ r = mac_selinux_unit_access_check( ++ u, message, ++ job_type_to_access_method(type), ++ error); ++ if (r < 0) ++ return r; ++ ++ r = bus_verify_manage_units_async_full( ++ u, ++ jtype, ++ CAP_SYS_ADMIN, ++ polkit_message_for_job[type], ++ true, ++ message, ++ error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ ++ ++ return bus_unit_queue_job(message, u, type, mode, flags, error); ++} ++ + int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Unit *u = userdata; + const char *swho; +@@ -722,6 +780,7 @@ const sd_bus_vtable bus_unit_vtable[] = { + SD_BUS_METHOD("TryRestart", "s", "o", method_try_restart, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReloadOrRestart", "s", "o", method_reload_or_restart, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReloadOrTryRestart", "s", "o", method_reload_or_try_restart, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("EnqueueJob", "ss", "uososa(uosos)", bus_unit_method_enqueue_job, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Kill", "si", NULL, bus_unit_method_kill, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ResetFailed", NULL, NULL, bus_unit_method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("SetProperties", "ba(sv)", NULL, bus_unit_method_set_properties, SD_BUS_VTABLE_UNPRIVILEGED), +@@ -1354,11 +1413,14 @@ int bus_unit_queue_job( + Unit *u, + JobType type, + JobMode mode, +- bool reload_if_possible, ++ BusUnitQueueFlags flags, + sd_bus_error *error) { + +- _cleanup_free_ char *path = NULL; +- Job *j; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; ++ _cleanup_free_ char *job_path = NULL, *unit_path = NULL; ++ _cleanup_(set_freep) Set *affected = NULL; ++ Iterator i; ++ Job *j, *a; + int r; + + assert(message); +@@ -1373,7 +1435,7 @@ int bus_unit_queue_job( + if (r < 0) + return r; + +- if (reload_if_possible && unit_can_reload(u)) { ++ if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) { + if (type == JOB_RESTART) + type = JOB_RELOAD_OR_START; + else if (type == JOB_TRY_RESTART) +@@ -1391,7 +1453,13 @@ int bus_unit_queue_job( + (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start)) + return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); + +- r = manager_add_job(u->manager, type, u, mode, error, &j); ++ if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) { ++ affected = set_new(NULL); ++ if (!affected) ++ return -ENOMEM; ++ } ++ ++ r = manager_add_job(u->manager, type, u, mode, affected, error, &j); + if (r < 0) + return r; + +@@ -1399,11 +1467,64 @@ int bus_unit_queue_job( + if (r < 0) + return r; + +- path = job_dbus_path(j); +- if (!path) ++ job_path = job_dbus_path(j); ++ if (!job_path) + return -ENOMEM; + +- return sd_bus_reply_method_return(message, "o", path); ++ /* The classic response is just a job object path */ ++ if (!FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) ++ return sd_bus_reply_method_return(message, "o", job_path); ++ ++ /* In verbose mode respond with the anchor job plus everything that has been affected */ ++ r = sd_bus_message_new_method_return(message, &reply); ++ if (r < 0) ++ return r; ++ ++ unit_path = unit_dbus_path(j->unit); ++ if (!unit_path) ++ return -ENOMEM; ++ ++ r = sd_bus_message_append(reply, "uosos", ++ j->id, job_path, ++ j->unit->id, unit_path, ++ job_type_to_string(j->type)); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_open_container(reply, 'a', "(uosos)"); ++ if (r < 0) ++ return r; ++ ++ SET_FOREACH(a, affected, i) { ++ ++ if (a->id == j->id) ++ continue; ++ ++ /* Free paths from previous iteration */ ++ job_path = mfree(job_path); ++ unit_path = mfree(unit_path); ++ ++ job_path = job_dbus_path(a); ++ if (!job_path) ++ return -ENOMEM; ++ ++ unit_path = unit_dbus_path(a->unit); ++ if (!unit_path) ++ return -ENOMEM; ++ ++ r = sd_bus_message_append(reply, "(uosos)", ++ a->id, job_path, ++ a->unit->id, unit_path, ++ job_type_to_string(a->type)); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_bus_message_close_container(reply); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_send(NULL, reply, NULL); + } + + static int bus_unit_set_live_property( +diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h +index 39aa1bb53c..d298fcc99e 100644 +--- a/src/core/dbus-unit.h ++++ b/src/core/dbus-unit.h +@@ -15,6 +15,7 @@ int bus_unit_send_pending_freezer_message(Unit *u); + void bus_unit_send_removed_signal(Unit *u); + + int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error); ++int bus_unit_method_enqueue_job(sd_bus_message *message, void *userdata, sd_bus_error *error); + int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error); + int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error); + +@@ -27,7 +28,12 @@ int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error + int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error *error); + int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error); + +-int bus_unit_queue_job(sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error); ++typedef enum BusUnitQueueFlags { ++ BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE = 1 << 0, ++ BUS_UNIT_QUEUE_VERBOSE_REPLY = 1 << 1, ++} BusUnitQueueFlags; ++ ++int bus_unit_queue_job(sd_bus_message *message, Unit *u, JobType type, JobMode mode, BusUnitQueueFlags flags, sd_bus_error *error); + int bus_unit_validate_load_state(Unit *u, sd_bus_error *error); + + int bus_unit_track_add_name(Unit *u, const char *name); +diff --git a/src/core/dbus.c b/src/core/dbus.c +index b69c11c519..584a8a1b01 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -176,7 +176,7 @@ static int signal_activation_request(sd_bus_message *message, void *userdata, sd + goto failed; + } + +- r = manager_add_job(m, JOB_START, u, JOB_REPLACE, &error, NULL); ++ r = manager_add_job(m, JOB_START, u, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto failed; + +diff --git a/src/core/device.c b/src/core/device.c +index 021c28dfbd..cb8b66dfc5 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -419,7 +419,7 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) { + if (strv_contains(d->wants_property, *i)) /* Was this unit already listed before? */ + continue; + +- r = manager_add_job_by_name(u->manager, JOB_START, *i, JOB_FAIL, &error, NULL); ++ r = manager_add_job_by_name(u->manager, JOB_START, *i, JOB_FAIL, NULL, &error, NULL); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to enqueue SYSTEMD_WANTS= job, ignoring: %s", bus_error_message(&error, r)); + } +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 76e1124cff..766a3b4d2b 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -54,8 +54,7 @@ int emergency_action( + log_and_status(m, "Rebooting", reason); + + (void) update_reboot_parameter_and_warn(reboot_arg); +- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); +- ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_REBOOT_FORCE: +@@ -83,7 +82,7 @@ int emergency_action( + + case EMERGENCY_ACTION_POWEROFF: + log_and_status(m, "Powering off", reason); +- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_POWEROFF_FORCE: +diff --git a/src/core/main.c b/src/core/main.c +index 25536054b3..d897155644 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1952,13 +1952,13 @@ static int do_queue_default_job( + + assert(target->load_state == UNIT_LOADED); + +- r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, &error, &default_unit_job); ++ r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, NULL, &error, &default_unit_job); + if (r == -EPERM) { + log_debug_errno(r, "Default target could not be isolated, starting instead: %s", bus_error_message(&error, r)); + + sd_bus_error_free(&error); + +- r = manager_add_job(m, JOB_START, target, JOB_REPLACE, &error, &default_unit_job); ++ r = manager_add_job(m, JOB_START, target, JOB_REPLACE, NULL, &error, &default_unit_job); + if (r < 0) { + *ret_error_message = "Failed to start default target"; + return log_emergency_errno(r, "Failed to start default target: %s", bus_error_message(&error, r)); +diff --git a/src/core/manager.c b/src/core/manager.c +index 4c04896aaa..012615e537 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1242,7 +1242,7 @@ static unsigned manager_dispatch_stop_when_unneeded_queue(Manager *m) { + } + + /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ +- r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, &error, NULL); ++ r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, NULL, &error, NULL); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r)); + } +@@ -1685,9 +1685,17 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + return 0; + } + +-int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret) { +- int r; ++int manager_add_job( ++ Manager *m, ++ JobType type, ++ Unit *unit, ++ JobMode mode, ++ Set *affected_jobs, ++ sd_bus_error *error, ++ Job **ret) { ++ + Transaction *tr; ++ int r; + + assert(m); + assert(type < _JOB_TYPE_MAX); +@@ -1695,10 +1703,10 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_e + assert(mode < _JOB_MODE_MAX); + + if (mode == JOB_ISOLATE && type != JOB_START) +- return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start."); ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start."); + + if (mode == JOB_ISOLATE && !unit->allow_isolate) +- return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated."); ++ return sd_bus_error_setf(error, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated."); + + log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode)); + +@@ -1710,7 +1718,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_e + + r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, false, + IN_SET(mode, JOB_IGNORE_DEPENDENCIES, JOB_IGNORE_REQUIREMENTS), +- mode == JOB_IGNORE_DEPENDENCIES, e); ++ mode == JOB_IGNORE_DEPENDENCIES, error); + if (r < 0) + goto tr_abort; + +@@ -1720,7 +1728,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_e + goto tr_abort; + } + +- r = transaction_activate(tr, m, mode, e); ++ r = transaction_activate(tr, m, mode, affected_jobs, error); + if (r < 0) + goto tr_abort; + +@@ -1728,8 +1736,8 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_e + "Enqueued job %s/%s as %u", unit->id, + job_type_to_string(type), (unsigned) tr->anchor_job->id); + +- if (_ret) +- *_ret = tr->anchor_job; ++ if (ret) ++ *ret = tr->anchor_job; + + transaction_free(tr); + return 0; +@@ -1740,7 +1748,7 @@ tr_abort: + return r; + } + +-int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **ret) { ++int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, sd_bus_error *e, Job **ret) { + Unit *unit = NULL; /* just to appease gcc, initialization is not really necessary */ + int r; + +@@ -1754,10 +1762,10 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode + return r; + assert(unit); + +- return manager_add_job(m, type, unit, mode, e, ret); ++ return manager_add_job(m, type, unit, mode, affected_jobs, e, ret); + } + +-int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret) { ++int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, Job **ret) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + +@@ -1766,7 +1774,7 @@ int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, + assert(name); + assert(mode < _JOB_MODE_MAX); + +- r = manager_add_job_by_name(m, type, name, mode, &error, ret); ++ r = manager_add_job_by_name(m, type, name, mode, affected_jobs, &error, ret); + if (r < 0) + return log_warning_errno(r, "Failed to enqueue %s job for %s: %s", job_mode_to_string(mode), name, bus_error_message(&error, r)); + +@@ -1794,7 +1802,7 @@ int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error + /* Failure in adding individual dependencies is ignored, so this always succeeds. */ + transaction_add_propagate_reload_jobs(tr, unit, tr->anchor_job, mode == JOB_IGNORE_DEPENDENCIES, e); + +- r = transaction_activate(tr, m, mode, e); ++ r = transaction_activate(tr, m, mode, NULL, e); + if (r < 0) + goto tr_abort; + +@@ -2512,7 +2520,7 @@ static void manager_start_target(Manager *m, const char *name, JobMode mode) { + + log_debug("Activating special unit %s", name); + +- r = manager_add_job_by_name(m, JOB_START, name, mode, &error, NULL); ++ r = manager_add_job_by_name(m, JOB_START, name, mode, NULL, &error, NULL); + if (r < 0) + log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r)); + } +diff --git a/src/core/manager.h b/src/core/manager.h +index 40568d3c8b..c4b8e80093 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -397,9 +397,9 @@ int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_err + int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret); + int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u); + +-int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret); +-int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **_ret); +-int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret); ++int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, Set *affected_jobs, sd_bus_error *e, Job **_ret); ++int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, sd_bus_error *e, Job **_ret); ++int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, Job **ret); + int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e); + + void manager_dump_units(Manager *s, FILE *f, const char *prefix); +diff --git a/src/core/path.c b/src/core/path.c +index dda4a3036b..ed40bc6c19 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -474,7 +474,7 @@ static void path_enter_running(Path *p) { + return; + } + +- r = manager_add_job(UNIT(p)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(p)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; + +diff --git a/src/core/service.c b/src/core/service.c +index 7cff419e4e..5e3e75b5ae 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2176,7 +2176,7 @@ static void service_enter_restart(Service *s) { + * restarted. We use JOB_RESTART (instead of the more obvious + * JOB_START) here so that those dependency jobs will be added + * as well. */ +- r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; + +diff --git a/src/core/socket.c b/src/core/socket.c +index 7c6d3dfad1..fe061eb73b 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2274,7 +2274,7 @@ static void socket_enter_running(Socket *s, int cfd) { + goto fail; + } + +- r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; + } +@@ -2349,7 +2349,7 @@ static void socket_enter_running(Socket *s, int cfd) { + + service->peer = TAKE_PTR(p); /* Pass ownership of the peer reference */ + +- r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + /* We failed to activate the new service, but it still exists. Let's make sure the service + * closes and forgets the connection fd again, immediately. */ +diff --git a/src/core/timer.c b/src/core/timer.c +index 2876d54a59..281ac7f97f 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -566,7 +566,7 @@ static void timer_enter_running(Timer *t) { + return; + } + +- r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); ++ r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; + +diff --git a/src/core/transaction.c b/src/core/transaction.c +index 045930838b..cdaaff4f55 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -585,7 +585,12 @@ rescan: + } + } + +-static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) { ++static int transaction_apply( ++ Transaction *tr, ++ Manager *m, ++ JobMode mode, ++ Set *affected_jobs) { ++ + Iterator i; + Job *j; + int r; +@@ -642,6 +647,11 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) { + job_add_to_dbus_queue(j); + job_start_timer(j, false); + job_shutdown_magic(j); ++ ++ /* When 'affected' is specified, let's track all in it all jobs that were touched because of ++ * this transaction. */ ++ if (affected_jobs) ++ (void) set_put(affected_jobs, j); + } + + return 0; +@@ -654,7 +664,13 @@ rollback: + return r; + } + +-int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error *e) { ++int transaction_activate( ++ Transaction *tr, ++ Manager *m, ++ JobMode mode, ++ Set *affected_jobs, ++ sd_bus_error *e) { ++ + Iterator i; + Job *j; + int r; +@@ -731,7 +747,7 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error + return log_notice_errno(r, "Requested transaction contradicts existing jobs: %s", bus_error_message(e, r)); + + /* Tenth step: apply changes */ +- r = transaction_apply(tr, m, mode); ++ r = transaction_apply(tr, m, mode, affected_jobs); + if (r < 0) + return log_warning_errno(r, "Failed to apply transaction: %m"); + +diff --git a/src/core/transaction.h b/src/core/transaction.h +index 70d74a4ccb..4b5620f5c8 100644 +--- a/src/core/transaction.h ++++ b/src/core/transaction.h +@@ -29,6 +29,6 @@ int transaction_add_job_and_dependencies( + bool ignore_requirements, + bool ignore_order, + sd_bus_error *e); +-int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error *e); ++int transaction_activate(Transaction *tr, Manager *m, JobMode mode, Set *affected, sd_bus_error *e); + int transaction_add_isolate_jobs(Transaction *tr, Manager *m); + void transaction_abort(Transaction *tr); +diff --git a/src/core/unit.c b/src/core/unit.c +index 29ce6c1fb7..ffbf3cfd48 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2033,7 +2033,7 @@ static void unit_check_binds_to(Unit *u) { + log_unit_info(u, "Unit is bound to inactive unit %s. Stopping, too.", other->id); + + /* A unit we need to run is gone. Sniff. Let's stop this. */ +- r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, &error, NULL); ++ r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, NULL, &error, NULL); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r)); + } +@@ -2049,25 +2049,25 @@ static void retroactively_start_dependencies(Unit *u) { + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRES], i) + if (!hashmap_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL); ++ manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL, NULL); + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BINDS_TO], i) + if (!hashmap_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL); ++ manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, NULL, NULL, NULL); + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_WANTS], i) + if (!hashmap_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_START, other, JOB_FAIL, NULL, NULL); ++ manager_add_job(u->manager, JOB_START, other, JOB_FAIL, NULL, NULL, NULL); + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_CONFLICTS], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL); ++ manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL, NULL); + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_CONFLICTED_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL); ++ manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL, NULL); + } + + static void retroactively_stop_dependencies(Unit *u) { +@@ -2081,7 +2081,7 @@ static void retroactively_stop_dependencies(Unit *u) { + /* Pull down units which are bound to us recursively if enabled */ + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BOUND_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) +- manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL); ++ manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, NULL, NULL, NULL); + } + + void unit_start_on_failure(Unit *u) { +@@ -2100,7 +2100,7 @@ void unit_start_on_failure(Unit *u) { + HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_ON_FAILURE], i) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + +- r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, &error, NULL); ++ r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, NULL, &error, NULL); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to enqueue OnFailure= job, ignoring: %s", bus_error_message(&error, r)); + } +diff --git a/src/test/test-engine.c b/src/test/test-engine.c +index 0f3e244dc1..f2e327b3f5 100644 +--- a/src/test/test-engine.c ++++ b/src/test/test-engine.c +@@ -46,7 +46,7 @@ int main(int argc, char *argv[]) { + manager_dump_units(m, stdout, "\t"); + + printf("Test1: (Trivial)\n"); +- r = manager_add_job(m, JOB_START, c, JOB_REPLACE, &err, &j); ++ r = manager_add_job(m, JOB_START, c, JOB_REPLACE, NULL, &err, &j); + if (sd_bus_error_is_set(&err)) + log_error("error: %s: %s", err.name, err.message); + assert_se(r == 0); +@@ -59,15 +59,15 @@ int main(int argc, char *argv[]) { + manager_dump_units(m, stdout, "\t"); + + printf("Test2: (Cyclic Order, Unfixable)\n"); +- assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, NULL, &j) == -EDEADLK); ++ assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, NULL, NULL, &j) == -EDEADLK); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test3: (Cyclic Order, Fixable, Garbage Collector)\n"); +- assert_se(manager_add_job(m, JOB_START, e, JOB_REPLACE, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_START, e, JOB_REPLACE, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test4: (Identical transaction)\n"); +- assert_se(manager_add_job(m, JOB_START, e, JOB_FAIL, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_START, e, JOB_FAIL, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load3:\n"); +@@ -75,21 +75,21 @@ int main(int argc, char *argv[]) { + manager_dump_units(m, stdout, "\t"); + + printf("Test5: (Colliding transaction, fail)\n"); +- assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, NULL, &j) == -EDEADLK); ++ assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, NULL, NULL, &j) == -EDEADLK); + + printf("Test6: (Colliding transaction, replace)\n"); +- assert_se(manager_add_job(m, JOB_START, g, JOB_REPLACE, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_START, g, JOB_REPLACE, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test7: (Unmergeable job type, fail)\n"); +- assert_se(manager_add_job(m, JOB_STOP, g, JOB_FAIL, NULL, &j) == -EDEADLK); ++ assert_se(manager_add_job(m, JOB_STOP, g, JOB_FAIL, NULL, NULL, &j) == -EDEADLK); + + printf("Test8: (Mergeable job type, fail)\n"); +- assert_se(manager_add_job(m, JOB_RESTART, g, JOB_FAIL, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_RESTART, g, JOB_FAIL, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test9: (Unmergeable job type, replace)\n"); +- assert_se(manager_add_job(m, JOB_STOP, g, JOB_REPLACE, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_STOP, g, JOB_REPLACE, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load4:\n"); +@@ -97,7 +97,7 @@ int main(int argc, char *argv[]) { + manager_dump_units(m, stdout, "\t"); + + printf("Test10: (Unmergeable job type of auxiliary job, fail)\n"); +- assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, NULL, &j) == 0); ++ assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, NULL, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b)); diff --git a/SOURCES/0445-systemctl-replace-switch-statement-by-table-of-struc.patch b/SOURCES/0445-systemctl-replace-switch-statement-by-table-of-struc.patch new file mode 100644 index 0000000..b95326c --- /dev/null +++ b/SOURCES/0445-systemctl-replace-switch-statement-by-table-of-struc.patch @@ -0,0 +1,115 @@ +From 8b34041ee97069bee8bf03ae5ba651b34b1b8460 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Mar 2019 15:20:26 +0100 +Subject: [PATCH] systemctl: replace switch statement by table of structures + +(cherry picked from commit c45e5fb877033c9e3f9b79121644ed71032af379) + +Related: #846319 +--- + src/systemctl/systemctl.c | 68 ++++++++++++--------------------------- + 1 file changed, 21 insertions(+), 47 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index e963f19b0a..04e24691d8 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3179,64 +3179,38 @@ static int logind_set_wall_message(void) { + } + #endif + +-/* Ask systemd-logind, which might grant access to unprivileged users +- * through PolicyKit */ ++/* Ask systemd-logind, which might grant access to unprivileged users through polkit */ + static int logind_reboot(enum action a) { + #if ENABLE_LOGIND ++ static const struct { ++ const char *method; ++ const char *description; ++ } actions[_ACTION_MAX] = { ++ [ACTION_POWEROFF] = { "PowerOff", "power off system" }, ++ [ACTION_REBOOT] = { "Reboot", "reboot system" }, ++ [ACTION_HALT] = { "Halt", "halt system" }, ++ [ACTION_SUSPEND] = { "Suspend", "suspend system" }, ++ [ACTION_HIBERNATE] = { "Hibernate", "hibernate system" }, ++ [ACTION_HYBRID_SLEEP] = { "HybridSleep", "put system into hybrid sleep" }, ++ [ACTION_SUSPEND_THEN_HIBERNATE] = { "SuspendThenHibernate", "suspend system, hibernate later" }, ++ }; ++ + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- const char *method, *description; + sd_bus *bus; + int r; + ++ if (a < 0 || a >= _ACTION_MAX || !actions[a].method) ++ return -EINVAL; ++ + r = acquire_bus(BUS_FULL, &bus); + if (r < 0) + return r; + +- switch (a) { +- +- case ACTION_POWEROFF: +- method = "PowerOff"; +- description = "power off system"; +- break; +- +- case ACTION_REBOOT: +- method = "Reboot"; +- description = "reboot system"; +- break; +- +- case ACTION_HALT: +- method = "Halt"; +- description = "halt system"; +- break; +- +- case ACTION_SUSPEND: +- method = "Suspend"; +- description = "suspend system"; +- break; +- +- case ACTION_HIBERNATE: +- method = "Hibernate"; +- description = "hibernate system"; +- break; +- +- case ACTION_HYBRID_SLEEP: +- method = "HybridSleep"; +- description = "put system into hybrid sleep"; +- break; +- +- case ACTION_SUSPEND_THEN_HIBERNATE: +- method = "SuspendThenHibernate"; +- description = "put system into suspend followed by hibernate"; +- break; +- +- default: +- return -EINVAL; +- } +- + polkit_agent_open_maybe(); + (void) logind_set_wall_message(); + +- log_debug("%s org.freedesktop.login1.Manager %s dbus call.", arg_dry_run ? "Would execute" : "Executing", method); ++ log_debug("%s org.freedesktop.login1.Manager %s dbus call.", arg_dry_run ? "Would execute" : "Executing", actions[a].method); ++ + if (arg_dry_run) + return 0; + +@@ -3245,12 +3219,12 @@ static int logind_reboot(enum action a) { + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", +- method, ++ actions[a].method, + &error, + NULL, + "b", arg_ask_password); + if (r < 0) +- return log_error_errno(r, "Failed to %s via logind: %s", description, bus_error_message(&error, r)); ++ return log_error_errno(r, "Failed to %s via logind: %s", actions[a].description, bus_error_message(&error, r)); + + return 0; + #else diff --git a/SOURCES/0446-systemctl-reindent-table.patch b/SOURCES/0446-systemctl-reindent-table.patch new file mode 100644 index 0000000..22ad788 --- /dev/null +++ b/SOURCES/0446-systemctl-reindent-table.patch @@ -0,0 +1,53 @@ +From 26d2d89c6216672cedf6abfe1b73081adebbdcf8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Mar 2019 15:49:52 +0100 +Subject: [PATCH] systemctl: reindent table + +(cherry picked from commit 5fd77930ad9980af5257f9f871556d6973db736c) + +Related: #846319 +--- + src/systemctl/systemctl.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 04e24691d8..f057dc829c 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -2974,21 +2974,21 @@ static const struct { + const char *verb; + const char *mode; + } action_table[_ACTION_MAX] = { +- [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" }, +- [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" }, +- [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" }, +- [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" }, +- [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, +- [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, +- [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, +- [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" }, +- [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" }, +- [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" }, +- [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" }, +- [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" }, +- [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" }, +- [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" }, +- [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" }, ++ [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" }, ++ [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" }, ++ [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" }, ++ [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" }, ++ [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, ++ [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, ++ [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, ++ [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" }, ++ [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" }, ++ [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" }, ++ [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" }, ++ [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" }, ++ [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" }, ++ [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" }, ++ [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" }, + [ACTION_SUSPEND_THEN_HIBERNATE] = { SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET, "suspend-then-hibernate", "replace-irreversibly" }, + }; + diff --git a/SOURCES/0447-systemctl-Only-wait-when-there-s-something-to-wait-f.patch b/SOURCES/0447-systemctl-Only-wait-when-there-s-something-to-wait-f.patch new file mode 100644 index 0000000..2cd38d4 --- /dev/null +++ b/SOURCES/0447-systemctl-Only-wait-when-there-s-something-to-wait-f.patch @@ -0,0 +1,29 @@ +From 91c83bde0904581fbc33eb7821119e665b9505ce Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Fri, 20 Jul 2018 11:32:55 -0700 +Subject: [PATCH] systemctl: Only wait when there's something to wait for. + +Tested: +- `systemctl --wait start i-do-not-exist.service` does not wait. +- `systemctl --wait start i-do-not-exist.service valid-unit.service` does. + +(cherry picked from commit 46f2579c2ac9f6780d5afec1000764defc6b581e) + +Related: #846319 +--- + src/systemctl/systemctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index f057dc829c..1929692480 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3130,7 +3130,7 @@ static int start_unit(int argc, char *argv[], void *userdata) { + check_triggering_units(bus, *name); + } + +- if (r >= 0 && arg_wait) { ++ if (r >= 0 && arg_wait && !set_isempty(wait_context.unit_paths)) { + int q; + q = sd_event_loop(wait_context.event); + if (q < 0) diff --git a/SOURCES/0448-systemctl-clean-up-start_unit_one-error-handling.patch b/SOURCES/0448-systemctl-clean-up-start_unit_one-error-handling.patch new file mode 100644 index 0000000..ffd9a76 --- /dev/null +++ b/SOURCES/0448-systemctl-clean-up-start_unit_one-error-handling.patch @@ -0,0 +1,99 @@ +From 7569756d005d4f780fffd2504eb6f461982833f2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 13 Oct 2018 14:38:46 +0200 +Subject: [PATCH] systemctl: clean up start_unit_one() error handling + +Let's split exit code handling in two: "r" is only used for errno-style +errors, and "ret" is used for exit() codes. Then, let's use EXIT_SUCCESS +for checking whether the latter is already used. + +This way it should always be clear what kind of error we are processing, +and when we propaate one into the other. + +Moreover this allows us to drop "q" form all inner loops, avoiding +confusion when to use "q" and when "r" to store received errors. + +Fixes: #9704 +(cherry picked from commit 0e8d9c0c4d7e71487c486f626c59853cfb031d16) + +Related: #846319 +--- + src/systemctl/systemctl.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 1929692480..4af9deb98d 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3004,12 +3004,12 @@ static enum action verb_to_action(const char *verb) { + + static int start_unit(int argc, char *argv[], void *userdata) { + _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; ++ _cleanup_(wait_context_free) WaitContext wait_context = {}; + const char *method, *mode, *one_name, *suffix = NULL; + _cleanup_strv_free_ char **names = NULL; ++ int r, ret = EXIT_SUCCESS; + sd_bus *bus; +- _cleanup_(wait_context_free) WaitContext wait_context = {}; + char **name; +- int r = 0; + + if (arg_wait && !STR_IN_SET(argv[0], "start", "restart")) { + log_error("--wait may only be used with the 'start' or 'restart' commands."); +@@ -3096,16 +3096,15 @@ static int start_unit(int argc, char *argv[], void *userdata) { + + STRV_FOREACH(name, names) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- int q; + +- q = start_unit_one(bus, method, *name, mode, &error, w, arg_wait ? &wait_context : NULL); +- if (r >= 0 && q < 0) +- r = translate_bus_error_to_exit_status(q, &error); ++ r = start_unit_one(bus, method, *name, mode, &error, w, arg_wait ? &wait_context : NULL); ++ if (ret == EXIT_SUCCESS && r < 0) ++ ret = translate_bus_error_to_exit_status(r, &error); + } + + if (!arg_no_block) { +- int q, arg_count = 0; + const char* extra_args[4] = {}; ++ int arg_count = 0; + + if (arg_scope != UNIT_FILE_SYSTEM) + extra_args[arg_count++] = "--user"; +@@ -3119,9 +3118,9 @@ static int start_unit(int argc, char *argv[], void *userdata) { + extra_args[arg_count++] = arg_host; + } + +- q = bus_wait_for_jobs(w, arg_quiet, extra_args); +- if (q < 0) +- return q; ++ r = bus_wait_for_jobs(w, arg_quiet, extra_args); ++ if (r < 0) ++ return r; + + /* When stopping units, warn if they can still be triggered by + * another active unit (socket, path, timer) */ +@@ -3130,16 +3129,15 @@ static int start_unit(int argc, char *argv[], void *userdata) { + check_triggering_units(bus, *name); + } + +- if (r >= 0 && arg_wait && !set_isempty(wait_context.unit_paths)) { +- int q; +- q = sd_event_loop(wait_context.event); +- if (q < 0) +- return log_error_errno(q, "Failed to run event loop: %m"); ++ if (ret == EXIT_SUCCESS && arg_wait && !set_isempty(wait_context.unit_paths)) { ++ r = sd_event_loop(wait_context.event); ++ if (r < 0) ++ return log_error_errno(r, "Failed to run event loop: %m"); + if (wait_context.any_failed) +- r = EXIT_FAILURE; ++ ret = EXIT_FAILURE; + } + +- return r; ++ return ret; + } + + #if ENABLE_LOGIND diff --git a/SOURCES/0449-systemctl-split-out-extra-args-generation-into-helpe.patch b/SOURCES/0449-systemctl-split-out-extra-args-generation-into-helpe.patch new file mode 100644 index 0000000..a580c7a --- /dev/null +++ b/SOURCES/0449-systemctl-split-out-extra-args-generation-into-helpe.patch @@ -0,0 +1,68 @@ +From cfb124260a0a9e68102a373c0d136f792e2d4ea7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Mar 2019 16:19:35 +0100 +Subject: [PATCH] systemctl: split out extra args generation into helper + function of its own + +(cherry picked from commit 94369fc0663255bbd327f97dba288ececf51a514) + +Related: #846319 +--- + src/systemctl/systemctl.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 4af9deb98d..e7a8fd559f 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3002,6 +3002,25 @@ static enum action verb_to_action(const char *verb) { + return _ACTION_INVALID; + } + ++static const char** make_extra_args(const char *extra_args[static 4]) { ++ size_t n = 0; ++ ++ if (arg_scope != UNIT_FILE_SYSTEM) ++ extra_args[n++] = "--user"; ++ ++ if (arg_transport == BUS_TRANSPORT_REMOTE) { ++ extra_args[n++] = "-H"; ++ extra_args[n++] = arg_host; ++ } else if (arg_transport == BUS_TRANSPORT_MACHINE) { ++ extra_args[n++] = "-M"; ++ extra_args[n++] = arg_host; ++ } else ++ assert(arg_transport == BUS_TRANSPORT_LOCAL); ++ ++ extra_args[n] = NULL; ++ return extra_args; ++} ++ + static int start_unit(int argc, char *argv[], void *userdata) { + _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; + _cleanup_(wait_context_free) WaitContext wait_context = {}; +@@ -3103,22 +3122,9 @@ static int start_unit(int argc, char *argv[], void *userdata) { + } + + if (!arg_no_block) { +- const char* extra_args[4] = {}; +- int arg_count = 0; +- +- if (arg_scope != UNIT_FILE_SYSTEM) +- extra_args[arg_count++] = "--user"; +- +- assert(IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_REMOTE, BUS_TRANSPORT_MACHINE)); +- if (arg_transport == BUS_TRANSPORT_REMOTE) { +- extra_args[arg_count++] = "-H"; +- extra_args[arg_count++] = arg_host; +- } else if (arg_transport == BUS_TRANSPORT_MACHINE) { +- extra_args[arg_count++] = "-M"; +- extra_args[arg_count++] = arg_host; +- } ++ const char* extra_args[4]; + +- r = bus_wait_for_jobs(w, arg_quiet, extra_args); ++ r = bus_wait_for_jobs(w, arg_quiet, make_extra_args(extra_args)); + if (r < 0) + return r; + diff --git a/SOURCES/0450-systemctl-add-new-show-transaction-switch.patch b/SOURCES/0450-systemctl-add-new-show-transaction-switch.patch new file mode 100644 index 0000000..1e804b0 --- /dev/null +++ b/SOURCES/0450-systemctl-add-new-show-transaction-switch.patch @@ -0,0 +1,362 @@ +From cacf7a619cdccd9a6da6c2fe7361eac121b9ea0b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 22 Mar 2019 20:58:13 +0100 +Subject: [PATCH] systemctl: add new --show-transaction switch + +This new switch uses the new method call EnqueueUnitJob() for enqueuing +a job and showing the jobs it enqueued. + +Fixes: #2297 +(cherry picked from commit 85d9b5981ba6b7ee3955f95fa6cf3bb8cdf3444d) + +Resolves: #846319 +--- + src/systemctl/systemctl.c | 183 ++++++++++++++++++++++++++------------ + 1 file changed, 128 insertions(+), 55 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index e7a8fd559f..8bec798373 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -126,6 +126,7 @@ static bool arg_dry_run = false; + static bool arg_quiet = false; + static bool arg_full = false; + static bool arg_recursive = false; ++static bool arg_show_transaction = false; + static int arg_force = 0; + static bool arg_ask_password = false; + static bool arg_runtime = false; +@@ -734,7 +735,6 @@ static int get_unit_list_recursive( + *_machines = NULL; + + *_unit_infos = TAKE_PTR(unit_infos); +- + *_replies = TAKE_PTR(replies); + + return c; +@@ -2688,25 +2688,26 @@ static int check_triggering_units(sd_bus *bus, const char *name) { + } + + static const struct { +- const char *verb; +- const char *method; ++ const char *verb; /* systemctl verb */ ++ const char *method; /* Name of the specific D-Bus method */ ++ const char *job_type; /* Job type when passing to the generic EnqueueUnitJob() method */ + } unit_actions[] = { +- { "start", "StartUnit" }, +- { "stop", "StopUnit" }, +- { "condstop", "StopUnit" }, +- { "reload", "ReloadUnit" }, +- { "restart", "RestartUnit" }, +- { "try-restart", "TryRestartUnit" }, +- { "condrestart", "TryRestartUnit" }, +- { "reload-or-restart", "ReloadOrRestartUnit" }, +- { "try-reload-or-restart", "ReloadOrTryRestartUnit" }, +- { "reload-or-try-restart", "ReloadOrTryRestartUnit" }, +- { "condreload", "ReloadOrTryRestartUnit" }, +- { "force-reload", "ReloadOrTryRestartUnit" } ++ { "start", "StartUnit", "start" }, ++ { "stop", "StopUnit", "stop" }, ++ { "condstop", "StopUnit", "stop" }, /* legacy alias */ ++ { "reload", "ReloadUnit", "reload" }, ++ { "restart", "RestartUnit", "restart" }, ++ { "try-restart", "TryRestartUnit", "try-restart" }, ++ { "condrestart", "TryRestartUnit", "try-restart" }, /* legacy alias */ ++ { "reload-or-restart", "ReloadOrRestartUnit", "reload-or-restart" }, ++ { "try-reload-or-restart", "ReloadOrTryRestartUnit", "reload-or-try-restart" }, ++ { "reload-or-try-restart", "ReloadOrTryRestartUnit", "reload-or-try-restart" }, /* legacy alias */ ++ { "condreload", "ReloadOrTryRestartUnit", "reload-or-try-restart" }, /* legacy alias */ ++ { "force-reload", "ReloadOrTryRestartUnit", "reload-or-try-restart" }, /* legacy alias */ + }; + + static const char *verb_to_method(const char *verb) { +- uint i; ++ size_t i; + + for (i = 0; i < ELEMENTSOF(unit_actions); i++) + if (streq_ptr(unit_actions[i].verb, verb)) +@@ -2715,14 +2716,14 @@ static const char *verb_to_method(const char *verb) { + return "StartUnit"; + } + +-static const char *method_to_verb(const char *method) { +- uint i; ++static const char *verb_to_job_type(const char *verb) { ++ size_t i; + + for (i = 0; i < ELEMENTSOF(unit_actions); i++) +- if (streq_ptr(unit_actions[i].method, method)) +- return unit_actions[i].verb; ++ if (streq_ptr(unit_actions[i].verb, verb)) ++ return unit_actions[i].job_type; + +- return "n/a"; ++ return "start"; + } + + typedef struct { +@@ -2805,7 +2806,8 @@ static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error + + static int start_unit_one( + sd_bus *bus, +- const char *method, ++ const char *method, /* When using classic per-job bus methods */ ++ const char *job_type, /* When using new-style EnqueueUnitJob() */ + const char *name, + const char *mode, + sd_bus_error *error, +@@ -2814,6 +2816,7 @@ static int start_unit_one( + + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + const char *path; ++ bool done = false; + int r; + + assert(method); +@@ -2859,44 +2862,81 @@ static int start_unit_one( + log_debug("%s dbus call org.freedesktop.systemd1.Manager %s(%s, %s)", + arg_dry_run ? "Would execute" : "Executing", + method, name, mode); ++ + if (arg_dry_run) + return 0; + +- r = sd_bus_call_method( +- bus, +- "org.freedesktop.systemd1", +- "/org/freedesktop/systemd1", +- "org.freedesktop.systemd1.Manager", +- method, +- error, +- &reply, +- "ss", name, mode); +- if (r < 0) { +- const char *verb; ++ if (arg_show_transaction) { ++ _cleanup_(sd_bus_error_free) sd_bus_error enqueue_error = SD_BUS_ERROR_NULL; + +- /* There's always a fallback possible for legacy actions. */ +- if (arg_action != ACTION_SYSTEMCTL) +- return r; ++ /* Use the new, fancy EnqueueUnitJob() API if the user wants us to print the transaction */ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "EnqueueUnitJob", ++ &enqueue_error, ++ &reply, ++ "sss", ++ name, job_type, mode); ++ if (r < 0) { ++ if (!sd_bus_error_has_name(&enqueue_error, SD_BUS_ERROR_UNKNOWN_METHOD)) { ++ (void) sd_bus_error_copy(error, &enqueue_error); ++ sd_bus_error_free(&enqueue_error); ++ goto fail; ++ } ++ ++ /* Hmm, the API is not yet available. Let's use the classic API instead (see below). */ ++ log_notice("--show-transaction not supported by this service manager, proceeding without."); ++ } else { ++ const char *u, *jt; ++ uint32_t id; + +- verb = method_to_verb(method); ++ r = sd_bus_message_read(reply, "uosos", &id, &path, &u, NULL, &jt); ++ if (r < 0) ++ return bus_log_parse_error(r); + +- log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r)); ++ log_info("Enqueued anchor job %" PRIu32 " %s/%s.", id, u, jt); + +- if (!sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) && +- !sd_bus_error_has_name(error, BUS_ERROR_UNIT_MASKED) && +- !sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE)) +- log_error("See %s logs and 'systemctl%s status%s %s' for details.", +- arg_scope == UNIT_FILE_SYSTEM ? "system" : "user", +- arg_scope == UNIT_FILE_SYSTEM ? "" : " --user", +- name[0] == '-' ? " --" : "", +- name); ++ r = sd_bus_message_enter_container(reply, 'a', "(uosos)"); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ for (;;) { ++ r = sd_bus_message_read(reply, "(uosos)", &id, NULL, &u, NULL, &jt); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ if (r == 0) ++ break; + +- return r; ++ log_info("Enqueued auxiliary job %" PRIu32 " %s/%s.", id, u, jt); ++ } ++ ++ r = sd_bus_message_exit_container(reply); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ ++ done = true; ++ } + } + +- r = sd_bus_message_read(reply, "o", &path); +- if (r < 0) +- return bus_log_parse_error(r); ++ if (!done) { ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ method, ++ error, ++ &reply, ++ "ss", name, mode); ++ if (r < 0) ++ goto fail; ++ ++ r = sd_bus_message_read(reply, "o", &path); ++ if (r < 0) ++ return bus_log_parse_error(r); ++ } + + if (need_daemon_reload(bus, name) > 0) + warn_unit_file_changed(name); +@@ -2909,6 +2949,24 @@ static int start_unit_one( + } + + return 0; ++ ++fail: ++ /* There's always a fallback possible for legacy actions. */ ++ if (arg_action != ACTION_SYSTEMCTL) ++ return r; ++ ++ log_error_errno(r, "Failed to %s %s: %s", job_type, name, bus_error_message(error, r)); ++ ++ if (!sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) && ++ !sd_bus_error_has_name(error, BUS_ERROR_UNIT_MASKED) && ++ !sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE)) ++ log_error("See %s logs and 'systemctl%s status%s %s' for details.", ++ arg_scope == UNIT_FILE_SYSTEM ? "system" : "user", ++ arg_scope == UNIT_FILE_SYSTEM ? "" : " --user", ++ name[0] == '-' ? " --" : "", ++ name); ++ ++ return r; + } + + static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) { +@@ -2965,7 +3023,6 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r + } + + *ret = TAKE_PTR(mangled); +- + return 0; + } + +@@ -3024,7 +3081,7 @@ static const char** make_extra_args(const char *extra_args[static 4]) { + static int start_unit(int argc, char *argv[], void *userdata) { + _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; + _cleanup_(wait_context_free) WaitContext wait_context = {}; +- const char *method, *mode, *one_name, *suffix = NULL; ++ const char *method, *job_type, *mode, *one_name, *suffix = NULL; + _cleanup_strv_free_ char **names = NULL; + int r, ret = EXIT_SUCCESS; + sd_bus *bus; +@@ -3050,27 +3107,34 @@ static int start_unit(int argc, char *argv[], void *userdata) { + action = verb_to_action(argv[0]); + + if (action != _ACTION_INVALID) { ++ /* A command in style "systemctl reboot", "systemctl poweroff", … */ + method = "StartUnit"; ++ job_type = "start"; + mode = action_table[action].mode; + one_name = action_table[action].target; + } else { + if (streq(argv[0], "isolate")) { ++ /* A "systemctl isolate …" command */ + method = "StartUnit"; ++ job_type = "start"; + mode = "isolate"; +- + suffix = ".target"; + } else { ++ /* A command in style of "systemctl start …", "sysemctl stop …" and so on */ + method = verb_to_method(argv[0]); ++ job_type = verb_to_job_type(argv[0]); + mode = arg_job_mode; + } + one_name = NULL; + } + } else { ++ /* A SysV legacy command such as "halt", "reboot", "poweroff", … */ + assert(arg_action >= 0 && arg_action < _ACTION_MAX); + assert(action_table[arg_action].target); + assert(action_table[arg_action].mode); + + method = "StartUnit"; ++ job_type = "start"; + mode = action_table[arg_action].mode; + one_name = action_table[arg_action].target; + } +@@ -3105,9 +3169,11 @@ static int start_unit(int argc, char *argv[], void *userdata) { + NULL); + if (r < 0) + return log_error_errno(r, "Failed to enable subscription: %m"); ++ + r = sd_event_default(&wait_context.event); + if (r < 0) + return log_error_errno(r, "Failed to allocate event loop: %m"); ++ + r = sd_bus_attach_event(bus, wait_context.event, 0); + if (r < 0) + return log_error_errno(r, "Failed to attach bus to event loop: %m"); +@@ -3116,7 +3182,7 @@ static int start_unit(int argc, char *argv[], void *userdata) { + STRV_FOREACH(name, names) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + +- r = start_unit_one(bus, method, *name, mode, &error, w, arg_wait ? &wait_context : NULL); ++ r = start_unit_one(bus, method, job_type, *name, mode, &error, w, arg_wait ? &wait_context : NULL); + if (ret == EXIT_SUCCESS && r < 0) + ret = translate_bus_error_to_exit_status(r, &error); + } +@@ -7167,6 +7233,8 @@ static void systemctl_help(void) { + " --reverse Show reverse dependencies with 'list-dependencies'\n" + " --job-mode=MODE Specify how to deal with already queued jobs, when\n" + " queueing a new job\n" ++ " -T --show-transaction\n" ++ " When enqueuing a unit job, show full transaction\n" + " --show-types When showing sockets, explicitly show their type\n" + " --value When showing properties, only print the value\n" + " -i --ignore-inhibitors\n" +@@ -7482,6 +7550,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP }, + { "now", no_argument, NULL, ARG_NOW }, + { "message", required_argument, NULL, ARG_MESSAGE }, ++ { "show-transaction", no_argument, NULL, 'T' }, + {} + }; + +@@ -7494,7 +7563,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */ + arg_ask_password = true; + +- while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0) ++ while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:iTr", options, NULL)) >= 0) + + switch (c) { + +@@ -7815,6 +7884,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + return log_oom(); + break; + ++ case 'T': ++ arg_show_transaction = true; ++ break; ++ + case '?': + return -EINVAL; + diff --git a/SOURCES/0451-test-add-some-basic-testing-that-systemctl-start-T-d.patch b/SOURCES/0451-test-add-some-basic-testing-that-systemctl-start-T-d.patch new file mode 100644 index 0000000..13c3808 --- /dev/null +++ b/SOURCES/0451-test-add-some-basic-testing-that-systemctl-start-T-d.patch @@ -0,0 +1,31 @@ +From f31afbfd2fa68e20a10a8432fb4714a6d4e1170a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Mar 2019 17:39:36 +0100 +Subject: [PATCH] test: add some basic testing that "systemctl start -T" does + something + +(cherry picked from commit f087c7e072bb338d5c7c0781c9fbc900612efd18) + +Related: #846319 +--- + test/TEST-03-JOBS/test-jobs.sh | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/TEST-03-JOBS/test-jobs.sh +index e66ea53621..42190cf478 100755 +--- a/test/TEST-03-JOBS/test-jobs.sh ++++ b/test/TEST-03-JOBS/test-jobs.sh +@@ -26,6 +26,13 @@ grep 'sleep\.service.*running' /root/list-jobs.txt + grep 'hello\.service' /root/list-jobs.txt && exit 1 + systemctl stop sleep.service hello-after-sleep.target + ++# Some basic testing that --show-transaction does something useful ++! systemctl is-active systemd-importd ++systemctl -T start systemd-importd ++systemctl is-active systemd-importd ++systemctl --show-transaction stop systemd-importd ++! systemctl is-active systemd-importd ++ + # Test for a crash when enqueuing a JOB_NOP when other job already exists + systemctl start --no-block hello-after-sleep.target + # hello.service should still be waiting, so these try-restarts will collapse diff --git a/SOURCES/0452-man-document-the-new-systemctl-show-transaction-opti.patch b/SOURCES/0452-man-document-the-new-systemctl-show-transaction-opti.patch new file mode 100644 index 0000000..1f8b8ce --- /dev/null +++ b/SOURCES/0452-man-document-the-new-systemctl-show-transaction-opti.patch @@ -0,0 +1,37 @@ +From 588e3e8008d24021ec025d54318fb07d2212293c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 26 Mar 2019 18:02:49 +0100 +Subject: [PATCH] man: document the new systemctl --show-transaction option + +(cherry picked from commit df4a7cb7323c8cf00553d766913312c5b7ccd508) + +Related: #846319 +--- + man/systemctl.xml | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 6145486123..fa08ab6c0a 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -298,6 +298,20 @@ + + + ++ ++ ++ ++ ++ ++ When enqueuing a unit job (for example as effect of a systemctl start ++ invocation or similar), show brief information about all jobs enqueued, covering both the requested ++ job and any added because of unit dependencies. Note that the output will only include jobs ++ immediately part of the transaction requested. It is possible that service start-up program code ++ run as effect of the enqueued jobs might request further jobs to be pulled in. This means that ++ completion of the listed jobs might ultimately entail more jobs than the listed ones. ++ ++ ++ + + + diff --git a/SOURCES/0453-socket-New-option-FlushPending-boolean-to-flush-sock.patch b/SOURCES/0453-socket-New-option-FlushPending-boolean-to-flush-sock.patch new file mode 100644 index 0000000..357f076 --- /dev/null +++ b/SOURCES/0453-socket-New-option-FlushPending-boolean-to-flush-sock.patch @@ -0,0 +1,153 @@ +From 262544a451c11c38e92c45047ec2adeaeb2a0a7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Thu, 20 Aug 2020 13:00:37 +0200 +Subject: [PATCH] socket: New option 'FlushPending' (boolean) to flush socket + before entering listening state + +Disabled by default. When Enabled, before listening on the socket, flush the content. +Applies when Accept=no only. + +(cherry picked from commit 3e5f04bf6468fcb79c080f02b0eab08f258bff0c) + +Resolves: #1870638 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.socket.xml | 12 ++++++++++++ + src/core/dbus-socket.c | 4 ++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/socket.c | 11 +++++++++++ + src/core/socket.h | 1 + + src/shared/bus-unit-util.c | 3 ++- + 7 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 1a4e79190a..995b8797ef 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -388,6 +388,7 @@ Most socket unit settings are available to transient units. + ✓ SocketMode= + ✓ DirectoryMode= + ✓ Accept= ++✓ FlushPending= + ✓ Writable= + ✓ MaxConnections= + ✓ MaxConnectionsPerSource= +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index 19c2ca9907..8676b4e03f 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -425,6 +425,18 @@ + false, in read-only mode. Defaults to false. + + ++ ++ FlushPending= ++ Takes a boolean argument. May only be used when ++ . If yes, the socket's buffers are cleared after the ++ triggered service exited. This causes any pending data to be ++ flushed and any pending incoming connections to be rejected. If no, the ++ socket's buffers won't be cleared, permitting the service to handle any ++ pending connections after restart, which is the usually expected behaviour. ++ Defaults to . ++ ++ ++ + + MaxConnections= + The maximum number of connections to +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index 913cc74918..bb77539030 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -85,6 +85,7 @@ const sd_bus_vtable bus_socket_vtable[] = { + SD_BUS_PROPERTY("SocketMode", "u", bus_property_get_mode, offsetof(Socket, socket_mode), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Accept", "b", bus_property_get_bool, offsetof(Socket, accept), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("FlushPending", "b", bus_property_get_bool, offsetof(Socket, flush_pending), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Writable", "b", bus_property_get_bool, offsetof(Socket, writable), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("KeepAlive", "b", bus_property_get_bool, offsetof(Socket, keep_alive), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("KeepAliveTimeUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_time), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -177,6 +178,9 @@ static int bus_socket_set_transient_property( + if (streq(name, "Accept")) + return bus_set_transient_bool(u, name, &s->accept, message, flags, error); + ++ if (streq(name, "FlushPending")) ++ return bus_set_transient_bool(u, name, &s->flush_pending, message, flags, error); ++ + if (streq(name, "Writable")) + return bus_set_transient_bool(u, name, &s->writable, message, flags, error); + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 6d21b2e433..24ee5ae6fe 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -359,6 +359,7 @@ Socket.SocketGroup, config_parse_user_group, 0, + Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) + Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) + Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) ++Socket.FlushPending, config_parse_bool, 0, offsetof(Socket, flush_pending) + Socket.Writable, config_parse_bool, 0, offsetof(Socket, writable) + Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections) + Socket.MaxConnectionsPerSource, config_parse_unsigned, 0, offsetof(Socket, max_connections_per_source) +diff --git a/src/core/socket.c b/src/core/socket.c +index fe061eb73b..97c3a7fc9a 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -70,6 +70,7 @@ static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { + + static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); + static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); ++static void flush_ports(Socket *s); + + static void socket_init(Unit *u) { + Socket *s = SOCKET(u); +@@ -703,6 +704,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + prefix, s->n_connections, + prefix, s->max_connections, + prefix, s->max_connections_per_source); ++ else ++ fprintf(f, ++ "%sFlushPending: %s\n", ++ prefix, yes_no(s->flush_pending)); ++ + + if (s->priority >= 0) + fprintf(f, +@@ -2111,6 +2117,11 @@ static void socket_enter_listening(Socket *s) { + int r; + assert(s); + ++ if (!s->accept && s->flush_pending) { ++ log_unit_debug(UNIT(s), "Flushing socket before listening."); ++ flush_ports(s); ++ } ++ + r = socket_watch_fds(s); + if (r < 0) { + log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m"); +diff --git a/src/core/socket.h b/src/core/socket.h +index c4e25db1fc..b7a25d91fd 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -109,6 +109,7 @@ struct Socket { + bool accept; + bool remove_on_stop; + bool writable; ++ bool flush_pending; + + int socket_protocol; + +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 77788f0fe2..7029aa5615 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -1468,7 +1468,8 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons + + if (STR_IN_SET(field, + "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast", +- "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet")) ++ "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet", ++ "FlushPending")) + + return bus_append_parse_boolean(m, field, eq); + diff --git a/SOURCES/0454-core-remove-support-for-API-bus-started-outside-our-.patch b/SOURCES/0454-core-remove-support-for-API-bus-started-outside-our-.patch new file mode 100644 index 0000000..2d454d8 --- /dev/null +++ b/SOURCES/0454-core-remove-support-for-API-bus-started-outside-our-.patch @@ -0,0 +1,62 @@ +From 9c0ed82f661a2296784970678746b0b4f130870e Mon Sep 17 00:00:00 2001 +From: Alan Jenkins +Date: Thu, 21 Jun 2018 14:12:30 +0100 +Subject: [PATCH] core: remove support for API bus "started outside our own + logic" + +Looking at a recent Bad Day, my log contains over 100 lines of + + systemd[23895]: Failed to connect to API bus: Connection refused + +It is due to "systemd --user" retrying to connect to an API bus.[*] I +would prefer to avoid spamming the logs. I don't think it is good for us +to retry so much like this. + +systemd was mislead by something setting DBUS_SESSION_BUS_ADDRESS. My best +guess is an unfortunate series of events caused gdm to set this. gdm has +code to start a session dbus if there is not a bus available already (and +in this case it exports the environment variable). I believe it does not +normally do this when running under systemd, because "systemd --user" and +hence "dbus.service" would already have been started by pam_systemd. + +I see two possibilities + +1. Rip out the check for DBUS_SESSION_BUS_ADDRESS entirely. +2. Only check for DBUS_SESSION_BUS_ADDRESS on startup. Not in the + "recheck" logic. + +The justification for 2), is that the recheck is called from unit_notify(), +this is used to check whether the service just started (or stopped) was +"dbus.service". This reason for rechecking does not apply if we think +the session bus was started outside our logic. + +But I think we can justify 1). dbus-daemon ships a statically-enabled +/usr/lib/systemd/user/dbus.service, which would conflict with an attempt to +use an external dbus. Also "systemd --user" is started from user@.service; +if you try to start it manually so that it inherits an environment +variable, it will conflict if user@.service was started by pam_systemd +(or loginctl enable-linger). + +(cherry picked from commit d3243f55ca9b5f305306ba4105ab29768e372a78) + +Resolves: #1764282 +--- + src/core/manager.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 012615e537..3c44ad3dbc 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1519,11 +1519,6 @@ static bool manager_dbus_is_running(Manager *m, bool deserialized) { + if (m->test_run_flags != 0) + return false; + +- /* If we are in the user instance, and the env var is already set for us, then this means D-Bus is ran +- * somewhere outside of our own logic. Let's use it */ +- if (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS")) +- return true; +- + u = manager_get_unit(m, SPECIAL_DBUS_SOCKET); + if (!u) + return false; diff --git a/SOURCES/0455-mount-setup-fix-segfault-in-mount_cgroup_controllers.patch b/SOURCES/0455-mount-setup-fix-segfault-in-mount_cgroup_controllers.patch new file mode 100644 index 0000000..a99e7de --- /dev/null +++ b/SOURCES/0455-mount-setup-fix-segfault-in-mount_cgroup_controllers.patch @@ -0,0 +1,56 @@ +From 1c8d1c3bbdf8bdfb2ee4f85b9f559f54c6e4cac4 Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Wed, 1 Jul 2020 04:45:33 +0800 +Subject: [PATCH] mount-setup: fix segfault in mount_cgroup_controllers when + using gcc9 compiler + +According to the documentation: +https://gcc.gnu.org/gcc-9/porting_to.html#complit + +The 'join_controllers' that relied on the extended lifetime needs +to be fixed, move the compound literals to the function scope it +need to accessible in. + +Resolves: #1868877 +--- + src/core/mount-setup.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c +index 16880e6157..a6594580e5 100644 +--- a/src/core/mount-setup.c ++++ b/src/core/mount-setup.c +@@ -237,20 +237,22 @@ int mount_cgroup_controllers(char ***join_controllers) { + if (!cg_is_legacy_wanted()) + return 0; + ++ /* The defaults: ++ * mount "cpu" + "cpuacct" together, and "net_cls" + "net_prio". ++ * ++ * We'd like to add "cpuset" to the mix, but "cpuset" doesn't really ++ * work for groups with no initialized attributes. ++ */ ++ char ***default_join_controllers = (char**[]) { ++ STRV_MAKE("cpu", "cpuacct"), ++ STRV_MAKE("net_cls", "net_prio"), ++ NULL, ++ }; ++ + /* Mount all available cgroup controllers that are built into the kernel. */ + + if (!has_argument) +- /* The defaults: +- * mount "cpu" + "cpuacct" together, and "net_cls" + "net_prio". +- * +- * We'd like to add "cpuset" to the mix, but "cpuset" doesn't really +- * work for groups with no initialized attributes. +- */ +- join_controllers = (char**[]) { +- STRV_MAKE("cpu", "cpuacct"), +- STRV_MAKE("net_cls", "net_prio"), +- NULL, +- }; ++ join_controllers = default_join_controllers; + + r = cg_kernel_controllers(&controllers); + if (r < 0) diff --git a/SOURCES/0456-dbus-execute-make-transfer-of-CPUAffinity-endian-saf.patch b/SOURCES/0456-dbus-execute-make-transfer-of-CPUAffinity-endian-saf.patch new file mode 100644 index 0000000..71758ee --- /dev/null +++ b/SOURCES/0456-dbus-execute-make-transfer-of-CPUAffinity-endian-saf.patch @@ -0,0 +1,39 @@ +From 1730f7bb306e13689a7684fd93ae5b8383a28d2f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 31 May 2019 15:23:23 +0200 +Subject: [PATCH] dbus-execute: make transfer of CPUAffinity endian safe + (#12711) + +We store the affinity mask in the native endian. However, over D-Bus we +must transfer the mask in little endian byte order. + +This is the second part of c367f996f5f091a63f812f0140b304c649be77fc. + +(cherry picked from commit 75e40119a471454516ad0acc96f6f4094e7fb652) + +Related: #1740657 +--- + src/core/dbus-execute.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index f9527e56b2..d5acca384f 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -215,12 +215,15 @@ static int property_get_cpu_affinity( + sd_bus_error *error) { + + ExecContext *c = userdata; ++ _cleanup_free_ uint8_t *array = NULL; ++ size_t allocated; + + assert(bus); + assert(reply); + assert(c); + +- return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated); ++ (void) cpu_set_to_dbus(&c->cpu_set, &array, &allocated); ++ return sd_bus_message_append_array(reply, 'y', array, allocated); + } + + static int property_get_numa_mask( diff --git a/SOURCES/0457-core-add-support-for-setting-CPUAffinity-to-special-.patch b/SOURCES/0457-core-add-support-for-setting-CPUAffinity-to-special-.patch new file mode 100644 index 0000000..3118171 --- /dev/null +++ b/SOURCES/0457-core-add-support-for-setting-CPUAffinity-to-special-.patch @@ -0,0 +1,426 @@ +From 1a822dbe19ab6634ffb2c0d3ce92b27b503e1612 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 17 Feb 2020 13:50:31 +0100 +Subject: [PATCH] core: add support for setting CPUAffinity= to special "numa" + value + +systemd will automatically derive CPU affinity mask from NUMA node +mask. + +Fixes #13248 + +(cherry picked from commit e2b2fb7f566d13a3de61952b5356cd4d2eaee917) + +Resolves: #1740657 +--- + man/systemd.exec.xml | 9 +++--- + src/basic/cpu-set-util.c | 43 ++++++++++++++++++++++++-- + src/basic/cpu-set-util.h | 1 + + src/core/dbus-execute.c | 30 +++++++++++++++++- + src/core/execute.c | 46 ++++++++++++++++++++++++++-- + src/core/execute.h | 3 ++ + src/core/load-fragment.c | 14 ++++++++- + src/shared/bus-unit-util.c | 9 ++++++ + src/test/test-cpu-set-util.c | 6 ++-- + test/TEST-36-NUMAPOLICY/testsuite.sh | 18 +++++++++++ + 10 files changed, 166 insertions(+), 13 deletions(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index e2a5ede968..696438c4ef 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -706,10 +706,11 @@ CapabilityBoundingSet=~CAP_B CAP_C + CPUAffinity= + + Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges +- separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated +- by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are +- merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no +- effect. See ++ separated by either whitespace or commas. Alternatively, takes a special "numa" value in which case systemd ++ automatically derives allowed CPU range based on the value of NUMAMask= option. CPU ranges ++ are specified by the lower and upper CPU indices separated by a dash. This option may be specified more than ++ once, in which case the specified CPU affinity masks are merged. If the empty string is assigned, the mask ++ is reset, all assignments prior to this will have no effect. See + sched_setaffinity2 for + details. + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 51752ad1a6..1922c95864 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -12,12 +12,14 @@ + #include "cpu-set-util.h" + #include "dirent-util.h" + #include "extract-word.h" ++#include "fileio.h" + #include "fd-util.h" + #include "log.h" + #include "macro.h" + #include "missing.h" + #include "parse-util.h" + #include "stat-util.h" ++#include "stdio-util.h" + #include "string-util.h" + #include "string-table.h" + #include "strv.h" +@@ -179,7 +181,7 @@ int cpu_set_add_all(CPUSet *a, const CPUSet *b) { + return r; + } + +- return 0; ++ return 1; + } + + int parse_cpu_set_full( +@@ -264,7 +266,7 @@ int parse_cpu_set_extend( + if (!old->set) { + *old = cpuset; + cpuset = (CPUSet) {}; +- return 0; ++ return 1; + } + + return cpu_set_add_all(old, &cpuset); +@@ -417,6 +419,43 @@ int apply_numa_policy(const NUMAPolicy *policy) { + return 0; + } + ++int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret) { ++ int r; ++ size_t i; ++ _cleanup_(cpu_set_reset) CPUSet s = {}; ++ ++ assert(policy); ++ assert(ret); ++ ++ for (i = 0; i < policy->nodes.allocated * 8; i++) { ++ _cleanup_free_ char *l = NULL; ++ char p[STRLEN("/sys/devices/system/node/node//cpulist") + DECIMAL_STR_MAX(size_t) + 1]; ++ _cleanup_(cpu_set_reset) CPUSet part = {}; ++ ++ if (!CPU_ISSET_S(i, policy->nodes.allocated, policy->nodes.set)) ++ continue; ++ ++ xsprintf(p, "/sys/devices/system/node/node%zu/cpulist", i); ++ ++ r = read_one_line_file(p, &l); ++ if (r < 0) ++ return r; ++ ++ r = parse_cpu_set(l, &part); ++ if (r < 0) ++ return r; ++ ++ r = cpu_set_add_all(&s, &part); ++ if (r < 0) ++ return r; ++ } ++ ++ *ret = s; ++ s = (CPUSet) {}; ++ ++ return 0; ++} ++ + static const char* const mpol_table[] = { + [MPOL_DEFAULT] = "default", + [MPOL_PREFERRED] = "preferred", +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 8519a9b6c8..795be807af 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -78,6 +78,7 @@ static inline void numa_policy_reset(NUMAPolicy *p) { + } + + int apply_numa_policy(const NUMAPolicy *policy); ++int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret); + + const char* mpol_to_string(int i) _const_; + int mpol_from_string(const char *s) _pure_; +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index d5acca384f..0fe4c14e48 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -58,6 +58,8 @@ static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, + static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL); + static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI); + static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC); ++static BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa); ++ + + static int property_get_environment_files( + sd_bus *bus, +@@ -215,6 +217,7 @@ static int property_get_cpu_affinity( + sd_bus_error *error) { + + ExecContext *c = userdata; ++ _cleanup_(cpu_set_reset) CPUSet s = {}; + _cleanup_free_ uint8_t *array = NULL; + size_t allocated; + +@@ -222,7 +225,16 @@ static int property_get_cpu_affinity( + assert(reply); + assert(c); + +- (void) cpu_set_to_dbus(&c->cpu_set, &array, &allocated); ++ if (c->cpu_affinity_from_numa) { ++ int r; ++ ++ r = numa_to_cpu_set(&c->numa_policy, &s); ++ if (r < 0) ++ return r; ++ } ++ ++ (void) cpu_set_to_dbus(c->cpu_affinity_from_numa ? &s : &c->cpu_set, &array, &allocated); ++ + return sd_bus_message_append_array(reply, 'y', array, allocated); + } + +@@ -743,6 +755,7 @@ const sd_bus_vtable bus_exec_vtable[] = { + SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("CPUAffinityFromNUMA", "b", property_get_cpu_affinity_from_numa, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST), +@@ -1639,6 +1652,20 @@ int bus_exec_context_set_transient_property( + + return 1; + ++ } else if (streq(name, "CPUAffinityFromNUMA")) { ++ int q; ++ ++ r = sd_bus_message_read_basic(message, 'b', &q); ++ if (r < 0) ++ return r; ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ c->cpu_affinity_from_numa = q; ++ unit_write_settingf(u, flags, name, "%s=%s", "CPUAffinity", "numa"); ++ } ++ ++ return 1; ++ + } else if (streq(name, "NUMAPolicy")) { + int32_t type; + +@@ -1653,6 +1680,7 @@ int bus_exec_context_set_transient_property( + c->numa_policy.type = type; + + return 1; ++ + } else if (streq(name, "IOSchedulingClass")) { + int32_t q; + +diff --git a/src/core/execute.c b/src/core/execute.c +index 3c54ac1110..d528d08830 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2750,6 +2750,33 @@ static int compile_suggested_paths(const ExecContext *c, const ExecParameters *p + + static char *exec_command_line(char **argv); + ++static int exec_context_cpu_affinity_from_numa(const ExecContext *c, CPUSet *ret) { ++ _cleanup_(cpu_set_reset) CPUSet s = {}; ++ int r; ++ ++ assert(c); ++ assert(ret); ++ ++ if (!c->numa_policy.nodes.set) { ++ log_debug("Can't derive CPU affinity mask from NUMA mask because NUMA mask is not set, ignoring"); ++ return 0; ++ } ++ ++ r = numa_to_cpu_set(&c->numa_policy, &s); ++ if (r < 0) ++ return r; ++ ++ cpu_set_reset(ret); ++ ++ return cpu_set_add_all(ret, &s); ++} ++ ++bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) { ++ assert(c); ++ ++ return c->cpu_affinity_from_numa; ++} ++ + static int exec_child( + Unit *unit, + const ExecCommand *command, +@@ -3012,11 +3039,26 @@ static int exec_child( + } + } + +- if (context->cpu_set.set) +- if (sched_setaffinity(0, context->cpu_set.allocated, context->cpu_set.set) < 0) { ++ if (context->cpu_affinity_from_numa || context->cpu_set.set) { ++ _cleanup_(cpu_set_reset) CPUSet converted_cpu_set = {}; ++ const CPUSet *cpu_set; ++ ++ if (context->cpu_affinity_from_numa) { ++ r = exec_context_cpu_affinity_from_numa(context, &converted_cpu_set); ++ if (r < 0) { ++ *exit_status = EXIT_CPUAFFINITY; ++ return log_unit_error_errno(unit, r, "Failed to derive CPU affinity mask from NUMA mask: %m"); ++ } ++ ++ cpu_set = &converted_cpu_set; ++ } else ++ cpu_set = &context->cpu_set; ++ ++ if (sched_setaffinity(0, cpu_set->allocated, cpu_set->set) < 0) { + *exit_status = EXIT_CPUAFFINITY; + return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m"); + } ++ } + + if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) { + r = apply_numa_policy(&context->numa_policy); +diff --git a/src/core/execute.h b/src/core/execute.h +index 86c1cee84c..62c6229621 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -152,6 +152,7 @@ struct ExecContext { + + CPUSet cpu_set; + NUMAPolicy numa_policy; ++ bool cpu_affinity_from_numa; + + ExecInput std_input; + ExecOutput std_output; +@@ -375,6 +376,8 @@ int exec_runtime_deserialize_compat(Unit *u, const char *key, const char *value, + void exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); + void exec_runtime_vacuum(Manager *m); + ++bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c); ++ + const char* exec_output_to_string(ExecOutput i) _const_; + ExecOutput exec_output_from_string(const char *s) _pure_; + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 33fdb82754..740401a582 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1251,13 +1251,25 @@ int config_parse_exec_cpu_affinity(const char *unit, + void *userdata) { + + ExecContext *c = data; ++ int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + +- return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue); ++ if (streq(rvalue, "numa")) { ++ c->cpu_affinity_from_numa = true; ++ cpu_set_reset(&c->cpu_set); ++ ++ return 0; ++ } ++ ++ r = parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue); ++ if (r >= 0) ++ c->cpu_affinity_from_numa = false; ++ ++ return r; + } + + int config_parse_capability_set( +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 7029aa5615..daa2c2dce5 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -26,6 +26,8 @@ + #include "securebits-util.h" + #include "signal-util.h" + #include "socket-protocol-list.h" ++#include "socket-util.h" ++#include "stdio-util.h" + #include "string-util.h" + #include "syslog-util.h" + #include "terminal-util.h" +@@ -997,6 +999,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + _cleanup_free_ uint8_t *array = NULL; + size_t allocated; + ++ if (eq && streq(eq, "numa")) { ++ r = sd_bus_message_append(m, "(sv)", "CPUAffinityFromNUMA", "b", true); ++ if (r < 0) ++ return bus_log_create_error(r); ++ return r; ++ } ++ + r = parse_cpu_set(eq, &cpuset); + if (r < 0) + return log_error_errno(r, "Failed to parse %s value: %s", field, eq); +diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c +index 136eaca82d..1b7be5df4e 100644 +--- a/src/test/test-cpu-set-util.c ++++ b/src/test/test-cpu-set-util.c +@@ -218,12 +218,12 @@ static void test_parse_cpu_set_extend(void) { + + log_info("/* %s */", __func__); + +- assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 1); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 2); + assert_se(s1 = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", s1); + +- assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 1); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 3); + assert_se(s2 = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", s2); +@@ -240,7 +240,7 @@ static void test_cpu_set_to_from_dbus(void) { + + log_info("/* %s */", __func__); + +- assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0); ++ assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 1); + assert_se(s = cpu_set_to_string(&c)); + log_info("cpu_set_to_string: %s", s); + assert_se(CPU_COUNT_S(c.allocated, c.set) == 104); +diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh +index bffac4ffe6..7ccaa5b412 100755 +--- a/test/TEST-36-NUMAPOLICY/testsuite.sh ++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh +@@ -279,6 +279,18 @@ else + # Maks must be ignored + grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog + ++ echo "Unit file CPUAffinity=NUMA support" ++ writeTestUnitNUMAPolicy "bind" "0" ++ echo "CPUAffinity=numa" >> $testUnitNUMAConf ++ systemctl daemon-reload ++ systemctl start $testUnit ++ systemctlCheckNUMAProperties $testUnit "bind" "0" ++ pid=$(systemctl show --value -p MainPID $testUnit) ++ cpulist=$(cat /sys/devices/system/node/node0/cpulist) ++ affinity_systemd=$(systemctl show --value -p CPUAffinity $testUnit) ++ [ $cpulist = $affinity_systemd ] ++ pid1StopUnit $testUnit ++ + echo "systemd-run NUMAPolicy support" + runUnit='numa-systemd-run-test.service' + +@@ -309,6 +321,12 @@ else + systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000 + systemctlCheckNUMAProperties $runUnit "local" "" + pid1StopUnit $runUnit ++ ++ systemd-run -p NUMAPolicy=local -p NUMAMask=0 -p CPUAffinity=numa --unit $runUnit sleep 1000 ++ systemctlCheckNUMAProperties $runUnit "local" "" ++ systemctl cat $runUnit | grep -q 'CPUAffinity=numa' ++ pid1StopUnit $runUnit ++ + fi + + # Cleanup diff --git a/SOURCES/0458-basic-user-util-always-use-base-10-for-user-group-nu.patch b/SOURCES/0458-basic-user-util-always-use-base-10-for-user-group-nu.patch new file mode 100644 index 0000000..59daa5f --- /dev/null +++ b/SOURCES/0458-basic-user-util-always-use-base-10-for-user-group-nu.patch @@ -0,0 +1,93 @@ +From 57d2e6e64ba490054f8de1a2aad4ffae7778eddc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 31 May 2020 18:21:09 +0200 +Subject: [PATCH] basic/user-util: always use base 10 for user/group numbers + +We would parse numbers with base prefixes as user identifiers. For example, +"0x2b3bfa0" would be interpreted as UID==45334432 and "01750" would be +interpreted as UID==1000. This parsing was used also in cases where either a +user/group name or number may be specified. This means that names like +0x2b3bfa0 would be ambiguous: they are a valid user name according to our +documented relaxed rules, but they would also be parsed as numeric uids. + +This behaviour is definitely not expected by users, since tools generally only +accept decimal numbers (e.g. id, getent passwd), while other tools only accept +user names and thus will interpret such strings as user names without even +attempting to convert them to numbers (su, ssh). So let's follow suit and only +accept numbers in decimal notation. Effectively this means that we will reject +such strings as a username/uid/groupname/gid where strict mode is used, and try +to look up a user/group with such a name in relaxed mode. + +Since the function changed is fairly low-level and fairly widely used, this +affects multiple tools: loginctl show-user/enable-linger/disable-linger foo', +the third argument in sysusers.d, fourth and fifth arguments in tmpfiles.d, +etc. + +Fixes #15985. + +(cherry picked from commit 156a5fd297b61bce31630d7a52c15614bf784843) + +Resolves: #1848373 +--- + src/basic/parse-util.h | 8 ++++++-- + src/basic/user-util.c | 2 +- + src/test/test-user-util.c | 10 ++++++++++ + 3 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h +index f3267f4cfe..1fc1af7615 100644 +--- a/src/basic/parse-util.h ++++ b/src/basic/parse-util.h +@@ -50,9 +50,13 @@ static inline int safe_atoux16(const char *s, uint16_t *ret) { + + int safe_atoi16(const char *s, int16_t *ret); + +-static inline int safe_atou32(const char *s, uint32_t *ret_u) { ++static inline int safe_atou32_full(const char *s, unsigned base, uint32_t *ret_u) { + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); +- return safe_atou(s, (unsigned*) ret_u); ++ return safe_atou_full(s, base, (unsigned*) ret_u); ++} ++ ++static inline int safe_atou32(const char *s, uint32_t *ret_u) { ++ return safe_atou32_full(s, 0, (unsigned*) ret_u); + } + + static inline int safe_atoi32(const char *s, int32_t *ret_i) { +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index d92969c966..10eeb256cd 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -49,7 +49,7 @@ int parse_uid(const char *s, uid_t *ret) { + assert(s); + + assert_cc(sizeof(uid_t) == sizeof(uint32_t)); +- r = safe_atou32(s, &uid); ++ r = safe_atou32_full(s, 10, &uid); + if (r < 0) + return r; + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 9114d30b8c..8bf3dcd567 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -46,9 +46,19 @@ static void test_parse_uid(void) { + + r = parse_uid("65535", &uid); + assert_se(r == -ENXIO); ++ assert_se(uid == 100); ++ ++ r = parse_uid("0x1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("01234", &uid); ++ assert_se(r == 0); ++ assert_se(uid == 1234); + + r = parse_uid("asdsdas", &uid); + assert_se(r == -EINVAL); ++ assert_se(uid == 1234); + } + + static void test_uid_ptr(void) { diff --git a/SOURCES/0459-parse-util-sometimes-it-is-useful-to-check-if-a-stri.patch b/SOURCES/0459-parse-util-sometimes-it-is-useful-to-check-if-a-stri.patch new file mode 100644 index 0000000..7d41bb9 --- /dev/null +++ b/SOURCES/0459-parse-util-sometimes-it-is-useful-to-check-if-a-stri.patch @@ -0,0 +1,149 @@ +From 2fd9a21a8b6a93c4fb2747839766adca15faa008 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 14 Nov 2019 14:49:40 +0100 +Subject: [PATCH] parse-util: sometimes it is useful to check if a string is a + valid integer, but not actually parse it + +(cherry picked from commit 22810041c2200fe72b0e0c985d0e404f8b80f9e2) + +Related: #1848373 +--- + src/basic/parse-util.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 6becf85878..056e56765e 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -383,7 +383,6 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + unsigned long l; + + assert(s); +- assert(ret_u); + assert(base <= 16); + + /* strtoul() is happy to parse negative values, and silently +@@ -407,7 +406,9 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + +- *ret_u = (unsigned) l; ++ if (ret_u) ++ *ret_u = (unsigned) l; ++ + return 0; + } + +@@ -416,7 +417,6 @@ int safe_atoi(const char *s, int *ret_i) { + long l; + + assert(s); +- assert(ret_i); + + errno = 0; + l = strtol(s, &x, 0); +@@ -427,7 +427,9 @@ int safe_atoi(const char *s, int *ret_i) { + if ((long) (int) l != l) + return -ERANGE; + +- *ret_i = (int) l; ++ if (ret_i) ++ *ret_i = (int) l; ++ + return 0; + } + +@@ -436,7 +438,6 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { + unsigned long long l; + + assert(s); +- assert(ret_llu); + + s += strspn(s, WHITESPACE); + +@@ -449,7 +450,9 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { + if (*s == '-') + return -ERANGE; + +- *ret_llu = l; ++ if (ret_llu) ++ *ret_llu = l; ++ + return 0; + } + +@@ -458,7 +461,6 @@ int safe_atolli(const char *s, long long int *ret_lli) { + long long l; + + assert(s); +- assert(ret_lli); + + errno = 0; + l = strtoll(s, &x, 0); +@@ -467,7 +469,9 @@ int safe_atolli(const char *s, long long int *ret_lli) { + if (!x || x == s || *x != 0) + return -EINVAL; + +- *ret_lli = l; ++ if (ret_lli) ++ *ret_lli = l; ++ + return 0; + } + +@@ -476,7 +480,6 @@ int safe_atou8(const char *s, uint8_t *ret) { + unsigned long l; + + assert(s); +- assert(ret); + + s += strspn(s, WHITESPACE); + +@@ -491,7 +494,8 @@ int safe_atou8(const char *s, uint8_t *ret) { + if ((unsigned long) (uint8_t) l != l) + return -ERANGE; + +- *ret = (uint8_t) l; ++ if (ret) ++ *ret = (uint8_t) l; + return 0; + } + +@@ -525,7 +529,6 @@ int safe_atoi16(const char *s, int16_t *ret) { + long l; + + assert(s); +- assert(ret); + + errno = 0; + l = strtol(s, &x, 0); +@@ -536,7 +539,9 @@ int safe_atoi16(const char *s, int16_t *ret) { + if ((long) (int16_t) l != l) + return -ERANGE; + +- *ret = (int16_t) l; ++ if (ret) ++ *ret = (int16_t) l; ++ + return 0; + } + +@@ -546,7 +551,6 @@ int safe_atod(const char *s, double *ret_d) { + double d = 0; + + assert(s); +- assert(ret_d); + + loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0); + if (loc == (locale_t) 0) +@@ -559,7 +563,9 @@ int safe_atod(const char *s, double *ret_d) { + if (!x || x == s || *x != 0) + return -EINVAL; + +- *ret_d = (double) d; ++ if (ret_d) ++ *ret_d = (double) d; ++ + return 0; + } + diff --git a/SOURCES/0460-basic-parse-util-add-safe_atoux64.patch b/SOURCES/0460-basic-parse-util-add-safe_atoux64.patch new file mode 100644 index 0000000..0405582 --- /dev/null +++ b/SOURCES/0460-basic-parse-util-add-safe_atoux64.patch @@ -0,0 +1,130 @@ +From bd47a98d3ce2c5e1d74deb7bc384e416a9070b96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 9 Apr 2020 11:18:26 +0200 +Subject: [PATCH] basic/parse-util: add safe_atoux64() + +(cherry picked from commit ce51632a357d347737bf40d3817df331cd8874cb) + +Related: #1848373 +--- + src/basic/parse-util.c | 4 ++-- + src/basic/parse-util.h | 12 +++++++++++- + src/test/test-parse-util.c | 39 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 52 insertions(+), 3 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 056e56765e..67056c0434 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -433,7 +433,7 @@ int safe_atoi(const char *s, int *ret_i) { + return 0; + } + +-int safe_atollu(const char *s, long long unsigned *ret_llu) { ++int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) { + char *x = NULL; + unsigned long long l; + +@@ -442,7 +442,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { + s += strspn(s, WHITESPACE); + + errno = 0; +- l = strtoull(s, &x, 0); ++ l = strtoull(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h +index 1fc1af7615..8a49257050 100644 +--- a/src/basic/parse-util.h ++++ b/src/basic/parse-util.h +@@ -33,7 +33,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) { + } + + int safe_atoi(const char *s, int *ret_i); +-int safe_atollu(const char *s, unsigned long long *ret_u); + int safe_atolli(const char *s, long long int *ret_i); + + int safe_atou8(const char *s, uint8_t *ret); +@@ -64,6 +63,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) { + return safe_atoi(s, (int*) ret_i); + } + ++int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu); ++ ++static inline int safe_atollu(const char *s, long long unsigned *ret_llu) { ++ return safe_atollu_full(s, 0, ret_llu); ++} ++ + static inline int safe_atou64(const char *s, uint64_t *ret_u) { + assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +@@ -74,6 +79,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) { + return safe_atolli(s, (long long int*) ret_i); + } + ++static inline int safe_atoux64(const char *s, uint64_t *ret) { ++ assert_cc(sizeof(int64_t) == sizeof(long long unsigned)); ++ return safe_atollu_full(s, 16, (long long unsigned*) ret); ++} ++ + #if LONG_MAX == INT_MAX + static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned)); +diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c +index e9aef5e882..8b182d9bdc 100644 +--- a/src/test/test-parse-util.c ++++ b/src/test/test-parse-util.c +@@ -561,6 +561,44 @@ static void test_safe_atoi64(void) { + assert_se(r == -EINVAL); + } + ++static void test_safe_atoux64(void) { ++ int r; ++ uint64_t l; ++ ++ r = safe_atoux64("12345", &l); ++ assert_se(r == 0); ++ assert_se(l == 0x12345); ++ ++ r = safe_atoux64(" 12345", &l); ++ assert_se(r == 0); ++ assert_se(l == 0x12345); ++ ++ r = safe_atoux64("0x12345", &l); ++ assert_se(r == 0); ++ assert_se(l == 0x12345); ++ ++ r = safe_atoux64("18446744073709551617", &l); ++ assert_se(r == -ERANGE); ++ ++ r = safe_atoux64("-1", &l); ++ assert_se(r == -ERANGE); ++ ++ r = safe_atoux64(" -1", &l); ++ assert_se(r == -ERANGE); ++ ++ r = safe_atoux64("junk", &l); ++ assert_se(r == -EINVAL); ++ ++ r = safe_atoux64("123x", &l); ++ assert_se(r == -EINVAL); ++ ++ r = safe_atoux64("12.3", &l); ++ assert_se(r == -EINVAL); ++ ++ r = safe_atoux64("", &l); ++ assert_se(r == -EINVAL); ++} ++ + static void test_safe_atod(void) { + int r; + double d; +@@ -836,6 +874,7 @@ int main(int argc, char *argv[]) { + test_safe_atoux16(); + test_safe_atou64(); + test_safe_atoi64(); ++ test_safe_atoux64(); + test_safe_atod(); + test_parse_percent(); + test_parse_percent_unbounded(); diff --git a/SOURCES/0461-parse-util-allow-tweaking-how-to-parse-integers.patch b/SOURCES/0461-parse-util-allow-tweaking-how-to-parse-integers.patch new file mode 100644 index 0000000..3e97f8b --- /dev/null +++ b/SOURCES/0461-parse-util-allow-tweaking-how-to-parse-integers.patch @@ -0,0 +1,137 @@ +From 1d11e79fefea34b4395043e8e951414c5b7817ba Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:06:19 +0200 +Subject: [PATCH] parse-util: allow tweaking how to parse integers + +This allows disabling a few alternative ways to decode integers +formatted as strings, for safety reasons. + +See: #15991 +(cherry picked from commit 707e93aff8f358f8a62117e54b857530d6594e4b) + +Related: #1848373 +--- + src/basic/parse-util.c | 65 +++++++++++++++++++++++++++++++++--------- + src/basic/parse-util.h | 6 ++++ + 2 files changed, 58 insertions(+), 13 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 67056c0434..6cc4fc3e57 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -383,20 +383,35 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + unsigned long l; + + assert(s); +- assert(base <= 16); ++ assert(SAFE_ATO_MASK_FLAGS(base) <= 16); + +- /* strtoul() is happy to parse negative values, and silently +- * converts them to unsigned values without generating an +- * error. We want a clean error, hence let's look for the "-" +- * prefix on our own, and generate an error. But let's do so +- * only after strtoul() validated that the string is clean +- * otherwise, so that we return EINVAL preferably over +- * ERANGE. */ ++ /* strtoul() is happy to parse negative values, and silently converts them to unsigned values without ++ * generating an error. We want a clean error, hence let's look for the "-" prefix on our own, and ++ * generate an error. But let's do so only after strtoul() validated that the string is clean ++ * otherwise, so that we return EINVAL preferably over ERANGE. */ ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && ++ strchr(WHITESPACE, s[0])) ++ return -EINVAL; + + s += strspn(s, WHITESPACE); + ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && ++ IN_SET(s[0], '+', '-')) ++ return -EINVAL; /* Note that we check the "-" prefix again a second time below, but return a ++ * different error. I.e. if the SAFE_ATO_REFUSE_PLUS_MINUS flag is set we ++ * blanket refuse +/- prefixed integers, while if it is missing we'll just ++ * return ERANGE, because the string actually parses correctly, but doesn't ++ * fit in the return type. */ ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && ++ s[0] == '0' && !streq(s, "0")) ++ return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal ++ * notation and assumed-to-be-decimal integers with a leading zero. */ ++ + errno = 0; +- l = strtoul(s, &x, base); ++ l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual ++ * base is left */); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +@@ -438,11 +453,24 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) + unsigned long long l; + + assert(s); ++ assert(SAFE_ATO_MASK_FLAGS(base) <= 16); ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && ++ strchr(WHITESPACE, s[0])) ++ return -EINVAL; + + s += strspn(s, WHITESPACE); + ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && ++ IN_SET(s[0], '+', '-')) ++ return -EINVAL; ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && ++ s[0] == '0' && s[1] != 0) ++ return -EINVAL; ++ + errno = 0; +- l = strtoull(s, &x, base); ++ l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +@@ -504,13 +532,24 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + unsigned long l; + + assert(s); +- assert(ret); +- assert(base <= 16); ++ assert(SAFE_ATO_MASK_FLAGS(base) <= 16); ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && ++ strchr(WHITESPACE, s[0])) ++ return -EINVAL; + + s += strspn(s, WHITESPACE); + ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && ++ IN_SET(s[0], '+', '-')) ++ return -EINVAL; ++ ++ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && ++ s[0] == '0' && s[1] != 0) ++ return -EINVAL; ++ + errno = 0; +- l = strtoul(s, &x, base); ++ l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h +index 8a49257050..c6bbc98dff 100644 +--- a/src/basic/parse-util.h ++++ b/src/basic/parse-util.h +@@ -26,6 +26,12 @@ int parse_syscall_and_errno(const char *in, char **name, int *error); + #define FORMAT_BYTES_MAX 8 + char *format_bytes(char *buf, size_t l, uint64_t t); + ++#define SAFE_ATO_REFUSE_PLUS_MINUS (1U << 30) ++#define SAFE_ATO_REFUSE_LEADING_ZERO (1U << 29) ++#define SAFE_ATO_REFUSE_LEADING_WHITESPACE (1U << 28) ++#define SAFE_ATO_ALL_FLAGS (SAFE_ATO_REFUSE_PLUS_MINUS|SAFE_ATO_REFUSE_LEADING_ZERO|SAFE_ATO_REFUSE_LEADING_WHITESPACE) ++#define SAFE_ATO_MASK_FLAGS(base) ((base) & ~SAFE_ATO_ALL_FLAGS) ++ + int safe_atou_full(const char *s, unsigned base, unsigned *ret_u); + + static inline int safe_atou(const char *s, unsigned *ret_u) { diff --git a/SOURCES/0462-parse-util-allow-0-as-alternative-to-0-and-0.patch b/SOURCES/0462-parse-util-allow-0-as-alternative-to-0-and-0.patch new file mode 100644 index 0000000..29884dc --- /dev/null +++ b/SOURCES/0462-parse-util-allow-0-as-alternative-to-0-and-0.patch @@ -0,0 +1,60 @@ +From 1c8e5070d8a88f35b5577e091de66727fa785ef7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:08:38 +0200 +Subject: [PATCH] parse-util: allow '-0' as alternative to '0' and '+0' + +Let's allow "-0" as alternative to "+0" and "0" when parsing integers, +unless the new SAFE_ATO_REFUSE_PLUS_MINUS flag is specified. + +In cases where allowing the +/- syntax shall not be allowed +SAFE_ATO_REFUSE_PLUS_MINUS is the right flag to use, but this also means +that -0 as only negative integer that fits into an unsigned value should +be acceptable if the flag is not specified. + +(cherry picked from commit c78eefc13562a8fc0c22c00a6d3001af89860258) + +Related: #1848373 +--- + src/basic/parse-util.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 6cc4fc3e57..53d181dd60 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -416,7 +416,7 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; +- if (s[0] == '-') ++ if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (unsigned) l != l) + return -ERANGE; +@@ -475,7 +475,7 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; +- if (*s == '-') ++ if (l != 0 && s[0] == '-') + return -ERANGE; + + if (ret_llu) +@@ -517,7 +517,7 @@ int safe_atou8(const char *s, uint8_t *ret) { + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; +- if (s[0] == '-') ++ if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (uint8_t) l != l) + return -ERANGE; +@@ -554,7 +554,7 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; +- if (s[0] == '-') ++ if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (uint16_t) l != l) + return -ERANGE; diff --git a/SOURCES/0463-parse-util-make-return-parameter-optional-in-safe_at.patch b/SOURCES/0463-parse-util-make-return-parameter-optional-in-safe_at.patch new file mode 100644 index 0000000..8cb4a65 --- /dev/null +++ b/SOURCES/0463-parse-util-make-return-parameter-optional-in-safe_at.patch @@ -0,0 +1,31 @@ +From 91ed5edcdea79773f6918e739637521e47129b07 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:10:27 +0200 +Subject: [PATCH] parse-util: make return parameter optional in + safe_atou16_full() + +All other safe_atoXYZ_full() functions have the parameter optional, +let's make it optoinal here, too. + +(cherry picked from commit aa85e4d3cef8ca8436e480bce9fa4ce72876b636) + +Related: #1848373 +--- + src/basic/parse-util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 53d181dd60..7a7cefe6ff 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -559,7 +559,9 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + if ((unsigned long) (uint16_t) l != l) + return -ERANGE; + +- *ret = (uint16_t) l; ++ if (ret) ++ *ret = (uint16_t) l; ++ + return 0; + } + diff --git a/SOURCES/0464-parse-util-rewrite-parse_mode-on-top-of-safe_atou_fu.patch b/SOURCES/0464-parse-util-rewrite-parse_mode-on-top-of-safe_atou_fu.patch new file mode 100644 index 0000000..318e18b --- /dev/null +++ b/SOURCES/0464-parse-util-rewrite-parse_mode-on-top-of-safe_atou_fu.patch @@ -0,0 +1,59 @@ +From 147a3696b45a872e0e21fb74e1497f02543ce871 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:16:04 +0200 +Subject: [PATCH] parse-util: rewrite parse_mode() on top of safe_atou_full() + +Parsing is hard, hence let's use our own careful wrappers wherever +possible. + +(cherry picked from commit c44702a8bd8cc8b7f2f1df21db9308d9af7dda5b) + +Related: #1848373 +--- + src/basic/parse-util.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 7a7cefe6ff..68c156c543 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -54,26 +54,24 @@ int parse_pid(const char *s, pid_t* ret_pid) { + } + + int parse_mode(const char *s, mode_t *ret) { +- char *x; +- long l; ++ unsigned m; ++ int r; + + assert(s); +- assert(ret); + +- s += strspn(s, WHITESPACE); +- if (s[0] == '-') +- return -ERANGE; +- +- errno = 0; +- l = strtol(s, &x, 8); +- if (errno > 0) +- return -errno; +- if (!x || x == s || *x != 0) +- return -EINVAL; +- if (l < 0 || l > 07777) ++ r = safe_atou_full(s, 8 | ++ SAFE_ATO_REFUSE_PLUS_MINUS, /* Leading '+' or even '-' char? that's just weird, ++ * refuse. User might have wanted to add mode flags or ++ * so, but this parser doesn't allow that, so let's ++ * better be safe. */ ++ &m); ++ if (r < 0) ++ return r; ++ if (m > 07777) + return -ERANGE; + +- *ret = (mode_t) l; ++ if (ret) ++ *ret = m; + return 0; + } + diff --git a/SOURCES/0465-user-util-be-stricter-in-parse_uid.patch b/SOURCES/0465-user-util-be-stricter-in-parse_uid.patch new file mode 100644 index 0000000..79cb570 --- /dev/null +++ b/SOURCES/0465-user-util-be-stricter-in-parse_uid.patch @@ -0,0 +1,78 @@ +From 87c22d3bb794118d25bc138108fd5bdd607365ef Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:16:46 +0200 +Subject: [PATCH] user-util: be stricter in parse_uid() + +Let's refuse "+" and "-" prefixed UIDs. Let's refuse whitespace-prefixed +UIDS, Let's refuse zero-prefixed UIDs. Let's be safe than sorry. + +(cherry picked from commit f5979b63cc305ba217dfd174b1bf0583bcf75a73) + +Related: #1848373 +--- + src/basic/user-util.c | 10 +++++++++- + src/test/test-user-util.c | 26 +++++++++++++++++++++++--- + 2 files changed, 32 insertions(+), 4 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 10eeb256cd..40f4e45db6 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -49,7 +49,15 @@ int parse_uid(const char *s, uid_t *ret) { + assert(s); + + assert_cc(sizeof(uid_t) == sizeof(uint32_t)); +- r = safe_atou32_full(s, 10, &uid); ++ ++ /* We are very strict when parsing UIDs, and prohibit +/- as prefix, leading zero as prefix, and ++ * whitespace. We do this, since this call is often used in a context where we parse things as UID ++ * first, and if that doesn't work we fall back to NSS. Thus we really want to make sure that UIDs ++ * are parsed as UIDs only if they really really look like UIDs. */ ++ r = safe_atou32_full(s, 10 ++ | SAFE_ATO_REFUSE_PLUS_MINUS ++ | SAFE_ATO_REFUSE_LEADING_ZERO ++ | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &uid); + if (r < 0) + return r; + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 8bf3dcd567..99203f7e48 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -52,13 +52,33 @@ static void test_parse_uid(void) { + assert_se(r == -EINVAL); + assert_se(uid == 100); + ++ r = parse_uid("+1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("-1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid(" 1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ + r = parse_uid("01234", &uid); +- assert_se(r == 0); +- assert_se(uid == 1234); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("-0", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("+0", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); + + r = parse_uid("asdsdas", &uid); + assert_se(r == -EINVAL); +- assert_se(uid == 1234); ++ assert_se(uid == 100); + } + + static void test_uid_ptr(void) { diff --git a/SOURCES/0466-strv-add-new-macro-STARTSWITH_SET.patch b/SOURCES/0466-strv-add-new-macro-STARTSWITH_SET.patch new file mode 100644 index 0000000..58a4b5a --- /dev/null +++ b/SOURCES/0466-strv-add-new-macro-STARTSWITH_SET.patch @@ -0,0 +1,75 @@ +From 50b103a982dfd6f1b2bf98bbc98a8063fa153e89 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 23 Nov 2018 16:27:15 +0100 +Subject: [PATCH] strv: add new macro STARTSWITH_SET() + +This is to startswith() what PATH_STARTSWITH_SET() is to +path_startswith(). + +Or in other words, checks if the specified string has any of the listed +prefixes, and if so, returns the remainder of the string. + +(cherry picked from commit 52f1552073047195d51901f7e5a5a4fa3189034e) + +Related: #1848373 +--- + src/basic/strv.h | 12 ++++++++++++ + src/test/test-strv.c | 15 +++++++++++++++ + 2 files changed, 27 insertions(+) + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index 51d03db940..c1e4c973b6 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -136,6 +136,18 @@ void strv_print(char **l); + _x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \ + }) + ++#define STARTSWITH_SET(p, ...) \ ++ ({ \ ++ const char *_p = (p); \ ++ char *_found = NULL, **_i; \ ++ STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ ++ _found = startswith(_p, *_i); \ ++ if (_found) \ ++ break; \ ++ } \ ++ _found; \ ++ }) ++ + #define FOREACH_STRING(x, ...) \ + for (char **_l = ({ \ + char **_ll = STRV_MAKE(__VA_ARGS__); \ +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 1c192239a2..79d999d3ed 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -56,6 +56,20 @@ static void test_strptr_in_set(void) { + assert_se(!STRPTR_IN_SET(NULL, NULL)); + } + ++static void test_startswith_set(void) { ++ assert_se(!STARTSWITH_SET("foo", "bar", "baz", "waldo")); ++ assert_se(!STARTSWITH_SET("foo", "bar")); ++ ++ assert_se(STARTSWITH_SET("abc", "a", "ab", "abc")); ++ assert_se(STARTSWITH_SET("abc", "ax", "ab", "abc")); ++ assert_se(STARTSWITH_SET("abc", "ax", "abx", "abc")); ++ assert_se(!STARTSWITH_SET("abc", "ax", "abx", "abcx")); ++ ++ assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "foo", "zzz"), "bar")); ++ assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "", "zzz"), "foobar")); ++ assert_se(streq_ptr(STARTSWITH_SET("", "hhh", "kkk", "zzz", ""), "")); ++} ++ + static const char* const input_table_multiple[] = { + "one", + "two", +@@ -700,6 +714,7 @@ int main(int argc, char *argv[]) { + test_specifier_printf(); + test_str_in_set(); + test_strptr_in_set(); ++ test_startswith_set(); + test_strv_foreach(); + test_strv_foreach_backwards(); + test_strv_foreach_pair(); diff --git a/SOURCES/0467-parse-util-also-parse-integers-prefixed-with-0b-and-.patch b/SOURCES/0467-parse-util-also-parse-integers-prefixed-with-0b-and-.patch new file mode 100644 index 0000000..d088a5a --- /dev/null +++ b/SOURCES/0467-parse-util-also-parse-integers-prefixed-with-0b-and-.patch @@ -0,0 +1,164 @@ +From e67e29d91a1ef90af545e4130c7b4c4cfde6202a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:31:51 +0200 +Subject: [PATCH] parse-util: also parse integers prefixed with 0b and 0o + +Let's adopt Python 3 style 0b and 0x syntaxes, because it makes a ton of +sense, in particular in bitmask settings. + +(cherry picked from commit fc80cabcf584a8b486bdff5be0c074fec4059cdc) + +Related: #1848373 +--- + src/basic/parse-util.c | 56 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 51 insertions(+), 5 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 68c156c543..992ea3605b 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -17,6 +17,7 @@ + #include "parse-util.h" + #include "process-util.h" + #include "string-util.h" ++#include "strv.h" + + int parse_boolean(const char *v) { + assert(v); +@@ -373,7 +374,32 @@ char *format_bytes(char *buf, size_t l, uint64_t t) { + finish: + buf[l-1] = 0; + return buf; ++} ++ ++static const char *mangle_base(const char *s, unsigned *base) { ++ const char *k; ++ ++ assert(s); ++ assert(base); ++ ++ /* Base already explicitly specified, then don't do anything. */ ++ if (SAFE_ATO_MASK_FLAGS(*base) != 0) ++ return s; + ++ /* Support Python 3 style "0b" and 0x" prefixes, because they truly make sense, much more than C's "0" prefix for octal. */ ++ k = STARTSWITH_SET(s, "0b", "0B"); ++ if (k) { ++ *base = 2 | (*base & SAFE_ATO_ALL_FLAGS); ++ return k; ++ } ++ ++ k = STARTSWITH_SET(s, "0o", "0O"); ++ if (k) { ++ *base = 8 | (*base & SAFE_ATO_ALL_FLAGS); ++ return k; ++ } ++ ++ return s; + } + + int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { +@@ -407,6 +433,8 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal + * notation and assumed-to-be-decimal integers with a leading zero. */ + ++ s = mangle_base(s, &base); ++ + errno = 0; + l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual + * base is left */); +@@ -426,13 +454,17 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + } + + int safe_atoi(const char *s, int *ret_i) { ++ unsigned base = 0; + char *x = NULL; + long l; + + assert(s); + ++ s += strspn(s, WHITESPACE); ++ s = mangle_base(s, &base); ++ + errno = 0; +- l = strtol(s, &x, 0); ++ l = strtol(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +@@ -467,6 +499,8 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) + s[0] == '0' && s[1] != 0) + return -EINVAL; + ++ s = mangle_base(s, &base); ++ + errno = 0; + l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) +@@ -483,13 +517,17 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) + } + + int safe_atolli(const char *s, long long int *ret_lli) { ++ unsigned base = 0; + char *x = NULL; + long long l; + + assert(s); + ++ s += strspn(s, WHITESPACE); ++ s = mangle_base(s, &base); ++ + errno = 0; +- l = strtoll(s, &x, 0); ++ l = strtoll(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +@@ -502,15 +540,17 @@ int safe_atolli(const char *s, long long int *ret_lli) { + } + + int safe_atou8(const char *s, uint8_t *ret) { +- char *x = NULL; ++ unsigned base = 0; + unsigned long l; ++ char *x = NULL; + + assert(s); + + s += strspn(s, WHITESPACE); ++ s = mangle_base(s, &base); + + errno = 0; +- l = strtoul(s, &x, 0); ++ l = strtoul(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) +@@ -546,6 +586,8 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + s[0] == '0' && s[1] != 0) + return -EINVAL; + ++ s = mangle_base(s, &base); ++ + errno = 0; + l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) +@@ -564,13 +606,17 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + } + + int safe_atoi16(const char *s, int16_t *ret) { ++ unsigned base = 0; + char *x = NULL; + long l; + + assert(s); + ++ s += strspn(s, WHITESPACE); ++ s = mangle_base(s, &base); ++ + errno = 0; +- l = strtol(s, &x, 0); ++ l = strtol(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) diff --git a/SOURCES/0468-tests-beef-up-integer-parsing-tests.patch b/SOURCES/0468-tests-beef-up-integer-parsing-tests.patch new file mode 100644 index 0000000..c33c38f --- /dev/null +++ b/SOURCES/0468-tests-beef-up-integer-parsing-tests.patch @@ -0,0 +1,204 @@ +From 457eada27f606e39f0efc6adc226542fd11eb815 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 1 Jun 2020 17:48:41 +0200 +Subject: [PATCH] tests: beef up integer parsing tests + +(cherry picked from commit 53c6db99fa4b52f97e19977f21d3133f8ceb3dcd) + +Related: #1848373 +--- + src/test/test-parse-util.c | 58 ++++++++++++++++++++++++++++++++++++++ + src/test/test-user-util.c | 40 ++++++++++++++++++++++++++ + 2 files changed, 98 insertions(+) + +diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c +index 8b182d9bdc..699499b665 100644 +--- a/src/test/test-parse-util.c ++++ b/src/test/test-parse-util.c +@@ -75,14 +75,22 @@ static void test_parse_mode(void) { + mode_t m; + + assert_se(parse_mode("-1", &m) < 0); ++ assert_se(parse_mode("+1", &m) < 0); + assert_se(parse_mode("", &m) < 0); + assert_se(parse_mode("888", &m) < 0); + assert_se(parse_mode("77777", &m) < 0); + + assert_se(parse_mode("544", &m) >= 0 && m == 0544); ++ assert_se(parse_mode("0544", &m) >= 0 && m == 0544); ++ assert_se(parse_mode("00544", &m) >= 0 && m == 0544); + assert_se(parse_mode("777", &m) >= 0 && m == 0777); ++ assert_se(parse_mode("0777", &m) >= 0 && m == 0777); ++ assert_se(parse_mode("00777", &m) >= 0 && m == 0777); + assert_se(parse_mode("7777", &m) >= 0 && m == 07777); ++ assert_se(parse_mode("07777", &m) >= 0 && m == 07777); ++ assert_se(parse_mode("007777", &m) >= 0 && m == 07777); + assert_se(parse_mode("0", &m) >= 0 && m == 0); ++ assert_se(parse_mode(" 1", &m) >= 0 && m == 1); + } + + static void test_parse_size(void) { +@@ -358,6 +366,18 @@ static void test_safe_atolli(void) { + assert_se(r == 0); + assert_se(l == -12345); + ++ r = safe_atolli("0x5", &l); ++ assert_se(r == 0); ++ assert_se(l == 5); ++ ++ r = safe_atolli("0o6", &l); ++ assert_se(r == 0); ++ assert_se(l == 6); ++ ++ r = safe_atolli("0B101", &l); ++ assert_se(r == 0); ++ assert_se(l == 5); ++ + r = safe_atolli("12345678901234567890", &l); + assert_se(r == -ERANGE); + +@@ -431,6 +451,14 @@ static void test_safe_atoi16(void) { + assert_se(r == 0); + assert_se(l == 32767); + ++ r = safe_atoi16("0o11", &l); ++ assert_se(r == 0); ++ assert_se(l == 9); ++ ++ r = safe_atoi16("0B110", &l); ++ assert_se(r == 0); ++ assert_se(l == 6); ++ + r = safe_atoi16("36536", &l); + assert_se(r == -ERANGE); + +@@ -475,6 +503,13 @@ static void test_safe_atoux16(void) { + r = safe_atoux16(" -1", &l); + assert_se(r == -ERANGE); + ++ r = safe_atoux16("0b1", &l); ++ assert_se(r == 0); ++ assert_se(l == 177); ++ ++ r = safe_atoux16("0o70", &l); ++ assert_se(r == -EINVAL); ++ + r = safe_atoux16("junk", &l); + assert_se(r == -EINVAL); + +@@ -500,6 +535,14 @@ static void test_safe_atou64(void) { + assert_se(r == 0); + assert_se(l == 12345); + ++ r = safe_atou64("0o11", &l); ++ assert_se(r == 0); ++ assert_se(l == 9); ++ ++ r = safe_atou64("0b11", &l); ++ assert_se(r == 0); ++ assert_se(l == 3); ++ + r = safe_atou64("18446744073709551617", &l); + assert_se(r == -ERANGE); + +@@ -542,6 +585,14 @@ static void test_safe_atoi64(void) { + assert_se(r == 0); + assert_se(l == 32767); + ++ r = safe_atoi64(" 0o20", &l); ++ assert_se(r == 0); ++ assert_se(l == 16); ++ ++ r = safe_atoi64(" 0b01010", &l); ++ assert_se(r == 0); ++ assert_se(l == 10); ++ + r = safe_atoi64("9223372036854775813", &l); + assert_se(r == -ERANGE); + +@@ -577,6 +628,13 @@ static void test_safe_atoux64(void) { + assert_se(r == 0); + assert_se(l == 0x12345); + ++ r = safe_atoux64("0b11011", &l); ++ assert_se(r == 0); ++ assert_se(l == 11603985); ++ ++ r = safe_atoux64("0o11011", &l); ++ assert_se(r == -EINVAL); ++ + r = safe_atoux64("18446744073709551617", &l); + assert_se(r == -ERANGE); + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 99203f7e48..04e86f5ac3 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -40,6 +40,22 @@ static void test_parse_uid(void) { + + log_info("/* %s */", __func__); + ++ r = parse_uid("0", &uid); ++ assert_se(r == 0); ++ assert_se(uid == 0); ++ ++ r = parse_uid("1", &uid); ++ assert_se(r == 0); ++ assert_se(uid == 1); ++ ++ r = parse_uid("01", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 1); ++ ++ r = parse_uid("001", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 1); ++ + r = parse_uid("100", &uid); + assert_se(r == 0); + assert_se(uid == 100); +@@ -52,6 +68,14 @@ static void test_parse_uid(void) { + assert_se(r == -EINVAL); + assert_se(uid == 100); + ++ r = parse_uid("0o1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("0b1234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ + r = parse_uid("+1234", &uid); + assert_se(r == -EINVAL); + assert_se(uid == 100); +@@ -68,6 +92,14 @@ static void test_parse_uid(void) { + assert_se(r == -EINVAL); + assert_se(uid == 100); + ++ r = parse_uid("001234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("0001234", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ + r = parse_uid("-0", &uid); + assert_se(r == -EINVAL); + assert_se(uid == 100); +@@ -76,6 +108,14 @@ static void test_parse_uid(void) { + assert_se(r == -EINVAL); + assert_se(uid == 100); + ++ r = parse_uid("00", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ ++ r = parse_uid("000", &uid); ++ assert_se(r == -EINVAL); ++ assert_se(uid == 100); ++ + r = parse_uid("asdsdas", &uid); + assert_se(r == -EINVAL); + assert_se(uid == 100); diff --git a/SOURCES/0469-shared-user-util-add-compat-forms-of-user-name-check.patch b/SOURCES/0469-shared-user-util-add-compat-forms-of-user-name-check.patch new file mode 100644 index 0000000..eefc47b --- /dev/null +++ b/SOURCES/0469-shared-user-util-add-compat-forms-of-user-name-check.patch @@ -0,0 +1,270 @@ +From 1e4ec1b29d15684a305bbc9ab54c6c8321504e7b Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 27 Oct 2020 10:31:05 +0100 +Subject: [PATCH] shared/user-util: add compat forms of user name checking + functions + +New functions are called valid_user_group_name_compat() and +valid_user_group_name_or_id_compat() and accept dots in the user +or group name. No functional change except the tests. + +(cherry picked from commit 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865) + +This completes previous partial cherry-pick of the same commit (commit +76176de0889c3e8b9b3a176da24e4f8dbbd380a3). + +Related: #1848373 +--- + src/basic/user-util.c | 32 +++++++------- + src/basic/user-util.h | 16 ++++++- + src/test/test-user-util.c | 91 +++++++++++++++++++++++++++++++++++++-- + 3 files changed, 117 insertions(+), 22 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 40f4e45db6..03cbbc2503 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -576,7 +576,7 @@ int take_etc_passwd_lock(const char *root) { + return fd; + } + +-bool valid_user_group_name(const char *u) { ++bool valid_user_group_name_full(const char *u, bool strict) { + const char *i; + long sz; + +@@ -585,12 +585,12 @@ bool valid_user_group_name(const char *u) { + * + * - We require that names fit into the appropriate utmp field + * - We don't allow empty user names ++ * - No dots or digits in the first character + * +- * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. ++ * If strict==true, additionally: ++ * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) + * +- * jsynacek: We now allow dots in user names. The checks are not exhaustive as user names like "..." are allowed +- * and valid according to POSIX, but can't be created using useradd. However, ".user" can be created. Let's not +- * complicate the code by adding additional checks for weird corner cases like these, as they don't really matter here. ++ * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. + */ + + if (isempty(u)) +@@ -598,16 +598,16 @@ bool valid_user_group_name(const char *u) { + + if (!(u[0] >= 'a' && u[0] <= 'z') && + !(u[0] >= 'A' && u[0] <= 'Z') && +- u[0] != '_' && u[0] != '.') ++ u[0] != '_') + return false; + +- for (i = u+1; *i; i++) { +- if (!(*i >= 'a' && *i <= 'z') && +- !(*i >= 'A' && *i <= 'Z') && +- !(*i >= '0' && *i <= '9') && +- !IN_SET(*i, '_', '-', '.')) ++ for (i = u+1; *i; i++) ++ if (!((*i >= 'a' && *i <= 'z') || ++ (*i >= 'A' && *i <= 'Z') || ++ (*i >= '0' && *i <= '9') || ++ IN_SET(*i, '_', '-') || ++ (!strict && *i == '.'))) + return false; +- } + + sz = sysconf(_SC_LOGIN_NAME_MAX); + assert_se(sz > 0); +@@ -621,15 +621,15 @@ bool valid_user_group_name(const char *u) { + return true; + } + +-bool valid_user_group_name_or_id(const char *u) { ++bool valid_user_group_name_or_id_full(const char *u, bool strict) { + +- /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the right +- * range, and not the invalid user ids. */ ++ /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the ++ * right range, and not the invalid user ids. */ + + if (isempty(u)) + return false; + +- if (valid_user_group_name(u)) ++ if (valid_user_group_name_full(u, strict)) + return true; + + return parse_uid(u, NULL) >= 0; +diff --git a/src/basic/user-util.h b/src/basic/user-util.h +index b74f168859..5ad0b2a2f9 100644 +--- a/src/basic/user-util.h ++++ b/src/basic/user-util.h +@@ -78,8 +78,20 @@ static inline bool userns_supported(void) { + return access("/proc/self/uid_map", F_OK) >= 0; + } + +-bool valid_user_group_name(const char *u); +-bool valid_user_group_name_or_id(const char *u); ++bool valid_user_group_name_full(const char *u, bool strict); ++bool valid_user_group_name_or_id_full(const char *u, bool strict); ++static inline bool valid_user_group_name(const char *u) { ++ return valid_user_group_name_full(u, true); ++} ++static inline bool valid_user_group_name_or_id(const char *u) { ++ return valid_user_group_name_or_id_full(u, true); ++} ++static inline bool valid_user_group_name_compat(const char *u) { ++ return valid_user_group_name_full(u, false); ++} ++static inline bool valid_user_group_name_or_id_compat(const char *u) { ++ return valid_user_group_name_or_id_full(u, false); ++} + bool valid_gecos(const char *d); + bool valid_home(const char *p); + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 04e86f5ac3..3a4211655d 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -131,6 +131,43 @@ static void test_uid_ptr(void) { + assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000); + } + ++static void test_valid_user_group_name_compat(void) { ++ log_info("/* %s */", __func__); ++ ++ assert_se(!valid_user_group_name_compat(NULL)); ++ assert_se(!valid_user_group_name_compat("")); ++ assert_se(!valid_user_group_name_compat("1")); ++ assert_se(!valid_user_group_name_compat("65535")); ++ assert_se(!valid_user_group_name_compat("-1")); ++ assert_se(!valid_user_group_name_compat("-kkk")); ++ assert_se(!valid_user_group_name_compat("rööt")); ++ assert_se(!valid_user_group_name_compat(".")); ++ assert_se(!valid_user_group_name_compat(".eff")); ++ assert_se(!valid_user_group_name_compat("foo\nbar")); ++ assert_se(!valid_user_group_name_compat("0123456789012345678901234567890123456789")); ++ assert_se(!valid_user_group_name_or_id_compat("aaa:bbb")); ++ assert_se(!valid_user_group_name_compat(".")); ++ assert_se(!valid_user_group_name_compat(".1")); ++ assert_se(!valid_user_group_name_compat(".65535")); ++ assert_se(!valid_user_group_name_compat(".-1")); ++ assert_se(!valid_user_group_name_compat(".-kkk")); ++ assert_se(!valid_user_group_name_compat(".rööt")); ++ assert_se(!valid_user_group_name_or_id_compat(".aaa:bbb")); ++ ++ assert_se(valid_user_group_name_compat("root")); ++ assert_se(valid_user_group_name_compat("lennart")); ++ assert_se(valid_user_group_name_compat("LENNART")); ++ assert_se(valid_user_group_name_compat("_kkk")); ++ assert_se(valid_user_group_name_compat("kkk-")); ++ assert_se(valid_user_group_name_compat("kk-k")); ++ assert_se(valid_user_group_name_compat("eff.eff")); ++ assert_se(valid_user_group_name_compat("eff.")); ++ ++ assert_se(valid_user_group_name_compat("some5")); ++ assert_se(!valid_user_group_name_compat("5some")); ++ assert_se(valid_user_group_name_compat("INNER5NUMBER")); ++} ++ + static void test_valid_user_group_name(void) { + log_info("/* %s */", __func__); + +@@ -141,9 +178,18 @@ static void test_valid_user_group_name(void) { + assert_se(!valid_user_group_name("-1")); + assert_se(!valid_user_group_name("-kkk")); + assert_se(!valid_user_group_name("rööt")); ++ assert_se(!valid_user_group_name(".")); ++ assert_se(!valid_user_group_name(".eff")); + assert_se(!valid_user_group_name("foo\nbar")); + assert_se(!valid_user_group_name("0123456789012345678901234567890123456789")); + assert_se(!valid_user_group_name_or_id("aaa:bbb")); ++ assert_se(!valid_user_group_name(".")); ++ assert_se(!valid_user_group_name(".1")); ++ assert_se(!valid_user_group_name(".65535")); ++ assert_se(!valid_user_group_name(".-1")); ++ assert_se(!valid_user_group_name(".-kkk")); ++ assert_se(!valid_user_group_name(".rööt")); ++ assert_se(!valid_user_group_name_or_id(".aaa:bbb")); + + assert_se(valid_user_group_name("root")); + assert_se(valid_user_group_name("lennart")); +@@ -151,14 +197,47 @@ static void test_valid_user_group_name(void) { + assert_se(valid_user_group_name("_kkk")); + assert_se(valid_user_group_name("kkk-")); + assert_se(valid_user_group_name("kk-k")); +- assert_se(valid_user_group_name(".moo")); +- assert_se(valid_user_group_name("eff.eff")); ++ assert_se(!valid_user_group_name("eff.eff")); ++ assert_se(!valid_user_group_name("eff.")); + + assert_se(valid_user_group_name("some5")); + assert_se(!valid_user_group_name("5some")); + assert_se(valid_user_group_name("INNER5NUMBER")); + } + ++static void test_valid_user_group_name_or_id_compat(void) { ++ log_info("/* %s */", __func__); ++ ++ assert_se(!valid_user_group_name_or_id_compat(NULL)); ++ assert_se(!valid_user_group_name_or_id_compat("")); ++ assert_se(valid_user_group_name_or_id_compat("0")); ++ assert_se(valid_user_group_name_or_id_compat("1")); ++ assert_se(valid_user_group_name_or_id_compat("65534")); ++ assert_se(!valid_user_group_name_or_id_compat("65535")); ++ assert_se(valid_user_group_name_or_id_compat("65536")); ++ assert_se(!valid_user_group_name_or_id_compat("-1")); ++ assert_se(!valid_user_group_name_or_id_compat("-kkk")); ++ assert_se(!valid_user_group_name_or_id_compat("rööt")); ++ assert_se(!valid_user_group_name_or_id_compat(".")); ++ assert_se(!valid_user_group_name_or_id_compat(".eff")); ++ assert_se(valid_user_group_name_or_id_compat("eff.eff")); ++ assert_se(valid_user_group_name_or_id_compat("eff.")); ++ assert_se(!valid_user_group_name_or_id_compat("foo\nbar")); ++ assert_se(!valid_user_group_name_or_id_compat("0123456789012345678901234567890123456789")); ++ assert_se(!valid_user_group_name_or_id_compat("aaa:bbb")); ++ ++ assert_se(valid_user_group_name_or_id_compat("root")); ++ assert_se(valid_user_group_name_or_id_compat("lennart")); ++ assert_se(valid_user_group_name_or_id_compat("LENNART")); ++ assert_se(valid_user_group_name_or_id_compat("_kkk")); ++ assert_se(valid_user_group_name_or_id_compat("kkk-")); ++ assert_se(valid_user_group_name_or_id_compat("kk-k")); ++ ++ assert_se(valid_user_group_name_or_id_compat("some5")); ++ assert_se(!valid_user_group_name_or_id_compat("5some")); ++ assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER")); ++} ++ + static void test_valid_user_group_name_or_id(void) { + log_info("/* %s */", __func__); + +@@ -172,6 +251,10 @@ static void test_valid_user_group_name_or_id(void) { + assert_se(!valid_user_group_name_or_id("-1")); + assert_se(!valid_user_group_name_or_id("-kkk")); + assert_se(!valid_user_group_name_or_id("rööt")); ++ assert_se(!valid_user_group_name_or_id(".")); ++ assert_se(!valid_user_group_name_or_id(".eff")); ++ assert_se(!valid_user_group_name_or_id("eff.eff")); ++ assert_se(!valid_user_group_name_or_id("eff.")); + assert_se(!valid_user_group_name_or_id("foo\nbar")); + assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789")); + assert_se(!valid_user_group_name_or_id("aaa:bbb")); +@@ -182,8 +265,6 @@ static void test_valid_user_group_name_or_id(void) { + assert_se(valid_user_group_name_or_id("_kkk")); + assert_se(valid_user_group_name_or_id("kkk-")); + assert_se(valid_user_group_name_or_id("kk-k")); +- assert_se(valid_user_group_name_or_id(".moo")); +- assert_se(valid_user_group_name_or_id("eff.eff")); + + assert_se(valid_user_group_name_or_id("some5")); + assert_se(!valid_user_group_name_or_id("5some")); +@@ -286,7 +367,9 @@ int main(int argc, char*argv[]) { + test_parse_uid(); + test_uid_ptr(); + ++ test_valid_user_group_name_compat(); + test_valid_user_group_name(); ++ test_valid_user_group_name_or_id_compat(); + test_valid_user_group_name_or_id(); + test_valid_gecos(); + test_valid_home(); diff --git a/SOURCES/0470-shared-user-util-emit-a-warning-on-names-with-dots.patch b/SOURCES/0470-shared-user-util-emit-a-warning-on-names-with-dots.patch new file mode 100644 index 0000000..83422bc --- /dev/null +++ b/SOURCES/0470-shared-user-util-emit-a-warning-on-names-with-dots.patch @@ -0,0 +1,50 @@ +From fa1fa19951fdadd63f2b5df6224678f91753f260 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 28 Aug 2019 12:05:52 +0200 +Subject: [PATCH] shared/user-util: emit a warning on names with dots + +(cherry picked from commit 88e2ed0b5bf6f08f5a2d4d64b1fefdc7192b9aac) + +Related: #1848373 +--- + src/basic/user-util.c | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 03cbbc2503..359da08a83 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -601,13 +601,26 @@ bool valid_user_group_name_full(const char *u, bool strict) { + u[0] != '_') + return false; + +- for (i = u+1; *i; i++) +- if (!((*i >= 'a' && *i <= 'z') || +- (*i >= 'A' && *i <= 'Z') || +- (*i >= '0' && *i <= '9') || +- IN_SET(*i, '_', '-') || +- (!strict && *i == '.'))) +- return false; ++ bool warned = false; ++ ++ for (i = u+1; *i; i++) { ++ if (((*i >= 'a' && *i <= 'z') || ++ (*i >= 'A' && *i <= 'Z') || ++ (*i >= '0' && *i <= '9') || ++ IN_SET(*i, '_', '-'))) ++ continue; ++ ++ if (*i == '.' && !strict) { ++ if (!warned) { ++ log_warning("Bad user or group name \"%s\", accepting for compatibility.", u); ++ warned = true; ++ } ++ ++ continue; ++ } ++ ++ return false; ++ } + + sz = sysconf(_SC_LOGIN_NAME_MAX); + assert_se(sz > 0); diff --git a/SOURCES/0471-user-util-Allow-names-starting-with-a-digit.patch b/SOURCES/0471-user-util-Allow-names-starting-with-a-digit.patch new file mode 100644 index 0000000..52a315a --- /dev/null +++ b/SOURCES/0471-user-util-Allow-names-starting-with-a-digit.patch @@ -0,0 +1,103 @@ +From f06434cc51eedd72f7d4a640a1fa118f57a5e68e Mon Sep 17 00:00:00 2001 +From: Balint Reczey +Date: Wed, 18 Mar 2020 18:29:02 +0100 +Subject: [PATCH] user-util: Allow names starting with a digit + +In 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865 the change inadvertedly +disabled names with digit as the first character. This follow-up change +allows a digit as the first character in compat mode. + +Fixes: #15141 +(cherry picked from commit 93c23c9297e48e594785e0bb9c51504aae5fbe3e) + +Related: #1848373 +--- + src/basic/user-util.c | 20 +++++++++++++++++--- + src/test/test-user-util.c | 4 ++-- + 2 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 359da08a83..7dd2bb2c84 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -579,16 +579,18 @@ int take_etc_passwd_lock(const char *root) { + bool valid_user_group_name_full(const char *u, bool strict) { + const char *i; + long sz; ++ bool warned = false; + + /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, + * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: + * + * - We require that names fit into the appropriate utmp field + * - We don't allow empty user names +- * - No dots or digits in the first character ++ * - No dots in the first character + * + * If strict==true, additionally: + * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) ++ * - We don't allow a digit as the first character + * + * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. + */ +@@ -598,17 +600,26 @@ bool valid_user_group_name_full(const char *u, bool strict) { + + if (!(u[0] >= 'a' && u[0] <= 'z') && + !(u[0] >= 'A' && u[0] <= 'Z') && ++ !(u[0] >= '0' && u[0] <= '9' && !strict) && + u[0] != '_') + return false; + +- bool warned = false; ++ bool only_digits_seen = u[0] >= '0' && u[0] <= '9'; ++ ++ if (only_digits_seen) { ++ log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u); ++ warned = true; ++ } + + for (i = u+1; *i; i++) { + if (((*i >= 'a' && *i <= 'z') || + (*i >= 'A' && *i <= 'Z') || + (*i >= '0' && *i <= '9') || +- IN_SET(*i, '_', '-'))) ++ IN_SET(*i, '_', '-'))) { ++ if (!(*i >= '0' && *i <= '9')) ++ only_digits_seen = false; + continue; ++ } + + if (*i == '.' && !strict) { + if (!warned) { +@@ -622,6 +633,9 @@ bool valid_user_group_name_full(const char *u, bool strict) { + return false; + } + ++ if (only_digits_seen) ++ return false; ++ + sz = sysconf(_SC_LOGIN_NAME_MAX); + assert_se(sz > 0); + +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 3a4211655d..56079f1486 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -164,7 +164,7 @@ static void test_valid_user_group_name_compat(void) { + assert_se(valid_user_group_name_compat("eff.")); + + assert_se(valid_user_group_name_compat("some5")); +- assert_se(!valid_user_group_name_compat("5some")); ++ assert_se(valid_user_group_name_compat("5some")); + assert_se(valid_user_group_name_compat("INNER5NUMBER")); + } + +@@ -234,7 +234,7 @@ static void test_valid_user_group_name_or_id_compat(void) { + assert_se(valid_user_group_name_or_id_compat("kk-k")); + + assert_se(valid_user_group_name_or_id_compat("some5")); +- assert_se(!valid_user_group_name_or_id_compat("5some")); ++ assert_se(valid_user_group_name_or_id_compat("5some")); + assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER")); + } + diff --git a/SOURCES/0472-shared-user-util-allow-usernames-with-dots-in-specif.patch b/SOURCES/0472-shared-user-util-allow-usernames-with-dots-in-specif.patch new file mode 100644 index 0000000..37544d6 --- /dev/null +++ b/SOURCES/0472-shared-user-util-allow-usernames-with-dots-in-specif.patch @@ -0,0 +1,193 @@ +From 40dff18947fa198810db4cd3e5291349fc84a0e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 1 Aug 2019 10:02:14 +0200 +Subject: [PATCH] shared/user-util: allow usernames with dots in specific + fields + +People do have usernames with dots, and it makes them very unhappy that systemd +doesn't like their that. It seems that there is no actual problem with allowing +dots in the username. In particular chown declares ":" as the official +separator, and internally in systemd we never rely on "." as the seperator +between user and group (nor do we call chown directly). Using dots in the name +is probably not a very good idea, but we don't need to care. Debian tools +(adduser) do not allow users with dots to be created. + +This patch allows *existing* names with dots to be used in User, Group, +SupplementaryGroups, SocketUser, SocketGroup fields, both in unit files and on +the command line. DynamicUsers and sysusers still follow the strict policy. +user@.service and tmpfiles already allowed arbitrary user names, and this +remains unchanged. + +Fixes #12754. + +(cherry picked from commit ae480f0b09aec815b64579bb1828ea935d8ee236) + +Related: #1848373 +--- + src/core/dbus-execute.c | 12 ++++++------ + src/core/dbus-socket.c | 4 ++-- + src/core/dbus-util.c | 2 +- + src/core/dbus-util.h | 2 +- + src/core/load-fragment-gperf.gperf.m4 | 10 +++++----- + src/core/load-fragment.c | 8 ++++---- + src/core/load-fragment.h | 4 ++-- + 7 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 0fe4c14e48..e004fb55c9 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1113,10 +1113,10 @@ int bus_exec_context_set_transient_property( + flags |= UNIT_PRIVATE; + + if (streq(name, "User")) +- return bus_set_transient_user(u, name, &c->user, message, flags, error); ++ return bus_set_transient_user_compat(u, name, &c->user, message, flags, error); + + if (streq(name, "Group")) +- return bus_set_transient_user(u, name, &c->group, message, flags, error); ++ return bus_set_transient_user_compat(u, name, &c->group, message, flags, error); + + if (streq(name, "TTYPath")) + return bus_set_transient_path(u, name, &c->tty_path, message, flags, error); +@@ -1297,10 +1297,10 @@ int bus_exec_context_set_transient_property( + if (r < 0) + return r; + +- STRV_FOREACH(p, l) { +- if (!isempty(*p) && !valid_user_group_name_or_id(*p)) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names"); +- } ++ STRV_FOREACH(p, l) ++ if (!isempty(*p) && !valid_user_group_name_or_id_compat(*p)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ "Invalid supplementary group names"); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + if (strv_isempty(l)) { +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index bb77539030..8fdbc05409 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -281,10 +281,10 @@ static int bus_socket_set_transient_property( + return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error); + + if (streq(name, "SocketUser")) +- return bus_set_transient_user(u, name, &s->user, message, flags, error); ++ return bus_set_transient_user_compat(u, name, &s->user, message, flags, error); + + if (streq(name, "SocketGroup")) +- return bus_set_transient_user(u, name, &s->group, message, flags, error); ++ return bus_set_transient_user_compat(u, name, &s->group, message, flags, error); + + if (streq(name, "BindIPv6Only")) + return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error); +diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c +index f4fbb72cb9..7862beaacb 100644 +--- a/src/core/dbus-util.c ++++ b/src/core/dbus-util.c +@@ -30,7 +30,7 @@ int bus_property_get_triggered_unit( + + BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o"); + BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32); +-BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user, valid_user_group_name_or_id); ++BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_compat, valid_user_group_name_or_id_compat); + BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute); + + int bus_set_transient_string( +diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h +index 12b055e4ac..a3316c6701 100644 +--- a/src/core/dbus-util.h ++++ b/src/core/dbus-util.h +@@ -235,7 +235,7 @@ int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *i + + int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +-int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); ++int bus_set_transient_user_compat(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 24ee5ae6fe..156a4d0a6d 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -25,9 +25,9 @@ m4_define(`EXEC_CONTEXT_CONFIG_ITEMS', + `$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context) + $1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory) + $1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image) +-$1.User, config_parse_user_group, 0, offsetof($1, exec_context.user) +-$1.Group, config_parse_user_group, 0, offsetof($1, exec_context.group) +-$1.SupplementaryGroups, config_parse_user_group_strv, 0, offsetof($1, exec_context.supplementary_groups) ++$1.User, config_parse_user_group_compat, 0, offsetof($1, exec_context.user) ++$1.Group, config_parse_user_group_compat, 0, offsetof($1, exec_context.group) ++$1.SupplementaryGroups, config_parse_user_group_strv_compat, 0, offsetof($1, exec_context.supplementary_groups) + $1.Nice, config_parse_exec_nice, 0, offsetof($1, exec_context) + $1.OOMScoreAdjust, config_parse_exec_oom_score_adjust, 0, offsetof($1, exec_context) + $1.IOSchedulingClass, config_parse_exec_io_class, 0, offsetof($1, exec_context) +@@ -354,8 +354,8 @@ Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC + Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command) + Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command) + Socket.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Socket, timeout_usec) +-Socket.SocketUser, config_parse_user_group, 0, offsetof(Socket, user) +-Socket.SocketGroup, config_parse_user_group, 0, offsetof(Socket, group) ++Socket.SocketUser, config_parse_user_group_compat, 0, offsetof(Socket, user) ++Socket.SocketGroup, config_parse_user_group_compat, 0, offsetof(Socket, group) + Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) + Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) + Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 740401a582..ba81d94504 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1899,7 +1899,7 @@ int config_parse_sec_fix_0( + return 0; + } + +-int config_parse_user_group( ++int config_parse_user_group_compat( + const char *unit, + const char *filename, + unsigned line, +@@ -1932,7 +1932,7 @@ int config_parse_user_group( + return -ENOEXEC; + } + +- if (!valid_user_group_name_or_id(k)) { ++ if (!valid_user_group_name_or_id_compat(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); + return -ENOEXEC; + } +@@ -1940,7 +1940,7 @@ int config_parse_user_group( + return free_and_replace(*user, k); + } + +-int config_parse_user_group_strv( ++int config_parse_user_group_strv_compat( + const char *unit, + const char *filename, + unsigned line, +@@ -1986,7 +1986,7 @@ int config_parse_user_group_strv( + return -ENOEXEC; + } + +- if (!valid_user_group_name_or_id(k)) { ++ if (!valid_user_group_name_or_id_compat(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); + return -ENOEXEC; + } +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index 65a94d53cc..f9d34d484d 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -96,8 +96,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_utmp_mode); + CONFIG_PARSER_PROTOTYPE(config_parse_working_directory); + CONFIG_PARSER_PROTOTYPE(config_parse_fdname); + CONFIG_PARSER_PROTOTYPE(config_parse_sec_fix_0); +-CONFIG_PARSER_PROTOTYPE(config_parse_user_group); +-CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv); ++CONFIG_PARSER_PROTOTYPE(config_parse_user_group_compat); ++CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv_compat); + CONFIG_PARSER_PROTOTYPE(config_parse_restrict_namespaces); + CONFIG_PARSER_PROTOTYPE(config_parse_bind_paths); + CONFIG_PARSER_PROTOTYPE(config_parse_exec_keyring_mode); diff --git a/SOURCES/0473-user-util-switch-order-of-checks-in-valid_user_group.patch b/SOURCES/0473-user-util-switch-order-of-checks-in-valid_user_group.patch new file mode 100644 index 0000000..b982f8c --- /dev/null +++ b/SOURCES/0473-user-util-switch-order-of-checks-in-valid_user_group.patch @@ -0,0 +1,38 @@ +From 7569168bea3d7e11cd3afe6167fcf4a3ac65a1a6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 30 Mar 2020 21:46:01 +0200 +Subject: [PATCH] user-util: switch order of checks in + valid_user_group_name_or_id_full() + +When we are supposed to accept numeric UIDs formatted as string, then +let's check that first, before passing things on to +valid_user_group_name_full(), since that might log about, and not the +other way round. + +See: #15201 +Follow-up for: 93c23c9297e48e594785e0bb9c51504aae5fbe3e + +(cherry picked from commit a85daa0dfb3eb03be9845760e90e54b9af8fb00e) + +Related: #1848373 +--- + src/basic/user-util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 7dd2bb2c84..68a924770b 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -656,10 +656,10 @@ bool valid_user_group_name_or_id_full(const char *u, bool strict) { + if (isempty(u)) + return false; + +- if (valid_user_group_name_full(u, strict)) ++ if (parse_uid(u, NULL) >= 0) + return true; + +- return parse_uid(u, NULL) >= 0; ++ return valid_user_group_name_full(u, strict); + } + + bool valid_gecos(const char *d) { diff --git a/SOURCES/0474-user-util-rework-how-we-validate-user-names.patch b/SOURCES/0474-user-util-rework-how-we-validate-user-names.patch new file mode 100644 index 0000000..9607f81 --- /dev/null +++ b/SOURCES/0474-user-util-rework-how-we-validate-user-names.patch @@ -0,0 +1,803 @@ +From 33b851f0c30e47fe71a293e2c990ef26573efe86 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 4 Apr 2020 12:23:02 +0200 +Subject: [PATCH] user-util: rework how we validate user names +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reworks the user validation infrastructure. There are now two +modes. In regular mode we are strict and test against a strict set of +valid chars. And in "relaxed" mode we just filter out some really +obvious, dangerous stuff. i.e. strict is whitelisting what is OK, but +"relaxed" is blacklisting what is really not OK. + +The idea is that we use strict mode whenver we allocate a new user +(i.e. in sysusers.d or homed), while "relaxed" mode is when we process +users registered elsewhere, (i.e. userdb, logind, …) + +The requirements on user name validity vary wildly. SSSD thinks its fine +to embedd "@" for example, while the suggested NAME_REGEX field on +Debian does not even allow uppercase chars… + +This effectively liberaralizes a lot what we expect from usernames. + +The code that warns about questionnable user names is now optional and +only used at places such as unit file parsing, so that it doesn't show +up on every userdb query, but only when processing configuration files +that know better. + +Fixes: #15149 #15090 +(cherry picked from commit 7a8867abfab10e5bbca10590ec2aa40c5b27d8fb) + +Resolves: #1848373 +--- + src/basic/user-util.c | 185 +++++++++++++---------- + src/basic/user-util.h | 21 +-- + src/core/dbus-execute.c | 6 +- + src/core/dbus-manager.c | 2 +- + src/core/dbus-socket.c | 4 +- + src/core/dbus-util.c | 7 +- + src/core/dbus-util.h | 2 +- + src/core/dynamic-user.c | 2 +- + src/core/load-fragment.c | 4 +- + src/core/unit.c | 2 +- + src/nss-systemd/nss-systemd.c | 6 +- + src/systemd/sd-messages.h | 3 + + src/sysusers/sysusers.c | 4 +- + src/test/test-user-util.c | 271 ++++++++++++++++++---------------- + 14 files changed, 287 insertions(+), 232 deletions(-) + +diff --git a/src/basic/user-util.c b/src/basic/user-util.c +index 68a924770b..cd870c4361 100644 +--- a/src/basic/user-util.c ++++ b/src/basic/user-util.c +@@ -14,6 +14,8 @@ + #include + #include + ++#include "sd-messages.h" ++ + #include "alloc-util.h" + #include "fd-util.h" + #include "fileio.h" +@@ -576,92 +578,125 @@ int take_etc_passwd_lock(const char *root) { + return fd; + } + +-bool valid_user_group_name_full(const char *u, bool strict) { ++bool valid_user_group_name(const char *u, ValidUserFlags flags) { + const char *i; +- long sz; +- bool warned = false; + +- /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, +- * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: +- * +- * - We require that names fit into the appropriate utmp field +- * - We don't allow empty user names +- * - No dots in the first character ++ /* Checks if the specified name is a valid user/group name. There are two flavours of this call: ++ * strict mode is the default which is POSIX plus some extra rules; and relaxed mode where we accept ++ * pretty much everything except the really worst offending names. + * +- * If strict==true, additionally: +- * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) +- * - We don't allow a digit as the first character +- * +- * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. +- */ ++ * Whenever we synthesize users ourselves we should use the strict mode. But when we process users ++ * created by other stuff, let's be more liberal. */ + +- if (isempty(u)) ++ if (isempty(u)) /* An empty user name is never valid */ + return false; + +- if (!(u[0] >= 'a' && u[0] <= 'z') && +- !(u[0] >= 'A' && u[0] <= 'Z') && +- !(u[0] >= '0' && u[0] <= '9' && !strict) && +- u[0] != '_') +- return false; +- +- bool only_digits_seen = u[0] >= '0' && u[0] <= '9'; +- +- if (only_digits_seen) { +- log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u); +- warned = true; +- } +- +- for (i = u+1; *i; i++) { +- if (((*i >= 'a' && *i <= 'z') || +- (*i >= 'A' && *i <= 'Z') || +- (*i >= '0' && *i <= '9') || +- IN_SET(*i, '_', '-'))) { +- if (!(*i >= '0' && *i <= '9')) +- only_digits_seen = false; +- continue; +- } +- +- if (*i == '.' && !strict) { +- if (!warned) { +- log_warning("Bad user or group name \"%s\", accepting for compatibility.", u); +- warned = true; +- } +- +- continue; +- } +- +- return false; ++ if (parse_uid(u, NULL) >= 0) /* Something that parses as numeric UID string is valid exactly when the ++ * flag for it is set */ ++ return FLAGS_SET(flags, VALID_USER_ALLOW_NUMERIC); ++ ++ if (FLAGS_SET(flags, VALID_USER_RELAX)) { ++ ++ /* In relaxed mode we just check very superficially. Apparently SSSD and other stuff is ++ * extremely liberal (way too liberal if you ask me, even inserting "@" in user names, which ++ * is bound to cause problems for example when used with an MTA), hence only filter the most ++ * obvious cases, or where things would result in an invalid entry if such a user name would ++ * show up in /etc/passwd (or equivalent getent output). ++ * ++ * Note that we stepped far out of POSIX territory here. It's not our fault though, but ++ * SSSD's, Samba's and everybody else who ignored POSIX on this. (I mean, I am happy to step ++ * outside of POSIX' bounds any day, but I must say in this case I probably wouldn't ++ * have...) */ ++ ++ if (startswith(u, " ") || endswith(u, " ")) /* At least expect whitespace padding is removed ++ * at front and back (accept in the middle, since ++ * that's apparently a thing on Windows). Note ++ * that this also blocks usernames consisting of ++ * whitespace only. */ ++ return false; ++ ++ if (!utf8_is_valid(u)) /* We want to synthesize JSON from this, hence insist on UTF-8 */ ++ return false; ++ ++ if (string_has_cc(u, NULL)) /* CC characters are just dangerous (and \n in particular is the ++ * record separator in /etc/passwd), so we can't allow that. */ ++ return false; ++ ++ if (strpbrk(u, ":/")) /* Colons are the field separator in /etc/passwd, we can't allow ++ * that. Slashes are special to file systems paths and user names ++ * typically show up in the file system as home directories, hence ++ * don't allow slashes. */ ++ return false; ++ ++ if (in_charset(u, "0123456789")) /* Don't allow fully numeric strings, they might be confused ++ * with with UIDs (note that this test is more broad than ++ * the parse_uid() test above, as it will cover more than ++ * the 32bit range, and it will detect 65535 (which is in ++ * invalid UID, even though in the unsigned 32 bit range) */ ++ return false; ++ ++ if (u[0] == '-' && in_charset(u + 1, "0123456789")) /* Don't allow negative fully numeric ++ * strings either. After all some people ++ * write 65535 as -1 (even though that's ++ * not even true on 32bit uid_t ++ * anyway) */ ++ return false; ++ ++ if (dot_or_dot_dot(u)) /* User names typically become home directory names, and these two are ++ * special in that context, don't allow that. */ ++ return false; ++ ++ /* Compare with strict result and warn if result doesn't match */ ++ if (FLAGS_SET(flags, VALID_USER_WARN) && !valid_user_group_name(u, 0)) ++ log_struct(LOG_NOTICE, ++ "MESSAGE=Accepting user/group name '%s', which does not match strict user/group name rules.", u, ++ "USER_GROUP_NAME=%s", u, ++ "MESSAGE_ID=" SD_MESSAGE_UNSAFE_USER_NAME_STR); ++ ++ /* Note that we make no restrictions on the length in relaxed mode! */ ++ } else { ++ long sz; ++ size_t l; ++ ++ /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.437. We are a bit stricter here ++ * however. Specifically we deviate from POSIX rules: ++ * ++ * - We don't allow empty user names (see above) ++ * - We require that names fit into the appropriate utmp field ++ * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) ++ * - We don't allow dashes or digit as the first character ++ * ++ * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. ++ */ ++ ++ if (!(u[0] >= 'a' && u[0] <= 'z') && ++ !(u[0] >= 'A' && u[0] <= 'Z') && ++ u[0] != '_') ++ return false; ++ ++ for (i = u+1; *i; i++) ++ if (!(*i >= 'a' && *i <= 'z') && ++ !(*i >= 'A' && *i <= 'Z') && ++ !(*i >= '0' && *i <= '9') && ++ !IN_SET(*i, '_', '-')) ++ return false; ++ ++ l = i - u; ++ ++ sz = sysconf(_SC_LOGIN_NAME_MAX); ++ assert_se(sz > 0); ++ ++ if (l > (size_t) sz) ++ return false; ++ if (l > FILENAME_MAX) ++ return false; ++ if (l > UT_NAMESIZE - 1) ++ return false; + } + +- if (only_digits_seen) +- return false; +- +- sz = sysconf(_SC_LOGIN_NAME_MAX); +- assert_se(sz > 0); +- +- if ((size_t) (i-u) > (size_t) sz) +- return false; +- +- if ((size_t) (i-u) > UT_NAMESIZE - 1) +- return false; +- + return true; + } + +-bool valid_user_group_name_or_id_full(const char *u, bool strict) { +- +- /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the +- * right range, and not the invalid user ids. */ +- +- if (isempty(u)) +- return false; +- +- if (parse_uid(u, NULL) >= 0) +- return true; +- +- return valid_user_group_name_full(u, strict); +-} +- + bool valid_gecos(const char *d) { + + if (!d) +diff --git a/src/basic/user-util.h b/src/basic/user-util.h +index 5ad0b2a2f9..939bded40d 100644 +--- a/src/basic/user-util.h ++++ b/src/basic/user-util.h +@@ -78,20 +78,13 @@ static inline bool userns_supported(void) { + return access("/proc/self/uid_map", F_OK) >= 0; + } + +-bool valid_user_group_name_full(const char *u, bool strict); +-bool valid_user_group_name_or_id_full(const char *u, bool strict); +-static inline bool valid_user_group_name(const char *u) { +- return valid_user_group_name_full(u, true); +-} +-static inline bool valid_user_group_name_or_id(const char *u) { +- return valid_user_group_name_or_id_full(u, true); +-} +-static inline bool valid_user_group_name_compat(const char *u) { +- return valid_user_group_name_full(u, false); +-} +-static inline bool valid_user_group_name_or_id_compat(const char *u) { +- return valid_user_group_name_or_id_full(u, false); +-} ++typedef enum ValidUserFlags { ++ VALID_USER_RELAX = 1 << 0, ++ VALID_USER_WARN = 1 << 1, ++ VALID_USER_ALLOW_NUMERIC = 1 << 2, ++} ValidUserFlags; ++ ++bool valid_user_group_name(const char *u, ValidUserFlags flags); + bool valid_gecos(const char *d); + bool valid_home(const char *p); + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index e004fb55c9..8348663000 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1113,10 +1113,10 @@ int bus_exec_context_set_transient_property( + flags |= UNIT_PRIVATE; + + if (streq(name, "User")) +- return bus_set_transient_user_compat(u, name, &c->user, message, flags, error); ++ return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error); + + if (streq(name, "Group")) +- return bus_set_transient_user_compat(u, name, &c->group, message, flags, error); ++ return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error); + + if (streq(name, "TTYPath")) + return bus_set_transient_path(u, name, &c->tty_path, message, flags, error); +@@ -1298,7 +1298,7 @@ int bus_exec_context_set_transient_property( + return r; + + STRV_FOREACH(p, l) +- if (!isempty(*p) && !valid_user_group_name_or_id_compat(*p)) ++ if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Invalid supplementary group names"); + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 0a1d3df42f..7488f22116 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -1762,7 +1762,7 @@ static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *use + + if (!MANAGER_IS_SYSTEM(m)) + return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance."); +- if (!valid_user_group_name(name)) ++ if (!valid_user_group_name(name, VALID_USER_RELAX)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name); + + r = dynamic_user_lookup_name(m, name, &uid); +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index 8fdbc05409..fa6bbe2c6f 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -281,10 +281,10 @@ static int bus_socket_set_transient_property( + return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error); + + if (streq(name, "SocketUser")) +- return bus_set_transient_user_compat(u, name, &s->user, message, flags, error); ++ return bus_set_transient_user_relaxed(u, name, &s->user, message, flags, error); + + if (streq(name, "SocketGroup")) +- return bus_set_transient_user_compat(u, name, &s->group, message, flags, error); ++ return bus_set_transient_user_relaxed(u, name, &s->group, message, flags, error); + + if (streq(name, "BindIPv6Only")) + return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error); +diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c +index 7862beaacb..951450e53d 100644 +--- a/src/core/dbus-util.c ++++ b/src/core/dbus-util.c +@@ -30,7 +30,12 @@ int bus_property_get_triggered_unit( + + BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o"); + BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32); +-BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_compat, valid_user_group_name_or_id_compat); ++ ++static inline bool valid_user_group_name_or_id_relaxed(const char *u) { ++ return valid_user_group_name(u, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX); ++} ++ ++BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed, valid_user_group_name_or_id_relaxed); + BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute); + + int bus_set_transient_string( +diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h +index a3316c6701..713b464dd9 100644 +--- a/src/core/dbus-util.h ++++ b/src/core/dbus-util.h +@@ -235,7 +235,7 @@ int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *i + + int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +-int bus_set_transient_user_compat(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); ++int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); + int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c +index 021fd93a76..548b3cc9df 100644 +--- a/src/core/dynamic-user.c ++++ b/src/core/dynamic-user.c +@@ -108,7 +108,7 @@ static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret) + return 0; + } + +- if (!valid_user_group_name_or_id(name)) ++ if (!valid_user_group_name(name, VALID_USER_ALLOW_NUMERIC)) + return -EINVAL; + + if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, storage_socket) < 0) +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index ba81d94504..e0d7b8f7f8 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1932,7 +1932,7 @@ int config_parse_user_group_compat( + return -ENOEXEC; + } + +- if (!valid_user_group_name_or_id_compat(k)) { ++ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); + return -ENOEXEC; + } +@@ -1986,7 +1986,7 @@ int config_parse_user_group_strv_compat( + return -ENOEXEC; + } + +- if (!valid_user_group_name_or_id_compat(k)) { ++ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k); + return -ENOEXEC; + } +diff --git a/src/core/unit.c b/src/core/unit.c +index ffbf3cfd48..cd3e7c806d 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4088,7 +4088,7 @@ static int user_from_unit_name(Unit *u, char **ret) { + if (r < 0) + return r; + +- if (valid_user_group_name(n)) { ++ if (valid_user_group_name(n, 0)) { + *ret = TAKE_PTR(n); + return 0; + } +diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c +index f8db27ae27..615c710257 100644 +--- a/src/nss-systemd/nss-systemd.c ++++ b/src/nss-systemd/nss-systemd.c +@@ -123,7 +123,7 @@ static int direct_lookup_uid(uid_t uid, char **ret) { + r = readlink_malloc(path, &s); + if (r < 0) + return r; +- if (!valid_user_group_name(s)) { /* extra safety check */ ++ if (!valid_user_group_name(s, VALID_USER_RELAX)) { /* extra safety check */ + free(s); + return -EINVAL; + } +@@ -153,7 +153,7 @@ enum nss_status _nss_systemd_getpwnam_r( + + /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't + * generate EINVAL here, because it isn't really out business to complain about invalid user names. */ +- if (!valid_user_group_name(name)) ++ if (!valid_user_group_name(name, VALID_USER_RELAX)) + return NSS_STATUS_NOTFOUND; + + /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */ +@@ -356,7 +356,7 @@ enum nss_status _nss_systemd_getgrnam_r( + assert(name); + assert(gr); + +- if (!valid_user_group_name(name)) ++ if (!valid_user_group_name(name, VALID_USER_RELAX)) + return NSS_STATUS_NOTFOUND; + + /* Synthesize records for root and nobody, in case they are missing form /etc/group */ +diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h +index bdd4fd3974..847b698ba4 100644 +--- a/src/systemd/sd-messages.h ++++ b/src/systemd/sd-messages.h +@@ -152,6 +152,9 @@ _SD_BEGIN_DECLARATIONS; + #define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57) + #define SD_MESSAGE_DNSSEC_DOWNGRADE_STR SD_ID128_MAKE_STR(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57) + ++#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f) ++#define SD_MESSAGE_UNSAFE_USER_NAME_STR SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f) ++ + _SD_END_DECLARATIONS; + + #endif +diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c +index 33959d3c11..a374ebaaf4 100644 +--- a/src/sysusers/sysusers.c ++++ b/src/sysusers/sysusers.c +@@ -1413,7 +1413,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { + return r; + } + +- if (!valid_user_group_name(resolved_name)) { ++ if (!valid_user_group_name(resolved_name, 0)) { + log_error("[%s:%u] '%s' is not a valid user or group name.", fname, line, resolved_name); + return -EINVAL; + } +@@ -1524,7 +1524,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { + return -EINVAL; + } + +- if (!valid_user_group_name(resolved_id)) { ++ if (!valid_user_group_name(resolved_id, 0)) { + log_error("[%s:%u] '%s' is not a valid user or group name.", fname, line, resolved_id); + return -EINVAL; + } +diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c +index 56079f1486..31ac018da9 100644 +--- a/src/test/test-user-util.c ++++ b/src/test/test-user-util.c +@@ -131,144 +131,163 @@ static void test_uid_ptr(void) { + assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000); + } + +-static void test_valid_user_group_name_compat(void) { ++static void test_valid_user_group_name_relaxed(void) { + log_info("/* %s */", __func__); + +- assert_se(!valid_user_group_name_compat(NULL)); +- assert_se(!valid_user_group_name_compat("")); +- assert_se(!valid_user_group_name_compat("1")); +- assert_se(!valid_user_group_name_compat("65535")); +- assert_se(!valid_user_group_name_compat("-1")); +- assert_se(!valid_user_group_name_compat("-kkk")); +- assert_se(!valid_user_group_name_compat("rööt")); +- assert_se(!valid_user_group_name_compat(".")); +- assert_se(!valid_user_group_name_compat(".eff")); +- assert_se(!valid_user_group_name_compat("foo\nbar")); +- assert_se(!valid_user_group_name_compat("0123456789012345678901234567890123456789")); +- assert_se(!valid_user_group_name_or_id_compat("aaa:bbb")); +- assert_se(!valid_user_group_name_compat(".")); +- assert_se(!valid_user_group_name_compat(".1")); +- assert_se(!valid_user_group_name_compat(".65535")); +- assert_se(!valid_user_group_name_compat(".-1")); +- assert_se(!valid_user_group_name_compat(".-kkk")); +- assert_se(!valid_user_group_name_compat(".rööt")); +- assert_se(!valid_user_group_name_or_id_compat(".aaa:bbb")); +- +- assert_se(valid_user_group_name_compat("root")); +- assert_se(valid_user_group_name_compat("lennart")); +- assert_se(valid_user_group_name_compat("LENNART")); +- assert_se(valid_user_group_name_compat("_kkk")); +- assert_se(valid_user_group_name_compat("kkk-")); +- assert_se(valid_user_group_name_compat("kk-k")); +- assert_se(valid_user_group_name_compat("eff.eff")); +- assert_se(valid_user_group_name_compat("eff.")); +- +- assert_se(valid_user_group_name_compat("some5")); +- assert_se(valid_user_group_name_compat("5some")); +- assert_se(valid_user_group_name_compat("INNER5NUMBER")); ++ assert_se(!valid_user_group_name(NULL, VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("1", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("65535", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("-1", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name(".", VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("..", VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("root", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("lennart", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("LENNART", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("_kkk", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("kkk-", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("kk-k", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("eff.eff", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("eff.", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("-kkk", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("rööt", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".eff", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".1", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".65535", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".-1", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".-kkk", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".rööt", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("...", VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("some5", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("5some", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("Dāvis", VALID_USER_RELAX)); + } + + static void test_valid_user_group_name(void) { + log_info("/* %s */", __func__); + +- assert_se(!valid_user_group_name(NULL)); +- assert_se(!valid_user_group_name("")); +- assert_se(!valid_user_group_name("1")); +- assert_se(!valid_user_group_name("65535")); +- assert_se(!valid_user_group_name("-1")); +- assert_se(!valid_user_group_name("-kkk")); +- assert_se(!valid_user_group_name("rööt")); +- assert_se(!valid_user_group_name(".")); +- assert_se(!valid_user_group_name(".eff")); +- assert_se(!valid_user_group_name("foo\nbar")); +- assert_se(!valid_user_group_name("0123456789012345678901234567890123456789")); +- assert_se(!valid_user_group_name_or_id("aaa:bbb")); +- assert_se(!valid_user_group_name(".")); +- assert_se(!valid_user_group_name(".1")); +- assert_se(!valid_user_group_name(".65535")); +- assert_se(!valid_user_group_name(".-1")); +- assert_se(!valid_user_group_name(".-kkk")); +- assert_se(!valid_user_group_name(".rööt")); +- assert_se(!valid_user_group_name_or_id(".aaa:bbb")); +- +- assert_se(valid_user_group_name("root")); +- assert_se(valid_user_group_name("lennart")); +- assert_se(valid_user_group_name("LENNART")); +- assert_se(valid_user_group_name("_kkk")); +- assert_se(valid_user_group_name("kkk-")); +- assert_se(valid_user_group_name("kk-k")); +- assert_se(!valid_user_group_name("eff.eff")); +- assert_se(!valid_user_group_name("eff.")); +- +- assert_se(valid_user_group_name("some5")); +- assert_se(!valid_user_group_name("5some")); +- assert_se(valid_user_group_name("INNER5NUMBER")); ++ assert_se(!valid_user_group_name(NULL, 0)); ++ assert_se(!valid_user_group_name("", 0)); ++ assert_se(!valid_user_group_name("1", 0)); ++ assert_se(!valid_user_group_name("65535", 0)); ++ assert_se(!valid_user_group_name("-1", 0)); ++ assert_se(!valid_user_group_name("-kkk", 0)); ++ assert_se(!valid_user_group_name("rööt", 0)); ++ assert_se(!valid_user_group_name(".", 0)); ++ assert_se(!valid_user_group_name(".eff", 0)); ++ assert_se(!valid_user_group_name("foo\nbar", 0)); ++ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", 0)); ++ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name(".", 0)); ++ assert_se(!valid_user_group_name("..", 0)); ++ assert_se(!valid_user_group_name("...", 0)); ++ assert_se(!valid_user_group_name(".1", 0)); ++ assert_se(!valid_user_group_name(".65535", 0)); ++ assert_se(!valid_user_group_name(".-1", 0)); ++ assert_se(!valid_user_group_name(".-kkk", 0)); ++ assert_se(!valid_user_group_name(".rööt", 0)); ++ assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_ALLOW_NUMERIC)); ++ ++ assert_se(valid_user_group_name("root", 0)); ++ assert_se(valid_user_group_name("lennart", 0)); ++ assert_se(valid_user_group_name("LENNART", 0)); ++ assert_se(valid_user_group_name("_kkk", 0)); ++ assert_se(valid_user_group_name("kkk-", 0)); ++ assert_se(valid_user_group_name("kk-k", 0)); ++ assert_se(!valid_user_group_name("eff.eff", 0)); ++ assert_se(!valid_user_group_name("eff.", 0)); ++ ++ assert_se(valid_user_group_name("some5", 0)); ++ assert_se(!valid_user_group_name("5some", 0)); ++ assert_se(valid_user_group_name("INNER5NUMBER", 0)); ++ ++ assert_se(!valid_user_group_name("piff.paff@ad.domain.example", 0)); ++ assert_se(!valid_user_group_name("Dāvis", 0)); + } + +-static void test_valid_user_group_name_or_id_compat(void) { ++static void test_valid_user_group_name_or_numeric_relaxed(void) { + log_info("/* %s */", __func__); + +- assert_se(!valid_user_group_name_or_id_compat(NULL)); +- assert_se(!valid_user_group_name_or_id_compat("")); +- assert_se(valid_user_group_name_or_id_compat("0")); +- assert_se(valid_user_group_name_or_id_compat("1")); +- assert_se(valid_user_group_name_or_id_compat("65534")); +- assert_se(!valid_user_group_name_or_id_compat("65535")); +- assert_se(valid_user_group_name_or_id_compat("65536")); +- assert_se(!valid_user_group_name_or_id_compat("-1")); +- assert_se(!valid_user_group_name_or_id_compat("-kkk")); +- assert_se(!valid_user_group_name_or_id_compat("rööt")); +- assert_se(!valid_user_group_name_or_id_compat(".")); +- assert_se(!valid_user_group_name_or_id_compat(".eff")); +- assert_se(valid_user_group_name_or_id_compat("eff.eff")); +- assert_se(valid_user_group_name_or_id_compat("eff.")); +- assert_se(!valid_user_group_name_or_id_compat("foo\nbar")); +- assert_se(!valid_user_group_name_or_id_compat("0123456789012345678901234567890123456789")); +- assert_se(!valid_user_group_name_or_id_compat("aaa:bbb")); +- +- assert_se(valid_user_group_name_or_id_compat("root")); +- assert_se(valid_user_group_name_or_id_compat("lennart")); +- assert_se(valid_user_group_name_or_id_compat("LENNART")); +- assert_se(valid_user_group_name_or_id_compat("_kkk")); +- assert_se(valid_user_group_name_or_id_compat("kkk-")); +- assert_se(valid_user_group_name_or_id_compat("kk-k")); +- +- assert_se(valid_user_group_name_or_id_compat("some5")); +- assert_se(valid_user_group_name_or_id_compat("5some")); +- assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER")); ++ assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ ++ assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); ++ assert_se(valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX)); + } + +-static void test_valid_user_group_name_or_id(void) { ++static void test_valid_user_group_name_or_numeric(void) { + log_info("/* %s */", __func__); + +- assert_se(!valid_user_group_name_or_id(NULL)); +- assert_se(!valid_user_group_name_or_id("")); +- assert_se(valid_user_group_name_or_id("0")); +- assert_se(valid_user_group_name_or_id("1")); +- assert_se(valid_user_group_name_or_id("65534")); +- assert_se(!valid_user_group_name_or_id("65535")); +- assert_se(valid_user_group_name_or_id("65536")); +- assert_se(!valid_user_group_name_or_id("-1")); +- assert_se(!valid_user_group_name_or_id("-kkk")); +- assert_se(!valid_user_group_name_or_id("rööt")); +- assert_se(!valid_user_group_name_or_id(".")); +- assert_se(!valid_user_group_name_or_id(".eff")); +- assert_se(!valid_user_group_name_or_id("eff.eff")); +- assert_se(!valid_user_group_name_or_id("eff.")); +- assert_se(!valid_user_group_name_or_id("foo\nbar")); +- assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789")); +- assert_se(!valid_user_group_name_or_id("aaa:bbb")); +- +- assert_se(valid_user_group_name_or_id("root")); +- assert_se(valid_user_group_name_or_id("lennart")); +- assert_se(valid_user_group_name_or_id("LENNART")); +- assert_se(valid_user_group_name_or_id("_kkk")); +- assert_se(valid_user_group_name_or_id("kkk-")); +- assert_se(valid_user_group_name_or_id("kk-k")); +- +- assert_se(valid_user_group_name_or_id("some5")); +- assert_se(!valid_user_group_name_or_id("5some")); +- assert_se(valid_user_group_name_or_id("INNER5NUMBER")); ++ assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC)); ++ ++ assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC)); ++ ++ assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC)); ++ ++ assert_se(!valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC)); ++ assert_se(!valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC)); + } + + static void test_valid_gecos(void) { +@@ -367,10 +386,10 @@ int main(int argc, char*argv[]) { + test_parse_uid(); + test_uid_ptr(); + +- test_valid_user_group_name_compat(); ++ test_valid_user_group_name_relaxed(); + test_valid_user_group_name(); +- test_valid_user_group_name_or_id_compat(); +- test_valid_user_group_name_or_id(); ++ test_valid_user_group_name_or_numeric_relaxed(); ++ test_valid_user_group_name_or_numeric(); + test_valid_gecos(); + test_valid_home(); + diff --git a/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch b/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch new file mode 100644 index 0000000..0fed0ab --- /dev/null +++ b/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch @@ -0,0 +1,35 @@ +From 11a9ea82827d7b57dbce307b77ef8233a4cc028a Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 28 Aug 2014 15:12:10 +0200 +Subject: [PATCH] man: mention System Administrator's Guide in systemctl + manpage + +(cherry picked from commit d4582346f47064de24470b5f92e418966004925f) + +Resolves: #1623116 +--- + man/systemctl.xml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index fa08ab6c0a..56f94d084c 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2000,6 +2000,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + ++ ++ Examples ++ ++ For examples how to use systemctl in comparsion ++ with old service and chkconfig command please see: ++ ++ Managing System Services ++ ++ ++ ++ + + See Also + diff --git a/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch b/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch new file mode 100644 index 0000000..d218efb --- /dev/null +++ b/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch @@ -0,0 +1,257 @@ +From 08ac9f7f55c138678c6415139e7510a05a75b81d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Wed, 14 Oct 2020 16:57:44 +0200 +Subject: [PATCH] udev: introduce udev net_id "naming schemes" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this we can stabilize how naming works for network interfaces. A +user can request through a kernel cmdline option or an env var which +scheme to follow. The idea is that installers use this to set into stone +(a very soft stone though) the scheme used during installation so that +interface naming doesn't change afterwards anymore. + +Why use env vars and kernel cmdline options, and not a config file of +its own? + +Well, first of all there's no obvious existing one to use. But more +importantly: I have the feeling that this logic is kind of an incomplete +hack, and I simply don't want to do advertise this as a perfectly +working solution. So far we used env vars for the non-so-official +options and proper config files for the official stuff. Given how +incomplete this logic is (i.e. the big variable for naming remains the +kernel, which might expose sysfs attributes in newer versions that we +check for and didn't exist in older versions — and other problems like +this), I am simply not confident in giving this first-class exposure in +a primary configuration file. + +Fixes: #10448 + +(cherry-picked from commit f7e81fd96fdfe0ac6dcdb72de43f7cb4720e363a) + +Related: #1827462 + +[msekleta: note that we are introducing our own naming schemes based on +RHEL-8 minor versions. Also we are not backporting all naming scheme +features that appeared in the original commit. We are backporting only +features relevant for v239 while original commit also converted +changes introduced in v240 into naming scheme flags.] +--- + doc/ENVIRONMENT.md | 9 +++ + man/kernel-command-line.xml | 1 + + man/systemd-udevd.service.xml | 16 +++++ + src/udev/udev-builtin-net_id.c | 106 ++++++++++++++++++++++++++++++++- + 4 files changed, 130 insertions(+), 2 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 39a36a52cc..1a4aa01ef4 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -76,6 +76,15 @@ systemd-logind: + hibernation is available even if the swap devices do not provide enough room + for it. + ++* `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of ++ v238, v239, v240 …) as parameter. If specified udev's net_id builtin will ++ follow the specified naming scheme when determining stable network interface ++ names. This may be used to revert to naming schemes of older udev versions, ++ in order to provide more stable naming across updates. This environment ++ variable takes precedence over the kernel command line option ++ `net.naming-scheme=`, except if the value is prefixed with `:` in which case ++ the kernel command line option takes precedence, if it is specified as well. ++ + installed systemd tests: + + * `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if +diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml +index 4d8cb4e50e..b753d0592c 100644 +--- a/man/kernel-command-line.xml ++++ b/man/kernel-command-line.xml +@@ -246,6 +246,7 @@ + udev.event_timeout= + rd.udev.event_timeout= + net.ifnames= ++ net.naming-scheme= + + + Parameters understood by the device event managing +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index 73c77ea690..6449103441 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -170,6 +170,22 @@ + when possible. It is enabled by default; specifying 0 disables it. + + ++ ++ net.naming-scheme= ++ ++ Network interfaces are renamed to give them predictable names when possible (unless ++ net.ifnames=0 is specified, see above). The names are derived from various device metadata ++ fields. Newer versions of systemd-udevd.service take more of these fields into account, ++ improving (and thus possibly changing) the names used for the same devices. With this kernel command line ++ option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as ++ argument. Currently the following identifiers are known: v238, v239, ++ v240 which each implement the naming scheme that was the default in the indicated systemd ++ version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the ++ naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated, ++ previously missing attributes systemd-udevd.service is checking might appear, which ++ affects older name derivation algorithms, too. ++ ++ + + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 147e04ab8c..148696183e 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -96,6 +96,7 @@ + #include "fileio.h" + #include "fs-util.h" + #include "parse-util.h" ++#include "proc-cmdline.h" + #include "stdio-util.h" + #include "string-util.h" + #include "udev.h" +@@ -103,6 +104,52 @@ + + #define ONBOARD_INDEX_MAX (16*1024-1) + ++/* So here's the deal: net_id is supposed to be an excercise in providing stable names for network devices. However, we ++ * also want to keep updating the naming scheme used in future versions of net_id. These two goals of course are ++ * contradictory: on one hand we want things to not change and on the other hand we want them to improve. Our way out ++ * of this dilemma is to introduce the "naming scheme" concept: each time we improve the naming logic we define a new ++ * flag for it. Then, we keep a list of schemes, each identified by a name associated with the flags it implements. Via ++ * a kernel command line and environment variable we then allow the user to pick the scheme they want us to follow: ++ * installers could "freeze" the used scheme at the moment of installation this way. ++ * ++ * Developers: each time you tweak the naming logic here, define a new flag below, and condition the tweak with ++ * it. Each time we do a release we'll then add a new scheme entry and include all newly defined flags. ++ * ++ * Note that this is only half a solution to the problem though: not only udev/net_id gets updated all the time, the ++ * kernel gets too. And thus a kernel that previously didn't expose some sysfs attribute we look for might eventually ++ * do, and thus affect our naming scheme too. Thus, enforcing a naming scheme will make interfacing more stable across ++ * OS versions, but not fully stabilize them. */ ++typedef enum NamingSchemeFlags { ++ /* First, the individual features */ ++ NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ ++ NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ ++ ++ /* And now the masks that combine the features above */ ++ NAMING_V238 = 0, ++ NAMING_V239 = NAMING_V238|NAMING_SR_IOV_V|NAMING_NPAR_ARI, ++ NAMING_RHEL_8_0 = NAMING_V239, ++ NAMING_RHEL_8_1 = NAMING_V239, ++ NAMING_RHEL_8_2 = NAMING_V239, ++ NAMING_RHEL_8_3 = NAMING_V239, ++ ++ _NAMING_SCHEME_FLAGS_INVALID = -1, ++} NamingSchemeFlags; ++ ++typedef struct NamingScheme { ++ const char *name; ++ NamingSchemeFlags flags; ++} NamingScheme; ++ ++static const NamingScheme naming_schemes[] = { ++ { "v238", NAMING_V238 }, ++ { "v239", NAMING_V239 }, ++ { "rhel-8.0", NAMING_RHEL_8_0 }, ++ { "rhel-8.1", NAMING_RHEL_8_1 }, ++ { "rhel-8.2", NAMING_RHEL_8_2 }, ++ { "rhel-8.3", NAMING_RHEL_8_3 }, ++ /* … add more schemes here, as the logic to name devices is updated … */ ++}; ++ + enum netname_type{ + NET_UNDEF, + NET_PCI, +@@ -138,6 +185,56 @@ struct virtfn_info { + char suffix[IFNAMSIZ]; + }; + ++static const NamingScheme* naming_scheme(void) { ++ static const NamingScheme *cache = NULL; ++ _cleanup_free_ char *buffer = NULL; ++ const char *e, *k; ++ ++ if (cache) ++ return cache; ++ ++ /* Acquire setting from the kernel command line */ ++ (void) proc_cmdline_get_key("net.naming-scheme", 0, &buffer); ++ ++ /* Also acquire it from an env var */ ++ e = getenv("NET_NAMING_SCHEME"); ++ if (e) { ++ if (*e == ':') { ++ /* If prefixed with ':' the kernel cmdline takes precedence */ ++ k = buffer ?: e + 1; ++ } else ++ k = e; /* Otherwise the env var takes precedence */ ++ } else ++ k = buffer; ++ ++ if (k) { ++ size_t i; ++ ++ for (i = 0; i < ELEMENTSOF(naming_schemes); i++) ++ if (streq(naming_schemes[i].name, k)) { ++ cache = naming_schemes + i; ++ break; ++ } ++ ++ if (!cache) ++ log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); ++ } ++ ++ if (cache) ++ log_info("Using interface naming scheme '%s'.", cache->name); ++ else { ++ /* RHEL-only: here we differ from the upstream and if no naming scheme was selected we default to naming from systemd-239 */ ++ cache = &naming_schemes[2]; ++ log_info("Using default interface naming scheme '%s'.", cache->name); ++ } ++ ++ return cache; ++} ++ ++static bool naming_scheme_has(NamingSchemeFlags flags) { ++ return FLAGS_SET(naming_scheme()->flags, flags); ++} ++ + /* skip intermediate virtio devices */ + static struct udev_device *skip_virtio(struct udev_device *dev) { + struct udev_device *parent = dev; +@@ -299,7 +396,9 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) + return -ENOENT; +- if (is_pci_ari_enabled(names->pcidev)) ++ ++ if (naming_scheme_has(NAMING_NPAR_ARI) && ++ is_pci_ari_enabled(names->pcidev)) + /* ARI devices support up to 256 functions on a single device ("slot"), and interpret the + * traditional 5-bit slot and 3-bit function number as a single 8-bit function number, + * where the slot makes up the upper 5 bits. */ +@@ -494,7 +593,8 @@ static int names_pci(struct udev_device *dev, struct netnames *names) { + return -ENOENT; + } + +- if (get_virtfn_info(dev, names, &vf_info) >= 0) { ++ if (naming_scheme_has(NAMING_SR_IOV_V) && ++ get_virtfn_info(dev, names, &vf_info) >= 0) { + /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */ + vf_names.pcidev = vf_info.physfn_pcidev; + dev_pci_onboard(dev, &vf_names); +@@ -741,6 +841,8 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + prefix = "ww"; + } + ++ udev_builtin_add_property(dev, test, "ID_NET_NAMING_SCHEME", naming_scheme()->name); ++ + err = names_mac(dev, &names); + if (err >= 0 && names.mac_valid) { + char str[IFNAMSIZ]; diff --git a/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch b/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch new file mode 100644 index 0000000..0c9f850 --- /dev/null +++ b/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch @@ -0,0 +1,188 @@ +From 8c263758fe196624005f19bd6f46d63e3841c5be Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 11 Dec 2018 23:28:29 +0100 +Subject: [PATCH] meson: make net.naming-scheme= default configurable + +This is useful for distributions, where the stability of interface names should +be preseved after an upgrade of systemd. So when some specific release of the +distro is made available, systemd defaults to the latest & greatest naming +scheme, and subsequent updates set the same default. This default may still +be overriden through the kernel and env var options. + +A special value "latest" is also allowed. Without a specific name, it is harder +to verride from meson. In case of 'combo' options, meson reads the default +during the initial configuration, and "remembers" this choice. When systemd is +updated, old build/ directories could keep the old default, which would be +annoying. Hence, "latest" is introduced to make it explicit, yet follow the +upstream. This is actually useful for the user too, because it may be used +as an override, without having to actually specify a version. + +(cherry picked from commit 06da5c63dd697ea4087e76c6d809b60b5780b87c) + +Related: #1827462 + +[msekleta: note that our default is not latest but rhel-8.0] +--- + doc/ENVIRONMENT.md | 15 +++++++------- + man/systemd-udevd.service.xml | 24 ++++++++++++--------- + meson.build | 4 ++++ + meson_options.txt | 3 +++ + src/udev/udev-builtin-net_id.c | 38 ++++++++++++++++++++-------------- + 5 files changed, 51 insertions(+), 33 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 1a4aa01ef4..0e763b6302 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -77,13 +77,14 @@ systemd-logind: + for it. + + * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of +- v238, v239, v240 …) as parameter. If specified udev's net_id builtin will +- follow the specified naming scheme when determining stable network interface +- names. This may be used to revert to naming schemes of older udev versions, +- in order to provide more stable naming across updates. This environment +- variable takes precedence over the kernel command line option +- `net.naming-scheme=`, except if the value is prefixed with `:` in which case +- the kernel command line option takes precedence, if it is specified as well. ++ "rhel-8.0", "rhel-8.1", "rhel-8.2"…, or the special value "latest") as ++ parameter. If specified udev's net_id builtin will follow the specified ++ naming scheme when determining stable network interface names. This may be ++ used to revert to naming schemes of older udev versions, in order to provide ++ more stable naming across updates. This environment variable takes precedence ++ over the kernel command line option `net.naming-scheme=`, except if the value ++ is prefixed with `:` in which case the kernel command line option takes ++ precedence, if it is specified as well. + + installed systemd tests: + +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index 6449103441..b738591c93 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -174,16 +174,20 @@ + net.naming-scheme= + + Network interfaces are renamed to give them predictable names when possible (unless +- net.ifnames=0 is specified, see above). The names are derived from various device metadata +- fields. Newer versions of systemd-udevd.service take more of these fields into account, +- improving (and thus possibly changing) the names used for the same devices. With this kernel command line +- option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as +- argument. Currently the following identifiers are known: v238, v239, +- v240 which each implement the naming scheme that was the default in the indicated systemd +- version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the +- naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated, +- previously missing attributes systemd-udevd.service is checking might appear, which +- affects older name derivation algorithms, too. ++ net.ifnames=0 is specified, see above). The names are derived from various ++ device metadata fields. Newer versions of systemd-udevd.service take more of ++ these fields into account, improving (and thus possibly changing) the names used for the same ++ devices. With this kernel command line option it is possible to pick a specific version of this ++ algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers ++ are known: rhel-8.0, rhel-8.1, rhel-8.2, ++ rhel-8.3 which each implement the naming scheme that was the default in the ++ indicated Red Hat Enterprise Linux minor version. In addition, latest may be ++ used to designate the latest scheme known (to this particular version of ++ systemd-udevd.service). ++ Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: ++ the naming is generally derived from driver attributes exposed by the kernel. As the kernel is ++ updated, previously missing attributes systemd-udevd.service is checking might ++ appear, which affects older name derivation algorithms, too. + + + +diff --git a/meson.build b/meson.build +index 65c1d0785e..57de947367 100644 +--- a/meson.build ++++ b/meson.build +@@ -639,6 +639,9 @@ else + conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL') + endif + ++default_net_naming_scheme = get_option('default-net-naming-scheme') ++conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme) ++ + time_epoch = get_option('time-epoch') + if time_epoch == '' + NEWS = files('NEWS') +@@ -2925,6 +2928,7 @@ status = [ + 'default DNSSEC mode: @0@'.format(default_dnssec), + 'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls), + 'default cgroup hierarchy: @0@'.format(default_hierarchy), ++ 'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme), + 'default KillUserProcesses setting: @0@'.format(kill_user_processes)] + + alt_dns_servers = '\n '.join(dns_servers.split(' ')) +diff --git a/meson_options.txt b/meson_options.txt +index 0996891177..213079ac15 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -158,6 +158,9 @@ option('default-hierarchy', type : 'combo', + description : 'default cgroup hierarchy') + option('time-epoch', type : 'string', + description : 'time epoch for time clients') ++option('default-net-naming-scheme', type : 'combo', ++ choices : ['rhel-8.0', 'rhel-8.1', 'rhel-8.2', 'rhel-8.3', 'latest'], ++ description : 'default net.naming-scheme= value') + option('system-uid-max', type : 'string', + description : 'maximum system UID') + option('system-gid-max', type : 'string', +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 148696183e..d85dc2848b 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -185,6 +185,19 @@ struct virtfn_info { + char suffix[IFNAMSIZ]; + }; + ++static const NamingScheme* naming_scheme_from_name(const char *name) { ++ size_t i; ++ ++ if (streq(name, "latest")) ++ return naming_schemes + ELEMENTSOF(naming_schemes) - 1; ++ ++ for (i = 0; i < ELEMENTSOF(naming_schemes); i++) ++ if (streq(naming_schemes[i].name, name)) ++ return naming_schemes + i; ++ ++ return NULL; ++} ++ + static const NamingScheme* naming_scheme(void) { + static const NamingScheme *cache = NULL; + _cleanup_free_ char *buffer = NULL; +@@ -208,25 +221,18 @@ static const NamingScheme* naming_scheme(void) { + k = buffer; + + if (k) { +- size_t i; +- +- for (i = 0; i < ELEMENTSOF(naming_schemes); i++) +- if (streq(naming_schemes[i].name, k)) { +- cache = naming_schemes + i; +- break; +- } ++ cache = naming_scheme_from_name(k); ++ if (cache) { ++ log_info("Using interface naming scheme '%s'.", cache->name); ++ return cache; ++ } + +- if (!cache) +- log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); ++ log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); + } + +- if (cache) +- log_info("Using interface naming scheme '%s'.", cache->name); +- else { +- /* RHEL-only: here we differ from the upstream and if no naming scheme was selected we default to naming from systemd-239 */ +- cache = &naming_schemes[2]; +- log_info("Using default interface naming scheme '%s'.", cache->name); +- } ++ cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME); ++ assert(cache); ++ log_info("Using default interface naming scheme '%s'.", cache->name); + + return cache; + } diff --git a/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch b/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch new file mode 100644 index 0000000..be9f964 --- /dev/null +++ b/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch @@ -0,0 +1,522 @@ +From af528dcffaab1efea760395cc6676fe4b01e89b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 9 May 2019 12:34:30 +0200 +Subject: [PATCH] man: describe naming schemes in a new man page + +I decided to make this a separate man page because it is freakin' long. +This content could equally well go in systemd-udevd.service(8), systemd.link(5), +or a new man page for the net_id builtin. + +v2: +- rename to systemd.net-naming-scheme +- add udevadm test-builtin net_id example + +(cherry picked from commit 0b1e5b6ed8c6b9a2bc53709eb75e381d360f05bf) + +Related: #1827462 + +[msekleta: I've removed parts that describe features which are not +available in RHEL-8] +--- + man/rules/meson.build | 1 + + man/systemd-udevd.service.xml | 19 +- + man/systemd.link.xml | 10 +- + man/systemd.net-naming-scheme.xml | 385 ++++++++++++++++++++++++++++++ + src/udev/udev-builtin-net_id.c | 1 + + 5 files changed, 402 insertions(+), 14 deletions(-) + create mode 100644 man/systemd.net-naming-scheme.xml + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 7ae94ea265..e6c0a99bbd 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -714,6 +714,7 @@ manpages = [ + ['systemd.kill', '5', [], ''], + ['systemd.link', '5', [], ''], + ['systemd.mount', '5', [], ''], ++ ['systemd.net-naming-scheme', '7', [], ''], + ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'], + ['systemd.network', '5', [], 'ENABLE_NETWORKD'], + ['systemd.nspawn', '5', [], ''], +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index b738591c93..f4cdb2f1e7 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -174,15 +174,11 @@ + net.naming-scheme= + + Network interfaces are renamed to give them predictable names when possible (unless +- net.ifnames=0 is specified, see above). The names are derived from various +- device metadata fields. Newer versions of systemd-udevd.service take more of +- these fields into account, improving (and thus possibly changing) the names used for the same +- devices. With this kernel command line option it is possible to pick a specific version of this +- algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers +- are known: rhel-8.0, rhel-8.1, rhel-8.2, +- rhel-8.3 which each implement the naming scheme that was the default in the +- indicated Red Hat Enterprise Linux minor version. In addition, latest may be +- used to designate the latest scheme known (to this particular version of ++ net.ifnames=0 is specified, see above). With this kernel command line option it ++ is possible to pick a specific version of this algorithm and override the default chosen at ++ compilation time. Expects one of the naming scheme identifiers listed in ++ systemd.net-naming-scheme7, ++ or latest to select the latest scheme known (to this particular version of + systemd-udevd.service). + Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: + the naming is generally derived from driver attributes exposed by the kernel. As the kernel is +@@ -191,9 +187,8 @@ + + + +- +- ++ ++ + + + See Also +diff --git a/man/systemd.link.xml b/man/systemd.link.xml +index 6708753e82..32657308d0 100644 +--- a/man/systemd.link.xml ++++ b/man/systemd.link.xml +@@ -286,6 +286,7 @@ + The name is set based on information given by + the firmware for on-board devices, as exported by the + udev property ID_NET_NAME_ONBOARD. ++ See systemd.net-naming-scheme7. + + + +@@ -295,6 +296,7 @@ + The name is set based on information given by + the firmware for hot-plug devices, as exported by the + udev property ID_NET_NAME_SLOT. ++ See systemd.net-naming-scheme7. + + + +@@ -303,7 +305,9 @@ + + The name is set based on the device's physical + location, as exported by the udev property +- ID_NET_NAME_PATH. ++ ID_NET_NAME_PATH. ++ See systemd.net-naming-scheme7. ++ + + + +@@ -311,7 +315,9 @@ + + The name is set based on the device's persistent + MAC address, as exported by the udev property +- ID_NET_NAME_MAC. ++ ID_NET_NAME_MAC. ++ See systemd.net-naming-scheme7. ++ + + + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +new file mode 100644 +index 0000000000..a12cc3c460 +--- /dev/null ++++ b/man/systemd.net-naming-scheme.xml +@@ -0,0 +1,385 @@ ++ ++ ++ ++ ++ ++ ++ systemd.net-naming-scheme ++ systemd ++ ++ ++ ++ systemd.net-naming-scheme ++ 7 ++ ++ ++ ++ systemd.net-naming-scheme ++ Network device naming schemes ++ ++ ++ ++ Description ++ ++ Network interfaces may be renamed to give them predictable names when there's enough information to ++ generate appropriate names and the use of certain types of names is configured. This page describes the ++ first part, i.e. what possible names may be generated. Those names are generated by the ++ systemd-udevd.service8 ++ builtin net_id and exported as udev properties ++ (ID_NET_NAME_ONBOARD=, ID_NET_LABEL_ONBOARD=, ++ ID_NET_NAME_PATH=, ID_NET_NAME_SLOT=). ++ ++ Names are derived from various device metadata attributes. Newer versions of udev take more of ++ these attributes into account, improving (and thus possibly changing) the names used for the same ++ devices. Differents version of the naming rules are called "naming schemes". The default naming scheme is ++ chosen at compilation time. Usually this will be the latest implemented version, but it is also possible ++ to set one of the older versions to preserve compatibility. This may be useful for example for ++ distributions, which may introduce new versions of systemd in stable releases without changing the naming ++ scheme. The naming scheme may also be overriden using the net.naming-scheme= kernel ++ command line switch, see ++ systemd-udevd.service8. ++ Available naming schemes are described below. ++ ++ After the udev proprties have been generated, appropriate udev rules may be used to actually rename ++ devices based on those properties. See the description of NamePolicy= in ++ systemd.link5. ++ ++ ++ ++ ++ Naming ++ ++ All names start with a two-character prefix that signifies the interface type. ++ ++ ++ Two character prefixes based on the type of interface ++ ++ ++ ++ ++ Prefix ++ Description ++ ++ ++ ++ ++ en ++ Ethernet ++ ++ ++ sl ++ serial line IP (slip) ++ ++ ++ wl ++ Wireless local area network (WLAN) ++ ++ ++ ww ++ Wireless wide area network (WWAN) ++ ++ ++ ++
++ ++ The udev net_id builtin exports the following udev device properties: ++ ++ ++ ++ ID_NET_NAME_ONBOARD=prefixonumber ++ ++ This name is set based on the ordering information given by the firmware for ++ on-board devices. The name consists of the prefix, letter o, and a number ++ specified by the firmware. This is only available for PCI devices. ++ ++ ++ ++ ++ ID_NET_LABEL_ONBOARD=prefix label ++ ++ This property is set based on label given by the firmware for on-board devices. The ++ name consists of the prefix concatenated with the label. This is only available for PCI devices. ++ ++ ++ ++ ++ ++ ID_NET_NAME_MAC=prefixxAABBCCDDEEFF ++ ++ This name consists of the prefix, letter x, and 12 hexadecimal ++ digits of the MAC address. It is available if the device has a fixed MAC address. Because this name ++ is based on an attribute of the card itself, it remains "stable" when the device is moved (even ++ between machines), but will change when the hardware is replaced. ++ ++ ++ ++ ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port] ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]bnumber ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]uport…[cconfig][iinterface] ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]vslot ++ ++ This property describes the slot position. Different schemes are used depending on ++ the bus type, as described in the table below. In all cases, PCI slot information must be known. In ++ case of USB, BCMA, and SR-VIO devices, the full name consists of the prefix, PCI slot identifier, ++ and USB or BCMA or SR-VIO slot identifier. The first two parts are denoted as "…" in the table ++ below. ++ ++ ++ Slot naming schemes ++ ++ ++ ++ ++ Format ++ Description ++ ++ ++ ++ ++ ++ prefix [Pdomainsslot [ffunction] [nport_name | ddev_port] ++ PCI slot number ++ ++ ++ ++ … bnumber ++ Broadcom bus (BCMA) core number ++ ++ ++ ++ … uport… [cconfig] [iinterface] ++ USB port number chain ++ ++ ++ ++ … vslot ++ SR-VIO slot number ++ ++ ++ ++
++ ++ The PCI domain is only prepended when it is not 0. All multi-function PCI devices will carry ++ the ffunction number in the device name, including ++ the function 0 device. For non-multi-function devices, the number is suppressed if 0. The port name ++ port_name is used, or the port number ++ ddev_port if the name is not known. ++ ++ For BCMA devices, the core number is suppressed when 0. ++ ++ For USB devices the full chain of port numbers of hubs is composed. If the name gets longer ++ than the maximum number of 15 characters, the name is not exported. The usual USB configuration ++ number 1 and interface number 0 values are suppressed. ++
++ ++ SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of ++ v and the virtual device number, with any leading zeros removed. The bus ++ number is ignored. This device type is found in IBM PowerVMs. ++
++ ++ ++ ID_NET_NAME_PATH=prefixcbus_id ++ ID_NET_NAME_PATH=prefixavendormodeliinstance ++ ID_NET_NAME_PATH=prefixiaddressnport_name ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port] ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port]bnumber ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port]uport…[cconfig][iinterface] ++ ++ This property describes the device installation location. Different schemes are ++ used depending on the bus type, as described in the table below. For BCMA and USB devices, PCI path ++ information must known, and the full name consists of the prefix, PCI slot identifier, and USB or ++ BCMA location. The first two parts are denoted as "…" in the table below. ++ ++ ++ Path naming schemes ++ ++ ++ ++ ++ Format ++ Description ++ ++ ++ ++ ++ ++ prefix cbus_id ++ CCW or grouped CCW device identifier ++ ++ ++ ++ prefix avendor model iinstance ++ ACPI path names for ARM64 platform devices ++ ++ ++ ++ prefix [Pdomainpbus sslot [ffunction] [nphys_port_name | ddev_port] ++ PCI geographical location ++ ++ ++ ++ … bnumber ++ Broadcom bus (BCMA) core number ++ ++ ++ ++ … uport… [cconfig] [iinterface] ++ USB port number chain ++ ++ ++ ++ ++
++ ++ CCW and grouped CCW devices are found in IBM System Z mainframes. Any leading zeros and ++ dots are suppressed. ++ ++ For PCI, BCMA, and USB devices, the same rules as described above for slot naming are ++ used. ++
++
++
++
++ ++ ++ History ++ ++ The following "naming schemes" have been defined: ++ ++ ++ ++ rhel-8.0 ++ ++ Naming was changed for virtual network interfaces created with SR-IOV and NPAR and ++ for devices where the PCI network controller device does not have a slot number associated. ++ ++ SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of ++ vport, where port is the ++ virtual device number. Previously those virtual devices were named as if completely independent. ++ ++ ++ The ninth and later NPAR virtual devices are named following the scheme used for the first ++ eight NPAR partitions. Previously those devices were not renamed and the kernel default ++ ("ethN") was used. ++ ++ Names are also generated for PCI devices where the PCI network controller device does not ++ have an associated slot number itself, but one of its parents does. Previously those devices were ++ not renamed and the kernel default was used. ++ ++ ++ ++ ++ rhel-8.1 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ ++ rhel-8.2 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ ++ rhel-8.3 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ Note that latest may be used to denote the latest scheme known (to this ++ particular version of systemd. ++ ++ ++ ++ ++ Examples ++ ++ ++ Using <command>udevadm test-builtin</command> to display device properties ++ ++ $ udevadm test-builtin net_id /sys/class/net/enp0s31f6 ++... ++Using default interface naming scheme 'rhel-8.3'. ++ID_NET_NAMING_SCHEME=rhel-8.3 ++ID_NET_NAME_MAC=enx54ee75cb1dc0 ++ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. ++ID_NET_NAME_PATH=enp0s31f6 ++... ++ ++ ++ ++ PCI Ethernet card with firmware index "1" ++ ++ ID_NET_NAME_ONBOARD=eno1 ++ID_NET_NAME_ONBOARD_LABEL=enEthernet Port 1 ++ ++ ++ ++ ++ ++ PCI Ethernet card in hotplug slot with firmware index number ++ ++ # /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1 ++ID_NET_NAME_MAC=enx000000000466 ++ID_NET_NAME_PATH=enp5s0 ++ID_NET_NAME_SLOT=ens1 ++ ++ ++ ++ PCI Ethernet multi-function card with 2 ports ++ ++ # /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0 ++ID_NET_NAME_MAC=enx78e7d1ea46da ++ID_NET_NAME_PATH=enp2s0f0 ++ ++# /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1 ++ID_NET_NAME_MAC=enx78e7d1ea46dc ++ID_NET_NAME_PATH=enp2s0f1 ++ ++ ++ ++ PCI WLAN card ++ ++ # /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0 ++ID_NET_NAME_MAC=wlx0024d7e31130 ++ID_NET_NAME_PATH=wlp3s0 ++ ++ ++ ++ USB built-in 3G modem ++ ++ # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6 ++ID_NET_NAME_MAC=wwx028037ec0200 ++ID_NET_NAME_PATH=wwp0s29u1u4i6 ++ ++ ++ ++ USB Android phone ++ ++ # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2 ++ID_NET_NAME_MAC=enxd626b3450fb5 ++ID_NET_NAME_PATH=enp0s29u1u2 ++ ++ ++ ++ s390 grouped CCW interface ++ ++ # /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0 ++ID_NET_NAME_MAC=enx026d3c00000a ++ID_NET_NAME_PATH=encf5f0 ++ ++ ++ ++ ++ See Also ++ ++ udev7, ++ udevadm8, ++ the ++ original page describing stable interface names ++ ++ ++ ++
+diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index d85dc2848b..aa553d5ade 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -78,6 +78,7 @@ + * /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0 + * ID_NET_NAME_MAC=enx026d3c00000a + * ID_NET_NAME_PATH=encf5f0 ++ * When the code here is changed, man/systemd.net-naming-scheme.xml must be updated too. + */ + + #include diff --git a/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch b/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch new file mode 100644 index 0000000..ea6dfa2 --- /dev/null +++ b/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch @@ -0,0 +1,51 @@ +From 462420bc7ea22a05bfc2d021d395aade2b8ee7dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 19 Oct 2020 10:56:11 +0200 +Subject: [PATCH] udev/net_id: parse _SUN ACPI index as a signed integer + +Negative value means there is no match between a PCI device and any of +the slots. In the following commit we will extend this and value of 0 +will indicate that there is a match between some slot and PCI device, +but that device is a PCI bridge. + +(cherry picked from commit 3e545ae5abcf258791eacbee60c829c100a33274) + +Related: #1827462 +--- + src/udev/udev-builtin-net_id.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index aa553d5ade..ede24dee41 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -391,7 +391,8 @@ static bool is_pci_ari_enabled(struct udev_device *dev) { + + static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + struct udev *udev = udev_device_get_udev(names->pcidev); +- unsigned domain, bus, slot, func, dev_port = 0, hotplug_slot = 0; ++ unsigned domain, bus, slot, func, dev_port = 0; ++ int hotplug_slot = -1; + size_t l; + char *s; + const char *attr, *port_name; +@@ -449,15 +450,15 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + hotplug_slot_dev = names->pcidev; + while (hotplug_slot_dev) { + FOREACH_DIRENT_ALL(dent, dir, break) { +- unsigned i; +- int r; ++ int i, r; + char str[PATH_MAX]; + _cleanup_free_ char *address = NULL; + + if (dent->d_name[0] == '.') + continue; +- r = safe_atou_full(dent->d_name, 10, &i); +- if (i < 1 || r < 0) ++ ++ r = safe_atoi(dent->d_name, &i); ++ if (r < 0 || i <= 0) + continue; + + if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && diff --git a/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch b/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch new file mode 100644 index 0000000..2bd2478 --- /dev/null +++ b/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch @@ -0,0 +1,124 @@ +From bb6114af097da0cd9c5081e42db718559130687f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 19 Oct 2020 11:10:31 +0200 +Subject: [PATCH] udev/net_id: don't generate slot based names if multiple + devices might claim the same slot + +(cherry picked from commit 2c8ec0095e6fd2e72879d4915ff8a9e5c0664d0b) + +Resolves: #1827462 +--- + man/systemd.net-naming-scheme.xml | 15 ++++++++++- + src/udev/udev-builtin-net_id.c | 41 ++++++++++++++++++++++++++----- + 2 files changed, 49 insertions(+), 7 deletions(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index a12cc3c460..10e71dcb15 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -176,7 +176,10 @@ + + SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of + v and the virtual device number, with any leading zeros removed. The bus +- number is ignored. This device type is found in IBM PowerVMs. ++ number is ignored. ++ ++ In some configurations a parent PCI bridge of a given network controller may be associated ++ with a slot. In such case we don't generate this device property to avoid possible naming conflicts. + + + +@@ -288,6 +291,16 @@ + Same as naming scheme rhel-8.0. + + ++ ++ rhel-8.4 ++ ++ If the PCI slot is assocated with PCI bridge and that has multiple child network ++ controllers then all of them might derive the same value of ID_NET_NAME_SLOT ++ property. That could cause naming conflict if the property is selected as a device name. Now, we detect the ++ situation, slot - bridge relation, and we don't produce the ID_NET_NAME_SLOT property to ++ avoid possible naming conflict. ++ ++ + Note that latest may be used to denote the latest scheme known (to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ede24dee41..d8c56b62bb 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -124,6 +124,7 @@ typedef enum NamingSchemeFlags { + /* First, the individual features */ + NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ + NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ ++ NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */ + + /* And now the masks that combine the features above */ + NAMING_V238 = 0, +@@ -132,6 +133,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_1 = NAMING_V239, + NAMING_RHEL_8_2 = NAMING_V239, + NAMING_RHEL_8_3 = NAMING_V239, ++ NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -389,6 +391,26 @@ static bool is_pci_ari_enabled(struct udev_device *dev) { + return streq_ptr(udev_device_get_sysattr_value(dev, "ari_enabled"), "1"); + } + ++static bool is_pci_bridge(struct udev_device *dev) { ++ const char *v, *p; ++ ++ v = udev_device_get_sysattr_value(dev, "modalias"); ++ if (!v) ++ return false; ++ ++ if (!startswith(v, "pci:")) ++ return false; ++ ++ p = strrchr(v, 's'); ++ if (!p) ++ return false; ++ if (p[1] != 'c') ++ return false; ++ ++ /* PCI device subclass 04 corresponds to PCI bridge */ ++ return strneq(p + 2, "04", 2); ++} ++ + static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + struct udev *udev = udev_device_get_udev(names->pcidev); + unsigned domain, bus, slot, func, dev_port = 0; +@@ -461,16 +483,23 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + if (r < 0 || i <= 0) + continue; + ++ /* match slot address with device by stripping the function */ + if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && +- read_one_line_file(str, &address) >= 0) +- /* match slot address with device by stripping the function */ +- if (startswith(udev_device_get_sysname(hotplug_slot_dev), address)) +- hotplug_slot = i; ++ read_one_line_file(str, &address) >= 0 && ++ startswith(udev_device_get_sysname(hotplug_slot_dev), address)) { ++ hotplug_slot = i; ++ ++ /* We found the match between PCI device and slot. However, we won't use the ++ * slot index if the device is a PCI bridge, because it can have other child ++ * devices that will try to claim the same index and that would create name ++ * collision. */ ++ if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev)) ++ hotplug_slot = 0; + +- if (hotplug_slot > 0) + break; ++ } + } +- if (hotplug_slot > 0) ++ if (hotplug_slot >= 0) + break; + rewinddir(dir); + hotplug_slot_dev = udev_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL); diff --git a/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch b/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch new file mode 100644 index 0000000..06f5f4c --- /dev/null +++ b/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch @@ -0,0 +1,25 @@ +From 573229efeb2c5ade25794deee8cfe2f967414ef7 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 6 Nov 2020 10:13:19 +0100 +Subject: [PATCH] fix typo in ProtectSystem= option + +This was introduced by commit d9ae3222cfbd5d2a48e6dbade6617085cc76f1c1 . + +Resolves: #1871139 +--- + units/systemd-resolved.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index aad1a53a5f..f10f1d1690 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -30,7 +30,7 @@ CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + PrivateTmp=yes + PrivateDevices=yes +-ProtectSystems=strict ++ProtectSystem=strict + ProtectHome=yes + ProtectControlGroups=yes + ProtectKernelTunables=yes diff --git a/SOURCES/0482-remove-references-of-non-existent-man-pages.patch b/SOURCES/0482-remove-references-of-non-existent-man-pages.patch new file mode 100644 index 0000000..31ae5e0 --- /dev/null +++ b/SOURCES/0482-remove-references-of-non-existent-man-pages.patch @@ -0,0 +1,34 @@ +From 5e74048399c4610da27b5f7fbbb53784030aeb70 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 9 Nov 2020 09:27:02 +0100 +Subject: [PATCH] remove references of non-existent man pages + +This is a follow-up to commit 8ad89170001c9aba8849630ddb5da81d9e24a1bc, +which introduced the man page change. + +Resolves: #1876807 +--- + man/systemd.special.xml | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/man/systemd.special.xml b/man/systemd.special.xml +index c9d4345016..fe6324a4a0 100644 +--- a/man/systemd.special.xml ++++ b/man/systemd.special.xml +@@ -657,16 +657,6 @@ + target unit and pull in the target from it, also with Requires=. Note that by default this + target unit is not part of the initial boot transaction, but is supposed to be pulled in only if required by + units that want to run only on successful boots. +- +- See +- systemd-boot-check-no-failures.service8 +- for a service that implements a generic system health check and orders itself before +- boot-complete.target. +- +- See +- systemd-bless-boot.service8 +- for a service that propagates boot success information to the boot loader, and orders itself after +- boot-complete.target. + + + diff --git a/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch b/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch new file mode 100644 index 0000000..72141ba --- /dev/null +++ b/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch @@ -0,0 +1,91 @@ +From b14c82dd9f9fcc42810614cf02efe8651897d36f Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 10 Jun 2020 20:19:41 +0200 +Subject: [PATCH] log: Prefer logging to CLI unless JOURNAL_STREAM is set + +(cherry picked from commit bc694c06e60505efeb09e5278a7b22cdfa23975e) + +Resolves: #1865840 +--- + src/basic/log.c | 32 +++++++++++++++++++++++++++++--- + test/TEST-21-SYSUSERS/test.sh | 3 +-- + 2 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/src/basic/log.c b/src/basic/log.c +index 48c094b548..9387e56a57 100644 +--- a/src/basic/log.c ++++ b/src/basic/log.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ + #include "sd-messages.h" + + #include "alloc-util.h" ++#include "extract-word.h" + #include "fd-util.h" + #include "format-util.h" + #include "io-util.h" +@@ -220,6 +222,32 @@ fail: + return r; + } + ++static bool stderr_is_journal(void) { ++ _cleanup_free_ char *w = NULL; ++ const char *e; ++ uint64_t dev, ino; ++ struct stat st; ++ ++ e = getenv("JOURNAL_STREAM"); ++ if (!e) ++ return false; ++ ++ if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0) ++ return false; ++ if (!e) ++ return false; ++ ++ if (safe_atou64(w, &dev) < 0) ++ return false; ++ if (safe_atou64(e, &ino) < 0) ++ return false; ++ ++ if (fstat(STDERR_FILENO, &st) < 0) ++ return false; ++ ++ return st.st_dev == dev && st.st_ino == ino; ++} ++ + int log_open(void) { + int r; + +@@ -239,9 +267,7 @@ int log_open(void) { + return 0; + } + +- if (log_target != LOG_TARGET_AUTO || +- getpid_cached() == 1 || +- isatty(STDERR_FILENO) <= 0) { ++ if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) { + + if (!prohibit_ipc && + IN_SET(log_target, LOG_TARGET_AUTO, +diff --git a/test/TEST-21-SYSUSERS/test.sh b/test/TEST-21-SYSUSERS/test.sh +index b1049e720d..3460d71f22 100755 +--- a/test/TEST-21-SYSUSERS/test.sh ++++ b/test/TEST-21-SYSUSERS/test.sh +@@ -108,8 +108,7 @@ test_run() { + echo "*** Running test $f" + prepare_testdir ${f%.input} + cp $f $TESTDIR/usr/lib/sysusers.d/test.conf +- systemd-sysusers --root=$TESTDIR 2> /dev/null +- journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err ++ systemd-sysusers --root=$TESTDIR 2>&1 | tail -n1 > $TESTDIR/tmp/err + if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then + echo "**** Unexpected error output for $f" + cat $TESTDIR/tmp/err diff --git a/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch b/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch new file mode 100644 index 0000000..902a685 --- /dev/null +++ b/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch @@ -0,0 +1,58 @@ +From f0d9e0cb24958bc11c8d83f0a3de651def2aa1d6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:30:56 +0200 +Subject: [PATCH] locale-util: add new helper locale_is_installed() + +This new helper checks whether the specified locale is installed. It's +distinct from locale_is_valid() which just superficially checks if a +string looks like something that could be a valid locale. + +Heavily inspired by @jsynacek's #13964. + +Replaces: #13964 +(cherry picked from commit 23fa786ca67ed3a32930ff1a7b175ac823db187c) + +Related: #1755287 +--- + src/basic/locale-util.c | 15 +++++++++++++++ + src/basic/locale-util.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c +index 7cd143ea6f..42ef309ebd 100644 +--- a/src/basic/locale-util.c ++++ b/src/basic/locale-util.c +@@ -204,6 +204,21 @@ bool locale_is_valid(const char *name) { + return true; + } + ++int locale_is_installed(const char *name) { ++ if (!locale_is_valid(name)) ++ return false; ++ ++ if (STR_IN_SET(name, "C", "POSIX")) /* These ones are always OK */ ++ return true; ++ ++ _cleanup_(freelocalep) locale_t loc = ++ newlocale(LC_ALL_MASK, name, 0); ++ if (loc == (locale_t) 0) ++ return errno == ENOMEM ? -ENOMEM : false; ++ ++ return true; ++} ++ + void init_gettext(void) { + setlocale(LC_ALL, ""); + textdomain(GETTEXT_PACKAGE); +diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h +index 368675f286..b40f9c641a 100644 +--- a/src/basic/locale-util.h ++++ b/src/basic/locale-util.h +@@ -31,6 +31,7 @@ typedef enum LocaleVariable { + + int get_locales(char ***l); + bool locale_is_valid(const char *name); ++int locale_is_installed(const char *name); + + #define _(String) gettext(String) + #define N_(String) String diff --git a/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch b/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch new file mode 100644 index 0000000..57abbe8 --- /dev/null +++ b/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch @@ -0,0 +1,53 @@ +From 3d08c7971a80370f60dd14b068779851e0f82c24 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:32:55 +0200 +Subject: [PATCH] test: add test case for locale_is_installed() + +(cherry picked from commit b45b0a69bb7ef3e6e66d443eae366b6d1c387cab) + +Related: #1755287 +--- + src/test/test-locale-util.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c +index 0c3f6a62ed..0d50c33ce5 100644 +--- a/src/test/test-locale-util.c ++++ b/src/test/test-locale-util.c +@@ -34,6 +34,28 @@ static void test_locale_is_valid(void) { + assert_se(!locale_is_valid("\x01gar\x02 bage\x03")); + } + ++static void test_locale_is_installed(void) { ++ log_info("/* %s */", __func__); ++ ++ /* Always available */ ++ assert_se(locale_is_installed("POSIX") > 0); ++ assert_se(locale_is_installed("C") > 0); ++ ++ /* Might, or might not be installed. */ ++ assert_se(locale_is_installed("en_EN.utf8") >= 0); ++ assert_se(locale_is_installed("fr_FR.utf8") >= 0); ++ assert_se(locale_is_installed("fr_FR@euro") >= 0); ++ assert_se(locale_is_installed("fi_FI") >= 0); ++ ++ /* Definitely not valid */ ++ assert_se(locale_is_installed("") == 0); ++ assert_se(locale_is_installed("/usr/bin/foo") == 0); ++ assert_se(locale_is_installed("\x01gar\x02 bage\x03") == 0); ++ ++ /* Definitely not installed */ ++ assert_se(locale_is_installed("zz_ZZ") == 0); ++} ++ + static void test_keymaps(void) { + _cleanup_strv_free_ char **kmaps = NULL; + char **p; +@@ -95,6 +117,7 @@ static void dump_special_glyphs(void) { + int main(int argc, char *argv[]) { + test_get_locales(); + test_locale_is_valid(); ++ test_locale_is_installed(); + test_keymaps(); + + dump_special_glyphs(); diff --git a/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch b/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch new file mode 100644 index 0000000..cb4ec8d --- /dev/null +++ b/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch @@ -0,0 +1,232 @@ +From 5813180a75aa1ef90f6d3459fc5beb099b815cfb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:32:44 +0200 +Subject: [PATCH] tree-wide: port various bits over to locale_is_installed() + +(cherry picked from commit a00a78b84e2ab352b3144bfae8bc578d172303be) + +Resolves: #1755287 +--- + src/firstboot/firstboot.c | 30 ++++++++------ + src/locale/localed.c | 87 ++++++++++++++++++++++++--------------- + 2 files changed, 71 insertions(+), 46 deletions(-) + +diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c +index a98e53b3a3..7e177a50fa 100644 +--- a/src/firstboot/firstboot.c ++++ b/src/firstboot/firstboot.c +@@ -192,6 +192,14 @@ static int prompt_loop(const char *text, char **l, bool (*is_valid)(const char * + } + } + ++static bool locale_is_ok(const char *name) { ++ ++ if (arg_root) ++ return locale_is_valid(name); ++ ++ return locale_is_installed(name) > 0; ++} ++ + static int prompt_locale(void) { + _cleanup_strv_free_ char **locales = NULL; + int r; +@@ -215,14 +223,14 @@ static int prompt_locale(void) { + + putchar('\n'); + +- r = prompt_loop("Please enter system locale name or number", locales, locale_is_valid, &arg_locale); ++ r = prompt_loop("Please enter system locale name or number", locales, locale_is_ok, &arg_locale); + if (r < 0) + return r; + + if (isempty(arg_locale)) + return 0; + +- r = prompt_loop("Please enter system message locale name or number", locales, locale_is_valid, &arg_locale_messages); ++ r = prompt_loop("Please enter system message locale name or number", locales, locale_is_ok, &arg_locale_messages); + if (r < 0) + return r; + +@@ -780,11 +788,6 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_LOCALE: +- if (!locale_is_valid(optarg)) { +- log_error("Locale %s is not valid.", optarg); +- return -EINVAL; +- } +- + r = free_and_strdup(&arg_locale, optarg); + if (r < 0) + return log_oom(); +@@ -792,11 +795,6 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_LOCALE_MESSAGES: +- if (!locale_is_valid(optarg)) { +- log_error("Locale %s is not valid.", optarg); +- return -EINVAL; +- } +- + r = free_and_strdup(&arg_locale_messages, optarg); + if (r < 0) + return log_oom(); +@@ -922,6 +920,14 @@ static int parse_argv(int argc, char *argv[]) { + assert_not_reached("Unhandled option"); + } + ++ /* We check if the specified locale strings are valid down here, so that we can take --root= into ++ * account when looking for the locale files. */ ++ ++ if (arg_locale && !locale_is_ok(arg_locale)) ++ return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale); ++ if (arg_locale_messages && !locale_is_ok(arg_locale_messages)) ++ return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale_messages); ++ + return 1; + } + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index 253973fd49..d6ed40babe 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -259,18 +259,57 @@ static void locale_free(char ***l) { + (*l)[p] = mfree((*l)[p]); + } + ++static int process_locale_list_item( ++ const char *assignment, ++ char *new_locale[static _VARIABLE_LC_MAX], ++ sd_bus_error *error) { ++ ++ assert(assignment); ++ assert(new_locale); ++ ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) { ++ const char *name, *e; ++ ++ assert_se(name = locale_variable_to_string(p)); ++ ++ e = startswith(assignment, name); ++ if (!e) ++ continue; ++ ++ if (*e != '=') ++ continue; ++ ++ e++; ++ ++ if (!locale_is_valid(e)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s is not valid, refusing.", e); ++ if (locale_is_installed(e) <= 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s not installed, refusing.", e); ++ if (new_locale[p]) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name); ++ ++ new_locale[p] = strdup(e); ++ if (!new_locale[p]) ++ return -ENOMEM; ++ ++ return 0; ++ } ++ ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment); ++} ++ + static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) { + Context *c = userdata; + _cleanup_strv_free_ char **settings = NULL, **l = NULL; + char *new_locale[_VARIABLE_LC_MAX] = {}, **i; + _cleanup_(locale_free) _unused_ char **dummy = new_locale; + bool modified = false; +- int interactive, p, r; ++ int interactive, r; + + assert(m); + assert(c); + +- r = bus_message_read_strv_extend(m, &l); ++ r = sd_bus_message_read_strv(m, &l); + if (r < 0) + return r; + +@@ -279,11 +318,13 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + return r; + + /* If single locale without variable name is provided, then we assume it is LANG=. */ +- if (strv_length(l) == 1 && !strchr(*l, '=')) { +- if (!locale_is_valid(*l)) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); ++ if (strv_length(l) == 1 && !strchr(l[0], '=')) { ++ if (!locale_is_valid(l[0])) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid locale specification: %s", l[0]); ++ if (locale_is_installed(l[0]) <= 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified locale is not installed: %s", l[0]); + +- new_locale[VARIABLE_LANG] = strdup(*l); ++ new_locale[VARIABLE_LANG] = strdup(l[0]); + if (!new_locale[VARIABLE_LANG]) + return -ENOMEM; + +@@ -292,31 +333,9 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + + /* Check whether a variable is valid */ + STRV_FOREACH(i, l) { +- bool valid = false; +- +- for (p = 0; p < _VARIABLE_LC_MAX; p++) { +- size_t k; +- const char *name; +- +- name = locale_variable_to_string(p); +- assert(name); +- +- k = strlen(name); +- if (startswith(*i, name) && +- (*i)[k] == '=' && +- locale_is_valid((*i) + k + 1)) { +- valid = true; +- +- new_locale[p] = strdup((*i) + k + 1); +- if (!new_locale[p]) +- return -ENOMEM; +- +- break; +- } +- } +- +- if (!valid) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); ++ r = process_locale_list_item(*i, new_locale, error); ++ if (r < 0) ++ return r; + } + + /* If LANG was specified, but not LANGUAGE, check if we should +@@ -339,7 +358,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + } + + /* Merge with the current settings */ +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + if (!isempty(c->locale[p]) && isempty(new_locale[p])) { + new_locale[p] = strdup(c->locale[p]); + if (!new_locale[p]) +@@ -348,7 +367,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + + locale_simplify(new_locale); + +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + if (!streq_ptr(c->locale[p], new_locale[p])) { + modified = true; + break; +@@ -373,7 +392,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + free_and_replace(c->locale[p], new_locale[p]); + + r = locale_write_data(c, &settings); diff --git a/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch b/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch new file mode 100644 index 0000000..363f424 --- /dev/null +++ b/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch @@ -0,0 +1,339 @@ +From 4c41ad9418058aefb2d2732b0b65da9c7cdf5151 Mon Sep 17 00:00:00 2001 +From: Ruixin Bao +Date: Tue, 21 Aug 2018 20:40:56 +0000 +Subject: [PATCH] install: allow instantiated units to be enabled via presets + +This patch implements https://github.com/systemd/systemd/issues/9421. + +The .preset file now is able to take a rule in the format of:(e.g) +enable foo@.service bar0 bar1 bar2 + +In the above example, when preset-all is called, all three instances of +foo@bar0.service, foo@bar1.service and foo@bar2.service will be enabled. + +When preset is called on a single service(e.g: foo@bar1.service), only +the mentioned one(foo@bar1.service) will be enabled. + +Tests are added for future regression. + +(cherry picked from commit 4c9565eea534cd233a913c8c21f7920dba229743) + +Resolves: #1812972 +--- + src/shared/install.c | 155 ++++++++++++++++++++++++++++++----- + src/test/test-install-root.c | 57 +++++++++++++ + 2 files changed, 193 insertions(+), 19 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 77ae812878..1d4beaa83b 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -60,6 +60,7 @@ typedef enum { + typedef struct { + char *pattern; + PresetAction action; ++ char **instances; + } PresetRule; + + typedef struct { +@@ -87,8 +88,10 @@ static inline void presets_freep(Presets *p) { + if (!p) + return; + +- for (i = 0; i < p->n_rules; i++) ++ for (i = 0; i < p->n_rules; i++) { + free(p->rules[i].pattern); ++ strv_free(p->rules[i].instances); ++ } + + free(p->rules); + p->n_rules = 0; +@@ -2755,6 +2758,39 @@ int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char * + return 1; + } + ++static int split_pattern_into_name_and_instances(const char *pattern, char **out_unit_name, char ***out_instances) { ++ _cleanup_strv_free_ char **instances = NULL; ++ _cleanup_free_ char *unit_name = NULL; ++ int r; ++ ++ assert(pattern); ++ assert(out_instances); ++ assert(out_unit_name); ++ ++ r = extract_first_word(&pattern, &unit_name, NULL, 0); ++ if (r < 0) ++ return r; ++ ++ /* We handle the instances logic when unit name is extracted */ ++ if (pattern) { ++ /* We only create instances when a rule of templated unit ++ * is seen. A rule like enable foo@.service a b c will ++ * result in an array of (a, b, c) as instance names */ ++ if (!unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) ++ return -EINVAL; ++ ++ instances = strv_split(pattern, WHITESPACE); ++ if (!instances) ++ return -ENOMEM; ++ ++ *out_instances = TAKE_PTR(instances); ++ } ++ ++ *out_unit_name = TAKE_PTR(unit_name); ++ ++ return 0; ++} ++ + static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) { + _cleanup_(presets_freep) Presets ps = {}; + size_t n_allocated = 0; +@@ -2824,15 +2860,20 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres + + parameter = first_word(l, "enable"); + if (parameter) { +- char *pattern; ++ char *unit_name; ++ char **instances = NULL; + +- pattern = strdup(parameter); +- if (!pattern) +- return -ENOMEM; ++ /* Unit_name will remain the same as parameter when no instances are specified */ ++ r = split_pattern_into_name_and_instances(parameter, &unit_name, &instances); ++ if (r < 0) { ++ log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line); ++ continue; ++ } + + rule = (PresetRule) { +- .pattern = pattern, ++ .pattern = unit_name, + .action = PRESET_ENABLE, ++ .instances = instances, + }; + } + +@@ -2868,15 +2909,71 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres + return 0; + } + +-static int query_presets(const char *name, const Presets presets) { ++static int pattern_match_multiple_instances( ++ const PresetRule rule, ++ const char *unit_name, ++ char ***ret) { ++ ++ _cleanup_free_ char *templated_name = NULL; ++ int r; ++ ++ /* If no ret is needed or the rule itself does not have instances ++ * initalized, we return not matching */ ++ if (!ret || !rule.instances) ++ return 0; ++ ++ r = unit_name_template(unit_name, &templated_name); ++ if (r < 0) ++ return r; ++ if (!streq(rule.pattern, templated_name)) ++ return 0; ++ ++ /* Compose a list of specified instances when unit name is a template */ ++ if (unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { ++ _cleanup_free_ char *prefix = NULL; ++ _cleanup_strv_free_ char **out_strv = NULL; ++ char **iter; ++ ++ r = unit_name_to_prefix(unit_name, &prefix); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH(iter, rule.instances) { ++ _cleanup_free_ char *name = NULL; ++ r = unit_name_build(prefix, *iter, ".service", &name); ++ if (r < 0) ++ return r; ++ r = strv_extend(&out_strv, name); ++ if (r < 0) ++ return r; ++ } ++ ++ *ret = TAKE_PTR(out_strv); ++ return 1; ++ } else { ++ /* We now know the input unit name is an instance name */ ++ _cleanup_free_ char *instance_name = NULL; ++ ++ r = unit_name_to_instance(unit_name, &instance_name); ++ if (r < 0) ++ return r; ++ ++ if (strv_find(rule.instances, instance_name)) ++ return 1; ++ } ++ return 0; ++} ++ ++static int query_presets(const char *name, const Presets presets, char ***instance_name_list) { + PresetAction action = PRESET_UNKNOWN; + size_t i; +- ++ char **s; + if (!unit_name_is_valid(name, UNIT_NAME_ANY)) + return -EINVAL; + + for (i = 0; i < presets.n_rules; i++) +- if (fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) { ++ if (pattern_match_multiple_instances(presets.rules[i], name, instance_name_list) > 0 || ++ fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) { + action = presets.rules[i].action; + break; + } +@@ -2886,7 +2983,11 @@ static int query_presets(const char *name, const Presets presets) { + log_debug("Preset files don't specify rule for %s. Enabling.", name); + return 1; + case PRESET_ENABLE: +- log_debug("Preset files say enable %s.", name); ++ if (instance_name_list && *instance_name_list) ++ STRV_FOREACH(s, *instance_name_list) ++ log_debug("Preset files say enable %s.", *s); ++ else ++ log_debug("Preset files say enable %s.", name); + return 1; + case PRESET_DISABLE: + log_debug("Preset files say disable %s.", name); +@@ -2904,7 +3005,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char + if (r < 0) + return r; + +- return query_presets(name, presets); ++ return query_presets(name, presets, NULL); + } + + static int execute_preset( +@@ -2964,6 +3065,7 @@ static int preset_prepare_one( + size_t *n_changes) { + + _cleanup_(install_context_done) InstallContext tmp = {}; ++ _cleanup_strv_free_ char **instance_name_list = NULL; + UnitFileInstallInfo *i; + int r; + +@@ -2979,19 +3081,34 @@ static int preset_prepare_one( + return 0; + } + +- r = query_presets(name, presets); ++ r = query_presets(name, presets, &instance_name_list); + if (r < 0) + return r; + + if (r > 0) { +- r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; ++ if (instance_name_list) { ++ char **s; ++ STRV_FOREACH(s, instance_name_list) { ++ r = install_info_discover(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ r = install_info_may_process(i, paths, changes, n_changes); ++ if (r < 0) ++ return r; ++ } ++ } else { ++ r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ r = install_info_may_process(i, paths, changes, n_changes); ++ if (r < 0) ++ return r; ++ } + +- r = install_info_may_process(i, paths, changes, n_changes); +- if (r < 0) +- return r; + } else + r = install_info_discover(scope, minus, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS, + &i, changes, n_changes); +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index 15dd3c6966..dbbcfe4297 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -983,6 +983,62 @@ static void test_with_dropin_template(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + } + ++static void test_preset_multiple_instances(const char *root) { ++ UnitFileChange *changes = NULL; ++ size_t n_changes = 0; ++ const char *p; ++ UnitFileState state; ++ ++ /* Set up template service files and preset file */ ++ p = strjoina(root, "/usr/lib/systemd/system/foo@.service"); ++ assert_se(write_string_file(p, ++ "[Install]\n" ++ "DefaultInstance=def\n" ++ "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset"); ++ assert_se(write_string_file(p, ++ "enable foo@.service bar0 bar1 bartest\n" ++ "enable emptylist@.service\n" /* This line ensures the old functionality for templated unit still works */ ++ "disable *\n" , WRITE_STRING_FILE_CREATE) >= 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ /* Preset a single instantiated unit specified in the list */ ++ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(n_changes == 1); ++ assert_se(changes[0].type == UNIT_FILE_SYMLINK); ++ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); ++ assert_se(streq(changes[0].path, p)); ++ unit_file_changes_free(changes, n_changes); ++ changes = NULL; n_changes = 0; ++ ++ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0); ++ assert_se(n_changes == 1); ++ assert_se(changes[0].type == UNIT_FILE_UNLINK); ++ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); ++ assert_se(streq(changes[0].path, p)); ++ unit_file_changes_free(changes, n_changes); ++ changes = NULL; n_changes = 0; ++ ++ /* Check for preset-all case, only instances on the list should be enabled, not including the default instance */ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); ++ assert_se(n_changes > 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ ++} ++ + int main(int argc, char *argv[]) { + char root[] = "/tmp/rootXXXXXX"; + const char *p; +@@ -1012,6 +1068,7 @@ int main(int argc, char *argv[]) { + test_indirect(root); + test_preset_and_list(root); + test_preset_order(root); ++ test_preset_multiple_instances(root); + test_revert(root); + test_static_instance(root); + test_with_dropin(root); diff --git a/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch b/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch new file mode 100644 index 0000000..68e7ae2 --- /dev/null +++ b/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch @@ -0,0 +1,127 @@ +From eacb511fc0d1e3c5857cb041ad162fb78b4381cc Mon Sep 17 00:00:00 2001 +From: Ruixin Bao +Date: Sun, 26 Aug 2018 20:00:03 +0000 +Subject: [PATCH] install: small refactor to combine two function calls into + one function + +Combine consecutive function calls of install_info_discover and +install_info_may_process into one short helper function. + +(cherry picked from commit 1e475a0ab4c46eb07f3df3fb24f5a7c3e1fa20b1) + +Related: #1812972 +--- + src/shared/install.c | 61 ++++++++++++++++++++++---------------------- + 1 file changed, 30 insertions(+), 31 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 1d4beaa83b..263b239f10 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1676,6 +1676,25 @@ static int install_info_discover( + return r; + } + ++static int install_info_discover_and_check( ++ UnitFileScope scope, ++ InstallContext *c, ++ const LookupPaths *paths, ++ const char *name, ++ SearchFlags flags, ++ UnitFileInstallInfo **ret, ++ UnitFileChange **changes, ++ size_t *n_changes) { ++ ++ int r; ++ ++ r = install_info_discover(scope, c, paths, name, flags, ret, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ return install_info_may_process(ret ? *ret : NULL, paths, changes, n_changes); ++} ++ + static int install_info_symlink_alias( + UnitFileInstallInfo *i, + const LookupPaths *paths, +@@ -2399,11 +2418,8 @@ int unit_file_add_dependency( + if (!config_path) + return -ENXIO; + +- r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &target_info, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(target_info, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &target_info, changes, n_changes); + if (r < 0) + return r; + +@@ -2412,11 +2428,8 @@ int unit_file_add_dependency( + STRV_FOREACH(f, files) { + char ***l; + +- r = install_info_discover(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + +@@ -2467,11 +2480,8 @@ int unit_file_enable( + return -ENXIO; + + STRV_FOREACH(f, files) { +- r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + +@@ -2585,10 +2595,7 @@ int unit_file_set_default( + if (r < 0) + return r; + +- r = install_info_discover(scope, &c, &paths, name, 0, &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, name, 0, &i, changes, n_changes); + if (r < 0) + return r; + +@@ -3089,22 +3096,14 @@ static int preset_prepare_one( + if (instance_name_list) { + char **s; + STRV_FOREACH(s, instance_name_list) { +- r = install_info_discover(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- +- r = install_info_may_process(i, paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + } + } else { +- r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- +- r = install_info_may_process(i, paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + } diff --git a/SOURCES/0489-test-fix-a-memleak.patch b/SOURCES/0489-test-fix-a-memleak.patch new file mode 100644 index 0000000..d01dea9 --- /dev/null +++ b/SOURCES/0489-test-fix-a-memleak.patch @@ -0,0 +1,28 @@ +From 7444c6ed3628484dfed2f204c5b78a06a50f4bd8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 29 Aug 2018 23:27:42 +0900 +Subject: [PATCH] test: fix a memleak + +Follow-up for #9901. + +Fixes #9968. + +(cherry picked from commit efa146369398fdb73f1cd177eb2522822ebf559c) + +Related: #1812972 +--- + src/test/test-install-root.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index dbbcfe4297..fe1ca5b16f 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -1037,6 +1037,7 @@ static void test_preset_multiple_instances(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + ++ unit_file_changes_free(changes, n_changes); + } + + int main(int argc, char *argv[]) { diff --git a/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch b/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch new file mode 100644 index 0000000..2f726d0 --- /dev/null +++ b/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch @@ -0,0 +1,55 @@ +From 55df2fd634f900419b718ed354132cc86cd533dd Mon Sep 17 00:00:00 2001 +From: Joerg Behrmann +Date: Tue, 10 Mar 2020 16:34:13 +0100 +Subject: [PATCH] docs: Add syntax for templated units to systemd.preset man + page + +This documents the syntax + + enable template@.service foo bar baz + +that was introduced in #9901 to preset templated units. + +(cherry picked from commit 1f667d8a7cff4355cd23ebebeb4d7179e3498eb8) + +Related: #1812972 +--- + man/systemd.preset.xml | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml +index cf807bd4c8..df401f00f3 100644 +--- a/man/systemd.preset.xml ++++ b/man/systemd.preset.xml +@@ -71,8 +71,11 @@ + either the word enable or + disable followed by a space and a unit name + (possibly with shell style wildcards), separated by newlines. +- Empty lines and lines whose first non-whitespace character is # or +- ; are ignored. ++ Empty lines and lines whose first non-whitespace character is # or ++ ; are ignored. Multiple instance names for unit ++ templates may be specified as a space separated list at the end of ++ the line instead of the customary position between @ ++ and the unit suffix. + + Presets must refer to the "real" unit file, and not to any aliases. See + systemd.unit5 +@@ -124,6 +127,17 @@ disable * + 99-, it will be read last and hence can easily + be overridden by spin or administrator preset policy. + ++ ++ Enable multiple template instances ++ ++ # /usr/lib/systemd/system-preset/80-dirsrv.preset ++ ++enable dirsrv@.service foo bar baz ++ ++ ++ This enables all three of dirsrv@foo.service, ++ dirsrv@bar.service and dirsrv@baz.service. ++ + + A GNOME spin + diff --git a/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch b/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch new file mode 100644 index 0000000..ea936c9 --- /dev/null +++ b/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch @@ -0,0 +1,45 @@ +From db2816ee32fc81ba339175469e46b5dca7af8833 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 22 Aug 2020 11:58:15 +0200 +Subject: [PATCH] shared/install: fix preset operations for non-service + instantiated units + +Fixes https://github.com/coreos/ignition/issues/1064. + +(cherry picked from commit 47ab95fe4315b3f7ee5a3694460a744bb88c52fd) + +Related: #1812972 +--- + src/shared/install.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 263b239f10..c2847df3f8 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -2937,20 +2937,17 @@ static int pattern_match_multiple_instances( + + /* Compose a list of specified instances when unit name is a template */ + if (unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { +- _cleanup_free_ char *prefix = NULL; + _cleanup_strv_free_ char **out_strv = NULL; +- char **iter; +- +- r = unit_name_to_prefix(unit_name, &prefix); +- if (r < 0) +- return r; + ++ char **iter; + STRV_FOREACH(iter, rule.instances) { + _cleanup_free_ char *name = NULL; +- r = unit_name_build(prefix, *iter, ".service", &name); ++ ++ r = unit_name_replace_instance(unit_name, *iter, &name); + if (r < 0) + return r; +- r = strv_extend(&out_strv, name); ++ ++ r = strv_consume(&out_strv, TAKE_PTR(name)); + if (r < 0) + return r; + } diff --git a/SOURCES/0492-introduce-setsockopt_int-helper.patch b/SOURCES/0492-introduce-setsockopt_int-helper.patch new file mode 100644 index 0000000..7991184 --- /dev/null +++ b/SOURCES/0492-introduce-setsockopt_int-helper.patch @@ -0,0 +1,30 @@ +From 8cff80d7fc28ca04bd6c8e2257b46d96bea338ce Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 18 Oct 2018 19:48:18 +0200 +Subject: [PATCH] introduce setsockopt_int() helper + +As suggested by @heftig: + +https://github.com/systemd/systemd/commit/6d5e65f6454212cd400d0ebda34978a9f20cc26a#commitcomment-30938667 +(cherry picked from commit 2ff48e981e6cd1ccbfae49943274d9c8319a5e5d) + +Related: #1887181 +--- + src/basic/socket-util.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 82781a0de1..616f2e0d05 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -183,3 +183,10 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng + }) + + int socket_ioctl_fd(void); ++ ++static inline int setsockopt_int(int fd, int level, int optname, int value) { ++ if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0) ++ return -errno; ++ ++ return 0; ++} diff --git a/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch b/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch new file mode 100644 index 0000000..aa0679b --- /dev/null +++ b/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch @@ -0,0 +1,57 @@ +From 96681723232e9eb0182279086fef291283004806 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:27:51 +0200 +Subject: [PATCH] socket-util: add generic socket_pass_pktinfo() helper + +The helper turns on the protocol specific "packet info" structure cmsg +for three relevant protocols we know. + +(cherry picked from commit 35a3eb9bdc95d1e6ba25bc65c78959ea104e45a1) + +Related: #1887181 +--- + src/basic/socket-util.c | 23 +++++++++++++++++++++++ + src/basic/socket-util.h | 2 ++ + 2 files changed, 25 insertions(+) + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index 986bc6e67f..053bcba670 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -1246,3 +1246,26 @@ int socket_ioctl_fd(void) { + + return fd; + } ++ ++int socket_pass_pktinfo(int fd, bool b) { ++ int af; ++ socklen_t sl = sizeof(af); ++ ++ if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0) ++ return -errno; ++ ++ switch (af) { ++ ++ case AF_INET: ++ return setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, b); ++ ++ case AF_INET6: ++ return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, b); ++ ++ case AF_NETLINK: ++ return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b); ++ ++ default: ++ return -EAFNOSUPPORT; ++ } ++} +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 616f2e0d05..c7c9ad34d6 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -190,3 +190,5 @@ static inline int setsockopt_int(int fd, int level, int optname, int value) { + + return 0; + } ++ ++int socket_pass_pktinfo(int fd, bool b); diff --git a/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch b/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch new file mode 100644 index 0000000..561e77c --- /dev/null +++ b/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch @@ -0,0 +1,156 @@ +From 905a97ce65352d80af7260d34b74fd8342792c35 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:36:56 +0200 +Subject: [PATCH] core: add new PassPacketInfo= socket unit property + +(cherry picked from commit a3d19f5d99c44940831a33df8b5bece4aaf749f7) + +Resolves: #1887181 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.socket.xml | 9 +++++++++ + src/core/dbus-socket.c | 4 ++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/socket.c | 8 ++++++++ + src/core/socket.h | 1 + + src/shared/bus-unit-util.c | 3 +-- + test/fuzz/fuzz-unit-file/directives.service | 1 + + 8 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 995b8797ef..de0ef9cc49 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -410,6 +410,7 @@ Most socket unit settings are available to transient units. + ✓ Broadcast= + ✓ PassCredentials= + ✓ PassSecurity= ++✓ PassPacketInfo= + ✓ TCPCongestion= + ✓ ReusePort= + ✓ MessageQueueMaxMessages= +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index 8676b4e03f..a908d5b6d8 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -712,6 +712,15 @@ + Defaults to . + + ++ ++ PassPacketInfo= ++ Takes a boolean value. This controls the IP_PKTINFO, ++ IPV6_RECVPKTINFO and NETLINK_PKTINFO socket options, which ++ enable reception of additional per-packet metadata as ancillary message, on ++ AF_INET, AF_INET6 and AF_UNIX sockets. ++ Defaults to . ++ ++ + + TCPCongestion= + Takes a string value. Controls the TCP +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index fa6bbe2c6f..17494b80c8 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -104,6 +104,7 @@ const sd_bus_vtable bus_socket_vtable[] = { + SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -205,6 +206,9 @@ static int bus_socket_set_transient_property( + if (streq(name, "PassSecurity")) + return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error); + ++ if (streq(name, "PassPacketInfo")) ++ return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error); ++ + if (streq(name, "ReusePort")) + return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error); + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 156a4d0a6d..7d683cc84b 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -381,6 +381,7 @@ Socket.Transparent, config_parse_bool, 0, + Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast) + Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred) + Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec) ++Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo) + Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion) + Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port) + Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg) +diff --git a/src/core/socket.c b/src/core/socket.c +index 97c3a7fc9a..50c32ed8f4 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -660,6 +660,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + "%sBroadcast: %s\n" + "%sPassCredentials: %s\n" + "%sPassSecurity: %s\n" ++ "%sPassPacketInfo: %s\n" + "%sTCPCongestion: %s\n" + "%sRemoveOnStop: %s\n" + "%sWritable: %s\n" +@@ -678,6 +679,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + prefix, yes_no(s->broadcast), + prefix, yes_no(s->pass_cred), + prefix, yes_no(s->pass_sec), ++ prefix, yes_no(s->pass_pktinfo), + prefix, strna(s->tcp_congestion), + prefix, yes_no(s->remove_on_stop), + prefix, yes_no(s->writable), +@@ -1099,6 +1101,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { + log_unit_warning_errno(UNIT(s), errno, "SO_PASSSEC failed: %m"); + } + ++ if (s->pass_pktinfo) { ++ r = socket_pass_pktinfo(fd, true); ++ if (r < 0) ++ log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m"); ++ } ++ + if (s->priority >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0) + log_unit_warning_errno(UNIT(s), errno, "SO_PRIORITY failed: %m"); +diff --git a/src/core/socket.h b/src/core/socket.h +index b7a25d91fd..2409dbf2a0 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -121,6 +121,7 @@ struct Socket { + bool broadcast; + bool pass_cred; + bool pass_sec; ++ bool pass_pktinfo; + + /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ + SocketAddressBindIPv6Only bind_ipv6_only; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index daa2c2dce5..9010448aaf 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -1478,8 +1478,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons + if (STR_IN_SET(field, + "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast", + "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet", +- "FlushPending")) +- ++ "FlushPending", "PassPacketInfo")) + return bus_append_parse_boolean(m, field, eq); + + if (STR_IN_SET(field, "Priority", "IPTTL", "Mark")) +diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +index 9d0530df72..8fde27fc90 100644 +--- a/test/fuzz/fuzz-unit-file/directives.service ++++ b/test/fuzz/fuzz-unit-file/directives.service +@@ -161,6 +161,7 @@ PIDFile= + PartOf= + PassCredentials= + PassSecurity= ++PassPacketInfo= + PathChanged= + PathExists= + PathExistsGlob= diff --git a/SOURCES/0495-resolved-tweak-cmsg-calculation.patch b/SOURCES/0495-resolved-tweak-cmsg-calculation.patch new file mode 100644 index 0000000..5ce13b6 --- /dev/null +++ b/SOURCES/0495-resolved-tweak-cmsg-calculation.patch @@ -0,0 +1,30 @@ +From 6ece87bef14ac5741fc870644504737b00607546 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:38:38 +0200 +Subject: [PATCH] resolved: tweak cmsg calculation + +We ask for the TTL, then have enough space for it. + +We probably can drop the extra cmsg space now, but let's figure that out +another time, since the extra cmsg space is used elsewhere in resolved +as well. + +(cherry picked from commit 08ab18618ec59022582f1513c0718ba369f5ba85) + +Related: #1887181 +--- + src/resolve/resolved-dns-stream.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index 066daef96e..555e200a23 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -70,6 +70,7 @@ static int dns_stream_identify(DnsStream *s) { + union { + struct cmsghdr header; /* For alignment */ + uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo)) ++ + CMSG_SPACE(int) + /* for the TTL */ + + EXTRA_CMSG_SPACE /* kernel appears to require extra space */]; + } control; + struct msghdr mh = {}; diff --git a/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch b/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch new file mode 100644 index 0000000..cd054ce --- /dev/null +++ b/SOURCES/0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch @@ -0,0 +1,26 @@ +From 07b154fbc817e93f58c597644570a633c38d1c72 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 12:51:02 +0100 +Subject: [PATCH] ci: PowerTools repo was renamed to powertools in RHEL 8.3 + +See: https://wiki.centos.org/Manuals/ReleaseNotes/CentOS8.2011#Yum_repo_file_and_repoid_changes + +rhel-only +Related: #1871827 +--- + ci/travis-centos-rhel8.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index cd0857fd29..43e2cb2585 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -95,7 +95,7 @@ for phase in "${PHASES[@]}"; do + # Upgrade the container to get the most recent environment + $DOCKER_EXEC dnf -y upgrade + # Install systemd's build dependencies +- $DOCKER_EXEC dnf -q -y --enablerepo "PowerTools" builddep systemd ++ $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd + ;; + RUN) + info "Run phase" diff --git a/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch b/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch new file mode 100644 index 0000000..db85595 --- /dev/null +++ b/SOURCES/0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch @@ -0,0 +1,33 @@ +From 2dd82aad646bde5a0d49df8562e2578c8b3d04f4 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 13:00:33 +0100 +Subject: [PATCH] ci: use quay.io instead of Docker Hub to avoid rate limits + +Docker Hub introduced rate limits for anonymous users (100 requests per +six hours), which break our CI in the busier periods. Let's try to use +the quay.io CentOS image to mitigate this. + +rhel-only +Related: #1871827 +--- + ci/travis-centos-rhel8.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh +index 43e2cb2585..ffe5813b1a 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/ci/travis-centos-rhel8.sh +@@ -81,11 +81,11 @@ for phase in "${PHASES[@]}"; do + info "Setup phase" + info "Using Travis $CENTOS_RELEASE" + # Pull a Docker image and start a new container +- docker pull centos:$CENTOS_RELEASE ++ docker pull quay.io/centos/centos:$CENTOS_RELEASE + info "Starting container $CONT_NAME" + $DOCKER_RUN -v $REPO_ROOT:/build:rw \ + -w /build --privileged=true --name $CONT_NAME \ +- -dit --net=host centos:$CENTOS_RELEASE /sbin/init ++ -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init + # Beautiful workaround for Fedora's version of Docker + sleep 1 + $DOCKER_EXEC dnf makecache diff --git a/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch b/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch new file mode 100644 index 0000000..70ba33f --- /dev/null +++ b/SOURCES/0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch @@ -0,0 +1,338 @@ +From 88ac207cc619935c64923e6f8fdef324a5b733d8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 15 Jan 2021 15:13:53 +0100 +Subject: [PATCH] ci: move jobs from Travis CI to GH Actions + +The OSS version of Travis CI is going to be merged with the commercial +one soon, essentially dropping the free tier, so let's move the CI jobs +to GitHub Actions to keep them up. + +rhel-only +Related: #1871827 +--- + .../workflows/unit_tests.sh | 28 +++---- + .github/workflows/unit_tests.yml | 28 +++++++ + .travis.yml | 48 ------------ + ci/travis-centos-rhel7.sh | 73 ------------------- + ci/travis_wait.bash | 61 ---------------- + 5 files changed, 37 insertions(+), 201 deletions(-) + rename ci/travis-centos-rhel8.sh => .github/workflows/unit_tests.sh (82%) + create mode 100644 .github/workflows/unit_tests.yml + delete mode 100644 .travis.yml + delete mode 100755 ci/travis-centos-rhel7.sh + delete mode 100644 ci/travis_wait.bash + +diff --git a/ci/travis-centos-rhel8.sh b/.github/workflows/unit_tests.sh +similarity index 82% +rename from ci/travis-centos-rhel8.sh +rename to .github/workflows/unit_tests.sh +index ffe5813b1a..ea4f7e7592 100755 +--- a/ci/travis-centos-rhel8.sh ++++ b/.github/workflows/unit_tests.sh +@@ -1,18 +1,9 @@ + #!/bin/bash + +-# Run this script from the root of the systemd's git repository +-# or set REPO_ROOT to a correct path. +-# +-# Example execution on Fedora: +-# dnf install docker +-# systemctl start docker +-# export CONT_NAME="my-fancy-container" +-# ci/travis-centos.sh SETUP RUN CLEANUP +- + PHASES=(${@:-SETUP RUN CLEANUP}) + CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" + CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" +-DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" ++DOCKER_EXEC="${DOCKER_EXEC:-docker exec $CONT_NAME}" + DOCKER_RUN="${DOCKER_RUN:-docker run}" + REPO_ROOT="${REPO_ROOT:-$PWD}" + ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq diffutils) +@@ -71,9 +62,7 @@ function info() { + echo -e "\033[33;1m$1\033[0m" + } + +-set -e +- +-source "$(dirname $0)/travis_wait.bash" ++set -ex + + for phase in "${PHASES[@]}"; do + case $phase in +@@ -86,6 +75,7 @@ for phase in "${PHASES[@]}"; do + $DOCKER_RUN -v $REPO_ROOT:/build:rw \ + -w /build --privileged=true --name $CONT_NAME \ + -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init ++ + # Beautiful workaround for Fedora's version of Docker + sleep 1 + $DOCKER_EXEC dnf makecache +@@ -97,10 +87,10 @@ for phase in "${PHASES[@]}"; do + # Install systemd's build dependencies + $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd + ;; +- RUN) ++ RUN|RUN_GCC) + info "Run phase" + # Build systemd +- docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}" ++ docker exec -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}" + $DOCKER_EXEC ninja -v -C build + # Let's install the new systemd and "reboot" the container to avoid + # unexpected fails due to incompatibilities with older systemd +@@ -108,16 +98,16 @@ for phase in "${PHASES[@]}"; do + docker restart $CONT_NAME + $DOCKER_EXEC ninja -C build test + ;; +- RUN_ASAN|RUN_CLANG_ASAN) ++ RUN_ASAN|RUN_GCC_ASAN|RUN_CLANG_ASAN) + if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then + ENV_VARS="-e CC=clang -e CXX=clang++" + MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 + fi +- docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}" +- docker exec -it $CONT_NAME ninja -v -C build ++ docker exec $ENV_VARS $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}" ++ docker exec $CONT_NAME ninja -v -C build + + # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. +- travis_wait docker exec --interactive=false \ ++ docker exec --interactive=false \ + -e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \ + -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \ + -e "TRAVIS=$TRAVIS" \ +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +new file mode 100644 +index 0000000000..15f5127a75 +--- /dev/null ++++ b/.github/workflows/unit_tests.yml +@@ -0,0 +1,28 @@ ++--- ++# vi: ts=2 sw=2 et: ++# ++name: Unit tests ++on: ++ pull_request: ++ branches: ++ - master ++ ++jobs: ++ build: ++ runs-on: ubuntu-20.04 ++ env: ++ CENTOS_RELEASE: "centos8" ++ CONT_NAME: "systemd-centos8-ci" ++ strategy: ++ fail-fast: false ++ matrix: ++ run_phase: [GCC, GCC_ASAN] ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v1 ++ - name: Install build dependencies ++ run: sudo -E .github/workflows/unit_tests.sh SETUP ++ - name: Build & test (${{ matrix.run_phase }}) ++ run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }} ++ - name: Cleanup ++ run: sudo -E .github/workflows/unit_tests.sh CLEANUP +diff --git a/.travis.yml b/.travis.yml +deleted file mode 100644 +index 70c60cf24e..0000000000 +--- a/.travis.yml ++++ /dev/null +@@ -1,48 +0,0 @@ +-sudo: required +-dist: xenial +-services: +- - docker +- +-env: +- global: +- - CI_ROOT="$TRAVIS_BUILD_DIR/ci/" +- +-jobs: +- include: +- - name: CentOS 8 +- language: bash +- env: +- - CENTOS_RELEASE="centos8" +- - CONT_NAME="systemd-centos-$CENTOS_RELEASE" +- - DOCKER_EXEC="docker exec -ti $CONT_NAME" +- before_install: +- - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce +- - docker --version +- install: +- - $CI_ROOT/travis-centos-rhel8.sh SETUP +- script: +- - set -e +- # Build systemd +- - $CI_ROOT/travis-centos-rhel8.sh RUN +- - set +e +- after_script: +- - $CI_ROOT/travis-centos-rhel8.sh CLEANUP +- +- - name: CentOS 8 (ASan+UBSan) +- language: bash +- env: +- - CENTOS_RELEASE="centos8" +- - CONT_NAME="systemd-centos-$CENTOS_RELEASE" +- - DOCKER_EXEC="docker exec -ti $CONT_NAME" +- before_install: +- - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce +- - docker --version +- install: +- - $CI_ROOT/travis-centos-rhel8.sh SETUP +- script: +- - set -e +- # Build systemd +- - $CI_ROOT/travis-centos-rhel8.sh RUN_ASAN +- - set +e +- after_script: +- - $CI_ROOT/travis-centos-rhel8.sh CLEANUP +diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh +deleted file mode 100755 +index 73416798ed..0000000000 +--- a/ci/travis-centos-rhel7.sh ++++ /dev/null +@@ -1,73 +0,0 @@ +-#!/bin/bash +- +-# Run this script from the root of the systemd's git repository +-# or set REPO_ROOT to a correct path. +-# +-# Example execution on Fedora: +-# dnf install docker +-# systemctl start docker +-# export CONT_NAME="my-fancy-container" +-# ci/travis-centos.sh SETUP RUN CLEANUP +- +-PHASES=(${@:-SETUP RUN CLEANUP}) +-CENTOS_RELEASE="${CENTOS_RELEASE:-latest}" +-CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" +-DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" +-DOCKER_RUN="${DOCKER_RUN:-docker run}" +-REPO_ROOT="${REPO_ROOT:-$PWD}" +-ADDITIONAL_DEPS=(yum-utils iputils hostname libasan libubsan clang llvm) +- +-function info() { +- echo -e "\033[33;1m$1\033[0m" +-} +- +-set -e +- +-source "$(dirname $0)/travis_wait.bash" +- +-for phase in "${PHASES[@]}"; do +- case $phase in +- SETUP) +- info "Setup phase" +- info "Using Travis $CENTOS_RELEASE" +- # Pull a Docker image and start a new container +- docker pull centos:$CENTOS_RELEASE +- info "Starting container $CONT_NAME" +- $DOCKER_RUN -v $REPO_ROOT:/build:rw \ +- -w /build --privileged=true --name $CONT_NAME \ +- -dit --net=host centos:$CENTOS_RELEASE /sbin/init +- # Beautiful workaround for Fedora's version of Docker +- sleep 1 +- $DOCKER_EXEC yum makecache +- # Install necessary build/test requirements +- $DOCKER_EXEC yum -y upgrade +- $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}" +- $DOCKER_EXEC yum-builddep -y systemd +- ;; +- RUN) +- info "Run phase" +- # Build systemd +- $DOCKER_EXEC ./autogen.sh +- $DOCKER_EXEC ./configure --disable-timesyncd --disable-kdbus --disable-terminal \ +- --enable-gtk-doc --enable-compat-libs --disable-sysusers \ +- --disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d +- $DOCKER_EXEC make +- # Let's install the new systemd and "reboot" the container to avoid +- # unexpected fails due to incompatibilities with older systemd +- $DOCKER_EXEC make install +- docker restart $CONT_NAME +- if ! $DOCKER_EXEC make check; then +- $DOCKER_EXEC cat test-suite.log +- exit 1 +- fi +- ;; +- CLEANUP) +- info "Cleanup phase" +- docker stop $CONT_NAME +- docker rm -f $CONT_NAME +- ;; +- *) +- echo >&2 "Unknown phase '$phase'" +- exit 1 +- esac +-done +diff --git a/ci/travis_wait.bash b/ci/travis_wait.bash +deleted file mode 100644 +index acf6ad15e4..0000000000 +--- a/ci/travis_wait.bash ++++ /dev/null +@@ -1,61 +0,0 @@ +-# This was borrowed from https://github.com/travis-ci/travis-build/tree/master/lib/travis/build/bash +-# to get around https://github.com/travis-ci/travis-ci/issues/9979. It should probably be removed +-# as soon as Travis CI has started to provide an easy way to export the functions to bash scripts. +- +-travis_jigger() { +- local cmd_pid="${1}" +- shift +- local timeout="${1}" +- shift +- local count=0 +- +- echo -e "\\n" +- +- while [[ "${count}" -lt "${timeout}" ]]; do +- count="$((count + 1))" +- echo -ne "Still running (${count} of ${timeout}): ${*}\\r" +- sleep 60 +- done +- +- echo -e "\\n${ANSI_RED}Timeout (${timeout} minutes) reached. Terminating \"${*}\"${ANSI_RESET}\\n" +- kill -9 "${cmd_pid}" +-} +- +-travis_wait() { +- local timeout="${1}" +- +- if [[ "${timeout}" =~ ^[0-9]+$ ]]; then +- shift +- else +- timeout=20 +- fi +- +- local cmd=("${@}") +- local log_file="travis_wait_${$}.log" +- +- "${cmd[@]}" &>"${log_file}" & +- local cmd_pid="${!}" +- +- travis_jigger "${!}" "${timeout}" "${cmd[@]}" & +- local jigger_pid="${!}" +- local result +- +- { +- set +e +- wait "${cmd_pid}" 2>/dev/null +- result="${?}" +- ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}" +- set -e +- } +- +- if [[ "${result}" -eq 0 ]]; then +- echo -e "\\n${ANSI_GREEN}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" +- else +- echo -e "\\n${ANSI_RED}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}" +- fi +- +- echo -e "\\n${ANSI_GREEN}Log:${ANSI_RESET}\\n" +- cat "${log_file}" +- +- return "${result}" +-} diff --git a/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch b/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch new file mode 100644 index 0000000..9f2143b --- /dev/null +++ b/SOURCES/0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch @@ -0,0 +1,31 @@ +From a11334f0eae67b5159a416193e2e37634281000a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Nov 2018 09:33:31 +0100 +Subject: [PATCH] unit: make UNIT() cast function deal with NULL pointers + +Fixes: #10681 +(cherry picked from commit bbf11206230d1b089118971f98a047151cb5c4fa) + +Related: #1871827 +--- + src/core/unit.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.h b/src/core/unit.h +index 6e37fd6f5a..ec45b5fb48 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -597,7 +597,12 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; + } + + /* For casting the various unit types into a unit */ +-#define UNIT(u) (&(u)->meta) ++#define UNIT(u) \ ++ ({ \ ++ typeof(u) _u_ = (u); \ ++ Unit *_w_ = _u_ ? &(_u_)->meta : NULL; \ ++ _w_; \ ++ }) + + #define UNIT_HAS_EXEC_CONTEXT(u) (UNIT_VTABLE(u)->exec_context_offset > 0) + #define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0) diff --git a/SOURCES/0500-use-link-to-RHEL-8-docs.patch b/SOURCES/0500-use-link-to-RHEL-8-docs.patch new file mode 100644 index 0000000..ecc4968 --- /dev/null +++ b/SOURCES/0500-use-link-to-RHEL-8-docs.patch @@ -0,0 +1,25 @@ +From 6fb6c218fda0d5c3404049243b9392e9b0c7d537 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 11 Dec 2020 09:34:19 +0100 +Subject: [PATCH] use link to RHEL-8 docs + +RHEL-only + +Related: #1623116 +--- + man/systemctl.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 56f94d084c..ed60a0739f 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2005,7 +2005,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + For examples how to use systemctl in comparsion + with old service and chkconfig command please see: +- ++ + Managing System Services + + diff --git a/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch b/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch new file mode 100644 index 0000000..88ad896 --- /dev/null +++ b/SOURCES/0501-cgroup-Also-set-blkio.bfq.weight.patch @@ -0,0 +1,37 @@ +From af9f03ba48dd75be8c6a923f70da9804b3a3a2c3 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Wed, 25 Nov 2020 09:05:36 +0100 +Subject: [PATCH] cgroup: Also set blkio.bfq.weight + +Commit [1] added a workaround when unified cgroups are used but missed +legacy cgroups where there is the same issue. + +[1] + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 35e7a62ca32a30169a94693b831e53c832251984) + +Resolves: #1657810 +--- + src/core/cgroup.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f1ce070f9a..71e30fd4db 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1063,6 +1063,14 @@ static void cgroup_context_apply( + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set blkio.weight: %m"); + ++ /* FIXME: drop this when distro kernels properly support BFQ through "blkio.weight" ++ * See also: https://github.com/systemd/systemd/pull/13335 */ ++ xsprintf(buf, "%" PRIu64 "\n", weight); ++ r = cg_set_attribute("blkio", path, "blkio.bfq.weight", buf); ++ if (r < 0) ++ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to set blkio.bfq.weight: %m"); ++ + if (has_io) { + CGroupIODeviceWeight *w; + diff --git a/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch b/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch new file mode 100644 index 0000000..3fdb46f --- /dev/null +++ b/SOURCES/0502-units-make-sure-initrd-cleanup.service-terminates-be.patch @@ -0,0 +1,37 @@ +From ea425381a675a2ce4d9519d534fe27c1012ac92e Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 28 Jan 2019 12:07:37 +0100 +Subject: [PATCH] units: make sure initrd-cleanup.service terminates before + switching to rootfs + +A follow-up for commit a8cb1dc3e0fa81aff. + +Commit a8cb1dc3e0fa81aff made sure that initrd-cleanup.service won't be stopped +when initrd-switch-root.target is isolated. + +However even with this change, it might happen that initrd-cleanup.service +survives the switch to rootfs (since it has no ordering constraints against +initrd-switch-root.target) and is stopped right after when default.target is +isolated. This led to initrd-cleanup.service entering in failed state as it +happens when oneshot services are stopped. + +This patch along with a8cb1dc3e0fa81aff should fix issue #4343. + +Fixes: #4343 +(cherry picked from commit e2c7c94ea35fe7e669afb51bfc2251158b522ea5) + +Related: #1657810 +--- + units/initrd-switch-root.target | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/initrd-switch-root.target b/units/initrd-switch-root.target +index ad82245121..ea4f02618f 100644 +--- a/units/initrd-switch-root.target ++++ b/units/initrd-switch-root.target +@@ -15,4 +15,4 @@ Requires=initrd-switch-root.service + Before=initrd-switch-root.service + AllowIsolate=yes + Wants=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target systemd-journald.service initrd-cleanup.service +-After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target ++After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target initrd-cleanup.service diff --git a/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch b/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch new file mode 100644 index 0000000..5e5d3d4 --- /dev/null +++ b/SOURCES/0503-core-reload-SELinux-label-cache-on-daemon-reload.patch @@ -0,0 +1,73 @@ +From c67be1c7d69a0662ab85720aa0209110c39479f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 27 Nov 2019 19:43:47 +0100 +Subject: [PATCH] core: reload SELinux label cache on daemon-reload + +Reloading the SELinux label cache here enables a light-wight follow-up of a SELinux policy change, e.g. adding a label for a RuntimeDirectory. + +Closes: #13363 +(cherry picked from commit a9dfac21ec850eb5dcaf1ae9ef729389e4c12802) + +Resolves: #1888912 +--- + src/basic/selinux-util.c | 20 ++++++++++++++++++++ + src/basic/selinux-util.h | 1 + + src/core/main.c | 2 ++ + 3 files changed, 23 insertions(+) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index e15bd7e1fa..f69d88eb1e 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -105,6 +105,26 @@ void mac_selinux_finish(void) { + #endif + } + ++void mac_selinux_reload(void) { ++ ++#if HAVE_SELINUX ++ struct selabel_handle *backup_label_hnd; ++ ++ if (!label_hnd) ++ return; ++ ++ backup_label_hnd = TAKE_PTR(label_hnd); ++ ++ /* try to initialize new handle ++ * on success close backup ++ * on failure restore backup */ ++ if (mac_selinux_init() == 0) ++ selabel_close(backup_label_hnd); ++ else ++ label_hnd = backup_label_hnd; ++#endif ++} ++ + int mac_selinux_fix(const char *path, LabelFixFlags flags) { + + #if HAVE_SELINUX +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index 08314057fb..abcfabe777 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -13,6 +13,7 @@ void mac_selinux_retest(void); + + int mac_selinux_init(void); + void mac_selinux_finish(void); ++void mac_selinux_reload(void); + + int mac_selinux_fix(const char *path, LabelFixFlags flags); + int mac_selinux_apply(const char *path, const char *label); +diff --git a/src/core/main.c b/src/core/main.c +index d897155644..d5c41da0c4 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1682,6 +1682,8 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + ++ mac_selinux_reload(); ++ + (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + set_manager_defaults(m); diff --git a/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch b/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch new file mode 100644 index 0000000..4b51123 --- /dev/null +++ b/SOURCES/0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch @@ -0,0 +1,140 @@ +From 4f4e8bbd9ad46fc146a36f52790bc4920f42ef1f Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 2 Jul 2018 10:22:56 +0200 +Subject: [PATCH] selinux: introduce mac_selinux_create_file_prepare_at() + +(cherry picked from commit 7e531a5265687aef5177b070c36ca4ceab42e768) + +Related: #1888912 +--- + src/basic/selinux-util.c | 83 ++++++++++++++++++++++++++++++---------- + src/basic/selinux-util.h | 1 + + 2 files changed, 63 insertions(+), 21 deletions(-) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index f69d88eb1e..a078ce23ef 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -336,48 +336,89 @@ char* mac_selinux_free(char *label) { + return NULL; + } + +-int mac_selinux_create_file_prepare(const char *path, mode_t mode) { +- + #if HAVE_SELINUX ++static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode) { + _cleanup_freecon_ char *filecon = NULL; ++ _cleanup_free_ char *path = NULL; + int r; + +- assert(path); +- +- if (!label_hnd) +- return 0; +- +- if (path_is_absolute(path)) +- r = selabel_lookup_raw(label_hnd, &filecon, path, mode); +- else { +- _cleanup_free_ char *newpath = NULL; +- +- r = path_make_absolute_cwd(path, &newpath); +- if (r < 0) +- return r; +- +- r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode); +- } ++ assert(abspath); ++ assert(path_is_absolute(abspath)); + ++ r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode); + if (r < 0) { + /* No context specified by the policy? Proceed without setting it. */ + if (errno == ENOENT) + return 0; + +- log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path); ++ log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath); + } else { + if (setfscreatecon_raw(filecon) >= 0) + return 0; /* Success! */ + +- log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, path); ++ log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath); + } + + if (security_getenforce() > 0) + return -errno; + +-#endif + return 0; + } ++#endif ++ ++int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) { ++ int r = 0; ++ ++#if HAVE_SELINUX ++ _cleanup_free_ char *abspath = NULL; ++ _cleanup_close_ int fd = -1; ++ ++ assert(path); ++ ++ if (!label_hnd) ++ return 0; ++ ++ if (!path_is_absolute(path)) { ++ _cleanup_free_ char *p = NULL; ++ ++ if (dirfd == AT_FDCWD) ++ r = safe_getcwd(&p); ++ else ++ r = fd_get_path(dirfd, &p); ++ if (r < 0) ++ return r; ++ ++ abspath = path_join(NULL, p, path); ++ if (!abspath) ++ return -ENOMEM; ++ ++ path = abspath; ++ } ++ ++ r = selinux_create_file_prepare_abspath(path, mode); ++#endif ++ return r; ++} ++ ++int mac_selinux_create_file_prepare(const char *path, mode_t mode) { ++ int r = 0; ++ ++#if HAVE_SELINUX ++ _cleanup_free_ char *abspath = NULL; ++ ++ assert(path); ++ ++ if (!label_hnd) ++ return 0; ++ ++ r = path_make_absolute_cwd(path, &abspath); ++ if (r < 0) ++ return r; ++ ++ r = selinux_create_file_prepare_abspath(abspath, mode); ++#endif ++ return r; ++} + + void mac_selinux_create_file_clear(void) { + +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index abcfabe777..639c35b687 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -24,6 +24,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char * + char* mac_selinux_free(char *label); + + int mac_selinux_create_file_prepare(const char *path, mode_t mode); ++int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode); + void mac_selinux_create_file_clear(void); + + int mac_selinux_create_socket_prepare(const char *label); diff --git a/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch b/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch new file mode 100644 index 0000000..4bba960 --- /dev/null +++ b/SOURCES/0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch @@ -0,0 +1,135 @@ +From 4e48673172b012a06575e4f5b681d3554eded2e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Mon, 6 Jan 2020 15:27:23 +0100 +Subject: [PATCH] selinux: add trigger for policy reload to refresh internal + selabel cache + +Reload the internal selabel cache automatically on SELinux policy reloads so non pid-1 daemons are participating. + +Run the reload function `mac_selinux_reload()` not manually on daemon-reload, but rather pass it as callback to libselinux. +Trigger the callback prior usage of the systemd internal selabel cache by depleting the selinux netlink socket via `avc_netlink_check_nb()`. + +Improves: a9dfac21ec85 ("core: reload SELinux label cache on daemon-reload") +Improves: #13363 +(cherry picked from commit 61f3e897f13101f29fb8027e8839498a469ad58e) + +Related: #1888912 +--- + src/basic/selinux-util.c | 23 +++++++++++++++++++---- + src/basic/selinux-util.h | 1 - + src/core/main.c | 2 -- + 3 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c +index a078ce23ef..bfe3d015aa 100644 +--- a/src/basic/selinux-util.c ++++ b/src/basic/selinux-util.c +@@ -10,6 +10,7 @@ + #include + + #if HAVE_SELINUX ++#include + #include + #include + #include +@@ -32,6 +33,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); + #define _cleanup_freecon_ _cleanup_(freeconp) + #define _cleanup_context_free_ _cleanup_(context_freep) + ++static int mac_selinux_reload(int seqno); ++ + static int cached_use = -1; + static struct selabel_handle *label_hnd = NULL; + +@@ -63,6 +66,8 @@ int mac_selinux_init(void) { + usec_t before_timestamp, after_timestamp; + struct mallinfo before_mallinfo, after_mallinfo; + ++ selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload); ++ + if (label_hnd) + return 0; + +@@ -105,13 +110,12 @@ void mac_selinux_finish(void) { + #endif + } + +-void mac_selinux_reload(void) { +- + #if HAVE_SELINUX ++static int mac_selinux_reload(int seqno) { + struct selabel_handle *backup_label_hnd; + + if (!label_hnd) +- return; ++ return 0; + + backup_label_hnd = TAKE_PTR(label_hnd); + +@@ -122,8 +126,10 @@ void mac_selinux_reload(void) { + selabel_close(backup_label_hnd); + else + label_hnd = backup_label_hnd; +-#endif ++ ++ return 0; + } ++#endif + + int mac_selinux_fix(const char *path, LabelFixFlags flags) { + +@@ -152,6 +158,9 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) { + if (fstat(fd, &st) < 0) + return -errno; + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) { + r = -errno; + +@@ -345,6 +354,9 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode) + assert(abspath); + assert(path_is_absolute(abspath)); + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode); + if (r < 0) { + /* No context specified by the policy? Proceed without setting it. */ +@@ -496,6 +508,9 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { + + path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path)); + ++ /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */ ++ (void) avc_netlink_check_nb(); ++ + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK); + else { +diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h +index 639c35b687..bd5207c318 100644 +--- a/src/basic/selinux-util.h ++++ b/src/basic/selinux-util.h +@@ -13,7 +13,6 @@ void mac_selinux_retest(void); + + int mac_selinux_init(void); + void mac_selinux_finish(void); +-void mac_selinux_reload(void); + + int mac_selinux_fix(const char *path, LabelFixFlags flags); + int mac_selinux_apply(const char *path, const char *label); +diff --git a/src/core/main.c b/src/core/main.c +index d5c41da0c4..d897155644 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1682,8 +1682,6 @@ static int invoke_main_loop( + saved_log_level = m->log_level_overridden ? log_get_max_level() : -1; + saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID; + +- mac_selinux_reload(); +- + (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock); + + set_manager_defaults(m); diff --git a/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch b/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch new file mode 100644 index 0000000..0ce9150 --- /dev/null +++ b/SOURCES/0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch @@ -0,0 +1,24 @@ +From fb58a56c6c1c2749ba634abd9ad76f4e718269a1 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 5 Jan 2021 12:30:15 +0100 +Subject: [PATCH] udev/net_id: give RHEL-8.4 naming scheme a name + +Follow-up for bb6114af097da0cd9c5081e42db718559130687f + +Related: #1827462 +--- + src/udev/udev-builtin-net_id.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index d8c56b62bb..7c153f0aef 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -150,6 +150,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.1", NAMING_RHEL_8_1 }, + { "rhel-8.2", NAMING_RHEL_8_2 }, + { "rhel-8.3", NAMING_RHEL_8_3 }, ++ { "rhel-8.4", NAMING_RHEL_8_4 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch b/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch new file mode 100644 index 0000000..e9ac657 --- /dev/null +++ b/SOURCES/0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch @@ -0,0 +1,63 @@ +From 29c5b8dd6228c4401f034ca0aa85f99ac42cf8dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 5 Nov 2020 17:55:25 +0100 +Subject: [PATCH] basic/stat-util: make mtime check stricter and use entire + timestamp + +Note that st_mtime member of struct stat is defined as follows, + + #define st_mtime st_mtim.tv_sec + +Hence we omitted checking nanosecond part of the timestamp (struct +timespec) and possibly would miss modifications that happened within the +same second. + +(cherry picked from commit a59b0a9f768f6e27b25f4f1bab6de08842e78d74) + +Related: #1642728 +--- + src/basic/stat-util.c | 22 ++++++++++++++++++++++ + src/basic/stat-util.h | 2 ++ + 2 files changed, 24 insertions(+) + +diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c +index 26aee9bad6..c61c4c0517 100644 +--- a/src/basic/stat-util.c ++++ b/src/basic/stat-util.c +@@ -287,3 +287,25 @@ int fd_verify_regular(int fd) { + + return stat_verify_regular(&st); + } ++ ++bool stat_inode_unmodified(const struct stat *a, const struct stat *b) { ++ ++ /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to ++ * be reasonably careful when detecting changes: we check both inode and mtime, to cater for file ++ * systems where mtimes are fixed to 0 (think: ostree/nixos type installations). We also check file ++ * size, backing device, inode type and if this refers to a device not the major/minor. ++ * ++ * Note that we don't care if file attributes such as ownership or access mode change, this here is ++ * about contents of the file. The purpose here is to detect file contents changes, and nothing ++ * else. */ ++ ++ return a && b && ++ (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */ ++ ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */ ++ a->st_mtim.tv_sec == b->st_mtim.tv_sec && ++ a->st_mtim.tv_nsec == b->st_mtim.tv_nsec && ++ (!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */ ++ a->st_dev == b->st_dev && ++ a->st_ino == b->st_ino && ++ (!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */ ++} +\ No newline at end of file +diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h +index f8014ed30b..9e1a2b70da 100644 +--- a/src/basic/stat-util.h ++++ b/src/basic/stat-util.h +@@ -58,3 +58,5 @@ int path_is_temporary_fs(const char *path); + + int stat_verify_regular(const struct stat *st); + int fd_verify_regular(int fd); ++ ++bool stat_inode_unmodified(const struct stat *a, const struct stat *b); diff --git a/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch b/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch new file mode 100644 index 0000000..e20137b --- /dev/null +++ b/SOURCES/0508-udev-make-algorithm-that-selects-highest-priority-de.patch @@ -0,0 +1,457 @@ +From 1d5f966c1758eb620755fcae54abd07a1ac36d3d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 6 Jan 2021 11:43:50 +0100 +Subject: [PATCH] udev: make algorithm that selects highest priority devlink + less susceptible to race conditions + +Previously it was very likely, when multiple contenders for the symlink +appear in parallel, that algorithm would select wrong symlink (i.e. one +with lower-priority). + +Now the algorithm is much more defensive and when we detect change in +set of contenders for the symlink we reevaluate the selection. Same +happens when new symlink replaces already existing symlink that points +to different device node. + +Resolves: #1642728 +--- + src/udev/udev-event.c | 71 +++++++----- + src/udev/udev-node.c | 244 ++++++++++++++++++++++++++++++------------ + 2 files changed, 216 insertions(+), 99 deletions(-) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index fd8406d959..9004634f65 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -833,6 +833,41 @@ static int rename_netif(struct udev_event *event) { + return 0; + } + ++static void update_devnode(struct udev_event *event) { ++ struct udev_device *dev = event->dev; ++ ++ if (major(udev_device_get_devnum(dev)) > 0) { ++ bool apply; ++ ++ /* remove/update possible left-over symlinks from old database entry */ ++ if (event->dev_db != NULL) ++ udev_node_update_old_links(dev, event->dev_db); ++ ++ if (!event->owner_set) ++ event->uid = udev_device_get_devnode_uid(dev); ++ ++ if (!event->group_set) ++ event->gid = udev_device_get_devnode_gid(dev); ++ ++ if (!event->mode_set) { ++ if (udev_device_get_devnode_mode(dev) > 0) { ++ /* kernel supplied value */ ++ event->mode = udev_device_get_devnode_mode(dev); ++ } else if (event->gid > 0) { ++ /* default 0660 if a group is assigned */ ++ event->mode = 0660; ++ } ++ else { ++ /* default 0600 */ ++ event->mode = 0600; ++ } ++ } ++ ++ apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; ++ udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); ++ } ++} ++ + void udev_event_execute_rules(struct udev_event *event, + usec_t timeout_usec, usec_t timeout_warn_usec, + struct udev_list *properties_list, +@@ -891,35 +926,7 @@ void udev_event_execute_rules(struct udev_event *event, + } + } + +- if (major(udev_device_get_devnum(dev)) > 0) { +- bool apply; +- +- /* remove/update possible left-over symlinks from old database entry */ +- if (event->dev_db != NULL) +- udev_node_update_old_links(dev, event->dev_db); +- +- if (!event->owner_set) +- event->uid = udev_device_get_devnode_uid(dev); +- +- if (!event->group_set) +- event->gid = udev_device_get_devnode_gid(dev); +- +- if (!event->mode_set) { +- if (udev_device_get_devnode_mode(dev) > 0) { +- /* kernel supplied value */ +- event->mode = udev_device_get_devnode_mode(dev); +- } else if (event->gid > 0) { +- /* default 0660 if a group is assigned */ +- event->mode = 0660; +- } else { +- /* default 0600 */ +- event->mode = 0600; +- } +- } +- +- apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; +- udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); +- } ++ update_devnode(event); + + /* preserve old, or get new initialization timestamp */ + udev_device_ensure_usec_initialized(event->dev, event->dev_db); +@@ -927,6 +934,12 @@ void udev_event_execute_rules(struct udev_event *event, + /* (re)write database file */ + udev_device_tag_index(dev, event->dev_db, true); + udev_device_update_db(dev); ++ ++ /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, ++ * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure ++ * symlinks point to devices that claim them with the highest priority. */ ++ update_devnode(event); ++ + udev_device_set_is_initialized(dev); + + event->dev_db = udev_device_unref(event->dev_db); +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 333dcae6b9..2eeeccdd3a 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -13,19 +13,27 @@ + #include + + #include "device-nodes.h" ++#include "device-private.h" + #include "dirent-util.h" ++#include "fd-util.h" + #include "format-util.h" + #include "fs-util.h" ++#include "sd-device.h" + #include "selinux-util.h" + #include "smack-util.h" ++#include "stat-util.h" + #include "stdio-util.h" + #include "string-util.h" + #include "udev.h" ++#include "libudev-device-internal.h" + +-static int node_symlink(struct udev_device *dev, const char *node, const char *slink) { ++#define LINK_UPDATE_MAX_RETRIES 128 ++ ++static int node_symlink(sd_device *dev, const char *node, const char *slink) { + struct stat stats; + char target[UTIL_PATH_SIZE]; + char *s; ++ const char *id_filename; + size_t l; + char slink_tmp[UTIL_PATH_SIZE + 32]; + int i = 0; +@@ -89,7 +97,10 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s + } + + log_debug("atomically replace '%s'", slink); +- strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL); ++ err = device_get_id_filename(dev, &id_filename); ++ if (err < 0) ++ return log_error_errno(err, "Failed to get id_filename: %m"); ++ strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", id_filename, NULL); + unlink(slink_tmp); + do { + err = mkdir_parents_label(slink_tmp, 0755); +@@ -109,104 +120,187 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s + if (err != 0) { + log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink); + unlink(slink_tmp); +- } ++ } else ++ /* Tell caller that we replaced already existing symlink. */ ++ return 1; + exit: + return err; + } + + /* find device node of device with highest priority */ +-static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) { +- struct udev *udev = udev_device_get_udev(dev); +- DIR *dir; ++static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) { ++ _cleanup_closedir_ DIR *dir = NULL; ++ _cleanup_free_ char *target = NULL; + struct dirent *dent; +- int priority = 0; +- const char *target = NULL; ++ int r, priority = 0; ++ ++ assert(!add || dev); ++ assert(stackdir); ++ assert(ret); + + if (add) { +- priority = udev_device_get_devlink_priority(dev); +- strscpy(buf, bufsize, udev_device_get_devnode(dev)); +- target = buf; ++ const char *devnode; ++ ++ r = device_get_devlink_priority(dev, &priority); ++ if (r < 0) ++ return r; ++ ++ r = sd_device_get_devname(dev, &devnode); ++ if (r < 0) ++ return r; ++ ++ target = strdup(devnode); ++ if (!target) ++ return -ENOMEM; + } + + dir = opendir(stackdir); +- if (dir == NULL) +- return target; ++ if (!dir) { ++ if (target) { ++ *ret = TAKE_PTR(target); ++ return 0; ++ } ++ ++ return -errno; ++ } ++ + FOREACH_DIRENT_ALL(dent, dir, break) { +- struct udev_device *dev_db; ++ _cleanup_(sd_device_unrefp) sd_device *dev_db = NULL; ++ const char *devnode, *id_filename; ++ int db_prio = 0; + + if (dent->d_name[0] == '\0') + break; + if (dent->d_name[0] == '.') + continue; + +- log_debug("found '%s' claiming '%s'", dent->d_name, stackdir); ++ log_debug("Found '%s' claiming '%s'", dent->d_name, stackdir); ++ ++ if (device_get_id_filename(dev, &id_filename) < 0) ++ continue; + + /* did we find ourself? */ +- if (streq(dent->d_name, udev_device_get_id_filename(dev))) ++ if (streq(dent->d_name, id_filename)) + continue; + +- dev_db = udev_device_new_from_device_id(udev, dent->d_name); +- if (dev_db != NULL) { +- const char *devnode; +- +- devnode = udev_device_get_devnode(dev_db); +- if (devnode != NULL) { +- if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) { +- log_debug("'%s' claims priority %i for '%s'", +- udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir); +- priority = udev_device_get_devlink_priority(dev_db); +- strscpy(buf, bufsize, devnode); +- target = buf; +- } +- } +- udev_device_unref(dev_db); ++ if (sd_device_new_from_device_id(&dev_db, dent->d_name) < 0) ++ continue; ++ ++ if (sd_device_get_devname(dev_db, &devnode) < 0) ++ continue; ++ ++ if (device_get_devlink_priority(dev_db, &db_prio) < 0) ++ continue; ++ ++ if (target && db_prio <= priority) ++ continue; ++ ++ if (DEBUG_LOGGING) { ++ const char *syspath = NULL; ++ ++ (void) sd_device_get_syspath(dev_db, &syspath); ++ log_debug("Device '%s' claims priority %i for '%s'", strnull(syspath), db_prio, stackdir); + } ++ ++ r = free_and_strdup(&target, devnode); ++ if (r < 0) ++ return r; ++ priority = db_prio; + } +- closedir(dir); +- return target; ++ ++ if (!target) ++ return -ENOENT; ++ ++ *ret = TAKE_PTR(target); ++ return 0; + } + ++ + /* manage "stack of names" with possibly specified device priorities */ +-static void link_update(struct udev_device *dev, const char *slink, bool add) { +- char name_enc[UTIL_PATH_SIZE]; +- char filename[UTIL_PATH_SIZE * 2]; +- char dirname[UTIL_PATH_SIZE]; +- const char *target; +- char buf[UTIL_PATH_SIZE]; ++static int link_update(sd_device *dev, const char *slink, bool add) { ++ _cleanup_free_ char *filename = NULL, *dirname = NULL; ++ char name_enc[PATH_MAX]; ++ const char *id_filename; ++ int i, r, retries; ++ ++ assert(dev); ++ assert(slink); ++ ++ r = device_get_id_filename(dev, &id_filename); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to get id_filename: %m"); + + util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc)); +- strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL); +- strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL); ++ dirname = path_join(NULL, "/run/udev/links/", name_enc); ++ if (!dirname) ++ return log_oom(); ++ filename = path_join(NULL, dirname, id_filename); ++ if (!filename) ++ return log_oom(); ++ ++ if (!add) { ++ if (unlink(filename) == 0) ++ (void) rmdir(dirname); ++ } else ++ for (;;) { ++ _cleanup_close_ int fd = -1; ++ ++ r = mkdir_parents(filename, 0755); ++ if (!IN_SET(r, 0, -ENOENT)) ++ return r; + +- if (!add && unlink(filename) == 0) +- rmdir(dirname); ++ fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); ++ if (fd >= 0) ++ break; ++ if (errno != ENOENT) ++ return -errno; ++ } + +- target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf)); +- if (target == NULL) { +- log_debug("no reference left, remove '%s'", slink); +- if (unlink(slink) == 0) +- rmdir_parents(slink, "/"); +- } else { +- log_debug("creating link '%s' to '%s'", slink, target); +- node_symlink(dev, target, slink); +- } ++ /* If the database entry is not written yet we will just do one iteration and possibly wrong symlink ++ * will be fixed in the second invocation. */ ++ (void) sd_device_get_is_initialized(dev, &r); ++ retries = r > 0 ? LINK_UPDATE_MAX_RETRIES : 1; + +- if (add) { +- int err; ++ for (i = 0; i < retries; i++) { ++ _cleanup_free_ char *target = NULL; ++ struct stat st1 = {}, st2 = {}; + +- do { +- int fd; ++ r = stat(dirname, &st1); ++ if (r < 0 && errno != ENOENT) ++ return -errno; + +- err = mkdir_parents(filename, 0755); +- if (!IN_SET(err, 0, -ENOENT)) ++ r = link_find_prioritized(dev, add, dirname, &target); ++ if (r == -ENOENT) { ++ log_debug("No reference left, removing '%s'", slink); ++ if (unlink(slink) == 0) ++ (void) rmdir_parents(slink, "/"); ++ ++ break; ++ } else if (r < 0) ++ return log_error_errno(r, "Failed to determine highest priority symlink: %m"); ++ ++ r = node_symlink(dev, target, slink); ++ if (r < 0) { ++ (void) unlink(filename); ++ break; ++ } else if (r == 1) ++ /* We have replaced already existing symlink, possibly there is some other device trying ++ * to claim the same symlink. Let's do one more iteration to give us a chance to fix ++ * the error if other device actually claims the symlink with higher priority. */ ++ continue; ++ ++ /* Skip the second stat() if the first failed, stat_inode_unmodified() would return false regardless. */ ++ if ((st1.st_mode & S_IFMT) != 0) { ++ r = stat(dirname, &st2); ++ if (r < 0 && errno != ENOENT) ++ return -errno; ++ ++ if (stat_inode_unmodified(&st1, &st2)) + break; +- fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); +- if (fd >= 0) +- close(fd); +- else +- err = -errno; +- } while (err == -ENOENT); ++ } + } ++ ++ return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP; + } + + void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) { +@@ -233,7 +327,7 @@ void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev + + log_debug("update old name, '%s' no longer belonging to '%s'", + name, udev_device_get_devpath(dev)); +- link_update(dev, name, false); ++ link_update(dev->device, name, false); + } + } + +@@ -338,11 +432,16 @@ void udev_node_add(struct udev_device *dev, bool apply, + xsprintf_dev_num_path(filename, + streq(udev_device_get_subsystem(dev), "block") ? "block" : "char", + udev_device_get_devnum(dev)); +- node_symlink(dev, udev_device_get_devnode(dev), filename); ++ node_symlink(dev->device, udev_device_get_devnode(dev), filename); + + /* create/update symlinks, add symlinks to name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) +- link_update(dev, udev_list_entry_get_name(list_entry), true); ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { ++ int r; ++ ++ r = link_update(dev->device, udev_list_entry_get_name(list_entry), true); ++ if (r < 0) ++ log_info_errno(r, "Failed to update device symlinks: %m"); ++ } + } + + void udev_node_remove(struct udev_device *dev) { +@@ -350,8 +449,13 @@ void udev_node_remove(struct udev_device *dev) { + char filename[DEV_NUM_PATH_MAX]; + + /* remove/update symlinks, remove symlinks from name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) +- link_update(dev, udev_list_entry_get_name(list_entry), false); ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { ++ int r; ++ ++ r = link_update(dev->device, udev_list_entry_get_name(list_entry), false); ++ if (r < 0) ++ log_info_errno(r, "Failed to update device symlinks: %m"); ++ } + + /* remove /dev/{block,char}/$major:$minor */ + xsprintf_dev_num_path(filename, diff --git a/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch b/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch new file mode 100644 index 0000000..4dccdbc --- /dev/null +++ b/SOURCES/0509-test-create-dev-null-in-test-udev.pl.patch @@ -0,0 +1,32 @@ +From 6a908a38135d050b7c271fdea9c061d7e7ad8ef7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 23 Oct 2018 07:23:01 +0900 +Subject: [PATCH] test: create /dev/null in test-udev.pl + +(cherry picked from commit a41ff38b0999fb83464309a29b8f39450b8d4b85) + +Related: #1642728 +--- + test/udev-test.pl | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 0433629c7c..a1c24f49b4 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1537,13 +1537,14 @@ sub udev_setup { + system("umount", $udev_tmpfs); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; +- system("mount", "-o", "rw,mode=755,nosuid,noexec,nodev", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; ++ system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; + + mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; + # setting group and mode of udev_dev ensures the tests work + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; ++ system("mknod", $udev_dev . "/null", "c", "1", "3") && "unable to create $udev_dev/null"; + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + diff --git a/SOURCES/0510-test-missing-die.patch b/SOURCES/0510-test-missing-die.patch new file mode 100644 index 0000000..959a689 --- /dev/null +++ b/SOURCES/0510-test-missing-die.patch @@ -0,0 +1,27 @@ +From 70bf708d5360372aa541e25ff512609230781dd6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 7 Nov 2018 14:56:20 +0900 +Subject: [PATCH] test: missing "die" + +Follow-up for a41ff38b0999fb83464309a29b8f39450b8d4b85. + +(cherry picked from commit 11d93952ea806de2b6e9fb381153115cccc7b5e8) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a1c24f49b4..61bd3d703a 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1544,7 +1544,7 @@ sub udev_setup { + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; +- system("mknod", $udev_dev . "/null", "c", "1", "3") && "unable to create $udev_dev/null"; ++ system("mknod", $udev_dev . "/null", "c", "1", "3") && die "unable to create $udev_dev/null"; + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + diff --git a/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch b/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch new file mode 100644 index 0000000..eeadbda --- /dev/null +++ b/SOURCES/0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch @@ -0,0 +1,33 @@ +From 1b133f2ca15f0a15b05407b2c04521d7de88dfa2 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 9 Nov 2018 03:14:04 +0100 +Subject: [PATCH] udev-test: remove a check for whether the test is run in a + container + +It's too broad a check that prevents the test from running on Travis CI. + +(cherry picked from commit 881886ef08d50951159633248b0f73977c5d6924) + +Related: #1642728 +--- + test/udev-test.pl | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 61bd3d703a..05b3e17188 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1646,13 +1646,6 @@ if ($? >> 8 == 0) { + exit($EXIT_TEST_SKIP); + } + +-# skip the test when running in a container +-system("systemd-detect-virt", "-c", "-q"); +-if ($? >> 8 == 0) { +- print "Running in a container, skipping the test.\n"; +- exit($EXIT_TEST_SKIP); +-} +- + udev_setup(); + + my $test_num = 1; diff --git a/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch b/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch new file mode 100644 index 0000000..37970ab --- /dev/null +++ b/SOURCES/0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch @@ -0,0 +1,94 @@ +From 8c82f3a4aa2d029dcc303cbf95a71194aa5ac9c3 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Fri, 9 Nov 2018 04:01:15 +0100 +Subject: [PATCH] udev-test: skip the test only if it can't setup its + environment + +This is basically a replacement for 0eb3cc88504b5d8f74. + +(cherry picked from commit 110a13202eab6d92678abcde08372d4afac1cc45) + +Related: #1642728 +--- + src/test/test-udev.c | 8 ++++++++ + test/udev-test.pl | 24 +++++++++++++++++++++--- + 2 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/src/test/test-udev.c b/src/test/test-udev.c +index bed51c1270..f098fab721 100644 +--- a/src/test/test-udev.c ++++ b/src/test/test-udev.c +@@ -65,6 +65,11 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + ++ if (!IN_SET(argc, 2, 3)) { ++ log_error("This program needs one or two arguments, %d given", argc - 1); ++ return EXIT_FAILURE; ++ } ++ + err = fake_filesystems(); + if (err < 0) + return EXIT_FAILURE; +@@ -73,6 +78,9 @@ int main(int argc, char *argv[]) { + if (udev == NULL) + return EXIT_FAILURE; + ++ if (argc == 2) ++ return EXIT_SUCCESS; ++ + log_debug("version %s", PACKAGE_VERSION); + mac_selinux_init(); + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 05b3e17188..aa38bae0b1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1537,18 +1537,28 @@ sub udev_setup { + system("umount", $udev_tmpfs); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; +- system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs) && die "unable to mount tmpfs"; ++ ++ if (system("mount", "-o", "rw,mode=755,nosuid,noexec", "-t", "tmpfs", "tmpfs", $udev_tmpfs)) { ++ warn "unable to mount tmpfs"; ++ return 0; ++ } + + mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; + # setting group and mode of udev_dev ensures the tests work + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; +- system("mknod", $udev_dev . "/null", "c", "1", "3") && die "unable to create $udev_dev/null"; ++ ++ if (system("mknod", $udev_dev . "/null", "c", "1", "3")) { ++ warn "unable to create $udev_dev/null"; ++ return 0; ++ } + + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + + system("rm", "-rf", "$udev_run"); ++ ++ return 1; + } + + sub run_test { +@@ -1646,7 +1656,15 @@ if ($? >> 8 == 0) { + exit($EXIT_TEST_SKIP); + } + +-udev_setup(); ++if (!udev_setup()) { ++ warn "Failed to set up the environment, skipping the test"; ++ exit($EXIT_TEST_SKIP); ++} ++ ++if (!system($udev_bin, "check")) { ++ warn "$udev_bin failed to set up the environment, skipping the test"; ++ exit($EXIT_TEST_SKIP); ++} + + my $test_num = 1; + my @list; diff --git a/SOURCES/0513-udev-test-fix-test-skip-condition.patch b/SOURCES/0513-udev-test-fix-test-skip-condition.patch new file mode 100644 index 0000000..165aadb --- /dev/null +++ b/SOURCES/0513-udev-test-fix-test-skip-condition.patch @@ -0,0 +1,33 @@ +From f44fcdde656036f0388fc8244b8960c1873a3a08 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Sat, 8 Dec 2018 11:02:30 +0300 +Subject: [PATCH] udev-test: fix test skip condition + +When there is a failure to setup the environment, the following happens: + +1. Command "./test-udev check" exits with non-zero code. +2. Perl function "system" returns the code. +3. The code is evaluated as true by Perl. + +Then we stop the test. + +(cherry picked from commit 7935dae547caf164d807237f1009a9e9fa510337) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index aa38bae0b1..3517feab15 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1661,7 +1661,7 @@ if (!udev_setup()) { + exit($EXIT_TEST_SKIP); + } + +-if (!system($udev_bin, "check")) { ++if (system($udev_bin, "check")) { + warn "$udev_bin failed to set up the environment, skipping the test"; + exit($EXIT_TEST_SKIP); + } diff --git a/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch b/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch new file mode 100644 index 0000000..5714a16 --- /dev/null +++ b/SOURCES/0514-udev-test-fix-missing-directory-test-run.patch @@ -0,0 +1,35 @@ +From 974431a70775d5127cd973c4b4705d2cf8884011 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Sat, 8 Dec 2018 15:35:30 +0300 +Subject: [PATCH] udev-test: fix missing directory test/run + +Fixes the following error: + + Failed to mount test /run: No such file or directory + +By the time command "./test-udev check" calls function "fake_filesystems", +directory "test/run" must be present. + +(cherry picked from commit 1e5548c0e0962424b6ca5fdfd35c866b70760c8f) + +Related: #1642728 +--- + test/udev-test.pl | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 3517feab15..eb76ebd72e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1558,6 +1558,11 @@ sub udev_setup { + + system("rm", "-rf", "$udev_run"); + ++ if (!mkdir($udev_run)) { ++ warn "unable to create directory $udev_run"; ++ return 0; ++ } ++ + return 1; + } + diff --git a/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch b/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch new file mode 100644 index 0000000..67037a2 --- /dev/null +++ b/SOURCES/0515-udev-test-check-if-permitted-to-create-block-device-.patch @@ -0,0 +1,31 @@ +From 57e9ee0f19098d56995955f6692437affdf94041 Mon Sep 17 00:00:00 2001 +From: Alexey Bogdanenko +Date: Tue, 11 Dec 2018 16:55:34 +0300 +Subject: [PATCH] udev-test: check if permitted to create block device nodes + +(cherry picked from commit dbfbc6c4e34366033cb340e8b0c3cbca683ff6f5) + +Related: #1642728 +--- + test/udev-test.pl | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index eb76ebd72e..957cda541c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1554,6 +1554,14 @@ sub udev_setup { + return 0; + } + ++ # check if we are permitted to create block device nodes ++ my $block_device_filename = $udev_dev . "/sda"; ++ if (system("mknod", $block_device_filename, "b", "8", "0")) { ++ warn "unable to create $block_device_filename"; ++ return 0; ++ } ++ unlink $block_device_filename; ++ + system("cp", "-r", "test/sys/", $udev_sys) && die "unable to copy test/sys"; + + system("rm", "-rf", "$udev_run"); diff --git a/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch b/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch new file mode 100644 index 0000000..7f712d8 --- /dev/null +++ b/SOURCES/0516-test-udev-add-a-testcase-of-too-long-line.patch @@ -0,0 +1,45 @@ +From 527d43064a93fae9a4490e5d152b120e91f5eade Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 18 Feb 2019 10:38:29 +0900 +Subject: [PATCH] test-udev: add a testcase of too long line + +(cherry picked from commit 1e797cf596df50a6bdd8cbf8e9b2467a3a934171) + +Related: #1642728 +--- + test/udev-test.pl | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 957cda541c..3a50694fa9 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -39,6 +39,11 @@ for (my $i = 1; $i <= 10000; ++$i) { + $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n"; + } + ++my $rules_10k_tags_continuation = ""; ++for (my $i = 1; $i <= 10000; ++$i) { ++ $rules_10k_tags_continuation .= 'KERNEL=="sda", TAG+="test' . $i . "\"\\\n"; ++} ++ + my @tests = ( + { + desc => "no rules", +@@ -1444,6 +1449,16 @@ EOF + exp_name => "found", + rules => $rules_10k_tags . < "don't crash with lots of tags with continuation", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad" , ++ rules => $rules_10k_tags_continuation . < +Date: Tue, 19 Feb 2019 09:21:42 +0900 +Subject: [PATCH] test-udev: use proper semantics for too long line with + continuation + +Follow-up for 1e797cf596df50a6bdd8cbf8e9b2467a3a934171. + +(cherry picked from commit e37a5d90b0c624b95f8d0c3400288fec60417ec4) + +Related: #1642728 +--- + test/udev-test.pl | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 3a50694fa9..58b5dc85e1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -39,10 +39,11 @@ for (my $i = 1; $i <= 10000; ++$i) { + $rules_10k_tags .= 'KERNEL=="sda", TAG+="test' . $i . "\"\n"; + } + +-my $rules_10k_tags_continuation = ""; +-for (my $i = 1; $i <= 10000; ++$i) { +- $rules_10k_tags_continuation .= 'KERNEL=="sda", TAG+="test' . $i . "\"\\\n"; ++my $rules_10k_tags_continuation = "KERNEL==\"sda\", \\\n"; ++for (my $i = 1; $i < 10000; ++$i) { ++ $rules_10k_tags_continuation .= 'TAG+="test' . $i . "\",\\\n"; + } ++$rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + + my @tests = ( + { diff --git a/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch b/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch new file mode 100644 index 0000000..9689d81 --- /dev/null +++ b/SOURCES/0518-test-udev-add-more-tests-for-line-continuations-and-.patch @@ -0,0 +1,40 @@ +From 66c41fbbeb472563993724352b1984aa3e7e47db Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 19 Feb 2019 09:22:45 +0900 +Subject: [PATCH] test-udev: add more tests for line continuations and comments + +(cherry picked from commit d35976c670b0e5c2d4081b781e5af88c0689ff00) + +Related: #1642728 +--- + test/udev-test.pl | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 58b5dc85e1..a5e1f8cda3 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1453,13 +1453,21 @@ TAGS=="test1", TAGS=="test500", TAGS=="test1234", TAGS=="test9999", TAGS=="test1 + EOF + }, + { +- desc => "don't crash with lots of tags with continuation", ++ desc => "continuations", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad" , + rules => $rules_10k_tags_continuation . < +Date: Thu, 21 Feb 2019 18:03:32 +0900 +Subject: [PATCH] test-udev: add more tests for line continuation + +(cherry picked from commit 84a0819c9d89a2ddb195a5d975ae1fd5c62fde3c) + +Related: #1642728 +--- + test/udev-test.pl | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a5e1f8cda3..002fabd9fd 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1466,8 +1466,42 @@ TAG+="hoge1",\\ + TAG+="hoge2",\\ + # spaces before and after token are dropped + TAG+="hoge3", \\ ++\\ ++ \\ + TAG+="hoge4" + TAGS=="hoge1", TAGS=="hoge2", TAGS=="hoge3", TAGS=="hoge4", SYMLINK+="found" ++EOF ++ }, ++ { ++ desc => "continuations with empty line", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "continuations with white only line", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Thu, 21 Feb 2019 18:04:12 +0900 +Subject: [PATCH] test-udev: fix alignment and drop unnecessary white spaces + +(cherry picked from commit 3dd2d524141d09d57443ae339e1a77d7ce40f847) + +Related: #1642728 +--- + test/udev-test.pl | 114 +++++++++++++++++++++++----------------------- + 1 file changed, 57 insertions(+), 57 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 002fabd9fd..122359e377 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -49,7 +49,7 @@ my @tests = ( + { + desc => "no rules", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda" , ++ exp_name => "sda", + exp_rem_error => "yes", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_name => "boot_disk", + rules => < "label test of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of pattern match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of multiple sysfs files", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "label test of max sysfs files (skip invalid rule)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_name => "boot_disk1", + rules => < "catch device by *", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by * - take 2", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by ?", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "catch device by character class", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_name => "modem/0", + rules => < "replace kernel name", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle comment lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle whitespace only lines (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace" , ++ exp_name => "whitespace", + rules => < "Handle empty lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "subdirectory handling", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem" , ++ exp_name => "sub/direct/ory/modem", + rules => < "parent device name match of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5" , ++ exp_name => "first_disk5", + rules => < "test substitution chars", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0", + rules => < "sustitution of sysfs value (%s{file})", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda" , ++ exp_name => "disk-ATA-sda", + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5" , +- not_exp_name => "not" , ++ exp_name => "special-device-5", ++ not_exp_name => "not", + rules => < "program result substitution (newline removal)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed" , ++ exp_name => "newline_removed", + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0" , ++ exp_name => "test-0:0:0:0", + rules => < "program with lots of arguments", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9" , ++ exp_name => "foo9", + rules => < "program with subshell", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9" , ++ exp_name => "bar9", + rules => < "program arguments combined with apostrophes", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7" , ++ exp_name => "foo7", + rules => < "program arguments combined with escaped double quotes, part 1", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "program arguments combined with escaped double quotes, part 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "program arguments combined with escaped double quotes, part 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_name => "foo2", + rules => < "characters before the %c{N} substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9" , ++ exp_name => "my-foo9", + rules => < "substitute the second to last argument", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8" , ++ exp_name => "my-foo8", + rules => < "test substitution by variable name 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05" , ++ exp_name => "850:0:0:05", + rules => < "test substitution by variable name 4", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855" , ++ exp_name => "855", + rules => < "test substitution by variable name 5", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0" , ++ exp_name => "8550:0:0:0", + rules => < "non matching SUBSYSTEMS", + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY" , ++ exp_name => "TTY", + rules => < "ATTRS match", + devpath => "/devices/virtual/tty/console", +- exp_name => "foo" , ++ exp_name => "foo", + rules => < "ATTR (empty file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty" , ++ exp_name => "empty", + rules => < "ATTR (non-existent file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent" , ++ exp_name => "non-existent", + rules => < "program and bus type match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0" , ++ exp_name => "scsi-0:0:0:0", + rules => < "sysfs parent hierarchy", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_name => "modem", + rules => < "name test with ! in the name", + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "is/a/fake/blockdev0" , ++ exp_name => "is/a/fake/blockdev0", + rules => < "name test with ! in the name, but no matching rule", + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0" , ++ exp_name => "fake/blockdev0", + exp_rem_error => "yes", + rules => < "KERNELS wildcard partial 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", +- rules => < < "/devices/virtual/misc/misc-fake1", + exp_name => "node", + exp_majorminor => "4095:1", +- rules => < < "multiple symlinks with a lot of s p a c e s", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "one", +- not_exp_name => " ", ++ not_exp_name => " ", + rules => < "multiple symlinks", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0" , ++ exp_name => "second-0", + rules => < "symlink name '.'", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => ".", +- exp_add_error => "yes", +- exp_rem_error => "yes", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", + rules => < "symlink node to itself", + devpath => "/devices/virtual/tty/tty0", + exp_name => "link", +- exp_add_error => "yes", +- exp_rem_error => "yes", +- option => "clean", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ option => "clean", + rules => < "add and match tag", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", +- not_exp_name => "bad" , ++ not_exp_name => "bad", + rules => < "continuations", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", +- not_exp_name => "bad" , ++ not_exp_name => "bad", + rules => $rules_10k_tags_continuation . < +Date: Fri, 5 Jul 2019 11:24:55 -0400 +Subject: [PATCH] test/udev-test.pl: cleanup if skipping test + +In Ubuntu CI, udev-test.pl is run from the debian/test/udev script, +in a test dir created for it; but udev-test.pl setup mounts a +dir, so if it doesn't cleanup/unmount before exiting, the test dir +autopkgtest created for it can't be removed, and autopkgtest +aborts the entire test suite, for example this output (from a +test run inside an armhf container): + +autopkgtest [12:45:36]: test udev: [----------------------- +umount: test/tmpfs: no mount point specified. +mknod: test/tmpfs/dev/null: Operation not permitted +unable to create test/tmpfs/dev/null at ./udev-test.pl line 1611. +Failed to set up the environment, skipping the test at ./udev-test.pl line 1731. +autopkgtest [12:45:41]: test udev: -----------------------] +autopkgtest [12:45:44]: test udev: - - - - - - - - - - results - - - - - - - - - - +udev FAIL non-zero exit status 77 +rm: cannot remove '/tmp/autopkgtest.ocPFA6/autopkgtest_tmp/test/tmpfs': Device or resource busy +autopkgtest [12:46:22]: ERROR: "rm -rf /tmp/autopkgtest.ocPFA6/udev-artifacts /tmp/autopkgtest.ocPFA6/autopkgtest_tmp" failed with stderr "rm: + +(cherry picked from commit abb9cc50afb3949c442849f43301fb33578f3888) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 122359e377..2fea72875b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1713,6 +1713,12 @@ sub run_test { + + } + ++sub cleanup { ++ system("rm", "-rf", "$udev_run"); ++ system("umount", "$udev_tmpfs"); ++ rmdir($udev_tmpfs); ++} ++ + # only run if we have root permissions + # due to mknod restrictions + if (!($<==0)) { +@@ -1729,11 +1735,13 @@ if ($? >> 8 == 0) { + + if (!udev_setup()) { + warn "Failed to set up the environment, skipping the test"; ++ cleanup(); + exit($EXIT_TEST_SKIP); + } + + if (system($udev_bin, "check")) { + warn "$udev_bin failed to set up the environment, skipping the test"; ++ cleanup(); + exit($EXIT_TEST_SKIP); + } + +@@ -1776,10 +1784,7 @@ if ($list[0]) { + + print "$error errors occurred\n\n"; + +-# cleanup +-system("rm", "-rf", "$udev_run"); +-system("umount", "$udev_tmpfs"); +-rmdir($udev_tmpfs); ++cleanup(); + + if ($error > 0) { + exit(1); diff --git a/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch b/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch new file mode 100644 index 0000000..acf7479 --- /dev/null +++ b/SOURCES/0522-test-add-test-cases-for-empty-string-match.patch @@ -0,0 +1,89 @@ +From 03bc565e6e3249385c4e1ca0ae27670ca2ad9a41 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 11 Sep 2019 09:06:15 +0900 +Subject: [PATCH] test: add test cases for empty string match + +(cherry picked from commit 48d26c90852c22ec94be961f5fbdcf462bb9a6e8) + +Related: #1642728 +--- + test/udev-test.pl | 66 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2fea72875b..50d978391b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1256,6 +1256,72 @@ KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1" + KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2" + KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right" + KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3" ++EOF ++ }, ++ { ++ desc => "test multi matches 5", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 6", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 7", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 8", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 9", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < "test multi matches 10", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Sun, 12 Jul 2020 03:27:45 -0400 +Subject: [PATCH] test: add test case for multi matches when use "||" + +Signed-off-by: gaoyi +(cherry picked from commit 0d3a8bc7ebd76591e14f7098b4266fd2065ac4db) + +Related: #1642728 +--- + test/udev-test.pl | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 50d978391b..4bf97d82bb 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1322,6 +1322,17 @@ EOF + KERNEL=="sda", TAG="" + TAGS=="foo|", SYMLINK+="found" + TAGS=="aaa|bbb", SYMLINK+="bad" ++EOF ++ }, ++ { ++ desc => "test multi matches 11", ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ rules => < +Date: Fri, 4 Sep 2020 18:09:20 +0200 +Subject: [PATCH] udev-test: do not rely on "mail" group being defined + +"audio" should be there, at least we declare it. "mail" nowadays is less +likely to exist than in the past. + +Fixes one of the items in #16942. + +(cherry picked from commit a9030b81c154c3ec92227d04cad6b13cc1125608) + +Related: #1642728 +--- + test/udev-test.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 4bf97d82bb..a4deffacb9 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -629,9 +629,9 @@ EOF + desc => "textual user/group id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", +- exp_perms => "root:mail:0660", ++ exp_perms => "root:audio:0660", + rules => < +Date: Fri, 20 Apr 2018 22:38:30 +0200 +Subject: [PATCH] test/udev-test.pl: allow multiple devices per test + +Allow testing cases where multiple devices are added and removed. +This implies a change of the data structure: every test allows +for multiple devices to be added, and "exp_name" etc. are now properties +of the device, not of the test. + +(cherry picked from commit 255c05b72455dcad1b5552d12a813b31f68201a7) + +Related: #1642728 +--- + test/udev-test.pl | 1352 +++++++++++++++++++++++++++++++-------------- + 1 file changed, 929 insertions(+), 423 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a4deffacb9..bd5401da75 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -48,17 +48,28 @@ $rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + my @tests = ( + { + desc => "no rules", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda" , ++ exp_rem_error => "yes", ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sda1" , ++ exp_rem_error => "yes", ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi disc", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "boot_disk" , ++ }], + rules => < "label test of scsi partition", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of pattern match", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of multiple sysfs files", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "label test of max sysfs files (skip invalid rule)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "boot_disk1" , ++ }], + rules => < "catch device by *", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by * - take 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by ?", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "catch device by character class", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem/0" , ++ }], + rules => < "replace kernel name", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle comment lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle whitespace only lines (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "whitespace" , ++ }], + rules => < "Handle empty lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "preserve backslashes, if they are not for a newline", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "aaa", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "aaa", ++ }], + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "subdirectory handling", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "sub/direct/ory/modem" , ++ }], + rules => < "parent device name match of scsi partition", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "first_disk5" , ++ }], + rules => < "test substitution chars", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ }], + rules => < "import of shell-value returned from program", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node12345678", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node12345678", ++ }], + rules => < "sustitution of sysfs value (%s{file})", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda", ++ desc => "substitution of sysfs value (%s{file})", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "disk-ATA-sda" , ++ }], + rules => < "program result substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5", +- not_exp_name => "not", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "special-device-5" , ++ not_exp_name => "not" , ++ }], + rules => < "program result substitution (newline removal)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "newline_removed" , ++ }], + rules => < "program result substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "test-0:0:0:0" , ++ }], + rules => < "program with lots of arguments", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo9" , ++ }], + rules => < "program with subshell", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "bar9" , ++ }], + rules => < "program arguments combined with apostrophes", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo7" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "program arguments combined with escaped double quotes, part 3", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "foo2" , ++ }], + rules => < "characters before the %c{N} substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "my-foo9" , ++ }], + rules => < "substitute the second to last argument", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "my-foo8" , ++ }], + rules => < "test substitution by variable name", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ }], + rules => < "test substitution by variable name 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ }], + rules => < "test substitution by variable name 3", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "850:0:0:05" , ++ }], + rules => < "test substitution by variable name 4", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "855" , ++ }], + rules => < "test substitution by variable name 5", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "8550:0:0:0" , ++ }], + rules => < "non matching SUBSYSTEMS for device with no parent", +- devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "TTY", ++ }], + rules => < "non matching SUBSYSTEMS", +- devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "TTY" , ++ }], + rules => < "ATTRS match", +- devpath => "/devices/virtual/tty/console", +- exp_name => "foo", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/console", ++ exp_name => "foo" , ++ }], + rules => < "ATTR (empty file)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "empty" , ++ }], + rules => < "ATTR (non-existent file)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "non-existent" , ++ }], + rules => < "program and bus type match", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0" , ++ }], + rules => < "sysfs parent hierarchy", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem" , ++ }], + rules => < "name test with ! in the name", +- devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "is/a/fake/blockdev0", ++ devices => [ ++ { ++ devpath => "/devices/virtual/block/fake!blockdev0", ++ exp_name => "is/a/fake/blockdev0" , ++ }], + rules => < "name test with ! in the name, but no matching rule", +- devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/virtual/block/fake!blockdev0", ++ exp_name => "fake/blockdev0" , ++ exp_rem_error => "yes", ++ }], + rules => < "KERNELS rule", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard all", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard partial", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], + rules => < "KERNELS wildcard partial 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", +- rules => < [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "scsi-0:0:0:0", ++ }], ++ rules => < "substitute attr with link target value (first match)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-sd", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "driver-is-sd", ++ }], + rules => < "substitute attr with link target value (currently selected device)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-ahci", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "driver-is-ahci", ++ }], + rules => < "ignore ATTRS attribute whitespace", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ignored", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ignored", ++ }], + rules => < "do not ignore ATTRS attribute whitespace", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "matched-with-space", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "matched-with-space", ++ }], + rules => < "permissions USER=bad GROUP=name", +- devpath => "/devices/virtual/tty/tty33", +- exp_name => "tty33", +- exp_perms => "0:0:0600", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/tty33", ++ exp_name => "tty33", ++ exp_perms => "0:0:0600", ++ }], + rules => < "permissions OWNER=1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "1::0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "1::0600", ++ }], + rules => < "permissions GROUP=1", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => ":1:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => ":1:0660", ++ }], + rules => < "textual user id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "daemon::0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "daemon::0600", ++ }], + rules => < "textual group id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => ":daemon:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => ":daemon:0660", ++ }], + rules => < "textual user/group id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "root:audio:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "root:audio:0660", ++ }], + rules => < "permissions MODE=0777", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "::0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "::0777", ++ }], + rules => < "permissions OWNER=1 GROUP=1 MODE=0777", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions OWNER to 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1::", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1::", ++ }], + rules => < "permissions GROUP to 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => ":1:0660", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => ":1:0660", ++ }], + rules => < "permissions MODE to 0060", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "::0060", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "::0060", ++ }], + rules => < "permissions OWNER, GROUP, MODE", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions only rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "multiple permissions only rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:1:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:1:0777", ++ }], + rules => < "permissions only rule with override at SYMLINK+ rule", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", +- exp_perms => "1:2:0777", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "ttyACM0", ++ exp_perms => "1:2:0777", ++ }], + rules => < "major/minor number test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", +- exp_majorminor => "8:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ exp_majorminor => "8:0", ++ }], + rules => < "big major number test", +- devpath => "/devices/virtual/misc/misc-fake1", +- exp_name => "node", +- exp_majorminor => "4095:1", +- rules => < [ ++ { ++ devpath => "/devices/virtual/misc/misc-fake1", ++ exp_name => "node", ++ exp_majorminor => "4095:1", ++ }], ++ rules => < "big major and big minor number test", +- devpath => "/devices/virtual/misc/misc-fake89999", +- exp_name => "node", +- exp_majorminor => "4095:89999", ++ devices => [ ++ { ++ devpath => "/devices/virtual/misc/misc-fake89999", ++ exp_name => "node", ++ exp_majorminor => "4095:89999", ++ }], + rules => < "multiple symlinks with format char", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink2-ttyACM0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink2-ttyACM0", ++ }], + rules => < "multiple symlinks with a lot of s p a c e s", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "one", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "one", ++ not_exp_name => " ", ++ }], + rules => < "symlink with spaces in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with leading space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with trailing space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with lots of space in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with multiple spaces in substituted variable", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 1", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "first", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "first", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "name-one_two_three-end", ++ not_exp_name => " ", ++ }], + rules => < "symlink with space and var with space, part 3", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "another_symlink", +- not_exp_name => " ", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "another_symlink", ++ not_exp_name => " ", ++ }], + rules => < "symlink creation (same directory)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "modem0", ++ }], + rules => < "multiple symlinks", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "second-0" , ++ }], + rules => < "symlink name '.'", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => ".", +- exp_add_error => "yes", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => ".", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ }], + rules => < "symlink node to itself", +- devpath => "/devices/virtual/tty/tty0", +- exp_name => "link", +- exp_add_error => "yes", +- exp_rem_error => "yes", +- option => "clean", ++ devices => [ ++ { ++ devpath => "/devices/virtual/tty/tty0", ++ exp_name => "link", ++ exp_add_error => "yes", ++ exp_rem_error => "yes", ++ }], ++ option => "clean", + rules => < "symlink %n substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink0", ++ }], + rules => < "symlink %k substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink-ttyACM0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "symlink-ttyACM0", ++ }], + rules => < "symlink %M:%m substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "major-166:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "major-166:0", ++ }], + rules => < "symlink %b substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "symlink-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "symlink-0:0:0:0", ++ }], + rules => < "symlink %c substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "test", ++ }], + rules => < "symlink %c{N} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "test", ++ }], + rules => < "symlink %c{N+} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "this", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "this", ++ }], + rules => < "symlink only rule with %c{N+}", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "test", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "test", ++ }], + rules => < "symlink %s{filename} substitution", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "166:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "166:0", ++ }], + rules => < "program result substitution (numbered part of)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "link1", ++ }], + rules => < "program result substitution (numbered part of+)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link4", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_name => "link4", ++ }], + rules => < "SUBSYSTEM match test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "DRIVERS match test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "devnode substitution test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node", ++ }], + rules => < "parent node name substitution test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda-part-1", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sda-part-1", ++ }], + rules => < "udev_root substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "start-/dev-end", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "start-/dev-end", ++ }], + rules => < "last_rule option", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "last", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "last", ++ }], + rules => < "negation KERNEL!=", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "match", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "match", ++ }], + rules => < "negation SUBSYSTEM!=", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "not-anything", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "not-anything", ++ }], + rules => < "negation PROGRAM!= exit code", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "nonzero-program", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "nonzero-program", ++ }], + rules => < "ENV{} test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign 2 times)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "true", ++ }], + rules => < "ENV{} test (assign2)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "part", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "part", ++ }], + rules => < "untrusted string sanitize", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sane", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "sane", ++ }], + rules => < "untrusted string sanitize (don't replace utf8)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "uber", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "uber", ++ }], + rules => < "untrusted string sanitize (replace invalid utf8)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "replaced", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "replaced", ++ }], + rules => < "read sysfs value from parent device", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "serial-354172020305000", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "serial-354172020305000", ++ }], + rules => < "match against empty key string", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ }], + rules => < "check ACTION value", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ }], + rules => < "final assignment", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", +- exp_perms => "root:tty:0640", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ exp_perms => "root:tty:0640", ++ }], + rules => < "final assignment 2", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", +- exp_perms => "root:tty:0640", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "ok", ++ exp_perms => "root:tty:0640", ++ }], + rules => < "env substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node-add-me", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "node-add-me", ++ }], + rules => < "reset list to current value", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "three", +- not_exp_name => "two", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "three", ++ not_exp_name => "two", ++ }], + rules => < "test empty SYMLINK+ (empty override)", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", +- not_exp_name => "wrong", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ not_exp_name => "wrong", ++ }], + rules => < "test multi matches", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 2", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 3", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 4", +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", ++ exp_name => "right", ++ }], + rules => < "test multi matches 5", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ desc => "test multi matches 5", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 6", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 7", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 8", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 9", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 10", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "test multi matches 11", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => < "IMPORT parent test sequence 1/2 (keep)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "parent", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "parent", ++ }], + option => "keep", + rules => < "IMPORT parent test sequence 2/2 (keep)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "parentenv-parent_right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "parentenv-parent_right", ++ }], + option => "clean", + rules => < "GOTO test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ }], + rules => < "GOTO label does not exist", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ }], + rules => < "SYMLINK+ compare test", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", +- not_exp_name => "wrong", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "right", ++ not_exp_name => "wrong", ++ }], + rules => < "invalid key operation", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "yes", ++ }], + rules => < "operator chars in attribute", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "yes", ++ }], + rules => < "overlong comment line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_name => "yes", ++ }], + rules => < "magic subsys/kernel lookup", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "00:16:41:e2:8d:ff", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "00:16:41:e2:8d:ff", ++ }], + rules => < "TEST absolute path", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "there", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "there", ++ }], + rules => < "TEST subsys/kernel lookup", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "yes", ++ }], + rules => < "TEST relative path", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "relative", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "relative", ++ }], + rules => < "TEST wildcard substitution (find queue/nr_requests)", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found-subdir", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found-subdir", ++ }], + rules => < "TEST MODE=0000", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "0:0:0000", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "0:0:0000", ++ exp_rem_error => "yes", ++ }], + rules => < "TEST PROGRAM feeds OWNER, GROUP, MODE", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "1:1:0400", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "1:1:0400", ++ exp_rem_error => "yes", ++ }], + rules => < "TEST PROGRAM feeds MODE with overflow", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", +- exp_perms => "0:0:0440", +- exp_rem_error => "yes", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda", ++ exp_perms => "0:0:0440", ++ exp_rem_error => "yes", ++ }], + rules => < "magic [subsys/sysname] attribute substitution", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda-8741C4G-end", +- exp_perms => "0:0:0600", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "sda-8741C4G-end", ++ exp_perms => "0:0:0600", ++ }], + rules => < "builtin path_id", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ }], + rules => < "add and match tag", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad" , ++ }], + rules => < "don't crash with lots of tags", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ }], + rules => $rules_10k_tags . < "continuations", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => $rules_10k_tags_continuation . < "continuations with empty line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ ++ }], + rules => < "continuations with white only line", +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_name => "found", ++ not_exp_name => "bad", ++ }], + rules => <{desc}\n"; +- print "device \'$rules->{devpath}\' expecting node/link \'$rules->{exp_name}\'\n"; ++sub check_add { ++ my ($device) = @_; + +- $rc = udev("add", $rules->{devpath}, \$rules->{rules}); +- if ($rc != 0) { +- print "$udev_bin add failed with code $rc\n"; +- $error++; +- } +- if (defined($rules->{not_exp_name})) { +- if ((-e "$udev_dev/$rules->{not_exp_name}") || +- (-l "$udev_dev/$rules->{not_exp_name}")) { +- print "nonexistent: error \'$rules->{not_exp_name}\' not expected to be there\n"; ++ if (defined($device->{not_exp_name})) { ++ if ((-e "$udev_dev/$device->{not_exp_name}") || ++ (-l "$udev_dev/$device->{not_exp_name}")) { ++ print "nonexistent: error \'$device->{not_exp_name}\' not expected to be there\n"; + $error++; + sleep(1); + } + } +- +- if ((-e "$udev_dev/$rules->{exp_name}") || +- (-l "$udev_dev/$rules->{exp_name}")) { ++ if ((-e "$udev_dev/$device->{exp_name}") || ++ (-l "$udev_dev/$device->{exp_name}")) { + + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, +- $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$rules->{exp_name}"); ++ $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$device->{exp_name}"); + +- if (defined($rules->{exp_perms})) { +- permissions_test($rules, $uid, $gid, $mode); ++ if (defined($device->{exp_perms})) { ++ permissions_test($device, $uid, $gid, $mode); + } +- if (defined($rules->{exp_majorminor})) { +- major_minor_test($rules, $rdev); ++ if (defined($device->{exp_majorminor})) { ++ major_minor_test($device, $rdev); + } +- print "add: ok\n"; ++ print "add $device->{devpath}: ok\n"; + } else { +- print "add: error"; +- if ($rules->{exp_add_error}) { ++ print "add $device->{devpath}: error"; ++ if ($device->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; +@@ -1755,21 +2231,15 @@ sub run_test { + sleep(1); + } + } ++} + +- if (defined($rules->{option}) && $rules->{option} eq "keep") { +- print "\n\n"; +- return; +- } ++sub check_remove { ++ my ($device) = @_; + +- $rc = udev("remove", $rules->{devpath}, \$rules->{rules}); +- if ($rc != 0) { +- print "$udev_bin remove failed with code $rc\n"; +- $error++; +- } +- if ((-e "$udev_dev/$rules->{exp_name}") || +- (-l "$udev_dev/$rules->{exp_name}")) { +- print "remove: error"; +- if ($rules->{exp_rem_error}) { ++ if ((-e "$udev_dev/$device->{exp_name}") || ++ (-l "$udev_dev/$device->{exp_name}")) { ++ print "remove $device->{devpath}: error"; ++ if ($device->{exp_rem_error}) { + print " as expected\n"; + } else { + print "\n"; +@@ -1779,7 +2249,43 @@ sub run_test { + sleep(1); + } + } else { +- print "remove: ok\n"; ++ print "remove $device->{devpath}: ok\n"; ++ } ++} ++ ++sub run_test { ++ my ($rules, $number) = @_; ++ my $rc; ++ my @devices = @{$rules->{devices}}; ++ ++ print "TEST $number: $rules->{desc}\n"; ++ foreach my $dev (@devices) { ++ print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; ++ $rc = udev("add", $dev->{devpath}, \$rules->{rules}); ++ if ($rc != 0) { ++ print "$udev_bin add failed with code $rc\n"; ++ $error++; ++ } ++ } ++ ++ foreach my $dev (@devices) { ++ check_add($dev); ++ } ++ ++ if (defined($rules->{option}) && $rules->{option} eq "keep") { ++ print "\n\n"; ++ return; ++ } ++ ++ foreach my $dev (@devices) { ++ $rc = udev("remove", $dev->{devpath}, \$rules->{rules}); ++ if ($rc != 0) { ++ print "$udev_bin remove failed with code $rc\n"; ++ $error++; ++ } ++ } ++ foreach my $dev (@devices) { ++ check_remove($dev); + } + + print "\n"; diff --git a/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch b/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch new file mode 100644 index 0000000..b394455 --- /dev/null +++ b/SOURCES/0526-test-udev-test.pl-create-rules-only-once.patch @@ -0,0 +1,61 @@ +From 9aa12f2f564c208c4c1eaef613d18d1c0b481a16 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 23 Apr 2018 21:58:12 +0200 +Subject: [PATCH] test/udev-test.pl: create rules only once + +It's not necessary to write the rules for every udev run, as we +now may have many (rather than just 2) per test. + +(cherry picked from commit af7ee3eae689f9c31b49ea13758ad9c901918ce3) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index bd5401da75..8b5a97ad61 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2069,14 +2069,18 @@ EOF + }, + ); + +-sub udev { +- my ($action, $devpath, $rules) = @_; ++sub create_rules { ++ my ($rules) = @_; + + # create temporary rules + system("mkdir", "-p", "$udev_rules_dir"); + open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; + print CONF $$rules; + close CONF; ++} ++ ++sub udev { ++ my ($action, $devpath) = @_; + + if ($valgrind > 0) { + return system("$udev_bin_valgrind $action $devpath"); +@@ -2259,9 +2263,10 @@ sub run_test { + my @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; ++ create_rules(\$rules->{rules}); + foreach my $dev (@devices) { + print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; +- $rc = udev("add", $dev->{devpath}, \$rules->{rules}); ++ $rc = udev("add", $dev->{devpath}); + if ($rc != 0) { + print "$udev_bin add failed with code $rc\n"; + $error++; +@@ -2278,7 +2283,7 @@ sub run_test { + } + + foreach my $dev (@devices) { +- $rc = udev("remove", $dev->{devpath}, \$rules->{rules}); ++ $rc = udev("remove", $dev->{devpath}); + if ($rc != 0) { + print "$udev_bin remove failed with code $rc\n"; + $error++; diff --git a/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch b/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch new file mode 100644 index 0000000..f87307f --- /dev/null +++ b/SOURCES/0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch @@ -0,0 +1,169 @@ +From 618d56c7ac8bd8cd701344a0eaca8373a78dea95 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 23 Apr 2018 21:59:05 +0200 +Subject: [PATCH] test/udev-test.pl: allow concurrent additions and removals + +Allow testing cases where multiple devices are added and removed +simultaneously. Tests are started as synchronously as possible using a +semaphore, in order to test possible race conditions. If this isn't desired, +the test parameter "sleep_us" can be set to the number of microseconds to wait +between udev invocations. + +(cherry picked from commit 09a4062d70b3a10d022e40066e2adf09df05bbbc) + +Related: #1642728 +--- + test/udev-test.pl | 90 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 72 insertions(+), 18 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 8b5a97ad61..db25ef13c1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -18,6 +18,10 @@ + + use warnings; + use strict; ++use POSIX qw(WIFEXITED WEXITSTATUS); ++use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); ++use IPC::Semaphore; ++use Time::HiRes qw(usleep); + + my $udev_bin = "./test-udev"; + my $valgrind = 0; +@@ -2210,6 +2214,8 @@ sub check_add { + sleep(1); + } + } ++ ++ print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { + +@@ -2257,21 +2263,72 @@ sub check_remove { + } + } + ++sub run_udev { ++ my ($action, $dev, $sleep_us, $sema) = @_; ++ ++ # Notify main process that this worker has started ++ $sema->op(0, 1, 0); ++ ++ # Wait for start ++ $sema->op(0, 0, 0); ++ usleep($sleep_us) if defined ($sleep_us); ++ my $rc = udev($action, $dev->{devpath}); ++ exit $rc; ++} ++ ++sub fork_and_run_udev { ++ my ($action, $rules, $sema) = @_; ++ my @devices = @{$rules->{devices}}; ++ my $dev; ++ my $k = 0; ++ ++ $sema->setval(0, 1); ++ foreach $dev (@devices) { ++ my $pid = fork(); ++ ++ if (!$pid) { ++ run_udev($action, $dev, ++ defined($rules->{sleep_us}) ? $k * $rules->{sleep_us} : undef, ++ $sema); ++ } else { ++ $dev->{pid} = $pid; ++ } ++ $k++; ++ } ++ ++ # This operation waits for all workers to become ready, and ++ # starts them off when that's the case. ++ $sema->op(0, -($#devices + 2), 0); ++ ++ foreach $dev (@devices) { ++ my $rc; ++ my $pid; ++ ++ $pid = waitpid($dev->{pid}, 0); ++ if ($pid == -1) { ++ print "error waiting for pid dev->{pid}\n"; ++ $error += 1; ++ } ++ if (WIFEXITED($?)) { ++ $rc = WEXITSTATUS($?); ++ ++ if ($rc) { ++ print "$udev_bin $action for $dev->{devpath} failed with code $rc\n"; ++ $error += 1; ++ } ++ } ++ } ++} ++ + sub run_test { +- my ($rules, $number) = @_; ++ my ($rules, $number, $sema) = @_; + my $rc; + my @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); +- foreach my $dev (@devices) { +- print "device \'$dev->{devpath}\' expecting node/link \'$dev->{exp_name}\'\n"; +- $rc = udev("add", $dev->{devpath}); +- if ($rc != 0) { +- print "$udev_bin add failed with code $rc\n"; +- $error++; +- } +- } ++ ++ fork_and_run_udev("add", $rules, $sema); + + foreach my $dev (@devices) { + check_add($dev); +@@ -2282,13 +2339,8 @@ sub run_test { + return; + } + +- foreach my $dev (@devices) { +- $rc = udev("remove", $dev->{devpath}); +- if ($rc != 0) { +- print "$udev_bin remove failed with code $rc\n"; +- $error++; +- } +- } ++ fork_and_run_udev("remove", $rules, $sema); ++ + foreach my $dev (@devices) { + check_remove($dev); + } +@@ -2350,12 +2402,13 @@ foreach my $arg (@ARGV) { + push(@list, $arg); + } + } ++my $sema = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR | IPC_CREAT); + + if ($list[0]) { + foreach my $arg (@list) { + if (defined($tests[$arg-1]->{desc})) { + print "udev-test will run test number $arg:\n\n"; +- run_test($tests[$arg-1], $arg); ++ run_test($tests[$arg-1], $arg, $sema); + } else { + print "test does not exist.\n"; + } +@@ -2365,11 +2418,12 @@ if ($list[0]) { + print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + + foreach my $rules (@tests) { +- run_test($rules, $test_num); ++ run_test($rules, $test_num, $sema); + $test_num++; + } + } + ++$sema->remove; + print "$error errors occurred\n\n"; + + cleanup(); diff --git a/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch b/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch new file mode 100644 index 0000000..a20ebbd --- /dev/null +++ b/SOURCES/0528-test-udev-test.pl-use-computed-devnode-name.patch @@ -0,0 +1,260 @@ +From 5f34ea55a8c6723240eb1641a655db7df3c428a2 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 09:38:26 +0200 +Subject: [PATCH] test/udev-test.pl: use computed devnode name + +More often than not, the created devnode is the basename of the +sysfs entry. The "devnode" device may be used to override the +auto-detected node name. + +Permissions and major/minor number are now verified on the devnode +itself, not on symlinks. + +For those tests where exp_name is set to the computed devnode name, +the explicit "exp_name" can be removed. "exp_name" is only required for +symlinks. + +This allows separate testing for devnodes and symlinks an a follow-up +patch. + +(cherry picked from commit f0dccf01a7b4e72278e14effd74782ea83d0a73b) + +Related: #1642728 +--- + test/udev-test.pl | 92 +++++++++++++++++++++++++++++++++-------------- + 1 file changed, 66 insertions(+), 26 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index db25ef13c1..aa9a8dc2ff 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -55,12 +55,10 @@ my @tests = ( + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda" , + exp_rem_error => "yes", + }, + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda1" , + exp_rem_error => "yes", + }], + rules => < [ + { + devpath => "/devices/virtual/block/fake!blockdev0", ++ devnode => "fake/blockdev0", + exp_name => "is/a/fake/blockdev0" , + }], + rules => < [ + { + devpath => "/devices/virtual/block/fake!blockdev0", +- exp_name => "fake/blockdev0" , ++ devnode => "fake/blockdev0", + exp_rem_error => "yes", + }], + rules => < [ + { + devpath => "/devices/virtual/tty/tty33", +- exp_name => "tty33", + exp_perms => "0:0:0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1::", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => ":1:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "::0060", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "ttyACM0", + exp_perms => "1:2:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "0:0:0000", + exp_rem_error => "yes", + }], +@@ -1935,7 +1925,6 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "1:1:0400", + exp_rem_error => "yes", + }], +@@ -1949,7 +1938,6 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda", + exp_perms => "0:0:0440", + exp_rem_error => "yes", + }], +@@ -2203,6 +2191,44 @@ sub udev_setup { + return 1; + } + ++sub get_devnode { ++ my ($device) = @_; ++ my $devnode; ++ ++ if (defined($device->{devnode})) { ++ $devnode = "$udev_dev/$device->{devnode}"; ++ } else { ++ $devnode = "$device->{devpath}"; ++ $devnode =~ s!.*/!$udev_dev/!; ++ } ++ return $devnode; ++} ++ ++sub check_devnode { ++ my ($device) = @_; ++ my $devnode = get_devnode($device); ++ ++ my @st = lstat("$devnode"); ++ if (! (-b _ || -c _)) { ++ print "add $devnode: error\n"; ++ system("tree", "$udev_dev"); ++ $error++; ++ return undef; ++ } ++ ++ my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, ++ $atime, $mtime, $ctime, $blksize, $blocks) = @st; ++ ++ if (defined($device->{exp_perms})) { ++ permissions_test($device, $uid, $gid, $mode); ++ } ++ if (defined($device->{exp_majorminor})) { ++ major_minor_test($device, $rdev); ++ } ++ print "add $devnode: ok\n"; ++ return $devnode; ++} ++ + sub check_add { + my ($device) = @_; + +@@ -2215,19 +2241,13 @@ sub check_add { + } + } + ++ my $devnode = check_devnode($device); ++ + print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; ++ return if (!defined($device->{exp_name})); ++ + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { +- +- my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, +- $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$device->{exp_name}"); +- +- if (defined($device->{exp_perms})) { +- permissions_test($device, $uid, $gid, $mode); +- } +- if (defined($device->{exp_majorminor})) { +- major_minor_test($device, $rdev); +- } + print "add $device->{devpath}: ok\n"; + } else { + print "add $device->{devpath}: error"; +@@ -2243,12 +2263,32 @@ sub check_add { + } + } + ++sub check_remove_devnode { ++ my ($device) = @_; ++ my $devnode = get_devnode($device); ++ ++ if (-e "$devnode") { ++ print "remove $devnode: error"; ++ print "\n"; ++ system("tree", "$udev_dev"); ++ print "\n"; ++ $error++; ++ sleep(1); ++ } else { ++ print "remove $devnode: ok\n"; ++ } ++} ++ + sub check_remove { + my ($device) = @_; + ++ check_remove_devnode($device); ++ ++ return if (!defined($device->{exp_name})); ++ + if ((-e "$udev_dev/$device->{exp_name}") || + (-l "$udev_dev/$device->{exp_name}")) { +- print "remove $device->{devpath}: error"; ++ print "remove $device->{exp_name}: error"; + if ($device->{exp_rem_error}) { + print " as expected\n"; + } else { +@@ -2259,7 +2299,7 @@ sub check_remove { + sleep(1); + } + } else { +- print "remove $device->{devpath}: ok\n"; ++ print "remove $device->{exp_name}: ok\n"; + } + } + diff --git a/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch b/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch new file mode 100644 index 0000000..3c6e624 --- /dev/null +++ b/SOURCES/0529-test-udev-test.pl-test-correctness-of-symlink-target.patch @@ -0,0 +1,61 @@ +From 8ee1cc626f616a2022d641a464fbde9108dd8ad9 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 10:50:24 +0200 +Subject: [PATCH] test/udev-test.pl: test correctness of symlink targets + +Test if symlinks are created correctly by comparing the symlink +targets to the devnode path. This implies (for the symlink) that +major/minor numbers and permissions are correct, as we have tested +that on the devnode already. + +(cherry picked from commit 997683c8f152e1c139a7ce537de81a0aeae4627f) + +Related: #1642728 +--- + test/udev-test.pl | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index aa9a8dc2ff..2e3089c5e0 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -22,6 +22,7 @@ use POSIX qw(WIFEXITED WEXITSTATUS); + use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); + use IPC::Semaphore; + use Time::HiRes qw(usleep); ++use Cwd qw(getcwd abs_path); + + my $udev_bin = "./test-udev"; + my $valgrind = 0; +@@ -2243,14 +2244,26 @@ sub check_add { + + my $devnode = check_devnode($device); + +- print "device \'$device->{devpath}\' expecting node/link \'$device->{exp_name}\'\n"; + return if (!defined($device->{exp_name})); + +- if ((-e "$udev_dev/$device->{exp_name}") || +- (-l "$udev_dev/$device->{exp_name}")) { +- print "add $device->{devpath}: ok\n"; ++ my @st = lstat("$udev_dev/$device->{exp_name}"); ++ if (-l _) { ++ my $cwd = getcwd(); ++ my $dir = "$udev_dev/$device->{exp_name}"; ++ $dir =~ s!/[^/]*$!!; ++ my $tgt = readlink("$udev_dev/$device->{exp_name}"); ++ $tgt = abs_path("$dir/$tgt"); ++ $tgt =~ s!^$cwd/!!; ++ ++ if ($tgt ne $devnode) { ++ print "symlink $device->{exp_name}: error, found -> $tgt\n"; ++ $error++; ++ system("tree", "$udev_dev"); ++ } else { ++ print "symlink $device->{exp_name}: ok\n"; ++ } + } else { +- print "add $device->{devpath}: error"; ++ print "symlink $device->{exp_name}: error"; + if ($device->{exp_add_error}) { + print " as expected\n"; + } else { diff --git a/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch b/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch new file mode 100644 index 0000000..f004054 --- /dev/null +++ b/SOURCES/0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch @@ -0,0 +1,1607 @@ +From fb8d10456d7d5a085e1adb5bfd45f1cda813ac22 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 17:15:58 +0200 +Subject: [PATCH] test/udev-test.pl: allow checking multiple symlinks + +Instead of testing the existence or non-exisitence of just a single +symlink, allow testing of several links per device. + +Change the test definitions accordingly. + +(cherry picked from commit e62acc3159935781f05fa59c48e5a74e85c61ce2) + +Related: #1642728 +--- + test/udev-test.pl | 495 +++++++++++++++++++++++++++------------------- + 1 file changed, 296 insertions(+), 199 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2e3089c5e0..f5edecefd0 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -71,7 +71,7 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "boot_disk" , ++ exp_links => ["boot_disk"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1", "boot_disk1-4", "boot_disk1-5"], ++ not_exp_links => ["boot_disk1-1", "boot_disk1-2", "boot_disk1-3"] + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1"], ++ not_exp_links => ["boot_diskX1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "boot_disk1" , ++ exp_links => ["boot_disk1", "boot_diskXY1"], ++ not_exp_links => ["boot_diskXX1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0", "catch-all"], + }], + rules => < "catch device by * - take 2", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["modem/0-1", "modem/0-2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem/0" , ++ exp_links => ["modem/0"], ++ not_exp_links => ["modem/0-1", "modem/0-2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "whitespace" , ++ exp_links => ["whitespace"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "aaa", ++ exp_links => ["aaa"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "sub/direct/ory/modem" , ++ exp_links => ["sub/direct/ory/modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "first_disk5" , ++ exp_links => ["first_disk5"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , ++ exp_links => ["Major:8:minor:5:kernelnumber:5:id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node12345678", ++ exp_links => ["node12345678"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk-ATA-sda" , ++ exp_links => ["disk-ATA-sda"], ++ not_exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "special-device-5" , +- not_exp_name => "not" , ++ exp_links => ["special-device-5"], ++ not_exp_links => ["not"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "newline_removed" , ++ exp_links => ["newline_removed"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "test-0:0:0:0" , ++ exp_links => ["test-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo9" , ++ exp_links => ["foo9"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "bar9" , ++ exp_links => ["bar9"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo7", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo7" , ++ exp_links => ["foo7"], ++ not_exp_links => ["foo3", "foo4", "foo5", "foo6", "foo8"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "foo2" , ++ exp_links => ["foo2"], ++ not_exp_links => ["foo1", "foo3"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo9" , ++ exp_links => ["my-foo9"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "my-foo8" , ++ exp_links => ["my-foo8"], ++ not_exp_links => ["my-foo3", "my-foo4", "my-foo5", "my-foo6", "my-foo7", "my-foo9"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", ++ exp_links => ["Major:8-minor:5-kernelnumber:5-id:0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "850:0:0:05" , ++ exp_links => ["850:0:0:05"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "855" , ++ exp_links => ["855"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "8550:0:0:0" , ++ exp_links => ["8550:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY", ++ exp_links => ["TTY"], ++ not_exp_links => ["foo"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "TTY" , ++ exp_links => ["TTY"], ++ not_exp_links => ["foo"], + }], + rules => < [ + { + devpath => "/devices/virtual/tty/console", +- exp_name => "foo" , ++ exp_links => ["foo", "TTY"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "empty" , ++ exp_links => ["empty", "not-something"], ++ not_exp_links => ["something", "not-empty"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "non-existent" , ++ exp_links => ["non-existent", "wrong"], ++ not_exp_links => ["something", "empty", "not-empty", ++ "not-something", "something"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0" , ++ exp_links => ["scsi-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem" , ++ exp_links => ["modem"], + }], + rules => < "/devices/virtual/block/fake!blockdev0", + devnode => "fake/blockdev0", +- exp_name => "is/a/fake/blockdev0" , ++ exp_links => ["is/a/fake/blockdev0"], ++ not_exp_links => ["is/not/a/fake/blockdev0", "modem"], + }], + rules => < "/devices/virtual/block/fake!blockdev0", + devnode => "fake/blockdev0", +- exp_rem_error => "yes", ++ not_exp_links => ["modem"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0"], ++ not_exp_links => ["no-match", "short-id", "not-scsi"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0"], ++ not_exp_links => ["no-match", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "scsi-0:0:0:0", ++ exp_links => ["scsi-0:0:0:0", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-sd", ++ exp_links => ["driver-is-sd"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "driver-is-ahci", ++ exp_links => ["driver-is-ahci"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ignored", ++ exp_links => ["ignored"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "matched-with-space", ++ exp_links => ["matched-with-space"], ++ not_exp_links => ["wrong-to-ignore"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "1::0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => ":1:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "daemon::0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => ":daemon:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "root:audio:0660", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "::0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_perms => "1:1:0777", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "8:0", + }], + rules => < [ + { + devpath => "/devices/virtual/misc/misc-fake1", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "4095:1", + }], + rules => < [ + { + devpath => "/devices/virtual/misc/misc-fake89999", +- exp_name => "node", ++ exp_links => ["node"], + exp_majorminor => "4095:89999", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink2-ttyACM0", ++ exp_links => ["symlink1-0", "symlink2-ttyACM0", "symlink3-"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "one", +- not_exp_name => " ", ++ exp_links => ["one", "two"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < "symlink with space and var with space, part 1", ++ desc => "symlink with space and var with space", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "first", +- not_exp_name => " ", ++ exp_links => ["first"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "name-one_two_three-end", +- not_exp_name => " ", ++ exp_links => ["name-one_two_three-end"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "another_symlink", +- not_exp_name => " ", ++ exp_links => ["another_symlink"], ++ not_exp_links => [" "], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "modem0", ++ exp_links => ["modem0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "second-0" , ++ exp_links => ["first-0", "second-0", "third-0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => ".", ++ exp_links => ["."], + exp_add_error => "yes", + exp_rem_error => "yes", + }], +@@ -1148,7 +1176,7 @@ EOF + devices => [ + { + devpath => "/devices/virtual/tty/tty0", +- exp_name => "link", ++ exp_links => ["link"], + exp_add_error => "yes", + exp_rem_error => "yes", + }], +@@ -1162,7 +1190,7 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink0", ++ exp_links => ["symlink0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "symlink-ttyACM0", ++ exp_links => ["symlink-ttyACM0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "major-166:0", ++ exp_links => ["major-166:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "symlink-0:0:0:0", ++ exp_links => ["symlink-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ exp_links => ["test"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "test", ++ exp_links => ["test"], ++ not_exp_links => ["symlink", "this"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "this", ++ exp_links => ["test", "this"], ++ not_exp_links => ["symlink"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "test", ++ exp_links => ["test", "this"], ++ not_exp_links => ["symlink"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "166:0", ++ exp_links => ["166:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link1", ++ exp_links => ["link1", "link2"], ++ not_exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_name => "link4", ++ exp_links => ["link1", "link2", "link3", "link4"], ++ not_exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], ++ not_exp_links => ["should_not_match", "should_not_match2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], ++ not_exp_links => ["should_not_match"] + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node", ++ exp_links => ["node"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sda-part-1", ++ exp_links => ["sda-part-1"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "start-/dev-end", ++ exp_links => ["start-/dev-end"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "last", ++ exp_links => ["last"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "match", ++ exp_links => ["match", "before"], ++ not_exp_links => ["matches-but-is-negated"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "not-anything", ++ exp_links => ["before", "not-anything"], ++ not_exp_links => ["matches-but-is-negated"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "nonzero-program", ++ exp_links => ["before", "nonzero-program"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true"], ++ not_exp_links => ["bad", "wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true"], ++ not_exp_links => ["bad", "wrong", "no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true", "before"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "true", ++ exp_links => ["true", "before"], ++ not_exp_links => ["no", "bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "part", +- }], ++ exp_links => ["part"], ++ not_exp_links => ["disk"], ++ }, ++ ], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "sane", ++ exp_links => ["sane"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "uber", ++ exp_links => ["uber"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "replaced", ++ exp_links => ["replaced"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "serial-354172020305000", ++ exp_links => ["serial-354172020305000"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], ++ not_exp_links => ["not-1-ok", "not-2-ok", "not-3-ok"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], ++ not_exp_links => ["unknown-not-ok"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], + exp_perms => "root:tty:0640", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "ok", ++ exp_links => ["ok"], + exp_perms => "root:tty:0640", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "node-add-me", ++ exp_links => ["node-add-me"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "three", +- not_exp_name => "two", ++ exp_links => ["three"], ++ not_exp_links => ["two", "one"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", +- not_exp_name => "wrong", ++ exp_links => ["right"], ++ not_exp_links => ["wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right", "before"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right", "before"], ++ not_exp_links => ["nomatch"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_links => ["nomatch", "wrong1", "wrong2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_links => ["nomatch", "wrong1", "wrong2", "wrong3"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "parent", ++ exp_links => ["parent"], + }], + option => "keep", + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "parentenv-parent_right", ++ exp_links => ["parentenv-parent_right"], + }], + option => "clean", + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ exp_links => ["right"], ++ not_exp_test => ["wrong", "wrong2"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", ++ exp_links => ["right"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "right", +- not_exp_name => "wrong", ++ exp_links => ["right", "link"], ++ not_exp_links => ["wrong"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ exp_links => ["yes"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ exp_links => ["yes"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_name => "yes", ++ exp_links => ["yes"], ++ not_exp_links => ["no"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "00:16:41:e2:8d:ff", ++ exp_links => ["00:16:41:e2:8d:ff"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "there", ++ exp_links => ["there"], ++ not_exp_links => ["notthere"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "yes", ++ exp_links => ["yes"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "relative", ++ exp_links => ["relative"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found-subdir", ++ exp_links => ["found-subdir"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "sda-8741C4G-end", ++ exp_links => ["sda-8741C4G-end"], + exp_perms => "0:0:0600", + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", ++ exp_links => ["disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", +- not_exp_name => "bad" , ++ exp_links => ["found"], ++ not_exp_links => ["bad"], + }], + rules => < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + }], + rules => $rules_10k_tags . < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => $rules_10k_tags_continuation . < [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + + }], +@@ -2046,7 +2098,7 @@ TAGS=="aaa", SYMLINK+="bad" + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_name => "found", ++ exp_links => ["found"], + not_exp_name => "bad", + }], + rules => <{not_exp_name})) { +- if ((-e "$udev_dev/$device->{not_exp_name}") || +- (-l "$udev_dev/$device->{not_exp_name}")) { +- print "nonexistent: error \'$device->{not_exp_name}\' not expected to be there\n"; +- $error++; +- sleep(1); +- } +- } ++sub get_link_target { ++ my ($link) = @_; + +- my $devnode = check_devnode($device); ++ my $cwd = getcwd(); ++ my $dir = "$udev_dev/$link"; ++ my $tgt = readlink("$udev_dev/$link"); ++ $dir =~ s!/[^/]*$!!; ++ $tgt = abs_path("$dir/$tgt"); ++ $tgt =~ s!^$cwd/!!; ++ return $tgt; ++} + +- return if (!defined($device->{exp_name})); ++sub check_link_add { ++ my ($link, $devnode, $err_expected) = @_; + +- my @st = lstat("$udev_dev/$device->{exp_name}"); ++ my @st = lstat("$udev_dev/$link"); + if (-l _) { +- my $cwd = getcwd(); +- my $dir = "$udev_dev/$device->{exp_name}"; +- $dir =~ s!/[^/]*$!!; +- my $tgt = readlink("$udev_dev/$device->{exp_name}"); +- $tgt = abs_path("$dir/$tgt"); +- $tgt =~ s!^$cwd/!!; ++ my $tgt = get_link_target($link); + + if ($tgt ne $devnode) { +- print "symlink $device->{exp_name}: error, found -> $tgt\n"; ++ print "symlink $link: error, found -> $tgt\n"; + $error++; + system("tree", "$udev_dev"); + } else { +- print "symlink $device->{exp_name}: ok\n"; ++ print "symlink $link: ok\n"; + } + } else { +- print "symlink $device->{exp_name}: error"; +- if ($device->{exp_add_error}) { ++ print "symlink $link: error"; ++ if ($err_expected) { + print " as expected\n"; + } else { + print "\n"; +@@ -2276,6 +2322,49 @@ sub check_add { + } + } + ++sub check_link_nonexistent { ++ my ($link, $devnode, $err_expected) = @_; ++ ++ if ((-e "$udev_dev/$link") || (-l "$udev_dev/$link")) { ++ my $tgt = get_link_target($link); ++ ++ if ($tgt ne $devnode) { ++ print "nonexistent: '$link' points to other device (ok)\n"; ++ } else { ++ print "nonexistent: error \'$link\' should not be there"; ++ if ($err_expected) { ++ print " (as expected)\n"; ++ } else { ++ print "\n"; ++ system("tree", "$udev_dev"); ++ print "\n"; ++ $error++; ++ sleep(1); ++ } ++ } ++ } else { ++ print "nonexistent $link: ok\n"; ++ } ++} ++ ++sub check_add { ++ my ($device) = @_; ++ my $devnode = check_devnode($device); ++ ++ if (defined($device->{exp_links})) { ++ foreach my $link (@{$device->{exp_links}}) { ++ check_link_add($link, $devnode, ++ $device->{exp_add_error}); ++ } ++ } ++ if (defined $device->{not_exp_links}) { ++ foreach my $link (@{$device->{not_exp_links}}) { ++ check_link_nonexistent($link, $devnode, ++ $device->{exp_nodev_error}); ++ } ++ } ++} ++ + sub check_remove_devnode { + my ($device) = @_; + my $devnode = get_devnode($device); +@@ -2292,17 +2381,13 @@ sub check_remove_devnode { + } + } + +-sub check_remove { +- my ($device) = @_; ++sub check_link_remove { ++ my ($link, $err_expected) = @_; + +- check_remove_devnode($device); +- +- return if (!defined($device->{exp_name})); +- +- if ((-e "$udev_dev/$device->{exp_name}") || +- (-l "$udev_dev/$device->{exp_name}")) { +- print "remove $device->{exp_name}: error"; +- if ($device->{exp_rem_error}) { ++ if ((-e "$udev_dev/$link") || ++ (-l "$udev_dev/$link")) { ++ print "remove $link: error"; ++ if ($err_expected) { + print " as expected\n"; + } else { + print "\n"; +@@ -2312,7 +2397,19 @@ sub check_remove { + sleep(1); + } + } else { +- print "remove $device->{exp_name}: ok\n"; ++ print "remove $link: ok\n"; ++ } ++} ++ ++sub check_remove { ++ my ($device) = @_; ++ ++ check_remove_devnode($device); ++ ++ return if (!defined($device->{exp_links})); ++ ++ foreach my $link (@{$device->{exp_links}}) { ++ check_link_remove($link, $device->{exp_rem_error}); + } + } + diff --git a/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch b/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch new file mode 100644 index 0000000..9c2ee94 --- /dev/null +++ b/SOURCES/0531-test-udev-test.pl-fix-wrong-test-descriptions.patch @@ -0,0 +1,83 @@ +From 0e0b90ffcf0731865846bfa2754a809cc2b8c53e Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 17:57:47 +0200 +Subject: [PATCH] test/udev-test.pl: fix wrong test descriptions + +udev hasn't supported renaming device nodes for some time. + +(cherry picked from commit 46bc71b2b73f8a1e27dc5e142730e9877dd05e3e) + +Related: #1642728 +--- + test/udev-test.pl | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index f5edecefd0..d5d0e130e3 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -212,7 +212,7 @@ KERNEL=="ttyACM[0-9]*", SYMLINK+="modem/%n" + EOF + }, + { +- desc => "replace kernel name", ++ desc => "don't replace kernel name", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -223,7 +223,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle comment lines in config file (and replace kernel name)", ++ desc => "Handle comment lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -236,7 +236,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle comment lines in config file with whitespace (and replace kernel name)", ++ desc => "Handle comment lines in config file with whitespace (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -249,7 +249,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle whitespace only lines (and replace kernel name)", ++ desc => "Handle whitespace only lines (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -267,7 +267,7 @@ KERNEL=="ttyACM0", SYMLINK+="whitespace" + EOF + }, + { +- desc => "Handle empty lines in config file (and replace kernel name)", ++ desc => "Handle empty lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -280,7 +280,7 @@ KERNEL=="ttyACM0", SYMLINK+="modem" + EOF + }, + { +- desc => "Handle backslashed multi lines in config file (and replace kernel name)", ++ desc => "Handle backslashed multi lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +@@ -303,8 +303,9 @@ EOF + KERNEL=="ttyACM0", PROGRAM=="/bin/echo -e \\101", RESULT=="A", SYMLINK+="aaa" + EOF + }, ++ # 20 + { +- desc => "Handle stupid backslashed multi lines in config file (and replace kernel name)", ++ desc => "Handle stupid backslashed multi lines in config file (and don't replace kernel name)", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", diff --git a/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch b/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch new file mode 100644 index 0000000..72021fb --- /dev/null +++ b/SOURCES/0532-test-udev-test.pl-last_rule-is-unsupported.patch @@ -0,0 +1,35 @@ +From 2d0b828715e67f7accda6f73481deb74febebcb6 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 18:08:18 +0200 +Subject: [PATCH] test/udev-test.pl: last_rule is unsupported + +the "last_rule" option hasn't been supported for some time. +Therefore this test fails if a "not_exp_links" attribute is added, +as it should be. Mark it appropriately. + +(cherry picked from commit 17cce031531a5d3f38a27374c99d1bdba5959dbd) + +Related: #1642728 +--- + test/udev-test.pl | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index d5d0e130e3..a9c2dd95f1 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1373,11 +1373,14 @@ SUBSYSTEMS=="scsi", KERNEL=="sda1", SYMLINK+="start-%r-end" + EOF + }, + { ++ # This is not supported any more + desc => "last_rule option", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_links => ["last"], ++ not_exp_links => ["very-last"], ++ exp_nodev_error => "yes", + }], + rules => < +Date: Tue, 24 Apr 2018 18:09:50 +0200 +Subject: [PATCH] test/udev-test.pl: Make some tests a little harder + +Add some rules that make it a bit harder to pass, mainly the +non-existence checks. + +(cherry picked from commit 06d4d4e24e7d0b51120b165e540d278842e8b1a3) + +Related: #1642728 +--- + test/udev-test.pl | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index a9c2dd95f1..7465b5859e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1358,7 +1358,7 @@ EOF + exp_links => ["sda-part-1"], + }], + rules => < ["part"], + not_exp_links => ["disk"], + }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", ++ exp_links => ["disk"], ++ not_exp_links => ["part"], ++ }, + ], + rules => < < < "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_perms => "1:1:0400", +- exp_rem_error => "yes", + }], + rules => < +Date: Tue, 24 Apr 2018 18:16:59 +0200 +Subject: [PATCH] test/udev-test.pl: remove bogus rules from magic subsys test + +These rules have survived from an ancient version of the code +and save no purpose any more. + +(cherry picked from commit 86634df43b715f3f77c7de73a3ef6566e5cdf571) + +Related: #1642728 +--- + test/udev-test.pl | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 7465b5859e..6928439d14 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2017,8 +2017,6 @@ EOF + exp_perms => "0:0:0600", + }], + rules => < +Date: Tue, 24 Apr 2018 18:27:25 +0200 +Subject: [PATCH] test/udev-test.pl: merge "space and var with space" tests + +As we can check multiple links in a single test now, these 3 +tests can be merged into one. + +(cherry picked from commit 2084fe0d3290c525ecb9faa07d07c3abc2488e59) + +Related: #1642728 +--- + test/udev-test.pl | 31 +++---------------------------- + 1 file changed, 3 insertions(+), 28 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 6928439d14..880a73b10b 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1103,34 +1103,9 @@ EOF + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["first"], +- not_exp_links => [" "], +- }], +- rules => < "symlink with space and var with space, part 2", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["name-one_two_three-end"], +- not_exp_links => [" "], +- }], +- rules => < "symlink with space and var with space, part 3", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", +- exp_links => ["another_symlink"], +- not_exp_links => [" "], ++ exp_links => ["first", "name-one_two_three-end", ++ "another_symlink", "a", "b", "c"], ++ not_exp_links => [" "], + }], + rules => < +Date: Tue, 24 Apr 2018 18:30:09 +0200 +Subject: [PATCH] test/udev-test.pl: merge import parent tests into one + +As we can test multiple devices and multiple links per device +in one test now, these two tests can be merged into one. + +(cherry picked from commit a96cd21d31cb7af211862768e133b50b085634e7) + +Related: #1642728 +--- + test/udev-test.pl | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 880a73b10b..0344d2e89c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1781,28 +1781,21 @@ TAGS=="aaa||bbb||ccc", SYMLINK+="bad" + EOF + }, + { +- desc => "IMPORT parent test sequence 1/2 (keep)", ++ desc => "IMPORT parent test", + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_links => ["parent"], +- }], +- option => "keep", +- rules => < "IMPORT parent test sequence 2/2 (keep)", +- devices => [ ++ }, + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_links => ["parentenv-parent_right"], + }], +- option => "clean", ++ sleep_us => 500000, # Serialized! We need to sleep here after adding sda + rules => < +Date: Tue, 24 Apr 2018 20:55:01 +0200 +Subject: [PATCH] test/udev-test.pl: count "good" results + +This is helpful to catch possible regressions in the test. +Also, don't count wait() errors, they are likely not udev errors. + +(cherry picked from commit b95c43982ab7d0253b552ad56cffb3d68fcbb4f6) + +Related: #1642728 +--- + test/udev-test.pl | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 0344d2e89c..813be70739 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2114,6 +2114,7 @@ sub udev { + } + + my $error = 0; ++my $good = 0; + + sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; +@@ -2144,6 +2145,7 @@ sub permissions_test { + } + if ($wrong == 0) { + print "permissions: ok\n"; ++ $good++; + } else { + printf " expected permissions are: %s:%s:%#o\n", $1, $2, oct($3); + printf " created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; +@@ -2169,6 +2171,7 @@ sub major_minor_test { + } + if ($wrong == 0) { + print "major:minor: ok\n"; ++ $good++; + } else { + printf " expected major:minor is: %i:%i\n", $1, $2; + printf " created major:minor is : %i:%i\n", $major, $minor; +@@ -2254,6 +2257,7 @@ sub check_devnode { + major_minor_test($device, $rdev); + } + print "add $devnode: ok\n"; ++ $good++; + return $devnode; + } + +@@ -2282,11 +2286,13 @@ sub check_link_add { + system("tree", "$udev_dev"); + } else { + print "symlink $link: ok\n"; ++ $good++; + } + } else { + print "symlink $link: error"; + if ($err_expected) { + print " as expected\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2305,10 +2311,12 @@ sub check_link_nonexistent { + + if ($tgt ne $devnode) { + print "nonexistent: '$link' points to other device (ok)\n"; ++ $good++; + } else { + print "nonexistent: error \'$link\' should not be there"; + if ($err_expected) { + print " (as expected)\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2319,6 +2327,7 @@ sub check_link_nonexistent { + } + } else { + print "nonexistent $link: ok\n"; ++ $good++; + } + } + +@@ -2353,6 +2362,7 @@ sub check_remove_devnode { + sleep(1); + } else { + print "remove $devnode: ok\n"; ++ $good++; + } + } + +@@ -2364,6 +2374,7 @@ sub check_link_remove { + print "remove $link: error"; + if ($err_expected) { + print " as expected\n"; ++ $good++; + } else { + print "\n"; + system("tree", "$udev_dev"); +@@ -2373,6 +2384,7 @@ sub check_link_remove { + } + } else { + print "remove $link: ok\n"; ++ $good++; + } + } + +@@ -2432,7 +2444,6 @@ sub fork_and_run_udev { + $pid = waitpid($dev->{pid}, 0); + if ($pid == -1) { + print "error waiting for pid dev->{pid}\n"; +- $error += 1; + } + if (WIFEXITED($?)) { + $rc = WEXITSTATUS($?); +@@ -2440,6 +2451,8 @@ sub fork_and_run_udev { + if ($rc) { + print "$udev_bin $action for $dev->{devpath} failed with code $rc\n"; + $error += 1; ++ } else { ++ $good++; + } + } + } +@@ -2549,7 +2562,7 @@ if ($list[0]) { + } + + $sema->remove; +-print "$error errors occurred\n\n"; ++print "$error errors occurred. $good good results.\n\n"; + + cleanup(); + diff --git a/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch b/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch new file mode 100644 index 0000000..e01add4 --- /dev/null +++ b/SOURCES/0538-tests-udev-test.pl-add-multiple-device-test.patch @@ -0,0 +1,199 @@ +From 8ab9d11b925e7f39b350ce69a1e28752de411b35 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 24 Apr 2018 22:04:55 +0200 +Subject: [PATCH] tests/udev-test.pl: add multiple device test + +Add 4 new tests using multiple devices. Number 2-4 use many +devices claiming the same symlink, where only one device has +a higher priority thatn the others. They fail sporadically with +the current code, if a race condition causes the symlink to point +to the wrong device. Test 4 is like test 2 with sleeps in between, +it's much less likely to fail. + +(cherry picked from commit 4a0ec82daf32446519e1d86329bb802325b82104) + +Related: #1642728 +--- + test/udev-test.pl | 169 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 169 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 813be70739..d964c664b6 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2085,6 +2085,175 @@ KERNEL=="sda", TAG+="aaa" \\ + KERNEL=="sdb", TAG+="bbb" + TAGS=="foo", SYMLINK+="found" + TAGS=="aaa", SYMLINK+="bad" ++EOF ++ }, ++ { ++ desc => "multiple devices", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, positive prio", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, negative prio", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ rules => < "multiple devices, same link name, positive prio, sleep", ++ devices => [ ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", ++ exp_links => ["part-1"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", ++ exp_links => ["part-5"], ++ not_exp_links => ["partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", ++ not_exp_links => ["partition"], ++ exp_links => ["part-6"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", ++ exp_links => ["part-7", "partition"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", ++ not_exp_links => ["partition"], ++ exp_links => ["part-8"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", ++ not_exp_links => ["partition"], ++ exp_links => ["part-9"], ++ }, ++ { ++ devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", ++ not_exp_links => ["partition"], ++ exp_links => ["part-10"], ++ }, ++ ], ++ sleep_us => 10000, ++ rules => < +Date: Tue, 24 Apr 2018 22:24:43 +0200 +Subject: [PATCH] test/udev-test.pl: add repeat count + +for easier reproduction of sporadic test failures. + +(cherry picked from commit 2ab0a8d00bc48d3531e953d938db889d8a932d65) + +Related: #1642728 +--- + test/udev-test.pl | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index d964c664b6..8b1ab3c06c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2125,6 +2125,7 @@ EOF + }, + { + desc => "multiple devices, same link name, positive prio", ++ repeat => 100, + devices => [ + { + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +@@ -2635,6 +2636,7 @@ sub run_test { + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); + ++ REPEAT: + fork_and_run_udev("add", $rules, $sema); + + foreach my $dev (@devices) { +@@ -2653,6 +2655,9 @@ sub run_test { + } + + print "\n"; ++ if (defined($rules->{repeat}) && --($rules->{repeat}) > 0) { ++ goto REPEAT; ++ } + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + udev_setup(); diff --git a/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch b/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch new file mode 100644 index 0000000..02e407d --- /dev/null +++ b/SOURCES/0540-test-udev-test.pl-generator-for-large-list-of-block-.patch @@ -0,0 +1,101 @@ +From 6c3191e979165700f98903b76621c214186a110c Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 25 Apr 2018 09:54:26 +0200 +Subject: [PATCH] test/udev-test.pl: generator for large list of block devices + +Manually listing all devices in the test definition becomes cumbersome with +lots of devices. Add a function that scans on all block devices in +the test sysfs and generates a list of devices to test. + +(cherry picked from commit eb44d715ebee2fe11288433b99f8e1dc5fdac84a) + +Related: #1642728 +--- + test/udev-test.pl | 60 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 59 insertions(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 8b1ab3c06c..2866fdb77a 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -50,6 +50,50 @@ for (my $i = 1; $i < 10000; ++$i) { + } + $rules_10k_tags_continuation .= "TAG+=\"test10000\"\\n"; + ++# Create a device list with all block devices under /sys ++# (except virtual devices and cd-roms) ++# the optional argument exp_func returns expected and non-expected ++# symlinks for the device. ++sub all_block_devs { ++ my ($exp_func) = @_; ++ my @devices; ++ ++ foreach my $bd (glob "$udev_sys/dev/block/*") { ++ my $tgt = readlink($bd); ++ my ($exp, $notexp) = (undef, undef); ++ ++ next if ($tgt =~ m!/virtual/! || $tgt =~ m!/sr[0-9]*$!); ++ ++ $tgt =~ s!^\.\./\.\.!!; ++ ($exp, $notexp) = $exp_func->($tgt) if defined($exp_func); ++ my $device = { ++ devpath => $tgt, ++ exp_links => $exp, ++ not_exp_links => $notexp, ++ }; ++ push(@devices, $device); ++ } ++ return \@devices; ++} ++ ++# This generator returns a suitable exp_func for use with ++# all_block_devs(). ++sub expect_for_some { ++ my ($pattern, $links, $donot) = @_; ++ my $_expect = sub { ++ my ($name) = @_; ++ ++ if ($name =~ /$pattern/) { ++ return ($links, undef); ++ } elsif ($donot) { ++ return (undef, $links); ++ } else { ++ return (undef, undef); ++ } ++ }; ++ return $_expect; ++} ++ + my @tests = ( + { + desc => "no rules", +@@ -2257,6 +2301,15 @@ SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNEL=="sda?*", ENV{DEVTYPE}=="partitio + KERNEL=="*7", OPTIONS+="link_priority=10" + EOF + }, ++ { ++ desc => 'all_block_devs', ++ generator => expect_for_some("\\/sda6\$", ["blockdev"]), ++ repeat => 10, ++ rules => <{devices}}; ++ my @devices; ++ ++ if (!defined $rules->{devices}) { ++ $rules->{devices} = all_block_devs($rules->{generator}); ++ } ++ @devices = @{$rules->{devices}}; + + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); diff --git a/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch b/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch new file mode 100644 index 0000000..fbe9d4b --- /dev/null +++ b/SOURCES/0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch @@ -0,0 +1,29 @@ +From 453df9eb2bbfa34f3e4b78e917812f0ac6958010 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 26 Apr 2018 13:25:11 +0200 +Subject: [PATCH] test/udev-test.pl: suppress umount error message at startup + +umount emits an error message "no mount point specified" if the +tmpfs isn't mounted yet, which is the normal case. +Suppress that by redirecting stderr. + +(cherry picked from commit f1cb0860549e775be5f91237b5a3b97698dd14dd) + +Related: #1642728 +--- + test/udev-test.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 2866fdb77a..33a76ad292 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2405,7 +2405,7 @@ sub major_minor_test { + } + + sub udev_setup { +- system("umount", $udev_tmpfs); ++ system("umount \"$udev_tmpfs\" 2>/dev/null"); + rmdir($udev_tmpfs); + mkdir($udev_tmpfs) || die "unable to create udev_tmpfs: $udev_tmpfs\n"; + diff --git a/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch b/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch new file mode 100644 index 0000000..d1f61ca --- /dev/null +++ b/SOURCES/0542-test-udev_test.pl-add-expected-good-count.patch @@ -0,0 +1,78 @@ +From e0cee95e0cc401ce120a1b56cdb7a8b9afbd6bcf Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 26 Apr 2018 14:07:27 +0200 +Subject: [PATCH] test/udev_test.pl: add "expected good" count + +Since 'test/udev-test.pl: count "good" results', we know how many +checks succeeded. Add an "expected good" count to make that number +more meaningful. + +(cherry picked from commit cbeb23d863d540408cd1fb274d78213f59639df2) + +Related: #1642728 +--- + test/udev-test.pl | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 33a76ad292..cf6ca6b80c 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2338,6 +2338,7 @@ sub udev { + + my $error = 0; + my $good = 0; ++my $exp_good = 0; + + sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; +@@ -2685,12 +2686,27 @@ sub run_test { + my ($rules, $number, $sema) = @_; + my $rc; + my @devices; ++ my $ntests; ++ my $cur_good = $good; ++ my $cur_error = $error; + + if (!defined $rules->{devices}) { + $rules->{devices} = all_block_devs($rules->{generator}); + } + @devices = @{$rules->{devices}}; ++ # For each device: exit status and devnode test for add & remove ++ $ntests += 4 * ($#devices + 1); + ++ foreach my $dev (@devices) { ++ $ntests += 2 * ($#{$dev->{exp_links}} + 1) ++ + ($#{$dev->{not_exp_links}} + 1) ++ + (defined $dev->{exp_perms} ? 1 : 0) ++ + (defined $dev->{exp_majorminor} ? 1 : 0); ++ } ++ if (defined $rules->{repeat}) { ++ $ntests *= $rules->{repeat}; ++ } ++ $exp_good += $ntests; + print "TEST $number: $rules->{desc}\n"; + create_rules(\$rules->{rules}); + +@@ -2712,10 +2728,11 @@ sub run_test { + check_remove($dev); + } + +- print "\n"; + if (defined($rules->{repeat}) && --($rules->{repeat}) > 0) { + goto REPEAT; + } ++ printf "TEST $number: errors: %d good: %d/%d\n\n", $error-$cur_error, ++ $good-$cur_good, $ntests; + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + udev_setup(); +@@ -2794,7 +2811,7 @@ if ($list[0]) { + } + + $sema->remove; +-print "$error errors occurred. $good good results.\n\n"; ++print "$error errors occurred. $good/$exp_good good results.\n\n"; + + cleanup(); + diff --git a/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch b/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch new file mode 100644 index 0000000..3e5c348 --- /dev/null +++ b/SOURCES/0543-test-udev-test-gracefully-exit-when-imports-fail.patch @@ -0,0 +1,48 @@ +From 2e50a00f6930f1c65ca804b78f4a853e2ae2d2c0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 17 Nov 2020 17:13:31 +0100 +Subject: [PATCH] test/udev-test: gracefully exit when imports fail + +In Fedora rawhide various perl modules are now available as separate +packages that are not pulled in by dependencies. If we don't have some +package, skip the tests. + +This ugly code is apparently the way to do conditional imports: +https://www.cs.ait.ac.th/~on/O/oreilly/perl/cookbook/ch12_03.htm. + +(cherry picked from commit d40763838278246e2073d15ca927ee700e583afc) + +Related: #1642728 +--- + test/udev-test.pl | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index cf6ca6b80c..5b1e33504e 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -18,11 +18,19 @@ + + use warnings; + use strict; +-use POSIX qw(WIFEXITED WEXITSTATUS); +-use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); +-use IPC::Semaphore; +-use Time::HiRes qw(usleep); +-use Cwd qw(getcwd abs_path); ++ ++BEGIN { ++ my $EXIT_TEST_SKIP = 77; ++ ++ unless (eval "use POSIX qw(WIFEXITED WEXITSTATUS); ++ use Cwd qw(getcwd abs_path); ++ use IPC::Semaphore; ++ use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT); ++ use Time::HiRes qw(usleep); 1") { ++ warn "Failed to import dependencies, skipping the test: $@"; ++ exit($EXIT_TEST_SKIP); ++ } ++} + + my $udev_bin = "./test-udev"; + my $valgrind = 0; diff --git a/SOURCES/0544-Revert-test-add-test-cases-for-empty-string-match-an.patch b/SOURCES/0544-Revert-test-add-test-cases-for-empty-string-match-an.patch new file mode 100644 index 0000000..fcfec2d --- /dev/null +++ b/SOURCES/0544-Revert-test-add-test-cases-for-empty-string-match-an.patch @@ -0,0 +1,123 @@ +From b05c8d2e10c773b9bcae17055be48a2291ca6fa6 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 2 Mar 2021 12:57:59 -0500 +Subject: [PATCH] Revert "test: add test cases for empty string match" and + "test: add test case for multi matches when use ||" + +This effectively reverts commits 03bc565e6e3249385c4e1ca0ae27670ca2ad9a41 +and 03b766cc937ffa4dcb7cfb25b2ac20d8a00cb6db. + +Resolves: #1931947 +--- + test/udev-test.pl | 98 ----------------------------------------------- + 1 file changed, 98 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 5b1e33504e..0612859cda 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -1732,104 +1732,6 @@ KERNEL=="dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong1" + KERNEL=="X|attyACM0|dontknow|ttyACM0a|nothing|attyACM0", SYMLINK+="wrong2" + KERNEL=="all|dontknow|ttyACM0", SYMLINK+="right" + KERNEL=="ttyACM0a|nothing", SYMLINK+="wrong3" +-EOF +- }, +- { +- desc => "test multi matches 5", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 6", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 7", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 8", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 9", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 10", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < "test multi matches 11", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", +- exp_links => ["found"], +- not_exp_name => "bad", +- }], +- rules => < +Date: Tue, 24 Apr 2018 21:40:23 +0200 +Subject: [PATCH] test/sys-script.py: add missing DEVNAME entries to uevents + +Resolves: #1931947 +--- + test/sys-script.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/test/sys-script.py b/test/sys-script.py +index a51112603e..f4a847e356 100755 +--- a/test/sys-script.py ++++ b/test/sys-script.py +@@ -11677,6 +11677,7 @@ f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0: + f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/uevent', 0o644, b'''MAJOR=8 + MINOR=16 + DEVTYPE=disk ++DEVNAME=sdb + ''') + d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue', 0o755) + l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/bsg', '../../../bsg/7:0:0:0') +@@ -11709,6 +11710,7 @@ f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0: + f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/uevent', 0o644, b'''MAJOR=8 + MINOR=17 + DEVTYPE=partition ++DEVNAME=sdb1 + ''') + d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/power', 0o755) + f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/power/wakeup', 0o644, b'\n') +@@ -13150,6 +13152,7 @@ f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10 + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/uevent', 0o644, b'''MAJOR=8 + MINOR=10 + DEVTYPE=partition ++DEVNAME=sda10 + ''') + d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/power', 0o755) + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/power/wakeup', 0o644, b'\n') +@@ -13163,6 +13166,7 @@ f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/ + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/uevent', 0o644, b'''MAJOR=8 + MINOR=9 + DEVTYPE=partition ++DEVNAME=sda9 + ''') + d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/holders', 0o755) + l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/holders/md0', '../../../../../../../../../virtual/block/md0') +@@ -13178,6 +13182,7 @@ f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/ + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/uevent', 0o644, b'''MAJOR=8 + MINOR=7 + DEVTYPE=partition ++DEVNAME=sda7 + ''') + d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/power', 0o755) + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/power/wakeup', 0o644, b'\n') +@@ -13205,6 +13210,7 @@ f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/ + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/uevent', 0o644, b'''MAJOR=8 + MINOR=8 + DEVTYPE=partition ++DEVNAME=sda8 + ''') + d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/power', 0o755) + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/power/wakeup', 0o644, b'\n') +@@ -13232,6 +13238,7 @@ f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/ + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/uevent', 0o644, b'''MAJOR=8 + MINOR=6 + DEVTYPE=partition ++DEVNAME=sda6 + ''') + d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/power', 0o755) + f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/power/wakeup', 0o644, b'\n') diff --git a/SOURCES/0546-sd-event-split-out-helper-functions-for-reshuffling-.patch b/SOURCES/0546-sd-event-split-out-helper-functions-for-reshuffling-.patch new file mode 100644 index 0000000..afc2d7e --- /dev/null +++ b/SOURCES/0546-sd-event-split-out-helper-functions-for-reshuffling-.patch @@ -0,0 +1,207 @@ +From 4ce10f8e41a85a56ad9b805442eb1149ece7c82a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Fri, 23 Oct 2020 18:29:27 +0200 +Subject: [PATCH] sd-event: split out helper functions for reshuffling prioqs + +We typically don't just reshuffle a single prioq at once, but always +two. Let's add two helper functions that do this, and reuse them +everywhere. + +(Note that this drops one minor optimization: +sd_event_source_set_time_accuracy() previously only reshuffled the +"latest" prioq, since changing the accuracy has no effect on the +earliest time of an event source, just the latest time an event source +can run. This optimization is removed to simplify things, given that +it's not really worth the effort as prioq_reshuffle() on properly +ordered prioqs has practically zero cost O(1)). + +(Slightly generalized, commented and split out of #17284 by Lennart) + +(cherry picked from commit e1951c16a8fbe5b0b9ecc08f4f835a806059d28f) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 96 ++++++++++++------------------ + 1 file changed, 38 insertions(+), 58 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 0d3bf5cbb6..47f99eb096 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -889,6 +889,33 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig) + event_unmask_signal_data(e, d, sig); + } + ++static void event_source_pp_prioq_reshuffle(sd_event_source *s) { ++ assert(s); ++ ++ /* Reshuffles the pending + prepare prioqs. Called whenever the dispatch order changes, i.e. when ++ * they are enabled/disabled or marked pending and such. */ ++ ++ if (s->pending) ++ prioq_reshuffle(s->event->pending, s, &s->pending_index); ++ ++ if (s->prepare) ++ prioq_reshuffle(s->event->prepare, s, &s->prepare_index); ++} ++ ++static void event_source_time_prioq_reshuffle(sd_event_source *s) { ++ struct clock_data *d; ++ ++ assert(s); ++ assert(EVENT_SOURCE_IS_TIME(s->type)); ++ ++ /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, ++ * pending, enable state. Makes sure the two prioq's are ordered properly again. */ ++ assert_se(d = event_get_clock_data(s->event, s->type)); ++ prioq_reshuffle(d->earliest, s, &s->time.earliest_index); ++ prioq_reshuffle(d->latest, s, &s->time.latest_index); ++ d->needs_rearm = true; ++} ++ + static void source_disconnect(sd_event_source *s) { + sd_event *event; + +@@ -1052,16 +1079,8 @@ static int source_set_pending(sd_event_source *s, bool b) { + } else + assert_se(prioq_remove(s->event->pending, s, &s->pending_index)); + +- if (EVENT_SOURCE_IS_TIME(s->type)) { +- struct clock_data *d; +- +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; +- } ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ event_source_time_prioq_reshuffle(s); + + if (s->type == SOURCE_SIGNAL && !b) { + struct signal_data *d; +@@ -2215,11 +2234,7 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) + } else + s->priority = priority; + +- if (s->pending) +- prioq_reshuffle(s->event->pending, s, &s->pending_index); +- +- if (s->prepare) +- prioq_reshuffle(s->event->prepare, s, &s->prepare_index); ++ event_source_pp_prioq_reshuffle(s); + + if (s->type == SOURCE_EXIT) + prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +@@ -2280,18 +2295,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { + case SOURCE_TIME_BOOTTIME: + case SOURCE_TIME_MONOTONIC: + case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: { +- struct clock_data *d; +- ++ case SOURCE_TIME_BOOTTIME_ALARM: + s->enabled = m; +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; ++ event_source_time_prioq_reshuffle(s); + break; +- } + + case SOURCE_SIGNAL: + s->enabled = m; +@@ -2346,18 +2353,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { + case SOURCE_TIME_BOOTTIME: + case SOURCE_TIME_MONOTONIC: + case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: { +- struct clock_data *d; +- ++ case SOURCE_TIME_BOOTTIME_ALARM: + s->enabled = m; +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; ++ event_source_time_prioq_reshuffle(s); + break; +- } + + case SOURCE_SIGNAL: + +@@ -2405,11 +2404,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { + } + } + +- if (s->pending) +- prioq_reshuffle(s->event->pending, s, &s->pending_index); +- +- if (s->prepare) +- prioq_reshuffle(s->event->prepare, s, &s->prepare_index); ++ event_source_pp_prioq_reshuffle(s); + + return 0; + } +@@ -2425,7 +2420,6 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) { + } + + _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { +- struct clock_data *d; + int r; + + assert_return(s, -EINVAL); +@@ -2439,13 +2433,7 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { + + s->time.next = usec; + +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; +- ++ event_source_time_prioq_reshuffle(s); + return 0; + } + +@@ -2460,7 +2448,6 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use + } + + _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) { +- struct clock_data *d; + int r; + + assert_return(s, -EINVAL); +@@ -2478,12 +2465,7 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec + + s->time.accuracy = usec; + +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; +- ++ event_source_time_prioq_reshuffle(s); + return 0; + } + +@@ -2773,9 +2755,7 @@ static int process_timer( + if (r < 0) + return r; + +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; ++ event_source_time_prioq_reshuffle(s); + } + + return 0; diff --git a/SOURCES/0547-sd-event-split-out-enable-and-disable-codepaths-from.patch b/SOURCES/0547-sd-event-split-out-enable-and-disable-codepaths-from.patch new file mode 100644 index 0000000..040b83f --- /dev/null +++ b/SOURCES/0547-sd-event-split-out-enable-and-disable-codepaths-from.patch @@ -0,0 +1,306 @@ +From d7ad6ad123200f562081ff09f7bed3c6d969ac0a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 23 Oct 2020 21:21:58 +0200 +Subject: [PATCH] sd-event: split out enable and disable codepaths from + sd_event_source_set_enabled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far half of sd_event_source_set_enabled() was doing enabling, the +other half was doing disabling. Let's split that into two separate +calls. + +(This also adds a new shortcut to sd_event_source_set_enabled(): if the +caller toggles between "ON" and "ONESHOT" we'll now shortcut this, since +the event source is already enabled in that case and shall remain +enabled.) + +This heavily borrows and is inspired from Michal Sekletár's #17284 +refactoring. + +(cherry picked from commit ddfde737b546c17e54182028153aa7f7e78804e3) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 227 +++++++++++++++-------------- + 1 file changed, 121 insertions(+), 106 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 47f99eb096..df5ed0dce8 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2260,152 +2260,167 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) { + return 0; + } + +-_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { ++static int event_source_disable(sd_event_source *s) { + int r; + +- assert_return(s, -EINVAL); +- assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL); +- assert_return(!event_pid_changed(s->event), -ECHILD); ++ assert(s); ++ assert(s->enabled != SD_EVENT_OFF); + +- /* If we are dead anyway, we are fine with turning off +- * sources, but everything else needs to fail. */ +- if (s->event->state == SD_EVENT_FINISHED) +- return m == SD_EVENT_OFF ? 0 : -ESTALE; ++ /* Unset the pending flag when this event source is disabled */ ++ if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { ++ r = source_set_pending(s, false); ++ if (r < 0) ++ return r; ++ } + +- if (s->enabled == m) +- return 0; ++ s->enabled = SD_EVENT_OFF; + +- if (m == SD_EVENT_OFF) { ++ switch (s->type) { + +- /* Unset the pending flag when this event source is disabled */ +- if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { +- r = source_set_pending(s, false); +- if (r < 0) +- return r; +- } ++ case SOURCE_IO: ++ source_io_unregister(s); ++ break; + +- switch (s->type) { ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: ++ event_source_time_prioq_reshuffle(s); ++ break; + +- case SOURCE_IO: +- source_io_unregister(s); +- s->enabled = m; +- break; ++ case SOURCE_SIGNAL: ++ event_gc_signal_data(s->event, &s->priority, s->signal.sig); ++ break; + +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- s->enabled = m; +- event_source_time_prioq_reshuffle(s); +- break; ++ case SOURCE_CHILD: ++ assert(s->event->n_enabled_child_sources > 0); ++ s->event->n_enabled_child_sources--; + +- case SOURCE_SIGNAL: +- s->enabled = m; ++ event_gc_signal_data(s->event, &s->priority, SIGCHLD); ++ break; + +- event_gc_signal_data(s->event, &s->priority, s->signal.sig); +- break; ++ case SOURCE_EXIT: ++ prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); ++ break; + +- case SOURCE_CHILD: +- s->enabled = m; ++ case SOURCE_DEFER: ++ case SOURCE_POST: ++ case SOURCE_INOTIFY: ++ break; + +- assert(s->event->n_enabled_child_sources > 0); +- s->event->n_enabled_child_sources--; ++ default: ++ assert_not_reached("Wut? I shouldn't exist."); ++ } + +- event_gc_signal_data(s->event, &s->priority, SIGCHLD); +- break; ++ return 0; ++} + +- case SOURCE_EXIT: +- s->enabled = m; +- prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +- break; ++static int event_source_enable(sd_event_source *s, int m) { ++ int r; + +- case SOURCE_DEFER: +- case SOURCE_POST: +- case SOURCE_INOTIFY: +- s->enabled = m; +- break; ++ assert(s); ++ assert(IN_SET(m, SD_EVENT_ON, SD_EVENT_ONESHOT)); ++ assert(s->enabled == SD_EVENT_OFF); + +- default: +- assert_not_reached("Wut? I shouldn't exist."); +- } ++ /* Unset the pending flag when this event source is enabled */ ++ if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { ++ r = source_set_pending(s, false); ++ if (r < 0) ++ return r; ++ } + +- } else { ++ s->enabled = m; + +- /* Unset the pending flag when this event source is enabled */ +- if (s->enabled == SD_EVENT_OFF && !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { +- r = source_set_pending(s, false); +- if (r < 0) +- return r; ++ switch (s->type) { ++ ++ case SOURCE_IO: ++ r = source_io_register(s, m, s->io.events); ++ if (r < 0) { ++ s->enabled = SD_EVENT_OFF; ++ return r; + } + +- switch (s->type) { ++ break; + +- case SOURCE_IO: +- r = source_io_register(s, m, s->io.events); +- if (r < 0) +- return r; ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: ++ event_source_time_prioq_reshuffle(s); ++ break; + +- s->enabled = m; +- break; ++ case SOURCE_SIGNAL: ++ r = event_make_signal_data(s->event, s->signal.sig, NULL); ++ if (r < 0) { ++ s->enabled = SD_EVENT_OFF; ++ event_gc_signal_data(s->event, &s->priority, s->signal.sig); ++ return r; ++ } + +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- s->enabled = m; +- event_source_time_prioq_reshuffle(s); +- break; ++ break; + +- case SOURCE_SIGNAL: ++ case SOURCE_CHILD: ++ s->event->n_enabled_child_sources++; + +- s->enabled = m; ++ r = event_make_signal_data(s->event, SIGCHLD, NULL); ++ if (r < 0) { ++ s->enabled = SD_EVENT_OFF; ++ s->event->n_enabled_child_sources--; ++ event_gc_signal_data(s->event, &s->priority, SIGCHLD); ++ return r; ++ } + +- r = event_make_signal_data(s->event, s->signal.sig, NULL); +- if (r < 0) { +- s->enabled = SD_EVENT_OFF; +- event_gc_signal_data(s->event, &s->priority, s->signal.sig); +- return r; +- } + +- break; ++ break; + +- case SOURCE_CHILD: ++ case SOURCE_EXIT: ++ prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); ++ break; + +- if (s->enabled == SD_EVENT_OFF) +- s->event->n_enabled_child_sources++; ++ case SOURCE_DEFER: ++ case SOURCE_POST: ++ case SOURCE_INOTIFY: ++ break; + +- s->enabled = m; ++ default: ++ assert_not_reached("Wut? I shouldn't exist."); ++ } + +- r = event_make_signal_data(s->event, SIGCHLD, NULL); +- if (r < 0) { +- s->enabled = SD_EVENT_OFF; +- s->event->n_enabled_child_sources--; +- event_gc_signal_data(s->event, &s->priority, SIGCHLD); +- return r; +- } ++ return 0; ++} + +- break; ++_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { ++ int r; + +- case SOURCE_EXIT: +- s->enabled = m; +- prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +- break; ++ assert_return(s, -EINVAL); ++ assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL); ++ assert_return(!event_pid_changed(s->event), -ECHILD); + +- case SOURCE_DEFER: +- case SOURCE_POST: +- case SOURCE_INOTIFY: +- s->enabled = m; +- break; ++ /* If we are dead anyway, we are fine with turning off sources, but everything else needs to fail. */ ++ if (s->event->state == SD_EVENT_FINISHED) ++ return m == SD_EVENT_OFF ? 0 : -ESTALE; + +- default: +- assert_not_reached("Wut? I shouldn't exist."); ++ if (s->enabled == m) /* No change? */ ++ return 0; ++ ++ if (m == SD_EVENT_OFF) ++ r = event_source_disable(s); ++ else { ++ if (s->enabled != SD_EVENT_OFF) { ++ /* Switching from "on" to "oneshot" or back? If that's the case, we can take a shortcut, the ++ * event source is already enabled after all. */ ++ s->enabled = m; ++ return 0; + } ++ ++ r = event_source_enable(s, m); + } ++ if (r < 0) ++ return r; + + event_source_pp_prioq_reshuffle(s); +- + return 0; + } + diff --git a/SOURCES/0548-sd-event-mention-that-two-debug-logged-events-are-ig.patch b/SOURCES/0548-sd-event-mention-that-two-debug-logged-events-are-ig.patch new file mode 100644 index 0000000..6ea67ca --- /dev/null +++ b/SOURCES/0548-sd-event-mention-that-two-debug-logged-events-are-ig.patch @@ -0,0 +1,37 @@ +From e8904b5b7957bfc9328f1ab8b6851c7b0d8920c9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 11:39:40 +0100 +Subject: [PATCH] sd-event: mention that two debug logged events are ignored + +(cherry picked from commit f80a5d6a86dc2346f406ee086ba179879afaab70) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index df5ed0dce8..0f507f18d8 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -596,8 +596,6 @@ static bool event_pid_changed(sd_event *e) { + } + + static void source_io_unregister(sd_event_source *s) { +- int r; +- + assert(s); + assert(s->type == SOURCE_IO); + +@@ -607,9 +605,8 @@ static void source_io_unregister(sd_event_source *s) { + if (!s->io.registered) + return; + +- r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL); +- if (r < 0) +- log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m", ++ if (epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL) < 0) ++ log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll, ignoring: %m", + strna(s->description), event_source_type_to_string(s->type)); + + s->io.registered = false; diff --git a/SOURCES/0549-sd-event-split-clock-data-allocation-out-of-sd_event.patch b/SOURCES/0549-sd-event-split-clock-data-allocation-out-of-sd_event.patch new file mode 100644 index 0000000..6e512af --- /dev/null +++ b/SOURCES/0549-sd-event-split-clock-data-allocation-out-of-sd_event.patch @@ -0,0 +1,71 @@ +From 6cc0022115afbac9ac66c456b140601d90271687 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 11:40:24 +0100 +Subject: [PATCH] sd-event: split clock data allocation out of + sd_event_add_time() + +Just some simple refactoring, that will make things easier for us later. +But it looks better this way even without the later function reuse. + +(cherry picked from commit 41c63f36c3352af8bebf03b6181f5d866431d0af) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 34 ++++++++++++++++++++---------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 0f507f18d8..dc78dc7291 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1232,6 +1232,28 @@ static int time_exit_callback(sd_event_source *s, uint64_t usec, void *userdata) + return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata)); + } + ++static int setup_clock_data(sd_event *e, struct clock_data *d, clockid_t clock) { ++ int r; ++ ++ assert(d); ++ ++ if (d->fd < 0) { ++ r = event_setup_timer_fd(e, d, clock); ++ if (r < 0) ++ return r; ++ } ++ ++ r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare); ++ if (r < 0) ++ return r; ++ ++ r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + _public_ int sd_event_add_time( + sd_event *e, + sd_event_source **ret, +@@ -1265,20 +1287,10 @@ _public_ int sd_event_add_time( + d = event_get_clock_data(e, type); + assert(d); + +- r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare); +- if (r < 0) +- return r; +- +- r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare); ++ r = setup_clock_data(e, d, clock); + if (r < 0) + return r; + +- if (d->fd < 0) { +- r = event_setup_timer_fd(e, d, clock); +- if (r < 0) +- return r; +- } +- + s = source_new(e, !ret, type); + if (!s) + return -ENOMEM; diff --git a/SOURCES/0550-sd-event-split-out-code-to-add-remove-timer-event-so.patch b/SOURCES/0550-sd-event-split-out-code-to-add-remove-timer-event-so.patch new file mode 100644 index 0000000..0333f0d --- /dev/null +++ b/SOURCES/0550-sd-event-split-out-code-to-add-remove-timer-event-so.patch @@ -0,0 +1,112 @@ +From 88b2618e4de850060a1c5c22b049e6de0578fbb5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 15:25:35 +0100 +Subject: [PATCH] sd-event: split out code to add/remove timer event sources to + earliest/latest prioq + +Just some refactoring that makes code prettier, and will come handy +later, because we can reuse these functions at more places. + +(cherry picked from commit 1e45e3fecc303e7ae9946220c742f69675e99c34) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 57 +++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 16 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index dc78dc7291..de9bb02059 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -913,6 +913,19 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { + d->needs_rearm = true; + } + ++static void event_source_time_prioq_remove( ++ sd_event_source *s, ++ struct clock_data *d) { ++ ++ assert(s); ++ assert(d); ++ ++ prioq_remove(d->earliest, s, &s->time.earliest_index); ++ prioq_remove(d->latest, s, &s->time.latest_index); ++ s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL; ++ d->needs_rearm = true; ++} ++ + static void source_disconnect(sd_event_source *s) { + sd_event *event; + +@@ -937,13 +950,8 @@ static void source_disconnect(sd_event_source *s) { + case SOURCE_TIME_REALTIME_ALARM: + case SOURCE_TIME_BOOTTIME_ALARM: { + struct clock_data *d; +- +- d = event_get_clock_data(s->event, s->type); +- assert(d); +- +- prioq_remove(d->earliest, s, &s->time.earliest_index); +- prioq_remove(d->latest, s, &s->time.latest_index); +- d->needs_rearm = true; ++ assert_se(d = event_get_clock_data(s->event, s->type)); ++ event_source_time_prioq_remove(s, d); + break; + } + +@@ -1254,6 +1262,30 @@ static int setup_clock_data(sd_event *e, struct clock_data *d, clockid_t clock) + return 0; + } + ++static int event_source_time_prioq_put( ++ sd_event_source *s, ++ struct clock_data *d) { ++ ++ int r; ++ ++ assert(s); ++ assert(d); ++ ++ r = prioq_put(d->earliest, s, &s->time.earliest_index); ++ if (r < 0) ++ return r; ++ ++ r = prioq_put(d->latest, s, &s->time.latest_index); ++ if (r < 0) { ++ assert_se(prioq_remove(d->earliest, s, &s->time.earliest_index) > 0); ++ s->time.earliest_index = PRIOQ_IDX_NULL; ++ return r; ++ } ++ ++ d->needs_rearm = true; ++ return 0; ++} ++ + _public_ int sd_event_add_time( + sd_event *e, + sd_event_source **ret, +@@ -1284,8 +1316,7 @@ _public_ int sd_event_add_time( + if (!callback) + callback = time_exit_callback; + +- d = event_get_clock_data(e, type); +- assert(d); ++ assert_se(d = event_get_clock_data(e, type)); + + r = setup_clock_data(e, d, clock); + if (r < 0) +@@ -1302,13 +1333,7 @@ _public_ int sd_event_add_time( + s->userdata = userdata; + s->enabled = SD_EVENT_ONESHOT; + +- d->needs_rearm = true; +- +- r = prioq_put(d->earliest, s, &s->time.earliest_index); +- if (r < 0) +- goto fail; +- +- r = prioq_put(d->latest, s, &s->time.latest_index); ++ r = event_source_time_prioq_put(s, d); + if (r < 0) + goto fail; + diff --git a/SOURCES/0551-sd-event-fix-delays-assert-brain-o-17790.patch b/SOURCES/0551-sd-event-fix-delays-assert-brain-o-17790.patch new file mode 100644 index 0000000..64afc46 --- /dev/null +++ b/SOURCES/0551-sd-event-fix-delays-assert-brain-o-17790.patch @@ -0,0 +1,29 @@ +From 1aae57f763cacbdeb10647c627cf307f79ad00ca Mon Sep 17 00:00:00 2001 +From: Vito Caputo +Date: Tue, 1 Dec 2020 00:26:54 -0800 +Subject: [PATCH] sd-event: fix delays assert brain-o (#17790) + +s/sizeof/ELEMENTSOF/ + +Bug introduced in 34b87517749caa4142b19eb3c63bdf349fafbc49. + +(cherry picked from commit cb9d621ebbfa30bbd620c17e143daeb0d78c12f0) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index de9bb02059..9d42157206 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3586,7 +3586,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { + this_run = now(CLOCK_MONOTONIC); + + l = u64log2(this_run - e->last_run); +- assert(l < sizeof(e->delays)); ++ assert(l < ELEMENTSOF(e->delays)); + e->delays[l]++; + + if (this_run - e->last_log >= 5*USEC_PER_SEC) { diff --git a/SOURCES/0552-sd-event-let-s-suffix-last_run-last_log-with-_usec.patch b/SOURCES/0552-sd-event-let-s-suffix-last_run-last_log-with-_usec.patch new file mode 100644 index 0000000..1393d01 --- /dev/null +++ b/SOURCES/0552-sd-event-let-s-suffix-last_run-last_log-with-_usec.patch @@ -0,0 +1,60 @@ +From 5b5a590c5a8bbaebbecf4ab4797334a09a870287 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 15:33:50 +0100 +Subject: [PATCH] sd-event: let's suffix last_run/last_log with "_usec" + +Otherwise it's a bit confusing what this is about: two timestamps. + +(cherry picked from commit e6a7bee538f6638c2d5ca2afc66bf47cba3f075c) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 9d42157206..88641879cc 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -301,7 +301,7 @@ struct sd_event { + + LIST_HEAD(sd_event_source, sources); + +- usec_t last_run, last_log; ++ usec_t last_run_usec, last_log_usec; + unsigned delays[sizeof(usec_t) * 8]; + }; + +@@ -3579,19 +3579,19 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + +- if (e->profile_delays && e->last_run) { ++ if (e->profile_delays && e->last_run_usec != 0) { + usec_t this_run; + unsigned l; + + this_run = now(CLOCK_MONOTONIC); + +- l = u64log2(this_run - e->last_run); ++ l = u64log2(this_run - e->last_run_usec); + assert(l < ELEMENTSOF(e->delays)); + e->delays[l]++; + +- if (this_run - e->last_log >= 5*USEC_PER_SEC) { ++ if (this_run - e->last_log_usec >= 5*USEC_PER_SEC) { + event_log_delays(e); +- e->last_log = this_run; ++ e->last_log_usec = this_run; + } + } + +@@ -3601,7 +3601,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { + r = sd_event_wait(e, timeout); + + if (e->profile_delays) +- e->last_run = now(CLOCK_MONOTONIC); ++ e->last_run_usec = now(CLOCK_MONOTONIC); + + if (r > 0) { + /* There's something now, then let's dispatch it */ diff --git a/SOURCES/0553-sd-event-refuse-running-default-event-loops-in-any-o.patch b/SOURCES/0553-sd-event-refuse-running-default-event-loops-in-any-o.patch new file mode 100644 index 0000000..95ad16f --- /dev/null +++ b/SOURCES/0553-sd-event-refuse-running-default-event-loops-in-any-o.patch @@ -0,0 +1,42 @@ +From 4c5fdbde7e745126f31542a70b45cc4faec094d2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 30 Oct 2019 20:26:50 +0100 +Subject: [PATCH] sd-event: refuse running default event loops in any other + thread than the one they are default for + +(cherry picked from commit e544601536ac13a288d7476f4400c7b0f22b7ea1) + +Related: #1819868 +--- + TODO | 1 - + src/libsystemd/sd-event/sd-event.c | 5 +++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/TODO b/TODO +index 8f78000089..3100e067d6 100644 +--- a/TODO ++++ b/TODO +@@ -581,7 +581,6 @@ Features: + - allow multiple signal handlers per signal? + - document chaining of signal handler for SIGCHLD and child handlers + - define more intervals where we will shift wakeup intervals around in, 1h, 6h, 24h, ... +- - generate a failure of a default event loop is executed out-of-thread + - maybe add support for inotify events (which we can do safely now, with O_PATH) + + * investigate endianness issues of UUID vs. GUID +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 88641879cc..537a0b81d4 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3360,6 +3360,11 @@ _public_ int sd_event_prepare(sd_event *e) { + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + ++ /* Let's check that if we are a default event loop we are executed in the correct thread. We only do ++ * this check here once, since gettid() is typically not cached, and thus want to minimize ++ * syscalls */ ++ assert_return(!e->default_event_ptr || e->tid == gettid(), -EREMOTEIO); ++ + if (e->exit_requested) + goto pending; + diff --git a/SOURCES/0554-sd-event-ref-event-loop-while-in-sd_event_prepare-ot.patch b/SOURCES/0554-sd-event-ref-event-loop-while-in-sd_event_prepare-ot.patch new file mode 100644 index 0000000..4824f09 --- /dev/null +++ b/SOURCES/0554-sd-event-ref-event-loop-while-in-sd_event_prepare-ot.patch @@ -0,0 +1,92 @@ +From 441684c6c961edec1391562fb2f48ff997a6169e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 15:38:00 +0100 +Subject: [PATCH] sd-event: ref event loop while in sd_event_prepare() ot + sd_event_run() + +sd_event_prepare() invokes callbacks that might drop the last user ref +on our event loop. Let's make sure we keep an explicit ref around it, so +that we won't end up with an invalid pointer. Similar in sd_event_run(). + +Basically, any function that is publically callable that might end up +invoking callbacks should ref the relevant objects to be protected +against callbacks destroying these objects while we still want to access +them. We did this correctly in sd_event_dispatch() and sd_event_loop(), +but these are not the only ones which are callable from the outside. + +(cherry picked from commit f814c871e65df8552a055dd887bc94b074037833) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 537a0b81d4..be1e6e5f53 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3256,7 +3256,6 @@ static int event_prepare(sd_event *e) { + + static int dispatch_exit(sd_event *e) { + sd_event_source *p; +- _cleanup_(sd_event_unrefp) sd_event *ref = NULL; + int r; + + assert(e); +@@ -3267,7 +3266,7 @@ static int dispatch_exit(sd_event *e) { + return 0; + } + +- ref = sd_event_ref(e); ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); + e->iteration++; + e->state = SD_EVENT_EXITING; + r = source_dispatch(p); +@@ -3365,6 +3364,9 @@ _public_ int sd_event_prepare(sd_event *e) { + * syscalls */ + assert_return(!e->default_event_ptr || e->tid == gettid(), -EREMOTEIO); + ++ /* Make sure that none of the preparation callbacks ends up freeing the event source under our feet */ ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); ++ + if (e->exit_requested) + goto pending; + +@@ -3549,9 +3551,8 @@ _public_ int sd_event_dispatch(sd_event *e) { + + p = event_next_pending(e); + if (p) { +- _cleanup_(sd_event_unrefp) sd_event *ref = NULL; ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); + +- ref = sd_event_ref(e); + e->state = SD_EVENT_RUNNING; + r = source_dispatch(p); + e->state = SD_EVENT_INITIAL; +@@ -3600,6 +3601,9 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { + } + } + ++ /* Make sure that none of the preparation callbacks ends up freeing the event source under our feet */ ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); ++ + r = sd_event_prepare(e); + if (r == 0) + /* There was nothing? Then wait... */ +@@ -3621,7 +3625,6 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { + } + + _public_ int sd_event_loop(sd_event *e) { +- _cleanup_(sd_event_unrefp) sd_event *ref = NULL; + int r; + + assert_return(e, -EINVAL); +@@ -3629,7 +3632,7 @@ _public_ int sd_event_loop(sd_event *e) { + assert_return(!event_pid_changed(e), -ECHILD); + assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + +- ref = sd_event_ref(e); ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = NULL; + + while (e->state != SD_EVENT_FINISHED) { + r = sd_event_run(e, (uint64_t) -1); diff --git a/SOURCES/0555-sd-event-follow-coding-style-with-naming-return-para.patch b/SOURCES/0555-sd-event-follow-coding-style-with-naming-return-para.patch new file mode 100644 index 0000000..ab585e0 --- /dev/null +++ b/SOURCES/0555-sd-event-follow-coding-style-with-naming-return-para.patch @@ -0,0 +1,35 @@ +From 846b1dd75e626ad2e2483673eea65774edea9016 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 17:47:16 +0100 +Subject: [PATCH] sd-event: follow coding style with naming return parameter + +(cherry picked from commit cad143a8f26976a23e634d5e1ecfb7d7ba75c3bf) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index be1e6e5f53..739296abcf 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2285,13 +2285,14 @@ fail: + return r; + } + +-_public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) { ++_public_ int sd_event_source_get_enabled(sd_event_source *s, int *ret) { + assert_return(s, -EINVAL); +- assert_return(m, -EINVAL); + assert_return(!event_pid_changed(s->event), -ECHILD); + +- *m = s->enabled; +- return 0; ++ if (ret) ++ *ret = s->enabled; ++ ++ return s->enabled != SD_EVENT_OFF; + } + + static int event_source_disable(sd_event_source *s) { diff --git a/SOURCES/0556-sd-event-remove-earliest_index-latest_index-into-com.patch b/SOURCES/0556-sd-event-remove-earliest_index-latest_index-into-com.patch new file mode 100644 index 0000000..7fb9b47 --- /dev/null +++ b/SOURCES/0556-sd-event-remove-earliest_index-latest_index-into-com.patch @@ -0,0 +1,98 @@ +From 97f599bf57fdaee688ae5750e9b2b2587e2b597a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 17:49:27 +0100 +Subject: [PATCH] sd-event: remove earliest_index/latest_index into common part + of event source objects + +So far we used these fields to organize the earliest/latest timer event +priority queue. In a follow-up commit we want to introduce ratelimiting +to event sources, at which point we want any kind of event source to be +able to trigger time wakeups, and hence they all need to be included in +the earliest/latest prioqs. Thus, in preparation let's make this +generic. + +No change in behaviour, just some shifting around of struct members from +the type-specific to the generic part. + +(cherry picked from commit f41315fceb5208c496145cda2d6c865a5458ce44) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 739296abcf..34b42c298f 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -107,6 +107,9 @@ struct sd_event_source { + + LIST_FIELDS(sd_event_source, sources); + ++ unsigned earliest_index; ++ unsigned latest_index; ++ + union { + struct { + sd_event_io_handler_t callback; +@@ -119,8 +122,6 @@ struct sd_event_source { + struct { + sd_event_time_handler_t callback; + usec_t next, accuracy; +- unsigned earliest_index; +- unsigned latest_index; + } time; + struct { + sd_event_signal_handler_t callback; +@@ -908,8 +909,8 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { + /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, + * pending, enable state. Makes sure the two prioq's are ordered properly again. */ + assert_se(d = event_get_clock_data(s->event, s->type)); +- prioq_reshuffle(d->earliest, s, &s->time.earliest_index); +- prioq_reshuffle(d->latest, s, &s->time.latest_index); ++ prioq_reshuffle(d->earliest, s, &s->earliest_index); ++ prioq_reshuffle(d->latest, s, &s->latest_index); + d->needs_rearm = true; + } + +@@ -920,9 +921,9 @@ static void event_source_time_prioq_remove( + assert(s); + assert(d); + +- prioq_remove(d->earliest, s, &s->time.earliest_index); +- prioq_remove(d->latest, s, &s->time.latest_index); +- s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL; ++ prioq_remove(d->earliest, s, &s->earliest_index); ++ prioq_remove(d->latest, s, &s->latest_index); ++ s->earliest_index = s->latest_index = PRIOQ_IDX_NULL; + d->needs_rearm = true; + } + +@@ -1271,14 +1272,14 @@ static int event_source_time_prioq_put( + assert(s); + assert(d); + +- r = prioq_put(d->earliest, s, &s->time.earliest_index); ++ r = prioq_put(d->earliest, s, &s->earliest_index); + if (r < 0) + return r; + +- r = prioq_put(d->latest, s, &s->time.latest_index); ++ r = prioq_put(d->latest, s, &s->latest_index); + if (r < 0) { +- assert_se(prioq_remove(d->earliest, s, &s->time.earliest_index) > 0); +- s->time.earliest_index = PRIOQ_IDX_NULL; ++ assert_se(prioq_remove(d->earliest, s, &s->earliest_index) > 0); ++ s->earliest_index = PRIOQ_IDX_NULL; + return r; + } + +@@ -1329,7 +1330,7 @@ _public_ int sd_event_add_time( + s->time.next = usec; + s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy; + s->time.callback = callback; +- s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL; ++ s->earliest_index = s->latest_index = PRIOQ_IDX_NULL; + s->userdata = userdata; + s->enabled = SD_EVENT_ONESHOT; + diff --git a/SOURCES/0557-sd-event-update-state-at-the-end-in-event_source_ena.patch b/SOURCES/0557-sd-event-update-state-at-the-end-in-event_source_ena.patch new file mode 100644 index 0000000..e0a2145 --- /dev/null +++ b/SOURCES/0557-sd-event-update-state-at-the-end-in-event_source_ena.patch @@ -0,0 +1,116 @@ +From deb9e6ad3a1d7cfbc3b53d1e74cda6ae398a90fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 10 Nov 2020 10:38:37 +0100 +Subject: [PATCH] sd-event: update state at the end in event_source_enable + +Coverity in CID#1435966 was complaining that s->enabled is not "restored" in +all cases. But the code was actually correct, since it should only be +"restored" in the error paths. But let's still make this prettier by not setting +the state before all operations that may fail are done. + +We need to set .enabled for the prioq reshuffling operations, so move those down. + +No functional change intended. + +(cherry picked from commit d2eafe61ca07f8300dc741a0491a914213fa2b6b) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 51 +++++++++++++++++------------- + 1 file changed, 29 insertions(+), 22 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 34b42c298f..0cfba8fb39 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2352,11 +2352,11 @@ static int event_source_disable(sd_event_source *s) { + return 0; + } + +-static int event_source_enable(sd_event_source *s, int m) { ++static int event_source_enable(sd_event_source *s, int enable) { + int r; + + assert(s); +- assert(IN_SET(m, SD_EVENT_ON, SD_EVENT_ONESHOT)); ++ assert(IN_SET(enable, SD_EVENT_ON, SD_EVENT_ONESHOT)); + assert(s->enabled == SD_EVENT_OFF); + + /* Unset the pending flag when this event source is enabled */ +@@ -2366,31 +2366,16 @@ static int event_source_enable(sd_event_source *s, int m) { + return r; + } + +- s->enabled = m; +- + switch (s->type) { +- + case SOURCE_IO: +- r = source_io_register(s, m, s->io.events); +- if (r < 0) { +- s->enabled = SD_EVENT_OFF; ++ r = source_io_register(s, enable, s->io.events); ++ if (r < 0) + return r; +- } +- +- break; +- +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- event_source_time_prioq_reshuffle(s); + break; + + case SOURCE_SIGNAL: + r = event_make_signal_data(s->event, s->signal.sig, NULL); + if (r < 0) { +- s->enabled = SD_EVENT_OFF; + event_gc_signal_data(s->event, &s->priority, s->signal.sig); + return r; + } +@@ -2411,10 +2396,12 @@ static int event_source_enable(sd_event_source *s, int m) { + + break; + ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: + case SOURCE_EXIT: +- prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +- break; +- + case SOURCE_DEFER: + case SOURCE_POST: + case SOURCE_INOTIFY: +@@ -2424,6 +2411,26 @@ static int event_source_enable(sd_event_source *s, int m) { + assert_not_reached("Wut? I shouldn't exist."); + } + ++ s->enabled = enable; ++ ++ /* Non-failing operations below */ ++ switch (s->type) { ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: ++ event_source_time_prioq_reshuffle(s); ++ break; ++ ++ case SOURCE_EXIT: ++ prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); ++ break; ++ ++ default: ++ break; ++ } ++ + return 0; + } + diff --git a/SOURCES/0558-sd-event-increase-n_enabled_child_sources-just-once.patch b/SOURCES/0558-sd-event-increase-n_enabled_child_sources-just-once.patch new file mode 100644 index 0000000..2a41752 --- /dev/null +++ b/SOURCES/0558-sd-event-increase-n_enabled_child_sources-just-once.patch @@ -0,0 +1,36 @@ +From 188465c472996b426a1f22a9fc46d031b722c3b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 10 Nov 2020 12:57:34 +0100 +Subject: [PATCH] sd-event: increase n_enabled_child_sources just once + +Neither source_child_pidfd_register() nor event_make_signal_data() look at +n_enabled_child_sources. + +(cherry picked from commit ac9f2640cb9c107b43f47bba7e068d3b92b5337b) + +Related: #1819868 +--- + src/libsystemd/sd-event/sd-event.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 0cfba8fb39..d18ce28a92 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2383,8 +2383,6 @@ static int event_source_enable(sd_event_source *s, int enable) { + break; + + case SOURCE_CHILD: +- s->event->n_enabled_child_sources++; +- + r = event_make_signal_data(s->event, SIGCHLD, NULL); + if (r < 0) { + s->enabled = SD_EVENT_OFF; +@@ -2393,6 +2391,7 @@ static int event_source_enable(sd_event_source *s, int enable) { + return r; + } + ++ s->event->n_enabled_child_sources++; + + break; + diff --git a/SOURCES/0559-sd-event-add-ability-to-ratelimit-event-sources.patch b/SOURCES/0559-sd-event-add-ability-to-ratelimit-event-sources.patch new file mode 100644 index 0000000..b8c20d0 --- /dev/null +++ b/SOURCES/0559-sd-event-add-ability-to-ratelimit-event-sources.patch @@ -0,0 +1,858 @@ +From 395eb7753a9772f505102fbbe3ba3261b57abbe9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 23 Nov 2020 18:02:40 +0100 +Subject: [PATCH] sd-event: add ability to ratelimit event sources + +Let's a concept of "rate limiting" to event sources: if specific event +sources fire too often in some time interval temporarily take them +offline, and take them back online once the interval passed. + +This is a simple scheme of avoiding starvation of event sources if some +event source fires too often. + +This introduces the new conceptual states of "offline" and "online" for +event sources: an event source is "online" only when enabled *and* not +ratelimited, and offline in all other cases. An event source that is +online hence has its fds registered in the epoll, its signals in the +signalfd and so on. + +(cherry picked from commit b6d5481b3d9f7c9b1198ab54b54326ec73e855bf) + +Related: #1819868 +--- + src/basic/ratelimit.h | 8 + + src/libsystemd/libsystemd.sym | 7 + + src/libsystemd/sd-event/sd-event.c | 433 +++++++++++++++++++++++------ + src/systemd/sd-event.h | 3 + + 4 files changed, 369 insertions(+), 82 deletions(-) + +diff --git a/src/basic/ratelimit.h b/src/basic/ratelimit.h +index de91def28d..0012b49935 100644 +--- a/src/basic/ratelimit.h ++++ b/src/basic/ratelimit.h +@@ -38,3 +38,11 @@ typedef struct RateLimit { + } while (false) + + bool ratelimit_below(RateLimit *r); ++ ++static inline void ratelimit_reset(RateLimit *rl) { ++ rl->num = rl->begin = 0; ++} ++ ++static inline bool ratelimit_configured(RateLimit *rl) { ++ return rl->interval > 0 && rl->burst > 0; ++} +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 778e88a16c..149d2e7b82 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -572,3 +572,10 @@ global: + sd_bus_enqueue_for_read; + sd_event_source_disable_unref; + } LIBSYSTEMD_238; ++ ++LIBSYSTEMD_248 { ++global: ++ sd_event_source_set_ratelimit; ++ sd_event_source_get_ratelimit; ++ sd_event_source_is_ratelimited; ++} LIBSYSTEMD_239; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index d18ce28a92..be912d94e3 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -19,6 +19,7 @@ + #include "missing.h" + #include "prioq.h" + #include "process-util.h" ++#include "ratelimit.h" + #include "set.h" + #include "signal-util.h" + #include "string-table.h" +@@ -46,6 +47,7 @@ typedef enum EventSourceType { + _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 + } EventSourceType; + ++ + static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = { + [SOURCE_IO] = "io", + [SOURCE_TIME_REALTIME] = "realtime", +@@ -76,7 +78,25 @@ typedef enum WakeupType { + _WAKEUP_TYPE_INVALID = -1, + } WakeupType; + +-#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM) ++#define EVENT_SOURCE_IS_TIME(t) \ ++ IN_SET((t), \ ++ SOURCE_TIME_REALTIME, \ ++ SOURCE_TIME_BOOTTIME, \ ++ SOURCE_TIME_MONOTONIC, \ ++ SOURCE_TIME_REALTIME_ALARM, \ ++ SOURCE_TIME_BOOTTIME_ALARM) ++ ++#define EVENT_SOURCE_CAN_RATE_LIMIT(t) \ ++ IN_SET((t), \ ++ SOURCE_IO, \ ++ SOURCE_TIME_REALTIME, \ ++ SOURCE_TIME_BOOTTIME, \ ++ SOURCE_TIME_MONOTONIC, \ ++ SOURCE_TIME_REALTIME_ALARM, \ ++ SOURCE_TIME_BOOTTIME_ALARM, \ ++ SOURCE_SIGNAL, \ ++ SOURCE_DEFER, \ ++ SOURCE_INOTIFY) + + struct inode_data; + +@@ -96,6 +116,7 @@ struct sd_event_source { + bool pending:1; + bool dispatching:1; + bool floating:1; ++ bool ratelimited:1; + + int64_t priority; + unsigned pending_index; +@@ -107,6 +128,10 @@ struct sd_event_source { + + LIST_FIELDS(sd_event_source, sources); + ++ RateLimit rate_limit; ++ ++ /* These are primarily fields relevant for time event sources, but since any event source can ++ * effectively become one when rate-limited, this is part of the common fields. */ + unsigned earliest_index; + unsigned latest_index; + +@@ -266,7 +291,7 @@ struct sd_event { + Hashmap *signal_data; /* indexed by priority */ + + Hashmap *child_sources; +- unsigned n_enabled_child_sources; ++ unsigned n_online_child_sources; + + Set *post_sources; + +@@ -311,12 +336,23 @@ static thread_local sd_event *default_event = NULL; + static void source_disconnect(sd_event_source *s); + static void event_gc_inode_data(sd_event *e, struct inode_data *d); + ++static bool event_source_is_online(sd_event_source *s) { ++ assert(s); ++ return s->enabled != SD_EVENT_OFF && !s->ratelimited; ++} ++ ++static bool event_source_is_offline(sd_event_source *s) { ++ assert(s); ++ return s->enabled == SD_EVENT_OFF || s->ratelimited; ++} ++ + static sd_event *event_resolve(sd_event *e) { + return e == SD_EVENT_DEFAULT ? default_event : e; + } + + static int pending_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; ++ int r; + + assert(x->pending); + assert(y->pending); +@@ -327,23 +363,23 @@ static int pending_prioq_compare(const void *a, const void *b) { + if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) + return 1; + ++ /* Non rate-limited ones first. */ ++ r = CMP(!!x->ratelimited, !!y->ratelimited); ++ if (r != 0) ++ return r; ++ + /* Lower priority values first */ +- if (x->priority < y->priority) +- return -1; +- if (x->priority > y->priority) +- return 1; ++ r = CMP(x->priority, y->priority); ++ if (r != 0) ++ return r; + + /* Older entries first */ +- if (x->pending_iteration < y->pending_iteration) +- return -1; +- if (x->pending_iteration > y->pending_iteration) +- return 1; +- +- return 0; ++ return CMP(x->pending_iteration, y->pending_iteration); + } + + static int prepare_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; ++ int r; + + assert(x->prepare); + assert(y->prepare); +@@ -354,29 +390,46 @@ static int prepare_prioq_compare(const void *a, const void *b) { + if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) + return 1; + ++ /* Non rate-limited ones first. */ ++ r = CMP(!!x->ratelimited, !!y->ratelimited); ++ if (r != 0) ++ return r; ++ + /* Move most recently prepared ones last, so that we can stop + * preparing as soon as we hit one that has already been + * prepared in the current iteration */ +- if (x->prepare_iteration < y->prepare_iteration) +- return -1; +- if (x->prepare_iteration > y->prepare_iteration) +- return 1; ++ r = CMP(x->prepare_iteration, y->prepare_iteration); ++ if (r != 0) ++ return r; + + /* Lower priority values first */ +- if (x->priority < y->priority) +- return -1; +- if (x->priority > y->priority) +- return 1; ++ return CMP(x->priority, y->priority); ++} + +- return 0; ++static usec_t time_event_source_next(const sd_event_source *s) { ++ assert(s); ++ ++ /* We have two kinds of event sources that have elapsation times associated with them: the actual ++ * time based ones and the ones for which a ratelimit can be in effect (where we want to be notified ++ * once the ratelimit time window ends). Let's return the next elapsing time depending on what we are ++ * looking at here. */ ++ ++ if (s->ratelimited) { /* If rate-limited the next elapsation is when the ratelimit time window ends */ ++ assert(s->rate_limit.begin != 0); ++ assert(s->rate_limit.interval != 0); ++ return usec_add(s->rate_limit.begin, s->rate_limit.interval); ++ } ++ ++ /* Otherwise this must be a time event source, if not ratelimited */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ return s->time.next; ++ ++ return USEC_INFINITY; + } + + static int earliest_time_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; + +- assert(EVENT_SOURCE_IS_TIME(x->type)); +- assert(x->type == y->type); +- + /* Enabled ones first */ + if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) + return -1; +@@ -390,24 +443,30 @@ static int earliest_time_prioq_compare(const void *a, const void *b) { + return 1; + + /* Order by time */ +- if (x->time.next < y->time.next) +- return -1; +- if (x->time.next > y->time.next) +- return 1; +- +- return 0; ++ return CMP(time_event_source_next(x), time_event_source_next(y)); + } + + static usec_t time_event_source_latest(const sd_event_source *s) { +- return usec_add(s->time.next, s->time.accuracy); ++ assert(s); ++ ++ if (s->ratelimited) { /* For ratelimited stuff the earliest and the latest time shall actually be the ++ * same, as we should avoid adding additional inaccuracy on an inaccuracy time ++ * window */ ++ assert(s->rate_limit.begin != 0); ++ assert(s->rate_limit.interval != 0); ++ return usec_add(s->rate_limit.begin, s->rate_limit.interval); ++ } ++ ++ /* Must be a time event source, if not ratelimited */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ return usec_add(s->time.next, s->time.accuracy); ++ ++ return USEC_INFINITY; + } + + static int latest_time_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; + +- assert(EVENT_SOURCE_IS_TIME(x->type)); +- assert(x->type == y->type); +- + /* Enabled ones first */ + if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) + return -1; +@@ -852,12 +911,12 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig) + * the signalfd for it. */ + + if (sig == SIGCHLD && +- e->n_enabled_child_sources > 0) ++ e->n_online_child_sources > 0) + return; + + if (e->signal_sources && + e->signal_sources[sig] && +- e->signal_sources[sig]->enabled != SD_EVENT_OFF) ++ event_source_is_online(e->signal_sources[sig])) + return; + + /* +@@ -904,11 +963,17 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { + struct clock_data *d; + + assert(s); +- assert(EVENT_SOURCE_IS_TIME(s->type)); + + /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, + * pending, enable state. Makes sure the two prioq's are ordered properly again. */ +- assert_se(d = event_get_clock_data(s->event, s->type)); ++ ++ if (s->ratelimited) ++ d = &s->event->monotonic; ++ else { ++ assert(EVENT_SOURCE_IS_TIME(s->type)); ++ assert_se(d = event_get_clock_data(s->event, s->type)); ++ } ++ + prioq_reshuffle(d->earliest, s, &s->earliest_index); + prioq_reshuffle(d->latest, s, &s->latest_index); + d->needs_rearm = true; +@@ -949,12 +1014,18 @@ static void source_disconnect(sd_event_source *s) { + case SOURCE_TIME_BOOTTIME: + case SOURCE_TIME_MONOTONIC: + case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: { +- struct clock_data *d; +- assert_se(d = event_get_clock_data(s->event, s->type)); +- event_source_time_prioq_remove(s, d); ++ case SOURCE_TIME_BOOTTIME_ALARM: ++ /* Only remove this event source from the time event source here if it is not ratelimited. If ++ * it is ratelimited, we'll remove it below, separately. Why? Because the clock used might ++ * differ: ratelimiting always uses CLOCK_MONOTONIC, but timer events might use any clock */ ++ ++ if (!s->ratelimited) { ++ struct clock_data *d; ++ assert_se(d = event_get_clock_data(s->event, s->type)); ++ event_source_time_prioq_remove(s, d); ++ } ++ + break; +- } + + case SOURCE_SIGNAL: + if (s->signal.sig > 0) { +@@ -969,9 +1040,9 @@ static void source_disconnect(sd_event_source *s) { + + case SOURCE_CHILD: + if (s->child.pid > 0) { +- if (s->enabled != SD_EVENT_OFF) { +- assert(s->event->n_enabled_child_sources > 0); +- s->event->n_enabled_child_sources--; ++ if (event_source_is_online(s)) { ++ assert(s->event->n_online_child_sources > 0); ++ s->event->n_online_child_sources--; + } + + (void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid)); +@@ -1037,6 +1108,9 @@ static void source_disconnect(sd_event_source *s) { + if (s->prepare) + prioq_remove(s->event->prepare, s, &s->prepare_index); + ++ if (s->ratelimited) ++ event_source_time_prioq_remove(s, &s->event->monotonic); ++ + event = s->event; + + s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID; +@@ -1458,11 +1532,11 @@ _public_ int sd_event_add_child( + return r; + } + +- e->n_enabled_child_sources++; ++ e->n_online_child_sources++; + + r = event_make_signal_data(e, SIGCHLD, NULL); + if (r < 0) { +- e->n_enabled_child_sources--; ++ e->n_online_child_sources--; + source_free(s); + return r; + } +@@ -2079,7 +2153,7 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { + if (s->io.fd == fd) + return 0; + +- if (s->enabled == SD_EVENT_OFF) { ++ if (event_source_is_offline(s)) { + s->io.fd = fd; + s->io.registered = false; + } else { +@@ -2146,7 +2220,7 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) + if (r < 0) + return r; + +- if (s->enabled != SD_EVENT_OFF) { ++ if (event_source_is_online(s)) { + r = source_io_register(s, s->enabled, events); + if (r < 0) + return r; +@@ -2249,7 +2323,7 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) + + event_gc_inode_data(s->event, old_inode_data); + +- } else if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) { ++ } else if (s->type == SOURCE_SIGNAL && event_source_is_online(s)) { + struct signal_data *old, *d; + + /* Move us from the signalfd belonging to the old +@@ -2296,20 +2370,29 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *ret) { + return s->enabled != SD_EVENT_OFF; + } + +-static int event_source_disable(sd_event_source *s) { ++static int event_source_offline( ++ sd_event_source *s, ++ int enabled, ++ bool ratelimited) { ++ ++ bool was_offline; + int r; + + assert(s); +- assert(s->enabled != SD_EVENT_OFF); ++ assert(enabled == SD_EVENT_OFF || ratelimited); + + /* Unset the pending flag when this event source is disabled */ +- if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { ++ if (s->enabled != SD_EVENT_OFF && ++ enabled == SD_EVENT_OFF && ++ !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { + r = source_set_pending(s, false); + if (r < 0) + return r; + } + +- s->enabled = SD_EVENT_OFF; ++ was_offline = event_source_is_offline(s); ++ s->enabled = enabled; ++ s->ratelimited = ratelimited; + + switch (s->type) { + +@@ -2330,8 +2413,10 @@ static int event_source_disable(sd_event_source *s) { + break; + + case SOURCE_CHILD: +- assert(s->event->n_enabled_child_sources > 0); +- s->event->n_enabled_child_sources--; ++ if (!was_offline) { ++ assert(s->event->n_online_child_sources > 0); ++ s->event->n_online_child_sources--; ++ } + + event_gc_signal_data(s->event, &s->priority, SIGCHLD); + break; +@@ -2349,26 +2434,42 @@ static int event_source_disable(sd_event_source *s) { + assert_not_reached("Wut? I shouldn't exist."); + } + +- return 0; ++ return 1; + } + +-static int event_source_enable(sd_event_source *s, int enable) { ++static int event_source_online( ++ sd_event_source *s, ++ int enabled, ++ bool ratelimited) { ++ ++ bool was_online; + int r; + + assert(s); +- assert(IN_SET(enable, SD_EVENT_ON, SD_EVENT_ONESHOT)); +- assert(s->enabled == SD_EVENT_OFF); ++ assert(enabled != SD_EVENT_OFF || !ratelimited); + + /* Unset the pending flag when this event source is enabled */ +- if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { ++ if (s->enabled == SD_EVENT_OFF && ++ enabled != SD_EVENT_OFF && ++ !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { + r = source_set_pending(s, false); + if (r < 0) + return r; + } + ++ /* Are we really ready for onlining? */ ++ if (enabled == SD_EVENT_OFF || ratelimited) { ++ /* Nope, we are not ready for onlining, then just update the precise state and exit */ ++ s->enabled = enabled; ++ s->ratelimited = ratelimited; ++ return 0; ++ } ++ ++ was_online = event_source_is_online(s); ++ + switch (s->type) { + case SOURCE_IO: +- r = source_io_register(s, enable, s->io.events); ++ r = source_io_register(s, enabled, s->io.events); + if (r < 0) + return r; + break; +@@ -2386,13 +2487,13 @@ static int event_source_enable(sd_event_source *s, int enable) { + r = event_make_signal_data(s->event, SIGCHLD, NULL); + if (r < 0) { + s->enabled = SD_EVENT_OFF; +- s->event->n_enabled_child_sources--; ++ s->event->n_online_child_sources--; + event_gc_signal_data(s->event, &s->priority, SIGCHLD); + return r; + } + +- s->event->n_enabled_child_sources++; +- ++ if (!was_online) ++ s->event->n_online_child_sources++; + break; + + case SOURCE_TIME_REALTIME: +@@ -2410,7 +2511,8 @@ static int event_source_enable(sd_event_source *s, int enable) { + assert_not_reached("Wut? I shouldn't exist."); + } + +- s->enabled = enable; ++ s->enabled = enabled; ++ s->ratelimited = ratelimited; + + /* Non-failing operations below */ + switch (s->type) { +@@ -2430,7 +2532,7 @@ static int event_source_enable(sd_event_source *s, int enable) { + break; + } + +- return 0; ++ return 1; + } + + _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { +@@ -2448,7 +2550,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { + return 0; + + if (m == SD_EVENT_OFF) +- r = event_source_disable(s); ++ r = event_source_offline(s, m, s->ratelimited); + else { + if (s->enabled != SD_EVENT_OFF) { + /* Switching from "on" to "oneshot" or back? If that's the case, we can take a shortcut, the +@@ -2457,7 +2559,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { + return 0; + } + +- r = event_source_enable(s, m); ++ r = event_source_online(s, m, s->ratelimited); + } + if (r < 0) + return r; +@@ -2605,6 +2707,96 @@ _public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) + return ret; + } + ++static int event_source_enter_ratelimited(sd_event_source *s) { ++ int r; ++ ++ assert(s); ++ ++ /* When an event source becomes ratelimited, we place it in the CLOCK_MONOTONIC priority queue, with ++ * the end of the rate limit time window, much as if it was a timer event source. */ ++ ++ if (s->ratelimited) ++ return 0; /* Already ratelimited, this is a NOP hence */ ++ ++ /* Make sure we can install a CLOCK_MONOTONIC event further down. */ ++ r = setup_clock_data(s->event, &s->event->monotonic, CLOCK_MONOTONIC); ++ if (r < 0) ++ return r; ++ ++ /* Timer event sources are already using the earliest/latest queues for the timer scheduling. Let's ++ * first remove them from the prioq appropriate for their own clock, so that we can use the prioq ++ * fields of the event source then for adding it to the CLOCK_MONOTONIC prioq instead. */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ event_source_time_prioq_remove(s, event_get_clock_data(s->event, s->type)); ++ ++ /* Now, let's add the event source to the monotonic clock instead */ ++ r = event_source_time_prioq_put(s, &s->event->monotonic); ++ if (r < 0) ++ goto fail; ++ ++ /* And let's take the event source officially offline */ ++ r = event_source_offline(s, s->enabled, /* ratelimited= */ true); ++ if (r < 0) { ++ event_source_time_prioq_remove(s, &s->event->monotonic); ++ goto fail; ++ } ++ ++ event_source_pp_prioq_reshuffle(s); ++ ++ log_debug("Event source %p (%s) entered rate limit state.", s, strna(s->description)); ++ return 0; ++ ++fail: ++ /* Reinstall time event sources in the priority queue as before. This shouldn't fail, since the queue ++ * space for it should already be allocated. */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ assert_se(event_source_time_prioq_put(s, event_get_clock_data(s->event, s->type)) >= 0); ++ ++ return r; ++} ++ ++static int event_source_leave_ratelimit(sd_event_source *s) { ++ int r; ++ ++ assert(s); ++ ++ if (!s->ratelimited) ++ return 0; ++ ++ /* Let's take the event source out of the monotonic prioq first. */ ++ event_source_time_prioq_remove(s, &s->event->monotonic); ++ ++ /* Let's then add the event source to its native clock prioq again — if this is a timer event source */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) { ++ r = event_source_time_prioq_put(s, event_get_clock_data(s->event, s->type)); ++ if (r < 0) ++ goto fail; ++ } ++ ++ /* Let's try to take it online again. */ ++ r = event_source_online(s, s->enabled, /* ratelimited= */ false); ++ if (r < 0) { ++ /* Do something roughly sensible when this failed: undo the two prioq ops above */ ++ if (EVENT_SOURCE_IS_TIME(s->type)) ++ event_source_time_prioq_remove(s, event_get_clock_data(s->event, s->type)); ++ ++ goto fail; ++ } ++ ++ event_source_pp_prioq_reshuffle(s); ++ ratelimit_reset(&s->rate_limit); ++ ++ log_debug("Event source %p (%s) left rate limit state.", s, strna(s->description)); ++ return 0; ++ ++fail: ++ /* Do something somewhat reasonable when we cannot move an event sources out of ratelimited mode: ++ * simply put it back in it, maybe we can then process it more successfully next iteration. */ ++ assert_se(event_source_time_prioq_put(s, &s->event->monotonic) >= 0); ++ ++ return r; ++} ++ + static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) { + usec_t c; + assert(e); +@@ -2703,7 +2895,7 @@ static int event_arm_timer( + d->needs_rearm = false; + + a = prioq_peek(d->earliest); +- if (!a || a->enabled == SD_EVENT_OFF || a->time.next == USEC_INFINITY) { ++ if (!a || a->enabled == SD_EVENT_OFF || time_event_source_next(a) == USEC_INFINITY) { + + if (d->fd < 0) + return 0; +@@ -2723,7 +2915,7 @@ static int event_arm_timer( + b = prioq_peek(d->latest); + assert_se(b && b->enabled != SD_EVENT_OFF); + +- t = sleep_between(e, a->time.next, time_event_source_latest(b)); ++ t = sleep_between(e, time_event_source_next(a), time_event_source_latest(b)); + if (d->next == t) + return 0; + +@@ -2802,10 +2994,22 @@ static int process_timer( + + for (;;) { + s = prioq_peek(d->earliest); +- if (!s || +- s->time.next > n || +- s->enabled == SD_EVENT_OFF || +- s->pending) ++ if (!s || time_event_source_next(s) > n) ++ break; ++ ++ if (s->ratelimited) { ++ /* This is an event sources whose ratelimit window has ended. Let's turn it on ++ * again. */ ++ assert(s->ratelimited); ++ ++ r = event_source_leave_ratelimit(s); ++ if (r < 0) ++ return r; ++ ++ continue; ++ } ++ ++ if (s->enabled == SD_EVENT_OFF || s->pending) + break; + + r = source_set_pending(s, true); +@@ -2851,7 +3055,7 @@ static int process_child(sd_event *e) { + if (s->pending) + continue; + +- if (s->enabled == SD_EVENT_OFF) ++ if (event_source_is_offline(s)) + continue; + + zero(s->child.siginfo); +@@ -3024,7 +3228,7 @@ static int event_inotify_data_process(sd_event *e, struct inotify_data *d) { + + LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) { + +- if (s->enabled == SD_EVENT_OFF) ++ if (event_source_is_offline(s)) + continue; + + r = source_set_pending(s, true); +@@ -3060,7 +3264,7 @@ static int event_inotify_data_process(sd_event *e, struct inotify_data *d) { + * sources if IN_IGNORED or IN_UNMOUNT is set. */ + LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) { + +- if (s->enabled == SD_EVENT_OFF) ++ if (event_source_is_offline(s)) + continue; + + if ((d->buffer.ev.mask & (IN_IGNORED|IN_UNMOUNT)) == 0 && +@@ -3099,6 +3303,7 @@ static int process_inotify(sd_event *e) { + } + + static int source_dispatch(sd_event_source *s) { ++ _cleanup_(sd_event_unrefp) sd_event *saved_event = NULL; + EventSourceType saved_type; + int r = 0; + +@@ -3109,6 +3314,20 @@ static int source_dispatch(sd_event_source *s) { + * the event. */ + saved_type = s->type; + ++ /* Similar, store a reference to the event loop object, so that we can still access it after the ++ * callback might have invalidated/disconnected the event source. */ ++ saved_event = sd_event_ref(s->event); ++ ++ /* Check if we hit the ratelimit for this event source, if so, let's disable it. */ ++ assert(!s->ratelimited); ++ if (!ratelimit_below(&s->rate_limit)) { ++ r = event_source_enter_ratelimited(s); ++ if (r < 0) ++ return r; ++ ++ return 1; ++ } ++ + if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) { + r = source_set_pending(s, false); + if (r < 0) +@@ -3235,7 +3454,7 @@ static int event_prepare(sd_event *e) { + sd_event_source *s; + + s = prioq_peek(e->prepare); +- if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF) ++ if (!s || s->prepare_iteration == e->iteration || event_source_is_offline(s)) + break; + + s->prepare_iteration = e->iteration; +@@ -3269,7 +3488,7 @@ static int dispatch_exit(sd_event *e) { + assert(e); + + p = prioq_peek(e->exit); +- if (!p || p->enabled == SD_EVENT_OFF) { ++ if (!p || event_source_is_offline(p)) { + e->state = SD_EVENT_FINISHED; + return 0; + } +@@ -3291,7 +3510,7 @@ static sd_event_source* event_next_pending(sd_event *e) { + if (!p) + return NULL; + +- if (p->enabled == SD_EVENT_OFF) ++ if (event_source_is_offline(p)) + return NULL; + + return p; +@@ -3844,3 +4063,53 @@ _public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_d + + return !!s->destroy_callback; + } ++ ++_public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval, unsigned burst) { ++ int r; ++ ++ assert_return(s, -EINVAL); ++ ++ /* Turning on ratelimiting on event source types that don't support it, is a loggable offense. Doing ++ * so is a programming error. */ ++ assert_return(EVENT_SOURCE_CAN_RATE_LIMIT(s->type), -EDOM); ++ ++ /* When ratelimiting is configured we'll always reset the rate limit state first and start fresh, ++ * non-ratelimited. */ ++ r = event_source_leave_ratelimit(s); ++ if (r < 0) ++ return r; ++ ++ RATELIMIT_INIT(s->rate_limit, interval, burst); ++ return 0; ++} ++ ++_public_ int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval, unsigned *ret_burst) { ++ assert_return(s, -EINVAL); ++ ++ /* Querying whether an event source has ratelimiting configured is not a loggable offsense, hence ++ * don't use assert_return(). Unlike turning on ratelimiting it's not really a programming error */ ++ if (!EVENT_SOURCE_CAN_RATE_LIMIT(s->type)) ++ return -EDOM; ++ ++ if (!ratelimit_configured(&s->rate_limit)) ++ return -ENOEXEC; ++ ++ if (ret_interval) ++ *ret_interval = s->rate_limit.interval; ++ if (ret_burst) ++ *ret_burst = s->rate_limit.burst; ++ ++ return 0; ++} ++ ++_public_ int sd_event_source_is_ratelimited(sd_event_source *s) { ++ assert_return(s, -EINVAL); ++ ++ if (!EVENT_SOURCE_CAN_RATE_LIMIT(s->type)) ++ return false; ++ ++ if (!ratelimit_configured(&s->rate_limit)) ++ return false; ++ ++ return s->ratelimited; ++} +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index 9876be01c6..a17a9b3488 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -144,6 +144,9 @@ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid); + int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret); + int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback); + int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret); ++int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval_usec, unsigned burst); ++int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval_usec, unsigned *ret_burst); ++int sd_event_source_is_ratelimited(sd_event_source *s); + + /* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */ + _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref); diff --git a/SOURCES/0560-test-add-ratelimiting-test.patch b/SOURCES/0560-test-add-ratelimiting-test.patch new file mode 100644 index 0000000..8e398e1 --- /dev/null +++ b/SOURCES/0560-test-add-ratelimiting-test.patch @@ -0,0 +1,127 @@ +From c35ba62cd6f337c4eef64cdc3b9796f988802229 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 23 Nov 2020 18:04:57 +0100 +Subject: [PATCH] test: add ratelimiting test + +(Taken from Michal's #17274 by Lennart, and slightly adjusted) + +(cherry picked from commit 68d890651781904a4c762ac866af36e30c4f7ff8) + +Related: #1819868 +--- + src/libsystemd/sd-event/test-event.c | 96 ++++++++++++++++++++++++++++ + 1 file changed, 96 insertions(+) + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index bde00cf719..e3ee4cd5c3 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -482,6 +482,100 @@ static void test_inotify(unsigned n_create_events) { + sd_event_unref(e); + } + ++ ++static int ratelimit_io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ unsigned *c = (unsigned*) userdata; ++ *c += 1; ++ return 0; ++} ++ ++static int ratelimit_time_handler(sd_event_source *s, uint64_t usec, void *userdata) { ++ int r; ++ ++ r = sd_event_source_set_enabled(s, SD_EVENT_ON); ++ if (r < 0) ++ log_warning_errno(r, "Failed to turn on notify event source: %m"); ++ ++ r = sd_event_source_set_time(s, usec + 1000); ++ if (r < 0) ++ log_error_errno(r, "Failed to restart watchdog event source: %m"); ++ ++ unsigned *c = (unsigned*) userdata; ++ *c += 1; ++ ++ return 0; ++} ++ ++static void test_ratelimit(void) { ++ _cleanup_close_pair_ int p[2] = {-1, -1}; ++ _cleanup_(sd_event_unrefp) sd_event *e = NULL; ++ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; ++ uint64_t interval; ++ unsigned count, burst; ++ ++ assert_se(sd_event_default(&e) >= 0); ++ assert_se(pipe2(p, O_CLOEXEC|O_NONBLOCK) >= 0); ++ ++ assert_se(sd_event_add_io(e, &s, p[0], EPOLLIN, ratelimit_io_handler, &count) >= 0); ++ assert_se(sd_event_source_set_description(s, "test-ratelimit-io") >= 0); ++ assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5) >= 0); ++ assert_se(sd_event_source_get_ratelimit(s, &interval, &burst) >= 0); ++ assert_se(interval == 1 * USEC_PER_SEC && burst == 5); ++ ++ assert_se(write(p[1], "1", 1) == 1); ++ ++ count = 0; ++ for (unsigned i = 0; i < 10; i++) { ++ log_debug("slow loop iteration %u", i); ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ assert_se(usleep(250 * USEC_PER_MSEC) >= 0); ++ } ++ ++ assert_se(sd_event_source_is_ratelimited(s) == 0); ++ assert_se(count == 10); ++ log_info("ratelimit_io_handler: called %d times, event source not ratelimited", count); ++ ++ assert_se(sd_event_source_set_ratelimit(s, 0, 0) >= 0); ++ assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 5) >= 0); ++ ++ count = 0; ++ for (unsigned i = 0; i < 10; i++) { ++ log_debug("fast event loop iteration %u", i); ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ assert_se(usleep(10) >= 0); ++ } ++ log_info("ratelimit_io_handler: called %d times, event source got ratelimited", count); ++ assert_se(count < 10); ++ ++ s = sd_event_source_unref(s); ++ safe_close_pair(p); ++ ++ count = 0; ++ ++ assert_se(sd_event_add_time(e, &s, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 1000, 0, ratelimit_time_handler, &count) >= 0); ++ assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) == 0); ++ ++ do { ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ } while (!sd_event_source_is_ratelimited(s)); ++ ++ log_info("ratelimit_time_handler: called %d times, event source got ratelimited", count); ++ assert_se(count == 10); ++ ++ /* In order to get rid of active rate limit client needs to disable it explicitely */ ++ assert_se(sd_event_source_set_ratelimit(s, 0, 0) >= 0); ++ assert_se(!sd_event_source_is_ratelimited(s)); ++ ++ assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) >= 0); ++ ++ do { ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ } while (!sd_event_source_is_ratelimited(s)); ++ ++ log_info("ratelimit_time_handler: called 10 more times, event source got ratelimited"); ++ assert_se(count == 20); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -494,5 +588,7 @@ int main(int argc, char *argv[]) { + test_inotify(100); /* should work without overflow */ + test_inotify(33000); /* should trigger a q overflow */ + ++ test_ratelimit(); ++ + return 0; + } diff --git a/SOURCES/0561-core-prevent-excessive-proc-self-mountinfo-parsing.patch b/SOURCES/0561-core-prevent-excessive-proc-self-mountinfo-parsing.patch new file mode 100644 index 0000000..71075e0 --- /dev/null +++ b/SOURCES/0561-core-prevent-excessive-proc-self-mountinfo-parsing.patch @@ -0,0 +1,29 @@ +From 51737206afaa10d902c86ec9b5ec97cf425039c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Thu, 9 Jul 2020 18:16:44 +0200 +Subject: [PATCH] core: prevent excessive /proc/self/mountinfo parsing + +(cherry picked from commit d586f642fd90e3bb378f7b6d3e3a64a753e51756) + +Resolves: #1819868 +--- + src/core/mount.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 2746372db2..076dfd06a3 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1763,6 +1763,12 @@ static void mount_enumerate(Manager *m) { + goto fail; + } + ++ r = sd_event_source_set_ratelimit(m->mount_event_source, 1 * USEC_PER_SEC, 5); ++ if (r < 0) { ++ log_error_errno(r, "Failed to enable rate limit for mount events: %m"); ++ goto fail; ++ } ++ + (void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch"); + } + diff --git a/SOURCES/0562-udev-run-link_update-with-increased-retry-count-in-s.patch b/SOURCES/0562-udev-run-link_update-with-increased-retry-count-in-s.patch new file mode 100644 index 0000000..90fb6ad --- /dev/null +++ b/SOURCES/0562-udev-run-link_update-with-increased-retry-count-in-s.patch @@ -0,0 +1,44 @@ +From 1f3165bda13c8572c8c31d23c998835c4e2ad8f3 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 4 Mar 2021 17:35:22 +0100 +Subject: [PATCH] udev: run link_update() with increased retry count in second + invocation + +In PR #17431 we have introduced retry loop in link_update() in order to +maximize the chance that we end up with correct target when there are +multiple contenders for given symlink. + +Number of iterations in retry loop is either 1 or +LINK_UPDATE_MAX_RETRIES, depending on the value of 'initialized' db +flag. When device appears for the first time we need to set the +flag before calling link_update() via update_devnode() for the second +time to make sure we run the second invocation with higher retry loop +counter. + +(cherry picked from commit 996c83903da5bf8b371314b4207ff97afeef65a4) + +Related: #1931947 +--- + src/udev/udev-event.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index 9004634f65..eaec05523b 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -934,14 +934,13 @@ void udev_event_execute_rules(struct udev_event *event, + /* (re)write database file */ + udev_device_tag_index(dev, event->dev_db, true); + udev_device_update_db(dev); ++ udev_device_set_is_initialized(dev); + + /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, + * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure + * symlinks point to devices that claim them with the highest priority. */ + update_devnode(event); + +- udev_device_set_is_initialized(dev); +- + event->dev_db = udev_device_unref(event->dev_db); + } + } diff --git a/SOURCES/0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch b/SOURCES/0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch new file mode 100644 index 0000000..2eb7fc5 --- /dev/null +++ b/SOURCES/0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch @@ -0,0 +1,89 @@ +From fcd9a141d08d521c01dc1a1c06a8d43a2337a392 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 4 Feb 2019 10:23:43 +0100 +Subject: [PATCH] pam-systemd: use secure_getenv() rather than getenv() + +And explain why in a comment. + +(cherry picked from commit 83d4ab55336ff8a0643c6aa627b31e351a24040a) + +CVE-2019-3842 + +Resolves: #1687514 +--- + src/login/pam_systemd.c | 55 ++++++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 23 deletions(-) + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index 1fbf6ba585..78ddb7d398 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -274,6 +274,33 @@ static int append_session_cg_weight(pam_handle_t *handle, sd_bus_message *m, con + return 0; + } + ++static const char* getenv_harder(pam_handle_t *handle, const char *key, const char *fallback) { ++ const char *v; ++ ++ assert(handle); ++ assert(key); ++ ++ /* Looks for an environment variable, preferrably in the environment block associated with the ++ * specified PAM handle, falling back to the process' block instead. Why check both? Because we want ++ * to permit configuration of session properties from unit files that invoke PAM services, so that ++ * PAM services don't have to be reworked to set systemd-specific properties, but these properties ++ * can still be set from the unit file Environment= block. */ ++ ++ v = pam_getenv(handle, key); ++ if (!isempty(v)) ++ return v; ++ ++ /* We use secure_getenv() here, since we might get loaded into su/sudo, which are SUID. Ideally ++ * they'd clean up the environment before invoking foreign code (such as PAM modules), but alas they ++ * currently don't (to be precise, they clean up the environment they pass to their children, but ++ * not their own environ[]). */ ++ v = secure_getenv(key); ++ if (!isempty(v)) ++ return v; ++ ++ return fallback; ++} ++ + _public_ PAM_EXTERN int pam_sm_open_session( + pam_handle_t *handle, + int flags, +@@ -352,29 +379,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( + pam_get_item(handle, PAM_RUSER, (const void**) &remote_user); + pam_get_item(handle, PAM_RHOST, (const void**) &remote_host); + +- seat = pam_getenv(handle, "XDG_SEAT"); +- if (isempty(seat)) +- seat = getenv("XDG_SEAT"); +- +- cvtnr = pam_getenv(handle, "XDG_VTNR"); +- if (isempty(cvtnr)) +- cvtnr = getenv("XDG_VTNR"); +- +- type = pam_getenv(handle, "XDG_SESSION_TYPE"); +- if (isempty(type)) +- type = getenv("XDG_SESSION_TYPE"); +- if (isempty(type)) +- type = type_pam; +- +- class = pam_getenv(handle, "XDG_SESSION_CLASS"); +- if (isempty(class)) +- class = getenv("XDG_SESSION_CLASS"); +- if (isempty(class)) +- class = class_pam; +- +- desktop = pam_getenv(handle, "XDG_SESSION_DESKTOP"); +- if (isempty(desktop)) +- desktop = getenv("XDG_SESSION_DESKTOP"); ++ seat = getenv_harder(handle, "XDG_SEAT", NULL); ++ cvtnr = getenv_harder(handle, "XDG_VTNR", NULL); ++ type = getenv_harder(handle, "XDG_SESSION_TYPE", type_pam); ++ class = getenv_harder(handle, "XDG_SESSION_CLASS", class_pam); ++ desktop = getenv_harder(handle, "XDG_SESSION_DESKTOP", NULL); + + tty = strempty(tty); + diff --git a/SOURCES/0564-Revert-udev-run-link_update-with-increased-retry-cou.patch b/SOURCES/0564-Revert-udev-run-link_update-with-increased-retry-cou.patch new file mode 100644 index 0000000..a6ad6a9 --- /dev/null +++ b/SOURCES/0564-Revert-udev-run-link_update-with-increased-retry-cou.patch @@ -0,0 +1,33 @@ +From 1afb38f39a9b4508533cc1c7262e5fff418cb317 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 17 May 2021 15:49:08 +0200 +Subject: [PATCH] Revert "udev: run link_update() with increased retry count in + second invocation" + +This reverts commit 1f3165bda13c8572c8c31d23c998835c4e2ad8f3. + +Related: #1942299 +--- + src/udev/udev-event.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index eaec05523b..9004634f65 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -934,13 +934,14 @@ void udev_event_execute_rules(struct udev_event *event, + /* (re)write database file */ + udev_device_tag_index(dev, event->dev_db, true); + udev_device_update_db(dev); +- udev_device_set_is_initialized(dev); + + /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, + * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure + * symlinks point to devices that claim them with the highest priority. */ + update_devnode(event); + ++ udev_device_set_is_initialized(dev); ++ + event->dev_db = udev_device_unref(event->dev_db); + } + } diff --git a/SOURCES/0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch b/SOURCES/0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch new file mode 100644 index 0000000..3d5cc9c --- /dev/null +++ b/SOURCES/0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch @@ -0,0 +1,450 @@ +From 897b4d1e19c706d9198b9308125df57a5d469a6b Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 17 May 2021 15:50:31 +0200 +Subject: [PATCH] Revert "udev: make algorithm that selects highest priority + devlink less susceptible to race conditions" + +This reverts commit 1d5f966c1758eb620755fcae54abd07a1ac36d3d. + +Related: #1942299 +--- + src/udev/udev-event.c | 71 +++++------- + src/udev/udev-node.c | 244 ++++++++++++------------------------------ + 2 files changed, 99 insertions(+), 216 deletions(-) + +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index 9004634f65..fd8406d959 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -833,41 +833,6 @@ static int rename_netif(struct udev_event *event) { + return 0; + } + +-static void update_devnode(struct udev_event *event) { +- struct udev_device *dev = event->dev; +- +- if (major(udev_device_get_devnum(dev)) > 0) { +- bool apply; +- +- /* remove/update possible left-over symlinks from old database entry */ +- if (event->dev_db != NULL) +- udev_node_update_old_links(dev, event->dev_db); +- +- if (!event->owner_set) +- event->uid = udev_device_get_devnode_uid(dev); +- +- if (!event->group_set) +- event->gid = udev_device_get_devnode_gid(dev); +- +- if (!event->mode_set) { +- if (udev_device_get_devnode_mode(dev) > 0) { +- /* kernel supplied value */ +- event->mode = udev_device_get_devnode_mode(dev); +- } else if (event->gid > 0) { +- /* default 0660 if a group is assigned */ +- event->mode = 0660; +- } +- else { +- /* default 0600 */ +- event->mode = 0600; +- } +- } +- +- apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; +- udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); +- } +-} +- + void udev_event_execute_rules(struct udev_event *event, + usec_t timeout_usec, usec_t timeout_warn_usec, + struct udev_list *properties_list, +@@ -926,7 +891,35 @@ void udev_event_execute_rules(struct udev_event *event, + } + } + +- update_devnode(event); ++ if (major(udev_device_get_devnum(dev)) > 0) { ++ bool apply; ++ ++ /* remove/update possible left-over symlinks from old database entry */ ++ if (event->dev_db != NULL) ++ udev_node_update_old_links(dev, event->dev_db); ++ ++ if (!event->owner_set) ++ event->uid = udev_device_get_devnode_uid(dev); ++ ++ if (!event->group_set) ++ event->gid = udev_device_get_devnode_gid(dev); ++ ++ if (!event->mode_set) { ++ if (udev_device_get_devnode_mode(dev) > 0) { ++ /* kernel supplied value */ ++ event->mode = udev_device_get_devnode_mode(dev); ++ } else if (event->gid > 0) { ++ /* default 0660 if a group is assigned */ ++ event->mode = 0660; ++ } else { ++ /* default 0600 */ ++ event->mode = 0600; ++ } ++ } ++ ++ apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set; ++ udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list); ++ } + + /* preserve old, or get new initialization timestamp */ + udev_device_ensure_usec_initialized(event->dev, event->dev_db); +@@ -934,12 +927,6 @@ void udev_event_execute_rules(struct udev_event *event, + /* (re)write database file */ + udev_device_tag_index(dev, event->dev_db, true); + udev_device_update_db(dev); +- +- /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, +- * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure +- * symlinks point to devices that claim them with the highest priority. */ +- update_devnode(event); +- + udev_device_set_is_initialized(dev); + + event->dev_db = udev_device_unref(event->dev_db); +diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c +index 2eeeccdd3a..333dcae6b9 100644 +--- a/src/udev/udev-node.c ++++ b/src/udev/udev-node.c +@@ -13,27 +13,19 @@ + #include + + #include "device-nodes.h" +-#include "device-private.h" + #include "dirent-util.h" +-#include "fd-util.h" + #include "format-util.h" + #include "fs-util.h" +-#include "sd-device.h" + #include "selinux-util.h" + #include "smack-util.h" +-#include "stat-util.h" + #include "stdio-util.h" + #include "string-util.h" + #include "udev.h" +-#include "libudev-device-internal.h" + +-#define LINK_UPDATE_MAX_RETRIES 128 +- +-static int node_symlink(sd_device *dev, const char *node, const char *slink) { ++static int node_symlink(struct udev_device *dev, const char *node, const char *slink) { + struct stat stats; + char target[UTIL_PATH_SIZE]; + char *s; +- const char *id_filename; + size_t l; + char slink_tmp[UTIL_PATH_SIZE + 32]; + int i = 0; +@@ -97,10 +89,7 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) { + } + + log_debug("atomically replace '%s'", slink); +- err = device_get_id_filename(dev, &id_filename); +- if (err < 0) +- return log_error_errno(err, "Failed to get id_filename: %m"); +- strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", id_filename, NULL); ++ strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL); + unlink(slink_tmp); + do { + err = mkdir_parents_label(slink_tmp, 0755); +@@ -120,187 +109,104 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) { + if (err != 0) { + log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink); + unlink(slink_tmp); +- } else +- /* Tell caller that we replaced already existing symlink. */ +- return 1; ++ } + exit: + return err; + } + + /* find device node of device with highest priority */ +-static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) { +- _cleanup_closedir_ DIR *dir = NULL; +- _cleanup_free_ char *target = NULL; ++static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) { ++ struct udev *udev = udev_device_get_udev(dev); ++ DIR *dir; + struct dirent *dent; +- int r, priority = 0; +- +- assert(!add || dev); +- assert(stackdir); +- assert(ret); ++ int priority = 0; ++ const char *target = NULL; + + if (add) { +- const char *devnode; +- +- r = device_get_devlink_priority(dev, &priority); +- if (r < 0) +- return r; +- +- r = sd_device_get_devname(dev, &devnode); +- if (r < 0) +- return r; +- +- target = strdup(devnode); +- if (!target) +- return -ENOMEM; ++ priority = udev_device_get_devlink_priority(dev); ++ strscpy(buf, bufsize, udev_device_get_devnode(dev)); ++ target = buf; + } + + dir = opendir(stackdir); +- if (!dir) { +- if (target) { +- *ret = TAKE_PTR(target); +- return 0; +- } +- +- return -errno; +- } +- ++ if (dir == NULL) ++ return target; + FOREACH_DIRENT_ALL(dent, dir, break) { +- _cleanup_(sd_device_unrefp) sd_device *dev_db = NULL; +- const char *devnode, *id_filename; +- int db_prio = 0; ++ struct udev_device *dev_db; + + if (dent->d_name[0] == '\0') + break; + if (dent->d_name[0] == '.') + continue; + +- log_debug("Found '%s' claiming '%s'", dent->d_name, stackdir); +- +- if (device_get_id_filename(dev, &id_filename) < 0) +- continue; ++ log_debug("found '%s' claiming '%s'", dent->d_name, stackdir); + + /* did we find ourself? */ +- if (streq(dent->d_name, id_filename)) +- continue; +- +- if (sd_device_new_from_device_id(&dev_db, dent->d_name) < 0) ++ if (streq(dent->d_name, udev_device_get_id_filename(dev))) + continue; + +- if (sd_device_get_devname(dev_db, &devnode) < 0) +- continue; +- +- if (device_get_devlink_priority(dev_db, &db_prio) < 0) +- continue; +- +- if (target && db_prio <= priority) +- continue; +- +- if (DEBUG_LOGGING) { +- const char *syspath = NULL; +- +- (void) sd_device_get_syspath(dev_db, &syspath); +- log_debug("Device '%s' claims priority %i for '%s'", strnull(syspath), db_prio, stackdir); ++ dev_db = udev_device_new_from_device_id(udev, dent->d_name); ++ if (dev_db != NULL) { ++ const char *devnode; ++ ++ devnode = udev_device_get_devnode(dev_db); ++ if (devnode != NULL) { ++ if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) { ++ log_debug("'%s' claims priority %i for '%s'", ++ udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir); ++ priority = udev_device_get_devlink_priority(dev_db); ++ strscpy(buf, bufsize, devnode); ++ target = buf; ++ } ++ } ++ udev_device_unref(dev_db); + } +- +- r = free_and_strdup(&target, devnode); +- if (r < 0) +- return r; +- priority = db_prio; + } +- +- if (!target) +- return -ENOENT; +- +- *ret = TAKE_PTR(target); +- return 0; ++ closedir(dir); ++ return target; + } + +- + /* manage "stack of names" with possibly specified device priorities */ +-static int link_update(sd_device *dev, const char *slink, bool add) { +- _cleanup_free_ char *filename = NULL, *dirname = NULL; +- char name_enc[PATH_MAX]; +- const char *id_filename; +- int i, r, retries; +- +- assert(dev); +- assert(slink); +- +- r = device_get_id_filename(dev, &id_filename); +- if (r < 0) +- return log_debug_errno(r, "Failed to get id_filename: %m"); ++static void link_update(struct udev_device *dev, const char *slink, bool add) { ++ char name_enc[UTIL_PATH_SIZE]; ++ char filename[UTIL_PATH_SIZE * 2]; ++ char dirname[UTIL_PATH_SIZE]; ++ const char *target; ++ char buf[UTIL_PATH_SIZE]; + + util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc)); +- dirname = path_join(NULL, "/run/udev/links/", name_enc); +- if (!dirname) +- return log_oom(); +- filename = path_join(NULL, dirname, id_filename); +- if (!filename) +- return log_oom(); +- +- if (!add) { +- if (unlink(filename) == 0) +- (void) rmdir(dirname); +- } else +- for (;;) { +- _cleanup_close_ int fd = -1; +- +- r = mkdir_parents(filename, 0755); +- if (!IN_SET(r, 0, -ENOENT)) +- return r; +- +- fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); +- if (fd >= 0) +- break; +- if (errno != ENOENT) +- return -errno; +- } +- +- /* If the database entry is not written yet we will just do one iteration and possibly wrong symlink +- * will be fixed in the second invocation. */ +- (void) sd_device_get_is_initialized(dev, &r); +- retries = r > 0 ? LINK_UPDATE_MAX_RETRIES : 1; ++ strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL); ++ strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL); + +- for (i = 0; i < retries; i++) { +- _cleanup_free_ char *target = NULL; +- struct stat st1 = {}, st2 = {}; ++ if (!add && unlink(filename) == 0) ++ rmdir(dirname); + +- r = stat(dirname, &st1); +- if (r < 0 && errno != ENOENT) +- return -errno; +- +- r = link_find_prioritized(dev, add, dirname, &target); +- if (r == -ENOENT) { +- log_debug("No reference left, removing '%s'", slink); +- if (unlink(slink) == 0) +- (void) rmdir_parents(slink, "/"); +- +- break; +- } else if (r < 0) +- return log_error_errno(r, "Failed to determine highest priority symlink: %m"); ++ target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf)); ++ if (target == NULL) { ++ log_debug("no reference left, remove '%s'", slink); ++ if (unlink(slink) == 0) ++ rmdir_parents(slink, "/"); ++ } else { ++ log_debug("creating link '%s' to '%s'", slink, target); ++ node_symlink(dev, target, slink); ++ } + +- r = node_symlink(dev, target, slink); +- if (r < 0) { +- (void) unlink(filename); +- break; +- } else if (r == 1) +- /* We have replaced already existing symlink, possibly there is some other device trying +- * to claim the same symlink. Let's do one more iteration to give us a chance to fix +- * the error if other device actually claims the symlink with higher priority. */ +- continue; ++ if (add) { ++ int err; + +- /* Skip the second stat() if the first failed, stat_inode_unmodified() would return false regardless. */ +- if ((st1.st_mode & S_IFMT) != 0) { +- r = stat(dirname, &st2); +- if (r < 0 && errno != ENOENT) +- return -errno; ++ do { ++ int fd; + +- if (stat_inode_unmodified(&st1, &st2)) ++ err = mkdir_parents(filename, 0755); ++ if (!IN_SET(err, 0, -ENOENT)) + break; +- } ++ fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); ++ if (fd >= 0) ++ close(fd); ++ else ++ err = -errno; ++ } while (err == -ENOENT); + } +- +- return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP; + } + + void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) { +@@ -327,7 +233,7 @@ void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev + + log_debug("update old name, '%s' no longer belonging to '%s'", + name, udev_device_get_devpath(dev)); +- link_update(dev->device, name, false); ++ link_update(dev, name, false); + } + } + +@@ -432,16 +338,11 @@ void udev_node_add(struct udev_device *dev, bool apply, + xsprintf_dev_num_path(filename, + streq(udev_device_get_subsystem(dev), "block") ? "block" : "char", + udev_device_get_devnum(dev)); +- node_symlink(dev->device, udev_device_get_devnode(dev), filename); ++ node_symlink(dev, udev_device_get_devnode(dev), filename); + + /* create/update symlinks, add symlinks to name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { +- int r; +- +- r = link_update(dev->device, udev_list_entry_get_name(list_entry), true); +- if (r < 0) +- log_info_errno(r, "Failed to update device symlinks: %m"); +- } ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) ++ link_update(dev, udev_list_entry_get_name(list_entry), true); + } + + void udev_node_remove(struct udev_device *dev) { +@@ -449,13 +350,8 @@ void udev_node_remove(struct udev_device *dev) { + char filename[DEV_NUM_PATH_MAX]; + + /* remove/update symlinks, remove symlinks from name index */ +- udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { +- int r; +- +- r = link_update(dev->device, udev_list_entry_get_name(list_entry), false); +- if (r < 0) +- log_info_errno(r, "Failed to update device symlinks: %m"); +- } ++ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) ++ link_update(dev, udev_list_entry_get_name(list_entry), false); + + /* remove /dev/{block,char}/$major:$minor */ + xsprintf_dev_num_path(filename, diff --git a/SOURCES/0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch b/SOURCES/0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch new file mode 100644 index 0000000..72eea13 --- /dev/null +++ b/SOURCES/0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch @@ -0,0 +1,204 @@ +From 94ad224240140a7287f9e2be5905b9c506350193 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 17 May 2021 15:54:10 +0200 +Subject: [PATCH] test/udev-test.pl: drop test cases that add mutliple devices + +[msekleta: It is easier to delete test-cases that would make +udev test fail. Once we reintroduce the fix for link_update() +we will revert this commit.] + +Related: #1942299 +--- + test/udev-test.pl | 179 ---------------------------------------------- + 1 file changed, 179 deletions(-) + +diff --git a/test/udev-test.pl b/test/udev-test.pl +index 0612859cda..343d9c01ae 100755 +--- a/test/udev-test.pl ++++ b/test/udev-test.pl +@@ -2041,185 +2041,6 @@ TAGS=="foo", SYMLINK+="found" + TAGS=="aaa", SYMLINK+="bad" + EOF + }, +- { +- desc => "multiple devices", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_links => ["part-1"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_links => ["part-5"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", +- exp_links => ["part-6"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", +- exp_links => ["part-7"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", +- exp_links => ["part-8"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", +- exp_links => ["part-9"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", +- exp_links => ["part-10"], +- }, +- ], +- rules => < "multiple devices, same link name, positive prio", +- repeat => 100, +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_links => ["part-1"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_links => ["part-5"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", +- not_exp_links => ["partition"], +- exp_links => ["part-6"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", +- exp_links => ["part-7", "partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", +- not_exp_links => ["partition"], +- exp_links => ["part-8"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", +- not_exp_links => ["partition"], +- exp_links => ["part-9"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", +- not_exp_links => ["partition"], +- exp_links => ["part-10"], +- }, +- ], +- rules => < "multiple devices, same link name, negative prio", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_links => ["part-1"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_links => ["part-5"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", +- not_exp_links => ["partition"], +- exp_links => ["part-6"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", +- exp_links => ["part-7", "partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", +- not_exp_links => ["partition"], +- exp_links => ["part-8"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", +- not_exp_links => ["partition"], +- exp_links => ["part-9"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", +- not_exp_links => ["partition"], +- exp_links => ["part-10"], +- }, +- ], +- rules => < "multiple devices, same link name, positive prio, sleep", +- devices => [ +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", +- exp_links => ["part-1"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", +- exp_links => ["part-5"], +- not_exp_links => ["partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6", +- not_exp_links => ["partition"], +- exp_links => ["part-6"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7", +- exp_links => ["part-7", "partition"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8", +- not_exp_links => ["partition"], +- exp_links => ["part-8"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9", +- not_exp_links => ["partition"], +- exp_links => ["part-9"], +- }, +- { +- devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10", +- not_exp_links => ["partition"], +- exp_links => ["part-10"], +- }, +- ], +- sleep_us => 10000, +- rules => < 'all_block_devs', +- generator => expect_for_some("\\/sda6\$", ["blockdev"]), +- repeat => 10, +- rules => < +Date: Sat, 17 Aug 2019 02:33:43 +0200 +Subject: [PATCH] cgroup: Also set io.bfq.weight + +Current kernels with BFQ scheduler do not yet set their IO weight +through "io.weight" but through "io.bfq.weight" (using a slightly +different interface supporting only default weights, not per-device +weights). This commit enables "IOWeight=" to just to that. + +This patch may be dropped at some time later. + +Github-Link: https://github.com/systemd/systemd/issues/7057 +Signed-off-by: Kai Krakow + +(cherry picked from commit 21221ce1ce9a572e82d46d80692afd65c224fc50) + +Related: #1927290 +--- + src/core/cgroup.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 71e30fd4db..f02cc31c6e 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -984,6 +984,14 @@ static void cgroup_context_apply( + log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to set io.weight: %m"); + ++ /* FIXME: drop this when distro kernels properly support BFQ through "io.weight" ++ * See also: https://github.com/systemd/systemd/pull/13335 */ ++ xsprintf(buf, "%" PRIu64 "\n", weight); ++ r = cg_set_attribute("io", path, "io.bfq.weight", buf); ++ if (r < 0) ++ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r, ++ "Failed to set io.bfq.weight: %m"); ++ + if (has_io) { + CGroupIODeviceWeight *w; + diff --git a/SOURCES/0568-seccomp-allow-turning-off-of-seccomp-filtering-via-e.patch b/SOURCES/0568-seccomp-allow-turning-off-of-seccomp-filtering-via-e.patch new file mode 100644 index 0000000..58d8b14 --- /dev/null +++ b/SOURCES/0568-seccomp-allow-turning-off-of-seccomp-filtering-via-e.patch @@ -0,0 +1,82 @@ +From e706f5df66b7189a7df526aeeb45c86b8c4b057a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Nov 2020 14:51:10 +0100 +Subject: [PATCH] seccomp: allow turning off of seccomp filtering via env var + +Fixes: #17504 + +(While we are it, also move $SYSTEMD_SECCOMP_LOG= env var description +into the right document section) + +Also suggested in: https://github.com/systemd/systemd/issues/17245#issuecomment-704773603 + +(cherry picked from commit ce8f6d478e3f6c6a313fb19615aa5029bb18f86d) + +Resolves: #1916835 +--- + doc/ENVIRONMENT.md | 3 +++ + src/nspawn/nspawn-seccomp.c | 2 +- + src/shared/seccomp-util.c | 19 +++++++++++++++---- + 3 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 0e763b6302..36b649afe1 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -117,3 +117,6 @@ systemd-sulogin-shell: + * `$SYSTEMD_SULOGIN_FORCE=1` — This skips asking for the root password if the + root password is not available (such as when the root account is locked). + See `sulogin(8)` for more details. ++ ++* `$SYSTEMD_SECCOMP=0` – if set, seccomp filters will not be enforced, even if ++ support for it is compiled in and available in the kernel. +diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c +index b56c5b04a8..fba22644da 100644 +--- a/src/nspawn/nspawn-seccomp.c ++++ b/src/nspawn/nspawn-seccomp.c +@@ -172,7 +172,7 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **sys + int r; + + if (!is_seccomp_available()) { +- log_debug("SECCOMP features not detected in the kernel, disabling SECCOMP filterering"); ++ log_debug("SECCOMP features not detected in the kernel or disabled at runtime, disabling SECCOMP filtering"); + return 0; + } + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index d91fb4e269..e903512d45 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -12,6 +12,7 @@ + + #include "af-list.h" + #include "alloc-util.h" ++#include "env-util.h" + #include "macro.h" + #include "nsflags.h" + #include "process-util.h" +@@ -244,10 +245,20 @@ static bool is_seccomp_filter_available(void) { + bool is_seccomp_available(void) { + static int cached_enabled = -1; + +- if (cached_enabled < 0) +- cached_enabled = +- is_basic_seccomp_available() && +- is_seccomp_filter_available(); ++ if (cached_enabled < 0) { ++ int b; ++ ++ b = getenv_bool("SYSTEMD_SECCOMP"); ++ if (b != 0) { ++ if (b < 0 && b != -ENXIO) /* ENXIO: env var unset */ ++ log_debug_errno(b, "Failed to parse $SYSTEMD_SECCOMP value, ignoring."); ++ ++ cached_enabled = ++ is_basic_seccomp_available() && ++ is_seccomp_filter_available(); ++ } else ++ cached_enabled = false; ++ } + + return cached_enabled; + } diff --git a/SOURCES/0569-meson-remove-strange-dep-that-causes-meson-to-enter-.patch b/SOURCES/0569-meson-remove-strange-dep-that-causes-meson-to-enter-.patch new file mode 100644 index 0000000..9029c4b --- /dev/null +++ b/SOURCES/0569-meson-remove-strange-dep-that-causes-meson-to-enter-.patch @@ -0,0 +1,36 @@ +From 7fb2d86b58201341a582b739a5445821bec66eea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 6 Nov 2019 12:44:39 +0100 +Subject: [PATCH] meson: remove strange dep that causes meson to enter infinite + loop + +The value is obviously bogus, but didn't seem to cause problems so far. +With meson-0.52.0, it causes a hang. The number of aliases is always rather +small (usually just one or two, possibly up to a dozen in a few cases), so +even if this causes some looping, it is strange that it has such a huge impact. +But let's just remove it. + +Fixes #13742. + +Tested with meson-0.52.0-1.module_f31+6771+f5d842eb.noarch, +meson-0.51.1-1.fc29.noarch. + +(cherry picked from commit af336643a01d0b210b18312c253a50594ba54b0a) + +Resolves: #1970860 +--- + man/meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/man/meson.build b/man/meson.build +index ec05d73bc6..a953d34098 100644 +--- a/man/meson.build ++++ b/man/meson.build +@@ -68,7 +68,6 @@ foreach tuple : xsltproc.found() ? manpages : [] + foreach htmlalias : htmlaliases + link = custom_target( + htmlalias, +- input : p2, + output : htmlalias, + command : ['ln', '-fs', html, '@OUTPUT@']) + if want_html diff --git a/SOURCES/0570-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch b/SOURCES/0570-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch new file mode 100644 index 0000000..b14a3c7 --- /dev/null +++ b/SOURCES/0570-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch @@ -0,0 +1,182 @@ +From 8df650c7c5adc2bb24a0077d8332f5ee342e7fd8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Feb 2021 10:25:24 +0100 +Subject: [PATCH] copy: handle copy_file_range() weirdness on procfs/sysfs + +This addresses the issue described in https://lwn.net/Articles/846403/ +and makes sure we will be able to stream bytes from procfs/sysfs via +copy_bytes() if people ask us to. + +Based on: ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c +Related: #1970860 +--- + src/basic/copy.c | 75 +++++++++++++++++++++++++++++--------------- + src/test/test-copy.c | 17 ++++++++++ + 2 files changed, 66 insertions(+), 26 deletions(-) + +diff --git a/src/basic/copy.c b/src/basic/copy.c +index e06a503a29..a48c42c5c6 100644 +--- a/src/basic/copy.c ++++ b/src/basic/copy.c +@@ -92,7 +92,7 @@ int copy_bytes_full( + void **ret_remains, + size_t *ret_remains_size) { + +- bool try_cfr = true, try_sendfile = true, try_splice = true; ++ bool try_cfr = true, try_sendfile = true, try_splice = true, copied_something = false; + int r, nonblock_pipe = -1; + size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */ + +@@ -185,9 +185,20 @@ int copy_bytes_full( + + try_cfr = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ +- break; +- else ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ /* So, we hit EOF immediately, without having copied a single byte. This ++ * could indicate two things: the file is actually empty, or we are on some ++ * virtual file system such as procfs/sysfs where the syscall actually ++ * doesn't work but doesn't return an error. Try to handle that, by falling ++ * back to simple read()s in case we encounter empty files. ++ * ++ * See: https://lwn.net/Articles/846403/ */ ++ try_cfr = try_sendfile = try_splice = false; ++ } else + /* Success! */ + goto next; + } +@@ -201,9 +212,14 @@ int copy_bytes_full( + + try_sendfile = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */ + break; +- else ++ } else + /* Success! */ + goto next; + } +@@ -213,14 +229,14 @@ int copy_bytes_full( + + /* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file + * descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the +- * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour here, and +- * check if either of the specified fds are a pipe, and if so, let's pass the flag +- * automatically, depending on O_NONBLOCK being set. ++ * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour ++ * here, and check if either of the specified fds are a pipe, and if so, let's pass ++ * the flag automatically, depending on O_NONBLOCK being set. + * +- * Here's a twist though: when we use it to move data between two pipes of which one has +- * O_NONBLOCK set and the other has not, then we have no individual control over O_NONBLOCK +- * behaviour. Hence in that case we can't use splice() and still guarantee systematic +- * O_NONBLOCK behaviour, hence don't. */ ++ * Here's a twist though: when we use it to move data between two pipes of which one ++ * has O_NONBLOCK set and the other has not, then we have no individual control over ++ * O_NONBLOCK behaviour. Hence in that case we can't use splice() and still guarantee ++ * systematic O_NONBLOCK behaviour, hence don't. */ + + if (nonblock_pipe < 0) { + int a, b; +@@ -238,12 +254,13 @@ int copy_bytes_full( + (a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) || + (a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE)) + +- /* splice() only works if one of the fds is a pipe. If neither is, let's skip +- * this step right-away. As mentioned above, if one of the two fds refers to a +- * blocking pipe and the other to a non-blocking pipe, we can't use splice() +- * either, hence don't try either. This hence means we can only use splice() if +- * either only one of the two fds is a pipe, or if both are pipes with the same +- * nonblocking flag setting. */ ++ /* splice() only works if one of the fds is a pipe. If neither is, ++ * let's skip this step right-away. As mentioned above, if one of the ++ * two fds refers to a blocking pipe and the other to a non-blocking ++ * pipe, we can't use splice() either, hence don't try either. This ++ * hence means we can only use splice() if either only one of the two ++ * fds is a pipe, or if both are pipes with the same nonblocking flag ++ * setting. */ + + try_splice = false; + else +@@ -259,9 +276,13 @@ int copy_bytes_full( + + try_splice = false; + /* use fallback below */ +- } else if (n == 0) /* EOF */ +- break; +- else ++ } else if (n == 0) { /* likely EOF */ ++ ++ if (copied_something) ++ break; ++ ++ try_splice = false; /* same logic as above for copy_file_range() + sendfile() */ ++ } else + /* Success! */ + goto next; + } +@@ -312,11 +333,13 @@ int copy_bytes_full( + assert(max_bytes >= (uint64_t) n); + max_bytes -= n; + } +- /* sendfile accepts at most SSIZE_MAX-offset bytes to copy, +- * so reduce our maximum by the amount we already copied, +- * but don't go below our copy buffer size, unless we are +- * close the limit of bytes we are allowed to copy. */ ++ ++ /* sendfile accepts at most SSIZE_MAX-offset bytes to copy, so reduce our maximum by the ++ * amount we already copied, but don't go below our copy buffer size, unless we are close the ++ * limit of bytes we are allowed to copy. */ + m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n); ++ ++ copied_something = true; + } + + return 0; /* return 0 if we hit EOF earlier than the size limit */ +diff --git a/src/test/test-copy.c b/src/test/test-copy.c +index 2e8d251ac1..29ac33e47a 100644 +--- a/src/test/test-copy.c ++++ b/src/test/test-copy.c +@@ -253,6 +253,22 @@ static void test_copy_atomic(void) { + assert_se(copy_file_atomic("/etc/fstab", q, 0644, 0, COPY_REPLACE) >= 0); + } + ++static void test_copy_proc(void) { ++ _cleanup_(rm_rf_physical_and_freep) char *p = NULL; ++ _cleanup_free_ char *f = NULL, *a = NULL, *b = NULL; ++ ++ /* Check if copying data from /proc/ works correctly, i.e. let's see if https://lwn.net/Articles/846403/ is a problem for us */ ++ ++ assert_se(mkdtemp_malloc(NULL, &p) >= 0); ++ assert_se(f = path_join(NULL, p, "version")); ++ assert_se(copy_file("/proc/version", f, 0, (mode_t) -1, 0, 0) >= 0); ++ ++ assert_se(read_one_line_file("/proc/version", &a) >= 0); ++ assert_se(read_one_line_file(f, &b) >= 0); ++ assert_se(streq(a, b)); ++ assert_se(strlen(a) > 0); ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + +@@ -267,6 +283,7 @@ int main(int argc, char *argv[]) { + test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */ + test_copy_bytes_regular_file(argv[0], true, 32000); + test_copy_atomic(); ++ test_copy_proc(); + + return 0; + } diff --git a/SOURCES/0571-core-Hide-Deactivated-successfully-message.patch b/SOURCES/0571-core-Hide-Deactivated-successfully-message.patch new file mode 100644 index 0000000..1ec2d8a --- /dev/null +++ b/SOURCES/0571-core-Hide-Deactivated-successfully-message.patch @@ -0,0 +1,33 @@ +From 4dc498258bd0cce1bc8ad2311c5f12de5678e0af Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 27 May 2021 12:25:51 +0200 +Subject: [PATCH] core: Hide "Deactivated successfully" message + +Show message "Deactivated successfully" in debug mode (when manager is +user) rather than in info mode. This message has low information value +for regular users and it might be a bit overwhelming on a system with +a lot of devices. + +(cherry picked from commit edf2ee22f54005d76b2fb8fdcc9c60974feb88bc) + +Resolves: #1954802 +--- + src/core/unit.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index cd3e7c806d..93c13e58d9 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5525,7 +5525,10 @@ int unit_pid_attachable(Unit *u, pid_t pid, sd_bus_error *error) { + void unit_log_success(Unit *u) { + assert(u); + +- log_struct(LOG_INFO, ++ /* Let's show message "Deactivated successfully" in debug mode (when manager is user) rather than in info mode. ++ * This message has low information value for regular users and it might be a bit overwhelming on a system with ++ * a lot of devices. */ ++ log_struct(MANAGER_IS_USER(u->manager) ? LOG_DEBUG : LOG_INFO, + "MESSAGE_ID=" SD_MESSAGE_UNIT_SUCCESS_STR, + LOG_UNIT_ID(u), + LOG_UNIT_INVOCATION_ID(u), diff --git a/SOURCES/0572-util-rework-in_initrd-to-make-use-of-path_is_tempora.patch b/SOURCES/0572-util-rework-in_initrd-to-make-use-of-path_is_tempora.patch new file mode 100644 index 0000000..bdc3418 --- /dev/null +++ b/SOURCES/0572-util-rework-in_initrd-to-make-use-of-path_is_tempora.patch @@ -0,0 +1,35 @@ +From 42f639d3689b7cbc9ce6b9578a2790c254508384 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Fri, 8 Jan 2021 14:52:26 +0800 +Subject: [PATCH] util: rework in_initrd() to make use of + path_is_temporary_fs() + +(cherry picked from commit 96cceb35e7985f5ee6c9b17e129a76259273cdde) + +Related: #1959339 +--- + src/basic/util.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/basic/util.c b/src/basic/util.c +index 82cb937314..b443e639f3 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -130,7 +130,6 @@ int prot_from_flags(int flags) { + } + + bool in_initrd(void) { +- struct statfs s; + + if (saved_in_initrd >= 0) + return saved_in_initrd; +@@ -146,8 +145,7 @@ bool in_initrd(void) { + */ + + saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 && +- statfs("/", &s) >= 0 && +- is_temporary_fs(&s); ++ path_is_temporary_fs("/") > 0; + + return saved_in_initrd; + } diff --git a/SOURCES/0573-initrd-extend-SYSTEMD_IN_INITRD-to-accept-non-ramfs-.patch b/SOURCES/0573-initrd-extend-SYSTEMD_IN_INITRD-to-accept-non-ramfs-.patch new file mode 100644 index 0000000..0b3202f --- /dev/null +++ b/SOURCES/0573-initrd-extend-SYSTEMD_IN_INITRD-to-accept-non-ramfs-.patch @@ -0,0 +1,99 @@ +From 99ca5b681fceedd010b2616b1248a483f4bfbd97 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 13 Jan 2021 00:04:53 +0800 +Subject: [PATCH] initrd: extend SYSTEMD_IN_INITRD to accept non-ramfs rootfs + +Sometimes, non-ramfs initrd root are useful. Eg, for kdump, because +initramfs is memory consuming, so mount a compressed image in earlier +initrd, chroot into it then let systemd do the rest of job is a good +solution. + +But systemd doesn't recognize the initrd environment if rootfs is not a +temporary fs. This is a reasonable check, because switch-root in initrd +will wipe the whole rootfs, will be a disaster if there are any +misdetect. + +So extend SYSTEMD_IN_INITRD environment variable, now it accepts boolean +value and two extra keyword, "auto" and "lenient". "auto" is same as +before, and it's the default value. "lenient" will let systemd bypass +the rootfs check. + +(cherry picked from commit db4c45cf4f10ca094b9e9570b758abd445d65381) + +Related: #1959339 +--- + doc/ENVIRONMENT.md | 8 ++++++++ + src/basic/util.c | 28 +++++++++++++++++++++++++--- + 2 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 36b649afe1..8d7ce6ae2c 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -37,6 +37,14 @@ All tools: + useful for debugging, in order to test generators and other code against + specific kernel command lines. + ++* `$SYSTEMD_IN_INITRD=[auto|lenient|0|1]` — if set, specifies initrd detection ++ method. Defaults to `auto`. Behavior is defined as follows: ++ `auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted ++ on `/`. If both conditions meet, then it's in initrd. ++ `lenient`: Similiar to `auto`, but the rootfs check is skipped. ++ `0|1`: Simply overrides initrd detection. This is useful for debugging and ++ testing initrd-only programs in the main system. ++ + * `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will + not output graphical smiley emojis, but ASCII alternatives instead. Note that + this only controls use of Unicode emoji glyphs, and has no effect on other +diff --git a/src/basic/util.c b/src/basic/util.c +index b443e639f3..59bcf7b00c 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -130,11 +130,14 @@ int prot_from_flags(int flags) { + } + + bool in_initrd(void) { ++ int r; ++ const char *e; ++ bool lenient = false; + + if (saved_in_initrd >= 0) + return saved_in_initrd; + +- /* We make two checks here: ++ /* We have two checks here: + * + * 1. the flag file /etc/initrd-release must exist + * 2. the root file system must be a memory file system +@@ -142,10 +145,29 @@ bool in_initrd(void) { + * The second check is extra paranoia, since misdetecting an + * initrd can have bad consequences due the initrd + * emptying when transititioning to the main systemd. ++ * ++ * If env var $SYSTEMD_IN_INITRD is not set or set to "auto", ++ * both checks are used. If it's set to "lenient", only check ++ * 1 is used. If set to a booleen value, then the boolean ++ * value is returned. + */ + +- saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 && +- path_is_temporary_fs("/") > 0; ++ e = secure_getenv("SYSTEMD_IN_INITRD"); ++ if (e) { ++ if (streq(e, "lenient")) ++ lenient = true; ++ else if (!streq(e, "auto")) { ++ r = parse_boolean(e); ++ if (r >= 0) { ++ saved_in_initrd = r > 0; ++ return saved_in_initrd; ++ } ++ log_debug_errno(r, "Failed to parse $SYSTEMD_IN_INITRD, ignoring: %m"); ++ } ++ } ++ ++ saved_in_initrd = (lenient || path_is_temporary_fs("/") > 0) && ++ access("/etc/initrd-release", F_OK) >= 0; + + return saved_in_initrd; + } diff --git a/SOURCES/0574-initrd-do-a-debug-log-if-failed-to-detect-rootfs-typ.patch b/SOURCES/0574-initrd-do-a-debug-log-if-failed-to-detect-rootfs-typ.patch new file mode 100644 index 0000000..cda944e --- /dev/null +++ b/SOURCES/0574-initrd-do-a-debug-log-if-failed-to-detect-rootfs-typ.patch @@ -0,0 +1,35 @@ +From 3299c855c6e65596ff9d8635dcbd45ff6818499a Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Thu, 14 Jan 2021 00:39:10 +0800 +Subject: [PATCH] initrd: do a debug log if failed to detect rootfs type + +(cherry picked from commit 3377c740d9121f38385e70d6a380b5e4bd8c672a) + +Related: #1959339 +--- + src/basic/util.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/basic/util.c b/src/basic/util.c +index 59bcf7b00c..fef52ad5ff 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -166,8 +166,16 @@ bool in_initrd(void) { + } + } + +- saved_in_initrd = (lenient || path_is_temporary_fs("/") > 0) && +- access("/etc/initrd-release", F_OK) >= 0; ++ if (!lenient) { ++ r = path_is_temporary_fs("/"); ++ if (r < 0) ++ log_debug_errno(r, "Couldn't determine if / is a temporary file system: %m"); ++ ++ saved_in_initrd = r > 0; ++ } ++ ++ if (saved_in_initrd != 0) ++ saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0; + + return saved_in_initrd; + } diff --git a/SOURCES/0575-initrd-do-a-debug-log-if-etc-initrd-release-doesn-t-.patch b/SOURCES/0575-initrd-do-a-debug-log-if-etc-initrd-release-doesn-t-.patch new file mode 100644 index 0000000..f31ba4c --- /dev/null +++ b/SOURCES/0575-initrd-do-a-debug-log-if-etc-initrd-release-doesn-t-.patch @@ -0,0 +1,39 @@ +From a1417c121d19272b1389098648132106a5ffc661 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Thu, 14 Jan 2021 01:25:20 +0800 +Subject: [PATCH] initrd: do a debug log if /etc/initrd-release doesn't take + effect + +Signed-off-by: Kairui Song + +(cherry picked from commit 4a60d8cbcae574896a28f9f1f6204a1bddca8e99) + +Related: #1959339 +--- + src/basic/util.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/basic/util.c b/src/basic/util.c +index fef52ad5ff..609f8c2f33 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -174,8 +174,17 @@ bool in_initrd(void) { + saved_in_initrd = r > 0; + } + +- if (saved_in_initrd != 0) +- saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0; ++ r = access("/etc/initrd-release", F_OK); ++ if (r >= 0) { ++ if (saved_in_initrd == 0) ++ log_debug("/etc/initrd-release exists, but it's not an initrd."); ++ else ++ saved_in_initrd = 1; ++ } else { ++ if (errno != ENOENT) ++ log_debug_errno(errno, "Failed to test if /etc/initrd-release exists: %m"); ++ saved_in_initrd = 0; ++ } + + return saved_in_initrd; + } diff --git a/SOURCES/0576-units-assign-user-runtime-dir-.service-to-user-i.sli.patch b/SOURCES/0576-units-assign-user-runtime-dir-.service-to-user-i.sli.patch new file mode 100644 index 0000000..ea2c0ce --- /dev/null +++ b/SOURCES/0576-units-assign-user-runtime-dir-.service-to-user-i.sli.patch @@ -0,0 +1,25 @@ +From 64975b046d5a0877690aa6de9389b8234ee1cfab Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 10:45:31 +0200 +Subject: [PATCH] units: assign user-runtime-dir@.service to user-%i.slice + +This service won't use much resources, but it's certainly nicer to see +it attached th the user's slice along with user@.service, so that +everything we run for a specific user is properly bound into one unit. + +(cherry picked from commit 1193c11a04b3ecc29925904fbeb5d64834bce73e) + +Related: #1946453 +--- + units/user-runtime-dir@.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in +index 8c02beda3b..13b3ed52f8 100644 +--- a/units/user-runtime-dir@.service.in ++++ b/units/user-runtime-dir@.service.in +@@ -15,3 +15,4 @@ StopWhenUnneeded=yes + ExecStart=@rootlibexecdir@/systemd-user-runtime-dir start %i + ExecStop=@rootlibexecdir@/systemd-user-runtime-dir stop %i + RemainAfterExit=true ++Slice=user-%i.slice diff --git a/SOURCES/0577-units-order-user-runtime-dir-.service-after-systemd-.patch b/SOURCES/0577-units-order-user-runtime-dir-.service-after-systemd-.patch new file mode 100644 index 0000000..c852f8d --- /dev/null +++ b/SOURCES/0577-units-order-user-runtime-dir-.service-after-systemd-.patch @@ -0,0 +1,30 @@ +From 1fa9a6bf51a1a1d0fa2ccc23283739d16e9179b4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 10:42:09 +0200 +Subject: [PATCH] units: order user-runtime-dir@.service after + systemd-user-sessions.service + +We use systemd-user-sessions.service as barrier when to allow login +sessions. With this patch user@.service is ordered after that too, so +that any login related code (which user-runtime-dir@.service is) is +guaranteed to run after the barrier, and never before. + +(cherry picked from commit eb748aef4fbfd03b64938aa471bb8ceda1bc89a8) + +Related: #1946453 +--- + units/user-runtime-dir@.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in +index 13b3ed52f8..31354c9bf2 100644 +--- a/units/user-runtime-dir@.service.in ++++ b/units/user-runtime-dir@.service.in +@@ -9,6 +9,7 @@ + + [Unit] + Description=/run/user/%i mount wrapper ++After=systemd-user-sessions.service + StopWhenUnneeded=yes + + [Service] diff --git a/SOURCES/0578-units-make-sure-user-runtime-dir-.service-is-Type-on.patch b/SOURCES/0578-units-make-sure-user-runtime-dir-.service-is-Type-on.patch new file mode 100644 index 0000000..493f4c6 --- /dev/null +++ b/SOURCES/0578-units-make-sure-user-runtime-dir-.service-is-Type-on.patch @@ -0,0 +1,26 @@ +From 780d1d9fa7ccc036e6e237221ac51ed69453c8c6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 2 Aug 2018 20:57:56 +0200 +Subject: [PATCH] units: make sure user-runtime-dir@.service is Type=oneshot + +We order user@.service after it, hence we need to properly know when it +finished starting up. + +(cherry picked from commit d06e8fbce35c2b52ee1d09af4888876d5f2d7ae4) + +Related: #1946453 +--- + units/user-runtime-dir@.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in +index 31354c9bf2..bfd6488d61 100644 +--- a/units/user-runtime-dir@.service.in ++++ b/units/user-runtime-dir@.service.in +@@ -15,5 +15,6 @@ StopWhenUnneeded=yes + [Service] + ExecStart=@rootlibexecdir@/systemd-user-runtime-dir start %i + ExecStop=@rootlibexecdir@/systemd-user-runtime-dir stop %i ++Type=oneshot + RemainAfterExit=true + Slice=user-%i.slice diff --git a/SOURCES/0579-user-runtime-dir-downgrade-a-few-log-messages-to-LOG.patch b/SOURCES/0579-user-runtime-dir-downgrade-a-few-log-messages-to-LOG.patch new file mode 100644 index 0000000..1a577ba --- /dev/null +++ b/SOURCES/0579-user-runtime-dir-downgrade-a-few-log-messages-to-LOG.patch @@ -0,0 +1,52 @@ +From 354b894aa3e79f54ab75bf6fae76ce28ca80db38 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 2 Aug 2018 20:56:34 +0200 +Subject: [PATCH] user-runtime-dir: downgrade a few log messages to LOG_DEBUG + that we ignore + +As the comments already say it might be quite likely that +$XDG_RUNTIME_DIR is not set up as mount, and we shouldn't complain about +that. + +Moreover, let's make this idempotent, so that a runtime dir that is +already gone and is removed again doesn't cause failure. + +(cherry picked from commit 3a13442bbf72e7ebdd0b4d60c2922ea7c5cc9496) + +Related: #1946453 +--- + src/login/user-runtime-dir.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c +index 1bb26c99e4..9693821990 100644 +--- a/src/login/user-runtime-dir.c ++++ b/src/login/user-runtime-dir.c +@@ -95,20 +95,19 @@ static int user_remove_runtime_path(const char *runtime_path) { + + r = rm_rf(runtime_path, 0); + if (r < 0) +- log_error_errno(r, "Failed to remove runtime directory %s (before unmounting): %m", runtime_path); ++ log_debug_errno(r, "Failed to remove runtime directory %s (before unmounting), ignoring: %m", runtime_path); + +- /* Ignore cases where the directory isn't mounted, as that's +- * quite possible, if we lacked the permissions to mount +- * something */ ++ /* Ignore cases where the directory isn't mounted, as that's quite possible, if we lacked the permissions to ++ * mount something */ + r = umount2(runtime_path, MNT_DETACH); + if (r < 0 && !IN_SET(errno, EINVAL, ENOENT)) +- log_error_errno(errno, "Failed to unmount user runtime directory %s: %m", runtime_path); ++ log_debug_errno(errno, "Failed to unmount user runtime directory %s, ignoring: %m", runtime_path); + + r = rm_rf(runtime_path, REMOVE_ROOT); +- if (r < 0) +- log_error_errno(r, "Failed to remove runtime directory %s (after unmounting): %m", runtime_path); ++ if (r < 0 && r != -ENOENT) ++ return log_error_errno(r, "Failed to remove runtime directory %s (after unmounting): %m", runtime_path); + +- return r; ++ return 0; + } + + static int do_mount(const char *runtime_path, uid_t uid, gid_t gid) { diff --git a/SOURCES/0580-shared-install-Preserve-escape-characters-for-escape.patch b/SOURCES/0580-shared-install-Preserve-escape-characters-for-escape.patch new file mode 100644 index 0000000..beb7ac3 --- /dev/null +++ b/SOURCES/0580-shared-install-Preserve-escape-characters-for-escape.patch @@ -0,0 +1,33 @@ +From 91ed691ff73d4d71fae8f6896a1bba73e6a76bba Mon Sep 17 00:00:00 2001 +From: David Michael +Date: Wed, 20 Mar 2019 15:14:32 +0000 +Subject: [PATCH] shared/install: Preserve escape characters for escaped unit + names + +Since switching to extract_first_word with no flags for parsing +unit names in 4c9565eea534cd233a913c8c21f7920dba229743, escape +characters will be stripped from escaped unit names such as +"mnt-persistent\x2dvolume.mount" resulting in the unit not being +configured as defined. Preserve escape characters again for +compatibility with existing preset definitions. + +(cherry picked from commit 82bd4da71e9cdd5a2e9266332f5a7399845e31f6) + +Resolves: #1952686 +--- + src/shared/install.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index c2847df3f8..c9fef6bde2 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -2774,7 +2774,7 @@ static int split_pattern_into_name_and_instances(const char *pattern, char **out + assert(out_instances); + assert(out_unit_name); + +- r = extract_first_word(&pattern, &unit_name, NULL, 0); ++ r = extract_first_word(&pattern, &unit_name, NULL, EXTRACT_RETAIN_ESCAPE); + if (r < 0) + return r; + diff --git a/SOURCES/0581-basic-virt-Detect-PowerVM-hypervisor.patch b/SOURCES/0581-basic-virt-Detect-PowerVM-hypervisor.patch new file mode 100644 index 0000000..38da2c0 --- /dev/null +++ b/SOURCES/0581-basic-virt-Detect-PowerVM-hypervisor.patch @@ -0,0 +1,80 @@ +From 48dacf8d30cd61b72939e9c3419acced4b2fde74 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Fri, 2 Oct 2020 11:05:23 +0200 +Subject: [PATCH] basic/virt: Detect PowerVM hypervisor + +Currently systemd-detect-virt fails to detect running under PowerVM. + +Add code to detect PowerVM based on code in util-linux. + +Signed-off-by: Michal Suchanek +(cherry picked from commit 3224e38bb6b3287ca253cbafb460a150544d5818) + +Resolves: #1937989 +--- + man/systemd-detect-virt.xml | 7 ++++++- + src/basic/virt.c | 6 ++++++ + src/basic/virt.h | 1 + + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml +index c4763fd561..6beb2c2aa1 100644 +--- a/man/systemd-detect-virt.xml ++++ b/man/systemd-detect-virt.xml +@@ -65,7 +65,7 @@ + + + +- VM ++ VM + qemu + QEMU software virtualization, without KVM + +@@ -95,6 +95,11 @@ + Oracle VM VirtualBox (historically marketed by innotek and Sun Microsystems), for legacy and KVM hypervisor + + ++ ++ powervm ++ IBM PowerVM hypervisor - comes as firmware with some IBM POWER servers ++ ++ + + xen + Xen hypervisor (only domU, not dom0) +diff --git a/src/basic/virt.c b/src/basic/virt.c +index dfa1525219..0b88005ed6 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -92,6 +92,11 @@ static int detect_vm_device_tree(void) { + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *dent; + ++ if (access("/proc/device-tree/ibm,partition-name", F_OK) == 0 && ++ access("/proc/device-tree/hmc-managed?", F_OK) == 0 && ++ access("/proc/device-tree/chosen/qemu,graphic-width", F_OK) != 0) ++ return VIRTUALIZATION_POWERVM; ++ + dir = opendir("/proc/device-tree"); + if (!dir) { + if (errno == ENOENT) { +@@ -635,6 +640,7 @@ static const char *const virtualization_table[_VIRTUALIZATION_MAX] = { + [VIRTUALIZATION_PARALLELS] = "parallels", + [VIRTUALIZATION_BHYVE] = "bhyve", + [VIRTUALIZATION_QNX] = "qnx", ++ [VIRTUALIZATION_POWERVM] = "powervm", + [VIRTUALIZATION_VM_OTHER] = "vm-other", + + [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn", +diff --git a/src/basic/virt.h b/src/basic/virt.h +index c4cf4bfeab..640b3ed779 100644 +--- a/src/basic/virt.h ++++ b/src/basic/virt.h +@@ -21,6 +21,7 @@ enum { + VIRTUALIZATION_PARALLELS, + VIRTUALIZATION_BHYVE, + VIRTUALIZATION_QNX, ++ VIRTUALIZATION_POWERVM, + VIRTUALIZATION_VM_OTHER, + VIRTUALIZATION_VM_LAST = VIRTUALIZATION_VM_OTHER, + diff --git a/SOURCES/0582-man-document-differences-in-clean-exit-status-for-Ty.patch b/SOURCES/0582-man-document-differences-in-clean-exit-status-for-Ty.patch new file mode 100644 index 0000000..233523a --- /dev/null +++ b/SOURCES/0582-man-document-differences-in-clean-exit-status-for-Ty.patch @@ -0,0 +1,57 @@ +From 102f4ff97a24c2ddaf6e569c678a0a713f972863 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 Mar 2021 10:05:47 +0100 +Subject: [PATCH] man: document differences in clean exit status for + Type=oneshot + +See commit 1f0958f640b87175cd547c1e69084cfe54a22e9d . + +(cherry picked from commit f055cf77862bc580f3afbfaac161d1c060f39411) + +Resolves: #1940078 +--- + man/systemd.service.xml | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 54586d1948..1e30a564df 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -669,14 +669,19 @@ + If set to (the default), the service will + not be restarted. If set to , it + will be restarted only when the service process exits cleanly. +- In this context, a clean exit means an exit code of 0, or one +- of the signals +- SIGHUP, +- SIGINT, +- SIGTERM or +- SIGPIPE, and +- additionally, exit statuses and signals specified in +- SuccessExitStatus=. If set to ++ In this context, a clean exit means any of the following: ++ ++ exit code of 0; ++ for types other than ++ Type=oneshot, one of the signals ++ SIGHUP, ++ SIGINT, ++ SIGTERM, or ++ SIGPIPE; ++ exit statuses and signals specified in ++ SuccessExitStatus=. ++ ++ If set to + , the service will be restarted + when the process exits with a non-zero exit code, is + terminated by a signal (including on core dump, but excluding +@@ -798,7 +803,8 @@ + Takes a list of exit status definitions that, + when returned by the main service process, will be considered + successful termination, in addition to the normal successful +- exit code 0 and the signals SIGHUP, ++ exit code 0 and, except for Type=oneshot, ++ the signals SIGHUP, + SIGINT, SIGTERM, and + SIGPIPE. Exit status definitions can + either be numeric exit codes or termination signal names, diff --git a/SOURCES/0583-busctl-add-a-timestamp-to-the-output-of-the-busctl-m.patch b/SOURCES/0583-busctl-add-a-timestamp-to-the-output-of-the-busctl-m.patch new file mode 100644 index 0000000..c40d0fd --- /dev/null +++ b/SOURCES/0583-busctl-add-a-timestamp-to-the-output-of-the-busctl-m.patch @@ -0,0 +1,42 @@ +From 53673326ea78039b27e1dbd5328a8fe9a1a17445 Mon Sep 17 00:00:00 2001 +From: d032747 +Date: Tue, 15 Dec 2020 10:40:06 +0100 +Subject: [PATCH] busctl: add a timestamp to the output of the busctl monitor + command + +(cherry picked from commit 6fe2a70b9160e35fdeed9d37bd31727c2d46a8b2) + +Resolves: #1909214 +--- + src/libsystemd/sd-bus/bus-dump.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c +index 2bd06053a6..36f592e0ba 100644 +--- a/src/libsystemd/sd-bus/bus-dump.c ++++ b/src/libsystemd/sd-bus/bus-dump.c +@@ -55,6 +55,15 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { + f = stdout; + + if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) { ++ char buf[FORMAT_TIMESTAMP_MAX]; ++ const char *p; ++ usec_t ts = m->realtime; ++ ++ if (ts == 0) ++ ts = now(CLOCK_REALTIME); ++ ++ p = format_timestamp_us_utc(buf, sizeof(buf), ts); ++ + fprintf(f, + "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64, + m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() : +@@ -82,6 +91,8 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) { + if (m->reply_cookie != 0) + fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie); + ++ fprintf(f, " Timestamp=\"%s\"", strna(p)); ++ + fputs("\n", f); + + if (m->sender) diff --git a/SOURCES/0584-basic-cap-list-parse-print-numerical-capabilities.patch b/SOURCES/0584-basic-cap-list-parse-print-numerical-capabilities.patch new file mode 100644 index 0000000..2a0c9a6 --- /dev/null +++ b/SOURCES/0584-basic-cap-list-parse-print-numerical-capabilities.patch @@ -0,0 +1,90 @@ +From 240c55f1526300daac640ef2c1f4941de4579493 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 9 Jul 2020 23:15:47 +0200 +Subject: [PATCH] basic/cap-list: parse/print numerical capabilities + +We would refuse to print capabilities which were didn't have a name +for. The kernel adds new capabilities from time to time, most recently +cap_bpf. 'systmectl show -p CapabilityBoundingSet ...' would fail with +"Failed to parse bus message: Invalid argument" because +capability_set_to_string_alloc() would fail with -EINVAL. So let's +print such capabilities in hexadecimal: + +CapabilityBoundingSet=cap_chown cap_dac_override cap_dac_read_search + cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap + cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin + cap_net_raw cap_ipc_lock cap_ipc_owner 0x10 0x11 0x12 0x13 0x14 0x15 0x16 + 0x17 0x18 0x19 0x1a ... + +For symmetry, also allow capabilities that we don't know to be specified. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1853736. + +(cherry picked from commit 417770f3033c426ca848b158d0bf057cd8ad1329) + +Resolves: #1946943 +--- + src/basic/cap-list.c | 10 +++++++--- + src/test/test-cap-list.c | 4 +++- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c +index bfcda33520..56a81c7dfc 100644 +--- a/src/basic/cap-list.c ++++ b/src/basic/cap-list.c +@@ -10,6 +10,7 @@ + #include "macro.h" + #include "missing.h" + #include "parse-util.h" ++#include "stdio-util.h" + #include "util.h" + + static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len); +@@ -37,7 +38,7 @@ int capability_from_name(const char *name) { + /* Try to parse numeric capability */ + r = safe_atoi(name, &i); + if (r >= 0) { +- if (i >= 0 && i < (int) ELEMENTSOF(capability_names)) ++ if (i >= 0 && i < 64) + return i; + else + return -EINVAL; +@@ -65,11 +66,14 @@ int capability_set_to_string_alloc(uint64_t set, char **s) { + for (i = 0; i < cap_last_cap(); i++) + if (set & (UINT64_C(1) << i)) { + const char *p; ++ char buf[2 + 16 + 1]; + size_t add; + + p = capability_to_name(i); +- if (!p) +- return -EINVAL; ++ if (!p) { ++ xsprintf(buf, "0x%lx", i); ++ p = buf; ++ } + + add = strlen(p); + +diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c +index de5fa729cc..84bbb7b7e7 100644 +--- a/src/test/test-cap-list.c ++++ b/src/test/test-cap-list.c +@@ -30,6 +30,8 @@ static void test_cap_list(void) { + assert_se(capability_from_name("cAp_aUdIt_rEAd") == CAP_AUDIT_READ); + assert_se(capability_from_name("0") == 0); + assert_se(capability_from_name("15") == 15); ++ assert_se(capability_from_name("63") == 63); ++ assert_se(capability_from_name("64") == -EINVAL); + assert_se(capability_from_name("-1") == -EINVAL); + + for (i = 0; i < capability_list_length(); i++) { +@@ -64,7 +66,7 @@ static void test_capability_set_one(uint64_t c, const char *t) { + + free(t1); + assert_se(t1 = strjoin("'cap_chown cap_dac_override' \"cap_setgid cap_setuid\"", t, +- " hogehoge foobar 12345 3.14 -3 ", t)); ++ " hogehoge foobar 18446744073709551616 3.14 -3 ", t)); + assert_se(capability_set_from_string(t1, &c1) == 0); + assert_se(c1 == c_masked); + } diff --git a/SOURCES/0585-shared-mount-util-convert-to-libmount.patch b/SOURCES/0585-shared-mount-util-convert-to-libmount.patch new file mode 100644 index 0000000..0c3a221 --- /dev/null +++ b/SOURCES/0585-shared-mount-util-convert-to-libmount.patch @@ -0,0 +1,318 @@ +From ca634baa10e2249d4a706d59b67be764867e5f32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 30 Nov 2020 10:37:06 +0100 +Subject: [PATCH] shared/mount-util: convert to libmount + +It seems better to use just a single parsing algorithm for /proc/self/mountinfo. + +Also, unify the naming of variables in all places that use mnt_table_next_fs(). +It makes it easier to compare the different call sites. + +(cherry picked from commit 13dcfe4661b467131c943620d0f44711798bfd54) + +Related: #1885143 +--- + src/basic/mount-util.c | 133 ++++++++++++++++++----------------------- + src/core/mount.c | 22 +++---- + src/core/umount.c | 14 ++--- + 3 files changed, 76 insertions(+), 93 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 5b04e21f34..bac1a25cc8 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -13,7 +13,6 @@ + #include + + #include "alloc-util.h" +-#include "escape.h" + #include "extract-word.h" + #include "fd-util.h" + #include "fileio.h" +@@ -27,6 +26,9 @@ + #include "string-util.h" + #include "strv.h" + ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table); ++DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter); ++ + /* This is the original MAX_HANDLE_SZ definition from the kernel, when the API was introduced. We use that in place of + * any more currently defined value to future-proof things: if the size is increased in the API headers, and our code + * is recompiled then it would cease working on old kernels, as those refuse any sizes larger than this value with +@@ -313,55 +315,43 @@ int umount_recursive(const char *prefix, int flags) { + * unmounting them until they are gone. */ + + do { +- _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; ++ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; ++ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; + + again = false; +- r = 0; + +- proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); +- if (!proc_self_mountinfo) +- return -errno; ++ table = mnt_new_table(); ++ iter = mnt_new_iter(MNT_ITER_FORWARD); ++ if (!table || !iter) ++ return -ENOMEM; + +- (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER); ++ r = mnt_table_parse_mtab(table, NULL); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + + for (;;) { +- _cleanup_free_ char *path = NULL, *p = NULL; +- int k; +- +- k = fscanf(proc_self_mountinfo, +- "%*s " /* (1) mount id */ +- "%*s " /* (2) parent id */ +- "%*s " /* (3) major:minor */ +- "%*s " /* (4) root */ +- "%ms " /* (5) mount point */ +- "%*s" /* (6) mount options */ +- "%*[^-]" /* (7) optional fields */ +- "- " /* (8) separator */ +- "%*s " /* (9) file system type */ +- "%*s" /* (10) mount source */ +- "%*s" /* (11) mount options 2 */ +- "%*[^\n]", /* some rubbish at the end */ +- &path); +- if (k != 1) { +- if (k == EOF) +- break; ++ struct libmnt_fs *fs; ++ const char *path; + +- continue; +- } +- +- r = cunescape(path, UNESCAPE_RELAX, &p); ++ r = mnt_table_next_fs(table, iter, &fs); ++ if (r == 1) ++ break; + if (r < 0) +- return r; ++ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); + +- if (!path_startswith(p, prefix)) ++ path = mnt_fs_get_target(fs); ++ if (!path) + continue; + +- if (umount2(p, flags) < 0) { +- r = log_debug_errno(errno, "Failed to umount %s: %m", p); ++ if (!path_startswith(path, prefix)) ++ continue; ++ ++ if (umount2(path, flags) < 0) { ++ r = log_debug_errno(errno, "Failed to umount %s: %m", path); + continue; + } + +- log_debug("Successfully unmounted %s", p); ++ log_debug("Successfully unmounted %s", path); + + again = true; + n++; +@@ -416,6 +406,8 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl + + for (;;) { + _cleanup_set_free_free_ Set *todo = NULL; ++ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; ++ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; + bool top_autofs = false; + char *x; + unsigned long orig_flags; +@@ -424,58 +416,52 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl + if (!todo) + return -ENOMEM; + ++ table = mnt_new_table(); ++ iter = mnt_new_iter(MNT_ITER_FORWARD); ++ if (!table || !iter) ++ return -ENOMEM; ++ + rewind(proc_self_mountinfo); + +- for (;;) { +- _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL; +- int k; +- +- k = fscanf(proc_self_mountinfo, +- "%*s " /* (1) mount id */ +- "%*s " /* (2) parent id */ +- "%*s " /* (3) major:minor */ +- "%*s " /* (4) root */ +- "%ms " /* (5) mount point */ +- "%*s" /* (6) mount options (superblock) */ +- "%*[^-]" /* (7) optional fields */ +- "- " /* (8) separator */ +- "%ms " /* (9) file system type */ +- "%*s" /* (10) mount source */ +- "%*s" /* (11) mount options (bind mount) */ +- "%*[^\n]", /* some rubbish at the end */ +- &path, +- &type); +- if (k != 2) { +- if (k == EOF) +- break; ++ r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo"); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + +- continue; +- } ++ for (;;) { ++ struct libmnt_fs *fs; ++ const char *path, *type; + +- r = cunescape(path, UNESCAPE_RELAX, &p); ++ r = mnt_table_next_fs(table, iter, &fs); ++ if (r == 1) ++ break; + if (r < 0) +- return r; ++ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); ++ ++ path = mnt_fs_get_target(fs); ++ type = mnt_fs_get_fstype(fs); ++ if (!path || !type) ++ continue; + +- if (!path_startswith(p, cleaned)) ++ if (!path_startswith(path, cleaned)) + continue; + +- /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall +- * operate on. */ +- if (!path_equal(cleaned, p)) { ++ /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount ++ * we shall operate on. */ ++ if (!path_equal(path, cleaned)) { + bool blacklisted = false; + char **i; + + STRV_FOREACH(i, blacklist) { +- + if (path_equal(*i, cleaned)) + continue; + + if (!path_startswith(*i, cleaned)) + continue; + +- if (path_startswith(p, *i)) { ++ if (path_startswith(path, *i)) { + blacklisted = true; +- log_debug("Not remounting %s, because blacklisted by %s, called for %s", p, *i, cleaned); ++ log_debug("Not remounting %s blacklisted by %s, called for %s", ++ path, *i, cleaned); + break; + } + } +@@ -490,15 +476,12 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl + * already triggered, then we will find + * another entry for this. */ + if (streq(type, "autofs")) { +- top_autofs = top_autofs || path_equal(cleaned, p); ++ top_autofs = top_autofs || path_equal(path, cleaned); + continue; + } + +- if (!set_contains(done, p)) { +- r = set_consume(todo, p); +- p = NULL; +- if (r == -EEXIST) +- continue; ++ if (!set_contains(done, path)) { ++ r = set_put_strdup(todo, path); + if (r < 0) + return r; + } +diff --git a/src/core/mount.c b/src/core/mount.c +index 076dfd06a3..7e80a0c974 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1606,18 +1606,18 @@ fail: + } + + static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { +- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; +- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; +- int r = 0; ++ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; ++ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; ++ int r; + + assert(m); + +- t = mnt_new_table(); +- i = mnt_new_iter(MNT_ITER_FORWARD); +- if (!t || !i) ++ table = mnt_new_table(); ++ iter = mnt_new_iter(MNT_ITER_FORWARD); ++ if (!table || !iter) + return log_oom(); + +- r = mnt_table_parse_mtab(t, NULL); ++ r = mnt_table_parse_mtab(table, NULL); + if (r < 0) + return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + +@@ -1628,11 +1628,11 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + _cleanup_free_ char *d = NULL, *p = NULL; + int k; + +- k = mnt_table_next_fs(t, i, &fs); +- if (k == 1) ++ r = mnt_table_next_fs(table, iter, &fs); ++ if (r == 1) + break; +- if (k < 0) +- return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m"); ++ if (r < 0) ++ return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); + + device = mnt_fs_get_source(fs); + path = mnt_fs_get_target(fs); +diff --git a/src/core/umount.c b/src/core/umount.c +index 241fe6fc62..3f02bf141a 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -55,18 +55,18 @@ void mount_points_list_free(MountPoint **head) { + } + + int mount_points_list_get(const char *mountinfo, MountPoint **head) { +- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; +- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; ++ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; ++ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; + int r; + + assert(head); + +- t = mnt_new_table(); +- i = mnt_new_iter(MNT_ITER_FORWARD); +- if (!t || !i) ++ table = mnt_new_table(); ++ iter = mnt_new_iter(MNT_ITER_FORWARD); ++ if (!table || !iter) + return log_oom(); + +- r = mnt_table_parse_mtab(t, mountinfo); ++ r = mnt_table_parse_mtab(table, mountinfo); + if (r < 0) + return log_error_errno(r, "Failed to parse %s: %m", mountinfo); + +@@ -79,7 +79,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { + bool try_remount_ro; + MountPoint *m; + +- r = mnt_table_next_fs(t, i, &fs); ++ r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) + break; + if (r < 0) diff --git a/SOURCES/0586-mount-util-bind_remount-avoid-calling-statvfs.patch b/SOURCES/0586-mount-util-bind_remount-avoid-calling-statvfs.patch new file mode 100644 index 0000000..a212238 --- /dev/null +++ b/SOURCES/0586-mount-util-bind_remount-avoid-calling-statvfs.patch @@ -0,0 +1,92 @@ +From 996f88461c45e8620c5a8a0c958dc133bd02c50e Mon Sep 17 00:00:00 2001 +From: Jakob Unterwurzacher +Date: Mon, 30 Nov 2020 10:27:48 +0100 +Subject: [PATCH] mount-util: bind_remount: avoid calling statvfs + +The commit +"util: Do not clear parent mount flags when setting up namespaces" +introduced a statvfs call read the flags of the original mount +and have them applied to the bind mount. + +This has two problems: + +(1) The mount flags returned by statvfs(2) do not match the flags +accepted by mount(2). For example, the value 4096 means ST_RELATIME +when returned by statvfs(2), but means MS_BIND when passed to mount(2). + +(2) A call to statvfs blocks indefinitely when ran against a disconnected +network drive ( https://github.com/systemd/systemd/issues/12667 ). + +We already use libmount to parse `/proc/self/mountinfo` but did not use the +mount flag information from there. This patch changes that to use the mount +flags parsed by libmount instead of calling statvfs. Only if getting the +flags through libmount fails we call statvfs. + +Fixes https://github.com/systemd/systemd/issues/12667 + +(cherry picked from commit d34a40082db3ffca8de66bfa4df50951101bdae5) + +Resolves: #1885143 +--- + src/basic/mount-util.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index bac1a25cc8..2cf98eaa84 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -364,11 +364,34 @@ int umount_recursive(const char *prefix, int flags) { + return r ? r : n; + } + +-static int get_mount_flags(const char *path, unsigned long *flags) { +- struct statvfs buf; ++/* Get the mount flags for the mountpoint at "path" from "table" */ ++static int get_mount_flags(const char *path, unsigned long *flags, struct libmnt_table *table) { ++ struct statvfs buf = {}; ++ struct libmnt_fs *fs = NULL; ++ const char *opts = NULL; ++ int r = 0; ++ ++ fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD); ++ if (fs == NULL) { ++ log_warning("Could not find '%s' in mount table", path); ++ goto fallback; ++ } ++ ++ opts = mnt_fs_get_vfs_options(fs); ++ r = mnt_optstr_get_flags(opts, flags, mnt_get_builtin_optmap(MNT_LINUX_MAP)); ++ if (r != 0) { ++ log_warning_errno(r, "Could not get flags for '%s': %m", path); ++ goto fallback; ++ } + ++ /* relatime is default and trying to set it in an unprivileged container causes EPERM */ ++ *flags &= ~MS_RELATIME; ++ return 0; ++ ++fallback: + if (statvfs(path, &buf) < 0) + return -errno; ++ + *flags = buf.f_flag; + return 0; + } +@@ -501,7 +524,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl + return -errno; + + orig_flags = 0; +- (void) get_mount_flags(cleaned, &orig_flags); ++ (void) get_mount_flags(cleaned, &orig_flags, table); + orig_flags &= ~MS_RDONLY; + + if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) +@@ -535,7 +558,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl + + /* Try to reuse the original flag set */ + orig_flags = 0; +- (void) get_mount_flags(x, &orig_flags); ++ (void) get_mount_flags(x, &orig_flags, table); + orig_flags &= ~MS_RDONLY; + + if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) diff --git a/SOURCES/0587-mount-util-use-UMOUNT_NOFOLLOW-in-recursive-umounter.patch b/SOURCES/0587-mount-util-use-UMOUNT_NOFOLLOW-in-recursive-umounter.patch new file mode 100644 index 0000000..80fadef --- /dev/null +++ b/SOURCES/0587-mount-util-use-UMOUNT_NOFOLLOW-in-recursive-umounter.patch @@ -0,0 +1,30 @@ +From b6ffe7ec63d86c5ac66171d6731068b87e3e7b50 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 27 Jun 2020 11:13:01 +0200 +Subject: [PATCH] mount-util: use UMOUNT_NOFOLLOW in recursive umounter + +When we only want to unmount mount points below some path then it is +against our interest to follow symlinks. Hence don't. + +(cherry picked from commit 827ea5212507c3833b6ae14cdf65e446b36b5e05) + +Related: #1885143 +--- + src/basic/mount-util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 2cf98eaa84..be26bb5ec1 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -346,8 +346,8 @@ int umount_recursive(const char *prefix, int flags) { + if (!path_startswith(path, prefix)) + continue; + +- if (umount2(path, flags) < 0) { +- r = log_debug_errno(errno, "Failed to umount %s: %m", path); ++ if (umount2(path, flags | UMOUNT_NOFOLLOW) < 0) { ++ log_debug_errno(errno, "Failed to umount %s: %m", path); + continue; + } + diff --git a/SOURCES/0588-test-install-root-create-referenced-targets.patch b/SOURCES/0588-test-install-root-create-referenced-targets.patch new file mode 100644 index 0000000..7ac367e --- /dev/null +++ b/SOURCES/0588-test-install-root-create-referenced-targets.patch @@ -0,0 +1,29 @@ +From 55cde82204724df756a198da691471f2f3f83d5a Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 31 Mar 2021 10:08:31 +0200 +Subject: [PATCH] test-install-root: create referenced targets + +(cherry picked from commit cd228002ccedb927b4531a4b7dd9ea7015fdb657) + +Related: #1835351 +--- + src/test/test-install-root.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index fe1ca5b16f..f8b41b04db 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -1061,6 +1061,12 @@ int main(int argc, char *argv[]) { + p = strjoina(root, "/usr/lib/systemd/system-preset/"); + assert_se(mkdir_p(p, 0755) >= 0); + ++ p = strjoina(root, "/usr/lib/systemd/system/multi-user.target"); ++ assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0); ++ ++ p = strjoina(root, "/usr/lib/systemd/system/graphical.target"); ++ assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0); ++ + test_basic_mask_and_enable(root); + test_linked_units(root); + test_default(root); diff --git a/SOURCES/0589-install-warn-if-WantedBy-targets-don-t-exist.patch b/SOURCES/0589-install-warn-if-WantedBy-targets-don-t-exist.patch new file mode 100644 index 0000000..88f445c --- /dev/null +++ b/SOURCES/0589-install-warn-if-WantedBy-targets-don-t-exist.patch @@ -0,0 +1,113 @@ +From dfb4e03e0865d189a5c171072d6d7b31f49e1088 Mon Sep 17 00:00:00 2001 +From: Jan Synacek +Date: Wed, 3 Jun 2020 10:33:21 +0200 +Subject: [PATCH] install: warn if WantedBy targets don't exist + +Currently, if [Install] section contains WantedBy=target that doesn't exist, +systemd creates the symlinks anyway. That is just user-unfriendly. +Let's be nice and warn about installing non-existent targets. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1835351. + +Replaces: #15834 +(cherry picked from commit 8ae27441c2dcf585f58242991302b09778d4d710) + +Resolves: #1835351 +--- + src/shared/install.c | 25 ++++++++++++++++++------- + src/shared/install.h | 1 + + 2 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index c9fef6bde2..055b09f98c 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -362,6 +362,11 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang + log_info("Unit %s is an alias to a unit that is not present, ignoring.", + changes[i].path); + break; ++ case UNIT_FILE_DESTINATION_NOT_PRESENT: ++ if (!quiet) ++ log_warning("Unit %s is added as a dependency to a non-existent unit %s.", ++ changes[i].source, changes[i].path); ++ break; + case -EEXIST: + if (changes[i].source) + log_error_errno(changes[i].type, +@@ -1730,6 +1735,7 @@ static int install_info_symlink_alias( + } + + static int install_info_symlink_wants( ++ UnitFileScope scope, + UnitFileInstallInfo *i, + const LookupPaths *paths, + const char *config_path, +@@ -1795,6 +1801,9 @@ static int install_info_symlink_wants( + q = create_symlink(paths, i->path, path, true, changes, n_changes); + if (r == 0) + r = q; ++ ++ if (unit_file_exists(scope, paths, dst) == 0) ++ unit_file_changes_add(changes, n_changes, UNIT_FILE_DESTINATION_NOT_PRESENT, dst, i->path); + } + + return r; +@@ -1830,6 +1839,7 @@ static int install_info_symlink_link( + } + + static int install_info_apply( ++ UnitFileScope scope, + UnitFileInstallInfo *i, + const LookupPaths *paths, + const char *config_path, +@@ -1848,11 +1858,11 @@ static int install_info_apply( + + r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes); + +- q = install_info_symlink_wants(i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes); ++ q = install_info_symlink_wants(scope, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes); + if (r == 0) + r = q; + +- q = install_info_symlink_wants(i, paths, config_path, i->required_by, ".requires/", changes, n_changes); ++ q = install_info_symlink_wants(scope, i, paths, config_path, i->required_by, ".requires/", changes, n_changes); + if (r == 0) + r = q; + +@@ -1916,7 +1926,7 @@ static int install_context_apply( + if (i->type != UNIT_FILE_TYPE_REGULAR) + continue; + +- q = install_info_apply(i, paths, config_path, force, changes, n_changes); ++ q = install_info_apply(scope, i, paths, config_path, force, changes, n_changes); + if (r >= 0) { + if (q < 0) + r = q; +@@ -3324,10 +3334,11 @@ static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState); + + static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = { +- [UNIT_FILE_SYMLINK] = "symlink", +- [UNIT_FILE_UNLINK] = "unlink", +- [UNIT_FILE_IS_MASKED] = "masked", +- [UNIT_FILE_IS_DANGLING] = "dangling", ++ [UNIT_FILE_SYMLINK] = "symlink", ++ [UNIT_FILE_UNLINK] = "unlink", ++ [UNIT_FILE_IS_MASKED] = "masked", ++ [UNIT_FILE_IS_DANGLING] = "dangling", ++ [UNIT_FILE_DESTINATION_NOT_PRESENT] = "destination not present", + }; + + DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType); +diff --git a/src/shared/install.h b/src/shared/install.h +index e452940991..f07bebb415 100644 +--- a/src/shared/install.h ++++ b/src/shared/install.h +@@ -57,6 +57,7 @@ enum UnitFileChangeType { + UNIT_FILE_UNLINK, + UNIT_FILE_IS_MASKED, + UNIT_FILE_IS_DANGLING, ++ UNIT_FILE_DESTINATION_NOT_PRESENT, + _UNIT_FILE_CHANGE_TYPE_MAX, + _UNIT_FILE_CHANGE_TYPE_INVALID = INT_MIN + }; diff --git a/SOURCES/0590-test-install-root-add-test-for-unknown-WantedBy-targ.patch b/SOURCES/0590-test-install-root-add-test-for-unknown-WantedBy-targ.patch new file mode 100644 index 0000000..10b11cc --- /dev/null +++ b/SOURCES/0590-test-install-root-add-test-for-unknown-WantedBy-targ.patch @@ -0,0 +1,56 @@ +From 430445a936cdb4c32c55affdfdd94b7eb910d5e6 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 31 Mar 2021 10:38:00 +0200 +Subject: [PATCH] test-install-root: add test for unknown WantedBy= target + +(cherry picked from commit 8adbad370f522831dd9246fe272caf37ce748d4a) + +Related: #1835351 +--- + src/test/test-install-root.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index f8b41b04db..73e1e0ae03 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -20,6 +20,7 @@ static void test_basic_mask_and_enable(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) == -ENOENT); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) == -ENOENT); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) == -ENOENT); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", NULL) == -ENOENT); + + p = strjoina(root, "/usr/lib/systemd/system/a.service"); + assert_se(write_string_file(p, +@@ -147,6 +148,31 @@ static void test_basic_mask_and_enable(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ ++ /* Test enabling with unknown dependency target */ ++ ++ p = strjoina(root, "/usr/lib/systemd/system/f.service"); ++ assert_se(write_string_file(p, ++ "[Install]\n" ++ "WantedBy=x.target\n", WRITE_STRING_FILE_CREATE) >= 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", NULL) >= 0); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("f.service"), &changes, &n_changes) == 1); ++ assert_se(n_changes == 2); ++ assert_se(changes[0].type == UNIT_FILE_SYMLINK); ++ assert_se(streq(changes[0].source, "/usr/lib/systemd/system/f.service")); ++ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/x.target.wants/f.service"); ++ assert_se(streq(changes[0].path, p)); ++ assert_se(changes[1].type == UNIT_FILE_DESTINATION_NOT_PRESENT); ++ p = strjoina(root, "/usr/lib/systemd/system/f.service"); ++ assert_se(streq(changes[1].source, p)); ++ assert_se(streq(changes[1].path, "x.target")); ++ unit_file_changes_free(changes, n_changes); ++ changes = NULL; n_changes = 0; ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + } + + static void test_linked_units(const char *root) { diff --git a/SOURCES/0591-ceph-is-a-network-filesystem.patch b/SOURCES/0591-ceph-is-a-network-filesystem.patch new file mode 100644 index 0000000..78f408c --- /dev/null +++ b/SOURCES/0591-ceph-is-a-network-filesystem.patch @@ -0,0 +1,24 @@ +From d284fd2b036ed874f9f38da63f1ab4e9fd9e96a3 Mon Sep 17 00:00:00 2001 +From: Jonas Jelten +Date: Thu, 17 Oct 2019 12:10:13 +0200 +Subject: [PATCH] ceph is a network filesystem + +(cherry picked from commit c4742de6d801b125abf3c4d1c710280f51d7c701) + +Resolves: #1952013 +--- + src/basic/mount-util.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index be26bb5ec1..45348bf878 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -608,6 +608,7 @@ bool fstype_is_network(const char *fstype) { + + return STR_IN_SET(fstype, + "afs", ++ "ceph", + "cifs", + "smb3", + "smbfs", diff --git a/SOURCES/0592-sysctl-set-kernel.core_pipe_limit-16.patch b/SOURCES/0592-sysctl-set-kernel.core_pipe_limit-16.patch new file mode 100644 index 0000000..a3b7073 --- /dev/null +++ b/SOURCES/0592-sysctl-set-kernel.core_pipe_limit-16.patch @@ -0,0 +1,49 @@ +From 8bdc512d2651b4600f7e744b06633a7524b64346 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 12 Oct 2020 16:31:42 +0200 +Subject: [PATCH] sysctl: set kernel.core_pipe_limit=16 + +We need to make sure that our coredump pattern handler manages to read +process metadata from /proc/$PID/ before the kernel reaps the crashed +process. By default the kernel will reap the process as soon as it can. +By setting kernel.core_pipe_limit to a non-zero the kernel will wait for +userspace to finish before reaping. + +We'll set the value to 16, which allows 16 crashes to be +processed in parallel. This matches the MaxConnections= setting in +systemd-coredump.socket. + +See: #17301 + +(This doesn't close 17301, since we probably should also gracefully +handle if /proc/$PID/ vanished already while our coredump handler runs, +just in case people loclly set the sysctl back to zero. i.e. we should +collect what we can and rather issue an incomplete log record than +none.) + +(cherry picked from commit 2a9b9323cd844baae3229e9dba67e478bee70654) + +Resolves: #1949729 +--- + sysctl.d/50-coredump.conf.in | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index ccd5c2cc56..8d6fbb718c 100644 +--- a/sysctl.d/50-coredump.conf.in ++++ b/sysctl.d/50-coredump.conf.in +@@ -10,3 +10,14 @@ + # setting below. + + kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t %c %h %e ++ ++# Allow that 16 coredumps are dispatched in parallel by the kernel. We want to ++# be able to collect process metadata from /proc/%P/ while processing ++# coredumps, and thus need to make sure the crashed processes are not reaped ++# until we finished collecting what we need. The kernel default for this sysctl ++# is "0" which means the kernel doesn't wait for userspace processes to finish ++# processing before reaping the crashed processes — by setting this higher the ++# kernel will delay reaping until we are done, but only for the specified ++# number of crashes in parallel. The value of 16 is chosen to match ++# systemd-coredump.socket's MaxConnections= value. ++kernel.core_pipe_limit=16 diff --git a/SOURCES/0593-core-don-t-drop-timer-expired-but-not-yet-processed-.patch b/SOURCES/0593-core-don-t-drop-timer-expired-but-not-yet-processed-.patch new file mode 100644 index 0000000..d9774a8 --- /dev/null +++ b/SOURCES/0593-core-don-t-drop-timer-expired-but-not-yet-processed-.patch @@ -0,0 +1,116 @@ +From 73bf41a783edbff1b367e645956ed602de1889e2 Mon Sep 17 00:00:00 2001 +From: Insun +Date: Sun, 28 Oct 2018 21:26:13 +0900 +Subject: [PATCH] core: don't drop timer expired but not yet processed when + system date is changed + +There is difference between time set by the user and real elapsed time because of accuracy feature. +If you change the system date(or time) between these times, the timer drops. + +You can easily reproduce it with the following command. +----------------------------------------------------------- +$ systemd-run --on-active=3s ls; sleep 3; date -s "`date`" +----------------------------------------------------------- + +In the following command, the problem is rarely reproduced. But it exists. +--------------------------------------------------------------------------------------------- +$ systemd-run --on-active=3s --timer-property=AccuracySec=1us ls ; sleep 1; date -s "`date`" +--------------------------------------------------------------------------------------------- + +Note : Global AccuracySec value. +---------------------------------------------------------------------- +$ cat /etc/systemd/system.conf +DefaultTimerAccuracySec=1min +---------------------------------------------------------------------- + +(cherry picked from commit fee04d7f3ab810e99b97535ca5fda2f9517acda9) + +Related: #1899402 +--- + src/core/timer.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 281ac7f97f..ef240a6f19 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -262,7 +262,7 @@ static void timer_set_state(Timer *t, TimerState state) { + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0); + } + +-static void timer_enter_waiting(Timer *t, bool initial); ++static void timer_enter_waiting(Timer *t, bool initial, bool time_change); + + static int timer_coldplug(Unit *u) { + Timer *t = TIMER(u); +@@ -274,7 +274,7 @@ static int timer_coldplug(Unit *u) { + return 0; + + if (t->deserialized_state == TIMER_WAITING) +- timer_enter_waiting(t, false); ++ timer_enter_waiting(t, false, false); + else + timer_set_state(t, t->deserialized_state); + +@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) { + log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0)); + } + +-static void timer_enter_waiting(Timer *t, bool initial) { ++static void timer_enter_waiting(Timer *t, bool initial, bool time_change) { + bool found_monotonic = false, found_realtime = false; + bool leave_around = false; + triple_timestamp ts; +@@ -444,7 +444,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { + + v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value); + +- if (!initial && ++ if (!initial && !time_change && + v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) && + IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) { + /* This is a one time trigger, disable it now */ +@@ -642,7 +642,7 @@ static int timer_start(Unit *u) { + } + + t->result = TIMER_SUCCESS; +- timer_enter_waiting(t, true); ++ timer_enter_waiting(t, true, false); + return 1; + } + +@@ -764,14 +764,14 @@ static void timer_trigger_notify(Unit *u, Unit *other) { + case TIMER_ELAPSED: + + /* Recalculate sleep time */ +- timer_enter_waiting(t, false); ++ timer_enter_waiting(t, false, false); + break; + + case TIMER_RUNNING: + + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { + log_unit_debug(UNIT(t), "Got notified about unit deactivation."); +- timer_enter_waiting(t, false); ++ timer_enter_waiting(t, false, false); + } + break; + +@@ -813,7 +813,7 @@ static void timer_time_change(Unit *u) { + t->last_trigger.realtime = ts; + + log_unit_debug(u, "Time change, recalculating next elapse."); +- timer_enter_waiting(t, false); ++ timer_enter_waiting(t, false, true); + } + + static void timer_timezone_change(Unit *u) { +@@ -825,7 +825,7 @@ static void timer_timezone_change(Unit *u) { + return; + + log_unit_debug(u, "Timezone change, recalculating next elapse."); +- timer_enter_waiting(t, false); ++ timer_enter_waiting(t, false, false); + } + + static const char* const timer_base_table[_TIMER_BASE_MAX] = { diff --git a/SOURCES/0594-core-Detect-initial-timer-state-from-serialized-data.patch b/SOURCES/0594-core-Detect-initial-timer-state-from-serialized-data.patch new file mode 100644 index 0000000..4334cb5 --- /dev/null +++ b/SOURCES/0594-core-Detect-initial-timer-state-from-serialized-data.patch @@ -0,0 +1,152 @@ +From 3d4280d0a487109f8f648147083baf573e4418a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Koutn=C3=BD?= +Date: Fri, 2 Nov 2018 20:56:08 +0100 +Subject: [PATCH] core: Detect initial timer state from serialized data + +We keep a mark whether a single-shot timer was triggered in the caller's +variable initial. When such a timer elapses while we are +serializing/deserializing the inner state, we consider the timer +incorrectly as elapsed and don't trigger it later. + +This patch exploits last_trigger timestamp that we already serialize, +hence we can eliminate the argument initial completely. + +A reproducer for OnBootSec= timers: + cat >repro.c < + #include + #include + #include + #include + #include + #include + #include + + int main(int argc, char *argv[]) { + char command[1024]; + int pause; + + struct timespec now; + + while (1) { + usleep(rand() % 200000); // prevent periodic repeats + clock_gettime(CLOCK_MONOTONIC, &now); + printf("%i\n", now.tv_sec); + + system("rm -f $PWD/mark"); + snprintf(command, 1024, "systemd-run --user --on-boot=%i --timer-property=AccuracySec=100ms " + "touch $PWD/mark", now.tv_sec + 1); + system(command); + system("systemctl --user list-timers"); + pause = (1000000000 - now.tv_nsec)/1000 - 70000; // fiddle to hit the middle of reloading + usleep(pause > 0 ? pause : 0); + system("systemctl --user daemon-reload"); + sync(); + sleep(2); + if (open("./mark", 0) < 0) + if (errno == ENOENT) { + printf("mark file does not exist\n"); + break; + } + } + + return 0; + } + EOD + +(cherry picked from commit aa1f95d2647197eca84c33a0f10adaeada08467d) + +Resolves: #1899402 +--- + src/core/timer.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index ef240a6f19..1718ffc5a5 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -262,7 +262,7 @@ static void timer_set_state(Timer *t, TimerState state) { + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0); + } + +-static void timer_enter_waiting(Timer *t, bool initial, bool time_change); ++static void timer_enter_waiting(Timer *t, bool time_change); + + static int timer_coldplug(Unit *u) { + Timer *t = TIMER(u); +@@ -274,7 +274,7 @@ static int timer_coldplug(Unit *u) { + return 0; + + if (t->deserialized_state == TIMER_WAITING) +- timer_enter_waiting(t, false, false); ++ timer_enter_waiting(t, false); + else + timer_set_state(t, t->deserialized_state); + +@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) { + log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0)); + } + +-static void timer_enter_waiting(Timer *t, bool initial, bool time_change) { ++static void timer_enter_waiting(Timer *t, bool time_change) { + bool found_monotonic = false, found_realtime = false; + bool leave_around = false; + triple_timestamp ts; +@@ -444,7 +444,8 @@ static void timer_enter_waiting(Timer *t, bool initial, bool time_change) { + + v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value); + +- if (!initial && !time_change && ++ if (dual_timestamp_is_set(&t->last_trigger) && ++ !time_change && + v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) && + IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) { + /* This is a one time trigger, disable it now */ +@@ -642,7 +643,7 @@ static int timer_start(Unit *u) { + } + + t->result = TIMER_SUCCESS; +- timer_enter_waiting(t, true, false); ++ timer_enter_waiting(t, false); + return 1; + } + +@@ -764,14 +765,14 @@ static void timer_trigger_notify(Unit *u, Unit *other) { + case TIMER_ELAPSED: + + /* Recalculate sleep time */ +- timer_enter_waiting(t, false, false); ++ timer_enter_waiting(t, false); + break; + + case TIMER_RUNNING: + + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { + log_unit_debug(UNIT(t), "Got notified about unit deactivation."); +- timer_enter_waiting(t, false, false); ++ timer_enter_waiting(t, false); + } + break; + +@@ -813,7 +814,7 @@ static void timer_time_change(Unit *u) { + t->last_trigger.realtime = ts; + + log_unit_debug(u, "Time change, recalculating next elapse."); +- timer_enter_waiting(t, false, true); ++ timer_enter_waiting(t, true); + } + + static void timer_timezone_change(Unit *u) { +@@ -825,7 +826,7 @@ static void timer_timezone_change(Unit *u) { + return; + + log_unit_debug(u, "Timezone change, recalculating next elapse."); +- timer_enter_waiting(t, false, false); ++ timer_enter_waiting(t, false); + } + + static const char* const timer_base_table[_TIMER_BASE_MAX] = { diff --git a/SOURCES/0595-rc-local-order-after-network-online.target.patch b/SOURCES/0595-rc-local-order-after-network-online.target.patch new file mode 100644 index 0000000..438bb50 --- /dev/null +++ b/SOURCES/0595-rc-local-order-after-network-online.target.patch @@ -0,0 +1,29 @@ +From 8cd99937562cde7533519303a7a0ad1df749e075 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 11 Mar 2021 15:48:23 +0100 +Subject: [PATCH] rc-local: order after network-online.target + +I think this was the intent of commit 91b684c7300879a8d2006038f7d9185d92c3c3bf, +just network-online.target didn't exist back then. + +RHEL-only + +Resolves: #1934028 +--- + units/rc-local.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/units/rc-local.service.in b/units/rc-local.service.in +index 78ce69e0ae..74e83d8c07 100644 +--- a/units/rc-local.service.in ++++ b/units/rc-local.service.in +@@ -13,7 +13,8 @@ + Description=@RC_LOCAL_SCRIPT_PATH_START@ Compatibility + Documentation=man:systemd-rc-local-generator(8) + ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_START@ +-After=network.target ++After=network-online.target ++Wants=network-online.target + + [Service] + Type=forking diff --git a/SOURCES/0596-set-core-ulimit-to-0-like-on-RHEL-7.patch b/SOURCES/0596-set-core-ulimit-to-0-like-on-RHEL-7.patch new file mode 100644 index 0000000..147d4eb --- /dev/null +++ b/SOURCES/0596-set-core-ulimit-to-0-like-on-RHEL-7.patch @@ -0,0 +1,25 @@ +From 830bd662276ee117e65a4b3d541f77e8b172eafd Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 25 Jan 2021 16:19:56 +0100 +Subject: [PATCH] set core ulimit to 0 like on RHEL-7 + +RHEL-only + +Resolves: #1905582 +--- + src/core/system.conf.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index 0d93fbf147..b4d6dfa15a 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -52,7 +52,7 @@ + #DefaultLimitFSIZE= + #DefaultLimitDATA= + #DefaultLimitSTACK= +-#DefaultLimitCORE= ++DefaultLimitCORE=0 + #DefaultLimitRSS= + #DefaultLimitNOFILE= + #DefaultLimitAS= diff --git a/SOURCES/0597-test-mountpointutil-util-do-not-assert-in-test_mnt_i.patch b/SOURCES/0597-test-mountpointutil-util-do-not-assert-in-test_mnt_i.patch new file mode 100644 index 0000000..216c7d1 --- /dev/null +++ b/SOURCES/0597-test-mountpointutil-util-do-not-assert-in-test_mnt_i.patch @@ -0,0 +1,129 @@ +From 4ad39b0531f550cde6e01df0801f177c08514c8b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 14 Sep 2020 17:58:03 +0200 +Subject: [PATCH] test-mountpointutil-util: do not assert in test_mnt_id() + +https://bugzilla.redhat.com/show_bug.cgi?id=1803070 + +I *think* this a kernel bug: the mnt_id as listed in /proc/self/mountinfo is different +than the one we get from /proc/self/fdinfo/. This only matters when both statx and +name_to_handle_at are unavailable and we hit the fallback path that goes through fdinfo: + +(gdb) !uname -r +5.6.19-200.fc31.ppc64le + +(gdb) !cat /proc/self/mountinfo +697 664 253:0 /var/lib/mock/fedora-31-ppc64le/root / rw,relatime shared:298 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota +698 697 253:0 /var/cache/mock/fedora-31-ppc64le/yum_cache /var/cache/yum rw,relatime shared:299 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota +699 697 253:0 /var/cache/mock/fedora-31-ppc64le/dnf_cache /var/cache/dnf rw,relatime shared:300 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota +700 697 0:32 /mock-selinux-plugin.7me9bfpi /proc/filesystems rw,nosuid,nodev shared:301 master:18 - tmpfs tmpfs rw,seclabel <========================================================== +701 697 0:41 / /sys ro,nosuid,nodev,noexec,relatime shared:302 - sysfs sysfs ro,seclabel +702 701 0:21 / /sys/fs/selinux ro,nosuid,nodev,noexec,relatime shared:306 master:8 - selinuxfs selinuxfs rw +703 697 0:42 / /dev rw,nosuid shared:303 - tmpfs tmpfs rw,seclabel,mode=755 +704 703 0:43 / /dev/shm rw,nosuid,nodev shared:304 - tmpfs tmpfs rw,seclabel +705 703 0:45 / /dev/pts rw,nosuid,noexec,relatime shared:307 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=666 +706 703 0:6 /btrfs-control /dev/btrfs-control rw,nosuid shared:308 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +707 703 0:6 /loop-control /dev/loop-control rw,nosuid shared:309 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +708 703 0:6 /loop0 /dev/loop0 rw,nosuid shared:310 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +709 703 0:6 /loop1 /dev/loop1 rw,nosuid shared:311 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +710 703 0:6 /loop10 /dev/loop10 rw,nosuid shared:312 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +711 703 0:6 /loop11 /dev/loop11 rw,nosuid shared:313 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +712 703 0:6 /loop2 /dev/loop2 rw,nosuid shared:314 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +713 703 0:6 /loop3 /dev/loop3 rw,nosuid shared:315 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +714 703 0:6 /loop4 /dev/loop4 rw,nosuid shared:316 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +715 703 0:6 /loop5 /dev/loop5 rw,nosuid shared:317 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +716 703 0:6 /loop6 /dev/loop6 rw,nosuid shared:318 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +717 703 0:6 /loop7 /dev/loop7 rw,nosuid shared:319 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +718 703 0:6 /loop8 /dev/loop8 rw,nosuid shared:320 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +719 703 0:6 /loop9 /dev/loop9 rw,nosuid shared:321 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755 +720 697 0:44 / /run rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +721 720 0:25 /systemd/nspawn/propagate/9cc8a155d0244558b273f773d2b92142 /run/systemd/nspawn/incoming ro master:12 - tmpfs tmpfs rw,seclabel,mode=755 +722 697 0:32 /mock-resolv.dvml91hp /etc/resolv.conf rw,nosuid,nodev shared:322 master:18 - tmpfs tmpfs rw,seclabel +725 697 0:47 / /proc rw,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +603 725 0:47 /sys /proc/sys ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +604 725 0:44 /systemd/inaccessible/reg /proc/kallsyms ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +605 725 0:44 /systemd/inaccessible/reg /proc/kcore ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +606 725 0:44 /systemd/inaccessible/reg /proc/keys ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +607 725 0:44 /systemd/inaccessible/reg /proc/sysrq-trigger ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +608 725 0:44 /systemd/inaccessible/reg /proc/timer_list ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +609 725 0:47 /bus /proc/bus ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +610 725 0:47 /fs /proc/fs ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +611 725 0:47 /irq /proc/irq ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +612 725 0:47 /scsi /proc/scsi ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw +613 703 0:46 / /dev/mqueue rw,nosuid,nodev,noexec,relatime shared:324 - mqueue mqueue rw,seclabel +614 701 0:26 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:325 - cgroup2 cgroup rw,seclabel,nsdelegate +615 603 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +616 725 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755 +617 725 0:44 /.#proc-kmsg5b7a8bcfe6717139//deleted /proc/kmsg rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755 + +The test process does +name_to_handle_at("/proc/filesystems") which returns -EOPNOTSUPP, and then +openat(AT_FDCWD, "/proc/filesystems") which returns 4, and then +read(open("/proc/self/fdinfo/4", ...)) which gives +"pos:\t0\nflags:\t012100000\nmnt_id:\t725\n" + +and the "725" is clearly inconsistent with "700" in /proc/self/mountinfo. + +We could either drop the fallback path (and fail name_to_handle_at() is not +avaliable) or ignore the error in the test. Not sure what is better. I think +this issue only occurs sometimes and with older kernels, so probably continuing +with the current flaky implementation is better than ripping out the fallback. + +Another strace: +writev(2, [{iov_base="mnt ids of /proc/sys is 603", iov_len=27}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/sys is 603 +) = 28 +name_to_handle_at(AT_FDCWD, "/", {handle_bytes=128 => 12, handle_type=129, f_handle=0x52748401000000008b93e20d}, [697], 0) = 0 +writev(2, [{iov_base="mnt ids of / is 697", iov_len=19}, {iov_base="\n", iov_len=1}], 2mnt ids of / is 697 +) = 20 +name_to_handle_at(AT_FDCWD, "/proc/kcore", {handle_bytes=128 => 12, handle_type=1, f_handle=0x92ddcfcd2e802d0100000000}, [605], 0) = 0 +writev(2, [{iov_base="mnt ids of /proc/kcore is 605", iov_len=29}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/kcore is 605 +) = 30 +name_to_handle_at(AT_FDCWD, "/dev", {handle_bytes=128 => 12, handle_type=1, f_handle=0x8ae269160c802d0100000000}, [703], 0) = 0 +writev(2, [{iov_base="mnt ids of /dev is 703", iov_len=22}, {iov_base="\n", iov_len=1}], 2mnt ids of /dev is 703 +) = 23 +name_to_handle_at(AT_FDCWD, "/proc/filesystems", {handle_bytes=128}, 0x7fffe36ddb84, 0) = -1 EOPNOTSUPP (Operation not supported) +openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4 +openat(AT_FDCWD, "/proc/self/fdinfo/4", O_RDONLY|O_CLOEXEC) = 5 +fstat(5, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 +fstat(5, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 +read(5, "pos:\t0\nflags:\t012100000\nmnt_id:\t725\n", 2048) = 36 +read(5, "", 1024) = 0 +close(5) = 0 +close(4) = 0 +writev(2, [{iov_base="mnt ids of /proc/filesystems are 700, 725", iov_len=41}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/filesystems are 700, 725 +) = 42 +writev(2, [{iov_base="the other path for mnt id 725 is /proc", iov_len=38}, {iov_base="\n", iov_len=1}], 2the other path for mnt id 725 is /proc +) = 39 +writev(2, [{iov_base="Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting.", iov_len=108}, {iov_base="\n", iov_len=1}], 2Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting. +) = 109 +rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0 +rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0 +getpid() = 20 +gettid() = 20 +tgkill(20, 20, SIGABRT) = 0 +rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 + +Resolves: #1910425 +--- + src/test/test-mount-util.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c +index c10e1681fb..991d165fc3 100644 +--- a/src/test/test-mount-util.c ++++ b/src/test/test-mount-util.c +@@ -74,7 +74,13 @@ static void test_mnt_id(void) { + + /* The ids don't match? If so, then there are two mounts on the same path, let's check if that's really + * the case */ +- assert_se(path_equal_ptr(hashmap_get(h, INT_TO_PTR(mnt_id2)), p)); ++ char *t = hashmap_get(h, INT_TO_PTR(mnt_id2)); ++ log_debug("Path for mnt id %i from /proc/self/mountinfo is %s\n", mnt_id2, t); ++ ++ if (!path_equal(p, t)) ++ /* Apparent kernel bug in /proc/self/fdinfo */ ++ log_warning("Bad mount id given for %s: %d, should be %d", ++ p, mnt_id2, mnt_id); + } + + hashmap_free_free(h); diff --git a/SOURCES/0598-remove-a-left-over-break.patch b/SOURCES/0598-remove-a-left-over-break.patch new file mode 100644 index 0000000..7d68ff0 --- /dev/null +++ b/SOURCES/0598-remove-a-left-over-break.patch @@ -0,0 +1,29 @@ +From 5944138a54017fc8f1f4c878a1eea96ea18736c4 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 25 Jun 2021 10:42:53 +0200 +Subject: [PATCH] remove a left-over break + +By the "same logic as above...", we want to continue to fallback here, +but the break prohibits that. + +This is a follow-up for ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c . + +(cherry picked from commit 99df1cb6f50875db513a5b45f18191460a150f3d) + +Related: #1970860 +--- + src/basic/copy.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/basic/copy.c b/src/basic/copy.c +index a48c42c5c6..1a0db29ac9 100644 +--- a/src/basic/copy.c ++++ b/src/basic/copy.c +@@ -218,7 +218,6 @@ int copy_bytes_full( + break; + + try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */ +- break; + } else + /* Success! */ + goto next; diff --git a/SOURCES/0599-basic-unit-name-do-not-use-strdupa-on-a-path.patch b/SOURCES/0599-basic-unit-name-do-not-use-strdupa-on-a-path.patch new file mode 100644 index 0000000..adf5607 --- /dev/null +++ b/SOURCES/0599-basic-unit-name-do-not-use-strdupa-on-a-path.patch @@ -0,0 +1,65 @@ +From c5d2964d498da0ac06799e5f040de74a0f5d2deb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Jun 2021 11:46:41 +0200 +Subject: [PATCH] basic/unit-name: do not use strdupa() on a path + +The path may have unbounded length, for example through a fuse mount. + +CVE-2021-33910: attacked controlled alloca() leads to crash in systemd and +ultimately a kernel panic. Systemd parses the content of /proc/self/mountinfo +and each mountpoint is passed to mount_setup_unit(), which calls +unit_name_path_escape() underneath. A local attacker who is able to mount a +filesystem with a very long path can crash systemd and the whole system. + +https://bugzilla.redhat.com/show_bug.cgi?id=1970887 + +The resulting string length is bounded by UNIT_NAME_MAX, which is 256. But we +can't easily check the length after simplification before doing the +simplification, which in turns uses a copy of the string we can write to. +So we can't reject paths that are too long before doing the duplication. +Hence the most obvious solution is to switch back to strdup(), as before +7410616cd9dbbec97cf98d75324da5cda2b2f7a2. + +Resolves: #1974700 + +(cherry picked from commit 441e0115646d54f080e5c3bb0ba477c892861ab9) +--- + src/basic/unit-name.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 1b81fe268f..614eb8649b 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -369,12 +369,13 @@ int unit_name_unescape(const char *f, char **ret) { + } + + int unit_name_path_escape(const char *f, char **ret) { +- char *p, *s; ++ _cleanup_free_ char *p = NULL; ++ char *s; + + assert(f); + assert(ret); + +- p = strdupa(f); ++ p = strdup(f); + if (!p) + return -ENOMEM; + +@@ -386,13 +387,9 @@ int unit_name_path_escape(const char *f, char **ret) { + if (!path_is_normalized(p)) + return -EINVAL; + +- /* Truncate trailing slashes */ ++ /* Truncate trailing slashes and skip leading slashes */ + delete_trailing_chars(p, "/"); +- +- /* Truncate leading slashes */ +- p = skip_leading_chars(p, "/"); +- +- s = unit_name_escape(p); ++ s = unit_name_escape(skip_leading_chars(p, "/")); + } + if (!s) + return -ENOMEM; diff --git a/SOURCES/0600-sd-event-change-ordering-of-pending-ratelimited-even.patch b/SOURCES/0600-sd-event-change-ordering-of-pending-ratelimited-even.patch new file mode 100644 index 0000000..84836ab --- /dev/null +++ b/SOURCES/0600-sd-event-change-ordering-of-pending-ratelimited-even.patch @@ -0,0 +1,96 @@ +From f863f89d8a5cbb47676d5114e349918c4e009fe5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 8 Jun 2021 00:07:51 -0700 +Subject: [PATCH] sd-event: change ordering of pending/ratelimited events + +Instead of ordering non-pending before pending we should order +"non-pending OR ratelimited" before "pending AND not-ratelimited". +This fixes a bug where ratelimited events were ordered at the end of the +priority queue and could be stuck there for an indeterminate amount of +time. + +(cherry picked from commit 81107b8419c39f726fd2805517a5b9faab204e59) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 48 +++++++++++++----------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index be912d94e3..3e77f4e810 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -427,25 +427,6 @@ static usec_t time_event_source_next(const sd_event_source *s) { + return USEC_INFINITY; + } + +-static int earliest_time_prioq_compare(const void *a, const void *b) { +- const sd_event_source *x = a, *y = b; +- +- /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; +- +- /* Move the pending ones to the end */ +- if (!x->pending && y->pending) +- return -1; +- if (x->pending && !y->pending) +- return 1; +- +- /* Order by time */ +- return CMP(time_event_source_next(x), time_event_source_next(y)); +-} +- + static usec_t time_event_source_latest(const sd_event_source *s) { + assert(s); + +@@ -464,7 +445,15 @@ static usec_t time_event_source_latest(const sd_event_source *s) { + return USEC_INFINITY; + } + +-static int latest_time_prioq_compare(const void *a, const void *b) { ++static bool event_source_timer_candidate(const sd_event_source *s) { ++ assert(s); ++ ++ /* Returns true for event sources that either are not pending yet (i.e. where it's worth to mark them pending) ++ * or which are currently ratelimited (i.e. where it's worth leaving the ratelimited state) */ ++ return !s->pending || s->ratelimited; ++} ++ ++static int time_prioq_compare(const void *a, const void *b, usec_t (*time_func)(const sd_event_source *s)) { + const sd_event_source *x = a, *y = b; + + /* Enabled ones first */ +@@ -473,19 +462,22 @@ static int latest_time_prioq_compare(const void *a, const void *b) { + if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) + return 1; + +- /* Move the pending ones to the end */ +- if (!x->pending && y->pending) ++ /* Order "non-pending OR ratelimited" before "pending AND not-ratelimited" */ ++ if (event_source_timer_candidate(x) && !event_source_timer_candidate(y)) + return -1; +- if (x->pending && !y->pending) ++ if (!event_source_timer_candidate(x) && event_source_timer_candidate(y)) + return 1; + + /* Order by time */ +- if (time_event_source_latest(x) < time_event_source_latest(y)) +- return -1; +- if (time_event_source_latest(x) > time_event_source_latest(y)) +- return 1; ++ return CMP(time_func(x), time_func(y)); ++} + +- return 0; ++static int earliest_time_prioq_compare(const void *a, const void *b) { ++ return time_prioq_compare(a, b, time_event_source_next); ++} ++ ++static int latest_time_prioq_compare(const void *a, const void *b) { ++ return time_prioq_compare(a, b, time_event_source_latest); + } + + static int exit_prioq_compare(const void *a, const void *b) { diff --git a/SOURCES/0601-sd-event-drop-unnecessary-else.patch b/SOURCES/0601-sd-event-drop-unnecessary-else.patch new file mode 100644 index 0000000..d63606d --- /dev/null +++ b/SOURCES/0601-sd-event-drop-unnecessary-else.patch @@ -0,0 +1,27 @@ +From 9faf4d1a39b7fc8c9f986a808e1c0d3ed9b44357 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 00:44:04 +0900 +Subject: [PATCH] sd-event: drop unnecessary "else" + +(cherry picked from commit 7e2bf71ca3638e36ee33215ceee386ba8013da6d) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 3e77f4e810..2b0b76aa1c 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2883,8 +2883,8 @@ static int event_arm_timer( + + if (!d->needs_rearm) + return 0; +- else +- d->needs_rearm = false; ++ ++ d->needs_rearm = false; + + a = prioq_peek(d->earliest); + if (!a || a->enabled == SD_EVENT_OFF || time_event_source_next(a) == USEC_INFINITY) { diff --git a/SOURCES/0602-sd-event-use-CMP-macro.patch b/SOURCES/0602-sd-event-use-CMP-macro.patch new file mode 100644 index 0000000..2cf6223 --- /dev/null +++ b/SOURCES/0602-sd-event-use-CMP-macro.patch @@ -0,0 +1,90 @@ +From 7419222d3811d60c0a8f5ea27778108a1ca8ee71 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 00:51:33 +0900 +Subject: [PATCH] sd-event: use CMP() macro + +(cherry picked from commit 06e131477d82b83c5d516e66d6e413affd7c774a) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 37 ++++++++++++++---------------- + 1 file changed, 17 insertions(+), 20 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 2b0b76aa1c..6a20b658e4 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -358,10 +358,9 @@ static int pending_prioq_compare(const void *a, const void *b) { + assert(y->pending); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Non rate-limited ones first. */ + r = CMP(!!x->ratelimited, !!y->ratelimited); +@@ -385,10 +384,9 @@ static int prepare_prioq_compare(const void *a, const void *b) { + assert(y->prepare); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Non rate-limited ones first. */ + r = CMP(!!x->ratelimited, !!y->ratelimited); +@@ -455,18 +453,17 @@ static bool event_source_timer_candidate(const sd_event_source *s) { + + static int time_prioq_compare(const void *a, const void *b, usec_t (*time_func)(const sd_event_source *s)) { + const sd_event_source *x = a, *y = b; ++ int r; + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Order "non-pending OR ratelimited" before "pending AND not-ratelimited" */ +- if (event_source_timer_candidate(x) && !event_source_timer_candidate(y)) +- return -1; +- if (!event_source_timer_candidate(x) && event_source_timer_candidate(y)) +- return 1; ++ r = CMP(!event_source_timer_candidate(x), !event_source_timer_candidate(y)); ++ if (r != 0) ++ return r; + + /* Order by time */ + return CMP(time_func(x), time_func(y)); +@@ -482,15 +479,15 @@ static int latest_time_prioq_compare(const void *a, const void *b) { + + static int exit_prioq_compare(const void *a, const void *b) { + const sd_event_source *x = a, *y = b; ++ int r; + + assert(x->type == SOURCE_EXIT); + assert(y->type == SOURCE_EXIT); + + /* Enabled ones first */ +- if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) +- return -1; +- if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) +- return 1; ++ r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); ++ if (r != 0) ++ return r; + + /* Lower priority values first */ + if (x->priority < y->priority) diff --git a/SOURCES/0603-sd-event-use-usec_add.patch b/SOURCES/0603-sd-event-use-usec_add.patch new file mode 100644 index 0000000..c155350 --- /dev/null +++ b/SOURCES/0603-sd-event-use-usec_add.patch @@ -0,0 +1,27 @@ +From b79e00d8f97b8c959c5b17f0547c680f86dd9132 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 01:01:48 +0900 +Subject: [PATCH] sd-event: use usec_add() + +(cherry picked from commit a595fb5ca9c69c589e758e9ebe3b70ac90450ba3) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 6a20b658e4..f675c09d84 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3514,8 +3514,8 @@ static int arm_watchdog(sd_event *e) { + assert(e->watchdog_fd >= 0); + + t = sleep_between(e, +- e->watchdog_last + (e->watchdog_period / 2), +- e->watchdog_last + (e->watchdog_period * 3 / 4)); ++ usec_add(e->watchdog_last, (e->watchdog_period / 2)), ++ usec_add(e->watchdog_last, (e->watchdog_period * 3 / 4))); + + timespec_store(&its.it_value, t); + diff --git a/SOURCES/0604-sd-event-make-event_source_time_prioq_reshuffle-acce.patch b/SOURCES/0604-sd-event-make-event_source_time_prioq_reshuffle-acce.patch new file mode 100644 index 0000000..13ed16d --- /dev/null +++ b/SOURCES/0604-sd-event-make-event_source_time_prioq_reshuffle-acce.patch @@ -0,0 +1,40 @@ +From bf370d05bbc8c4d91c8c2b455116e59a24e48911 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 02:03:02 +0900 +Subject: [PATCH] sd-event: make event_source_time_prioq_reshuffle() accept all + event source type + +But it does nothing for an event source which is neither a timer nor +ratelimited. + +(cherry picked from commit 5c08c7ab23dbf02aaf4e4bbae8e08a195da230a4) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index f675c09d84..ae46392901 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -954,14 +954,15 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { + assert(s); + + /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, +- * pending, enable state. Makes sure the two prioq's are ordered properly again. */ ++ * pending, enable state, and ratelimiting state. Makes sure the two prioq's are ordered ++ * properly again. */ + + if (s->ratelimited) + d = &s->event->monotonic; +- else { +- assert(EVENT_SOURCE_IS_TIME(s->type)); ++ else if (EVENT_SOURCE_IS_TIME(s->type)) + assert_se(d = event_get_clock_data(s->event, s->type)); +- } ++ else ++ return; /* no-op for an event source which is neither a timer nor ratelimited. */ + + prioq_reshuffle(d->earliest, s, &s->earliest_index); + prioq_reshuffle(d->latest, s, &s->latest_index); diff --git a/SOURCES/0605-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch b/SOURCES/0605-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch new file mode 100644 index 0000000..23178cd --- /dev/null +++ b/SOURCES/0605-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch @@ -0,0 +1,90 @@ +From 1ce5187fb47bec57de4d8d3fd0068072228ec5e3 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 15 Jun 2021 02:13:59 +0900 +Subject: [PATCH] sd-event: always reshuffle time prioq on changing + online/offline state + +Before 81107b8419c39f726fd2805517a5b9faab204e59, the compare functions +for the latest or earliest prioq did not handle ratelimited flag. +So, it was ok to not reshuffle the time prioq when changing the flag. + +But now, those two compare functions also compare the source is +ratelimited or not. So, it is necessary to reshuffle the time prioq +after changing the ratelimited flag. + +Hopefully fixes #19903. + +(cherry picked from commit 2115b9b6629eeba7bc9f42f757f38205febb1cb7) + +Related: #1968528 +--- + src/libsystemd/sd-event/sd-event.c | 33 ++++++++++-------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index ae46392901..f78da00c3a 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2390,14 +2390,6 @@ static int event_source_offline( + source_io_unregister(s); + break; + +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- event_source_time_prioq_reshuffle(s); +- break; +- + case SOURCE_SIGNAL: + event_gc_signal_data(s->event, &s->priority, s->signal.sig); + break; +@@ -2415,6 +2407,11 @@ static int event_source_offline( + prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); + break; + ++ case SOURCE_TIME_REALTIME: ++ case SOURCE_TIME_BOOTTIME: ++ case SOURCE_TIME_MONOTONIC: ++ case SOURCE_TIME_REALTIME_ALARM: ++ case SOURCE_TIME_BOOTTIME_ALARM: + case SOURCE_DEFER: + case SOURCE_POST: + case SOURCE_INOTIFY: +@@ -2424,6 +2421,9 @@ static int event_source_offline( + assert_not_reached("Wut? I shouldn't exist."); + } + ++ /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ ++ event_source_time_prioq_reshuffle(s); ++ + return 1; + } + +@@ -2505,22 +2505,11 @@ static int event_source_online( + s->ratelimited = ratelimited; + + /* Non-failing operations below */ +- switch (s->type) { +- case SOURCE_TIME_REALTIME: +- case SOURCE_TIME_BOOTTIME: +- case SOURCE_TIME_MONOTONIC: +- case SOURCE_TIME_REALTIME_ALARM: +- case SOURCE_TIME_BOOTTIME_ALARM: +- event_source_time_prioq_reshuffle(s); +- break; +- +- case SOURCE_EXIT: ++ if (s->type == SOURCE_EXIT) + prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); +- break; + +- default: +- break; +- } ++ /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ ++ event_source_time_prioq_reshuffle(s); + + return 1; + } diff --git a/SOURCES/0606-ci-run-unit-tests-on-z-stream-branches-as-well.patch b/SOURCES/0606-ci-run-unit-tests-on-z-stream-branches-as-well.patch new file mode 100644 index 0000000..91d1c80 --- /dev/null +++ b/SOURCES/0606-ci-run-unit-tests-on-z-stream-branches-as-well.patch @@ -0,0 +1,27 @@ +From 68cedfd41f1ea3eda34b0023e951649b92953709 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 15 Jul 2021 12:27:33 +0200 +Subject: [PATCH] ci: run unit tests on z-stream branches as well + +Resolves: #1970860 +rhel-only +--- + .github/workflows/unit_tests.yml | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index 15f5127a75..428bde4ed8 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -2,10 +2,7 @@ + # vi: ts=2 sw=2 et: + # + name: Unit tests +-on: +- pull_request: +- branches: +- - master ++on: [pull_request] + + jobs: + build: diff --git a/SOURCES/0607-ci-drop-forgotten-Travis-references.patch b/SOURCES/0607-ci-drop-forgotten-Travis-references.patch new file mode 100644 index 0000000..4537e2e --- /dev/null +++ b/SOURCES/0607-ci-drop-forgotten-Travis-references.patch @@ -0,0 +1,32 @@ +From 9bb57b7bed93e79f578e7c5b0c95f1f454e5d829 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 3 Mar 2021 12:33:38 +0100 +Subject: [PATCH] ci: drop forgotten Travis references + +rhel-only +Related: #1934504 +--- + .github/workflows/unit_tests.sh | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index ea4f7e7592..43882b27da 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -68,7 +68,7 @@ for phase in "${PHASES[@]}"; do + case $phase in + SETUP) + info "Setup phase" +- info "Using Travis $CENTOS_RELEASE" ++ info "Using $CENTOS_RELEASE image" + # Pull a Docker image and start a new container + docker pull quay.io/centos/centos:$CENTOS_RELEASE + info "Starting container $CONT_NAME" +@@ -110,7 +110,6 @@ for phase in "${PHASES[@]}"; do + docker exec --interactive=false \ + -e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \ + -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \ +- -e "TRAVIS=$TRAVIS" \ + -t $CONT_NAME \ + meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs + ;; diff --git a/SOURCES/0608-ci-run-unit-tests-on-CentOS-8-Stream-as-well.patch b/SOURCES/0608-ci-run-unit-tests-on-CentOS-8-Stream-as-well.patch new file mode 100644 index 0000000..159399a --- /dev/null +++ b/SOURCES/0608-ci-run-unit-tests-on-CentOS-8-Stream-as-well.patch @@ -0,0 +1,113 @@ +From ccde55a339d211af488b1f1c148597d7977a9bb8 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 3 Mar 2021 12:49:20 +0100 +Subject: [PATCH] ci: run unit tests on CentOS 8 Stream as well + +rhel-only +Related: #1934504 +--- + .github/workflows/unit_tests.sh | 52 +++++++++++++++++++++++++++++++- + .github/workflows/unit_tests.yml | 13 ++++---- + 2 files changed, 58 insertions(+), 7 deletions(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index 43882b27da..8648e7149e 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -58,6 +58,53 @@ CONFIGURE_OPTS=( + -Ddefault-hierarchy=legacy + ) + ++# CentOS 8 Stream still doesn't provide SRPMs, so we can't use dnf's builddep ++# command to fetch this list for us. Hopefully, we'll be able to get rid ++# of this in the future. ++# See: https://bugs.centos.org/view.php?id=16715 ++SYSTEMD_BUILD_DEPS=( ++ audit-libs-devel ++ bzip2-devel ++ cryptsetup-devel ++ dbus-devel ++ docbook-style-xsl ++ elfutils-devel ++ firewalld-filesystem ++ gcc ++ gcc-c++ ++ gettext ++ git ++ gnu-efi ++ gnu-efi-devel ++ gnutls-devel ++ gobject-introspection-devel ++ gperf ++ iptables-devel ++ kmod-devel ++ libacl-devel ++ libblkid-devel ++ libcap-devel ++ libcurl-devel ++ libgcrypt-devel ++ libgpg-error-devel ++ libidn2-devel ++ libmicrohttpd-devel ++ libmount-devel ++ libseccomp-devel ++ libselinux-devel ++ libxkbcommon-devel ++ libxslt ++ lz4 ++ lz4-devel ++ meson ++ pam-devel ++ pkgconf-pkg-config ++ python3-lxml ++ python36-devel ++ tree ++ xz-devel ++) ++ + function info() { + echo -e "\033[33;1m$1\033[0m" + } +@@ -85,7 +132,10 @@ for phase in "${PHASES[@]}"; do + # Upgrade the container to get the most recent environment + $DOCKER_EXEC dnf -y upgrade + # Install systemd's build dependencies +- $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd ++ if ! $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd; then ++ # See the $SYSTEMD_BUILD_DEPS above for reasoning ++ $DOCKER_EXEC dnf -q -y --enablerepo "powertools" install "${SYSTEMD_BUILD_DEPS[@]}" ++ fi + ;; + RUN|RUN_GCC) + info "Run phase" +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index 428bde4ed8..b363118be8 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -7,19 +7,20 @@ on: [pull_request] + jobs: + build: + runs-on: ubuntu-20.04 +- env: +- CENTOS_RELEASE: "centos8" +- CONT_NAME: "systemd-centos8-ci" + strategy: + fail-fast: false + matrix: +- run_phase: [GCC, GCC_ASAN] ++ image: [centos8, stream8] ++ phase: [GCC, GCC_ASAN] ++ env: ++ CONT_NAME: "systemd-centos8-ci" ++ CENTOS_RELEASE: ${{ matrix.image }} + steps: + - name: Repository checkout + uses: actions/checkout@v1 + - name: Install build dependencies + run: sudo -E .github/workflows/unit_tests.sh SETUP +- - name: Build & test (${{ matrix.run_phase }}) +- run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }} ++ - name: Build & test (${{ env.CENTOS_RELEASE }} / ${{ matrix.phase }}) ++ run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.phase }} + - name: Cleanup + run: sudo -E .github/workflows/unit_tests.sh CLEANUP diff --git a/SOURCES/0609-ci-add-missing-test-dependencies.patch b/SOURCES/0609-ci-add-missing-test-dependencies.patch new file mode 100644 index 0000000..86c6c62 --- /dev/null +++ b/SOURCES/0609-ci-add-missing-test-dependencies.patch @@ -0,0 +1,37 @@ +From 68555d26da9e46efbd70703b39a81cee601d265a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 3 Mar 2021 13:14:02 +0100 +Subject: [PATCH] ci: add missing test dependencies + +rhel-only +Related: #1934504 +--- + .github/workflows/unit_tests.sh | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index 8648e7149e..ad4584ec1d 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -6,7 +6,20 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}" + DOCKER_EXEC="${DOCKER_EXEC:-docker exec $CONT_NAME}" + DOCKER_RUN="${DOCKER_RUN:-docker run}" + REPO_ROOT="${REPO_ROOT:-$PWD}" +-ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq diffutils) ++ADDITIONAL_DEPS=( ++ diffutils ++ dnsmasq ++ e2fsprogs ++ hostname ++ libasan ++ libubsan ++ nc ++ net-tools ++ perl-IPC-SysV ++ perl-Time-HiRes ++ quota ++ strace ++) + # RHEL8 options + CONFIGURE_OPTS=( + -Dsysvinit-path=/etc/rc.d/init.d diff --git a/SOURCES/0610-meson-bump-timeout-for-test-udev-to-180s.patch b/SOURCES/0610-meson-bump-timeout-for-test-udev-to-180s.patch new file mode 100644 index 0000000..f750215 --- /dev/null +++ b/SOURCES/0610-meson-bump-timeout-for-test-udev-to-180s.patch @@ -0,0 +1,30 @@ +From 998041fbb2b4114f2f1df604cdebc4afbf682d63 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 18 Jan 2019 22:32:42 +0100 +Subject: [PATCH] meson: bump timeout for test-udev to 180s + +On some (mainly virtual) machines the last test takes more than 30 +seconds, which causes unnecessary fails, as the test itself is working +properly. + +(cherry picked from commit bb0e960448fce037f5b82b1829863da8ccbe636b) + +Related: #1934504 +--- + test/meson.build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/meson.build b/test/meson.build +index 52e4fa2e3c..535354f3ab 100644 +--- a/test/meson.build ++++ b/test/meson.build +@@ -246,7 +246,8 @@ custom_target( + if perl.found() + udev_test_pl = find_program('udev-test.pl') + test('udev-test', +- udev_test_pl) ++ udev_test_pl, ++ timeout : 180) + else + message('Skipping udev-test because perl is not available') + endif diff --git a/SOURCES/0611-Added-option-check-inhibitors-for-non-tty-usage.patch b/SOURCES/0611-Added-option-check-inhibitors-for-non-tty-usage.patch new file mode 100644 index 0000000..c913f65 --- /dev/null +++ b/SOURCES/0611-Added-option-check-inhibitors-for-non-tty-usage.patch @@ -0,0 +1,222 @@ +From f875436b93c6c5e83f46ab32429c977db4f0b10c Mon Sep 17 00:00:00 2001 +From: Felix Stupp +Date: Thu, 29 Oct 2020 12:48:48 +0100 +Subject: [PATCH] Added option --check-inhibitors for non-tty usage + +As described in #2680, systemctl did ignore inhibitors if it is not +attached to a tty to allow scripts to ignore inhibitors automatically. +This pull request preserves this behavior but allows scripts to +explicit check inhibitors if required. + +The new parameter '--check-inhibitors=yes' enables this feature. +The old parameter '-i'/'--ignore-inhibitors' was deprecated in favor +of '--check-inhibitors=no', the default behaviour can be specified +with '--check-inhibitors=auto'. +The new parameter is also described in the documentations and shell +completions found here. + +(cherry picked from commit b8ebe378b49a31549b8531d4b3177095ef385d55) + +Related: #1269726 +--- + man/systemctl.xml | 38 ++++++++++++++++++++---------- + shell-completion/bash/systemctl.in | 7 ++++-- + shell-completion/zsh/_systemctl.in | 9 ++++++- + src/systemctl/systemctl.c | 37 +++++++++++++++++++++-------- + 4 files changed, 65 insertions(+), 26 deletions(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index ed60a0739f..9f0f4d46ea 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -323,23 +323,35 @@ + + + ++ ++ ++ ++ ++ When system shutdown or sleep state is request, this option controls how to deal with ++ inhibitor locks. It takes one of auto, yes or ++ no. Defaults to auto, which will behave like ++ yes for interactive invocations (i.e. from a TTY) and no ++ for non-interactive invocations. ++ yes will let the request respect inhibitor locks. ++ no will let the request ignore inhibitor locks. ++ ++ Applications can establish inhibitor locks to avoid that certain important operations ++ (such as CD burning or suchlike) are interrupted by system shutdown or a sleep state. Any user may ++ take these locks and privileged users may override these locks. ++ If any locks are taken, shutdown and sleep state requests will normally fail (unless privileged) ++ and a list of active locks is printed. ++ However, if no is specified or auto is specified on a ++ non-interactive requests, the established locks are ignored and not shown, and the operation ++ attempted anyway, possibly requiring additional privileges. ++ May be overriden by . ++ ++ ++ + + +- + + +- When system shutdown or a sleep state is requested, +- ignore inhibitor locks. Applications can establish inhibitor +- locks to avoid that certain important operations (such as CD +- burning or suchlike) are interrupted by system shutdown or a +- sleep state. Any user may take these locks and privileged +- users may override these locks. If any locks are taken, +- shutdown and sleep state requests will normally fail +- (regardless of whether privileged or not) and a list of active locks +- is printed. However, if +- is specified, the locks are ignored and not printed, and the +- operation attempted anyway, possibly requiring additional +- privileges. ++ Shortcut for . + + + +diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in +index ba51ae0d34..0c7afea57d 100644 +--- a/shell-completion/bash/systemctl.in ++++ b/shell-completion/bash/systemctl.in +@@ -111,9 +111,9 @@ _systemctl () { + [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global + --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now + --quiet -q --system --user --version --runtime --recursive -r --firmware-setup +- --show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait' ++ --show-types --plain --failed --value --fail --dry-run --wait' + [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root +- --preset-mode -n --lines -o --output -M --machine --message' ++ --preset-mode -n --lines -o --output -M --machine --message --check-inhibitors' + ) + + if __contains_word "--user" ${COMP_WORDS[*]}; then +@@ -163,6 +163,9 @@ _systemctl () { + --machine|-M) + comps=$( __get_machines ) + ;; ++ --check-inhibitors) ++ comps='auto yes no' ++ ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in +index 9f576ed77d..b3c51cc843 100644 +--- a/shell-completion/zsh/_systemctl.in ++++ b/shell-completion/zsh/_systemctl.in +@@ -363,6 +363,13 @@ _job_modes() { + _values -s , "${_modes[@]}" + } + ++(( $+functions[_systemctl_check_inhibitors] )) || ++ _systemctl_check_inhibitors() { ++ local -a _modes ++ _modes=(auto yes no) ++ _values -s , "${_modes[@]}" ++ } ++ + # Build arguments for "systemctl" to be used in completion. + local -a _modes; _modes=("--user" "--system") + # Use the last mode (they are exclusive and the last one is used). +@@ -380,7 +387,7 @@ _arguments -s \ + '--before[Show units ordered before]' \ + {-l,--full}"[Don't ellipsize unit names on output]" \ + '--show-types[When showing sockets, show socket type]' \ +- {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \ ++ '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \ + {-q,--quiet}'[Suppress output]' \ + '--no-block[Do not wait until operation finished]' \ + '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 8bec798373..8bcbf6bf4b 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -121,7 +121,7 @@ static bool arg_no_wall = false; + static bool arg_no_reload = false; + static bool arg_value = false; + static bool arg_show_types = false; +-static bool arg_ignore_inhibitors = false; ++static int arg_check_inhibitors = -1; + static bool arg_dry_run = false; + static bool arg_quiet = false; + static bool arg_full = false; +@@ -3313,17 +3313,19 @@ static int logind_check_inhibitors(enum action a) { + char **s; + int r; + +- if (arg_ignore_inhibitors || arg_force > 0) ++ if (arg_check_inhibitors == 0 || arg_force > 0) + return 0; + + if (arg_when > 0) + return 0; + +- if (geteuid() == 0) +- return 0; ++ if (arg_check_inhibitors < 0) { ++ if (geteuid() == 0) ++ return 0; + +- if (!on_tty()) +- return 0; ++ if (!on_tty()) ++ return 0; ++ } + + if (arg_transport != BUS_TRANSPORT_LOCAL) + return 0; +@@ -7237,8 +7239,10 @@ static void systemctl_help(void) { + " When enqueuing a unit job, show full transaction\n" + " --show-types When showing sockets, explicitly show their type\n" + " --value When showing properties, only print the value\n" +- " -i --ignore-inhibitors\n" +- " When shutting down or sleeping, ignore inhibitors\n" ++ " --check-inhibitors=MODE\n" ++ " Specify if checking inhibitors before shutting down,\n" ++ " sleeping or hibernating\n" ++ " -i Shortcut for --check-inhibitors=no\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " --now Start or stop unit in addition to enabling or disabling it\n" +@@ -7475,6 +7479,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + ARG_REVERSE, + ARG_AFTER, + ARG_BEFORE, ++ ARG_CHECK_INHIBITORS, + ARG_DRY_RUN, + ARG_SHOW_TYPES, + ARG_IRREVERSIBLE, +@@ -7520,7 +7525,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */ + { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */ + { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */ +- { "ignore-inhibitors", no_argument, NULL, 'i' }, ++ { "ignore-inhibitors", no_argument, NULL, 'i' }, /* compatibility only */ ++ { "check-inhibitors", required_argument, NULL, ARG_CHECK_INHIBITORS }, + { "value", no_argument, NULL, ARG_VALUE }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, +@@ -7813,7 +7819,18 @@ static int systemctl_parse_argv(int argc, char *argv[]) { + break; + + case 'i': +- arg_ignore_inhibitors = true; ++ arg_check_inhibitors = 0; ++ break; ++ ++ case ARG_CHECK_INHIBITORS: ++ if (streq(optarg, "auto")) ++ arg_check_inhibitors = -1; ++ else { ++ r = parse_boolean(optarg); ++ if (r < 0) ++ return log_error_errno(r, "Failed to parse --check-inhibitors= argument: %s", optarg); ++ arg_check_inhibitors = r; ++ } + break; + + case ARG_PLAIN: diff --git a/SOURCES/0612-logind-Introduce-RebootWithFlags-and-others.patch b/SOURCES/0612-logind-Introduce-RebootWithFlags-and-others.patch new file mode 100644 index 0000000..fc9c119 --- /dev/null +++ b/SOURCES/0612-logind-Introduce-RebootWithFlags-and-others.patch @@ -0,0 +1,769 @@ +From d375206fe822903b16f3b9006ea47ffd938d88cb Mon Sep 17 00:00:00 2001 +From: Deepak Rawat +Date: Mon, 25 Jan 2021 09:14:08 -0800 +Subject: [PATCH] logind: Introduce RebootWithFlags and others + +Add new systemd-logind WithFlags version for Reboot and others. These +methods add a unit64 parameter, with which can send additional control flags. + +(cherry picked from commit 00971ea5164e2e7a5f2d7ffe12a566b62d282556) + +Related: #1269726 +--- + src/basic/login-util.h | 8 + + src/login/logind-dbus.c | 498 +++++++++++++++++++++++++++++++----- + src/systemctl/systemctl.c | 26 ++ + src/systemd/sd-bus-vtable.h | 19 +- + 4 files changed, 480 insertions(+), 71 deletions(-) + +diff --git a/src/basic/login-util.h b/src/basic/login-util.h +index e1e62e12b7..9832207458 100644 +--- a/src/basic/login-util.h ++++ b/src/basic/login-util.h +@@ -4,6 +4,14 @@ + #include + #include + ++#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0) ++ ++/* For internal use only */ ++#define SD_LOGIND_INTERACTIVE (UINT64_C(1) << 63) ++ ++#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS) ++#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_INTERACTIVE) ++ + bool session_id_valid(const char *id); + + static inline bool logind_running(void) { +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 3f122fcbd9..0c43fbb3e0 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -1698,14 +1698,14 @@ static int verify_shutdown_creds( + Manager *m, + sd_bus_message *message, + InhibitWhat w, +- bool interactive, + const char *action, + const char *action_multiple_sessions, + const char *action_ignore_inhibit, ++ uint64_t flags, + sd_bus_error *error) { + + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; +- bool multiple_sessions, blocked; ++ bool multiple_sessions, blocked, interactive; + uid_t uid; + int r; + +@@ -1728,6 +1728,7 @@ static int verify_shutdown_creds( + + multiple_sessions = r > 0; + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); ++ interactive = flags & SD_LOGIND_INTERACTIVE; + + if (multiple_sessions && action_multiple_sessions) { + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error); +@@ -1737,12 +1738,19 @@ static int verify_shutdown_creds( + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + } + +- if (blocked && action_ignore_inhibit) { +- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error); +- if (r < 0) +- return r; +- if (r == 0) +- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ ++ if (blocked) { ++ /* We don't check polkit for root here, because you can't be more privileged than root */ ++ if (uid == 0 && (flags & SD_LOGIND_ROOT_CHECK_INHIBITORS)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, ++ "Access denied to root due to active block inhibitor"); ++ ++ if (action_ignore_inhibit) { ++ r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ ++ } + } + + if (!multiple_sessions && !blocked && action) { +@@ -1765,9 +1773,11 @@ static int method_do_shutdown_or_sleep( + const char *action_multiple_sessions, + const char *action_ignore_inhibit, + const char *sleep_verb, ++ bool with_flags, + sd_bus_error *error) { + +- int interactive, r; ++ int interactive = false, r; ++ uint64_t flags = 0; + + assert(m); + assert(message); +@@ -1775,10 +1785,20 @@ static int method_do_shutdown_or_sleep( + assert(w >= 0); + assert(w <= _INHIBIT_WHAT_MAX); + +- r = sd_bus_message_read(message, "b", &interactive); ++ if (with_flags) ++ r = sd_bus_message_read(message, "t", &flags); ++ else ++ r = sd_bus_message_read(message, "b", &interactive); ++ + if (r < 0) + return r; + ++ if (with_flags && (flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ "Invalid flags parameter"); ++ ++ SET_FLAG(flags, SD_LOGIND_INTERACTIVE, interactive); ++ + /* Don't allow multiple jobs being executed at the same time */ + if (m->action_what) + return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress"); +@@ -1795,8 +1815,8 @@ static int method_do_shutdown_or_sleep( + return r; + } + +- r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions, +- action_ignore_inhibit, error); ++ r = verify_shutdown_creds(m, message, w, action, action_multiple_sessions, ++ action_ignore_inhibit, flags, error); + if (r != 0) + return r; + +@@ -1818,6 +1838,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error + "org.freedesktop.login1.power-off-multiple-sessions", + "org.freedesktop.login1.power-off-ignore-inhibit", + NULL, ++ sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"), + error); + } + +@@ -1832,6 +1853,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * + "org.freedesktop.login1.reboot-multiple-sessions", + "org.freedesktop.login1.reboot-ignore-inhibit", + NULL, ++ sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"), + error); + } + +@@ -1846,6 +1868,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er + "org.freedesktop.login1.halt-multiple-sessions", + "org.freedesktop.login1.halt-ignore-inhibit", + NULL, ++ sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"), + error); + } + +@@ -1860,6 +1883,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error + "org.freedesktop.login1.suspend-multiple-sessions", + "org.freedesktop.login1.suspend-ignore-inhibit", + "suspend", ++ sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"), + error); + } + +@@ -1874,6 +1898,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "hibernate", ++ sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"), + error); + } + +@@ -1888,6 +1913,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "hybrid-sleep", ++ sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"), + error); + } + +@@ -1902,6 +1928,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "hybrid-sleep", ++ sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"), + error); + } + +@@ -2089,8 +2116,8 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_ + } else + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type"); + +- r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false, +- action, action_multiple_sessions, action_ignore_inhibit, error); ++ r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, action, action_multiple_sessions, ++ action_ignore_inhibit, 0, error); + if (r != 0) + return r; + +@@ -2683,60 +2710,395 @@ const sd_bus_vtable manager_vtable[] = { + SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0), + SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + +- SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0), +- SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0), +- SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("Halt", "b", NULL, method_halt, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("SuspendThenHibernate", "b", NULL, method_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanHalt", NULL, "s", method_can_halt, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanSuspendThenHibernate", NULL, "s", method_can_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED), +- +- SD_BUS_SIGNAL("SessionNew", "so", 0), +- SD_BUS_SIGNAL("SessionRemoved", "so", 0), +- SD_BUS_SIGNAL("UserNew", "uo", 0), +- SD_BUS_SIGNAL("UserRemoved", "uo", 0), +- SD_BUS_SIGNAL("SeatNew", "so", 0), +- SD_BUS_SIGNAL("SeatRemoved", "so", 0), +- SD_BUS_SIGNAL("PrepareForShutdown", "b", 0), +- SD_BUS_SIGNAL("PrepareForSleep", "b", 0), ++ SD_BUS_METHOD_WITH_NAMES("GetSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ "o", ++ SD_BUS_PARAM(object_path), ++ method_get_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("GetSessionByPID", ++ "u", ++ SD_BUS_PARAM(pid), ++ "o", ++ SD_BUS_PARAM(object_path), ++ method_get_session_by_pid, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("GetUser", ++ "u", ++ SD_BUS_PARAM(uid), ++ "o", ++ SD_BUS_PARAM(object_path), ++ method_get_user, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("GetUserByPID", ++ "u", ++ SD_BUS_PARAM(pid), ++ "o", ++ SD_BUS_PARAM(object_path), ++ method_get_user_by_pid, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("GetSeat", ++ "s", ++ SD_BUS_PARAM(seat_id), ++ "o", ++ SD_BUS_PARAM(object_path), ++ method_get_seat, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ListSessions", ++ NULL,, ++ "a(susso)", ++ SD_BUS_PARAM(sessions), ++ method_list_sessions, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ListUsers", ++ NULL,, ++ "a(uso)", ++ SD_BUS_PARAM(users), ++ method_list_users, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ListSeats", ++ NULL,, ++ "a(so)", ++ SD_BUS_PARAM(seats), ++ method_list_seats, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ListInhibitors", ++ NULL,, ++ "a(ssssuu)", ++ SD_BUS_PARAM(inhibitors), ++ method_list_inhibitors, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CreateSession", ++ "uusssssussbssa(sv)", ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(pid) ++ SD_BUS_PARAM(service) ++ SD_BUS_PARAM(type) ++ SD_BUS_PARAM(class) ++ SD_BUS_PARAM(desktop) ++ SD_BUS_PARAM(seat_id) ++ SD_BUS_PARAM(vtnr) ++ SD_BUS_PARAM(tty) ++ SD_BUS_PARAM(display) ++ SD_BUS_PARAM(remote) ++ SD_BUS_PARAM(remote_user) ++ SD_BUS_PARAM(remote_host) ++ SD_BUS_PARAM(properties), ++ "soshusub", ++ SD_BUS_PARAM(session_id) ++ SD_BUS_PARAM(object_path) ++ SD_BUS_PARAM(runtime_path) ++ SD_BUS_PARAM(fifo_fd) ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(seat_id) ++ SD_BUS_PARAM(vtnr) ++ SD_BUS_PARAM(existing), ++ method_create_session, ++ 0), ++ SD_BUS_METHOD_WITH_NAMES("ReleaseSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ NULL,, ++ method_release_session, ++ 0), ++ SD_BUS_METHOD_WITH_NAMES("ActivateSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ NULL,, ++ method_activate_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ActivateSessionOnSeat", ++ "ss", ++ SD_BUS_PARAM(session_id) ++ SD_BUS_PARAM(seat_id), ++ NULL,, ++ method_activate_session_on_seat, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("LockSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ NULL,, ++ method_lock_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("UnlockSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ NULL,, ++ method_lock_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("LockSessions", ++ NULL, ++ NULL, ++ method_lock_sessions, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("UnlockSessions", ++ NULL, ++ NULL, ++ method_lock_sessions, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("KillSession", ++ "ssi", ++ SD_BUS_PARAM(session_id) ++ SD_BUS_PARAM(who) ++ SD_BUS_PARAM(signal_number), ++ NULL,, ++ method_kill_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("KillUser", ++ "ui", ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(signal_number), ++ NULL,, ++ method_kill_user, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("TerminateSession", ++ "s", ++ SD_BUS_PARAM(session_id), ++ NULL,, ++ method_terminate_session, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("TerminateUser", ++ "u", ++ SD_BUS_PARAM(uid), ++ NULL,, ++ method_terminate_user, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("TerminateSeat", ++ "s", ++ SD_BUS_PARAM(seat_id), ++ NULL,, ++ method_terminate_seat, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SetUserLinger", ++ "ubb", ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(enable) ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_set_user_linger, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("AttachDevice", ++ "ssb", ++ SD_BUS_PARAM(seat_id) ++ SD_BUS_PARAM(sysfs_path) ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_attach_device, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("FlushDevices", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_flush_devices, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("PowerOff", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_poweroff, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("PowerOffWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_poweroff, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("Reboot", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_reboot, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("RebootWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_reboot, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("Halt", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_halt, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("HaltWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_halt, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("Suspend", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_suspend, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SuspendWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_suspend, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("Hibernate", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("HibernateWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("HybridSleep", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_hybrid_sleep, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("HybridSleepWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_hybrid_sleep, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernate", ++ "b", ++ SD_BUS_PARAM(interactive), ++ NULL,, ++ method_suspend_then_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernateWithFlags", ++ "t", ++ SD_BUS_PARAM(flags), ++ NULL,, ++ method_suspend_then_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanPowerOff", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_poweroff, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanReboot", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_reboot, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanHalt", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_halt, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanSuspend", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_suspend, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanHibernate", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanHybridSleep", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_hybrid_sleep, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanSuspendThenHibernate", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_suspend_then_hibernate, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("ScheduleShutdown", ++ "st", ++ SD_BUS_PARAM(type) ++ SD_BUS_PARAM(usec), ++ NULL,, ++ method_schedule_shutdown, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CancelScheduledShutdown", ++ NULL,, ++ "b", ++ SD_BUS_PARAM(cancelled), ++ method_cancel_scheduled_shutdown, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("Inhibit", ++ "ssss", ++ SD_BUS_PARAM(what) ++ SD_BUS_PARAM(who) ++ SD_BUS_PARAM(why) ++ SD_BUS_PARAM(mode), ++ "h", ++ SD_BUS_PARAM(pipe_fd), ++ method_inhibit, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("CanRebootToFirmwareSetup", ++ NULL,, ++ "s", ++ SD_BUS_PARAM(result), ++ method_can_reboot_to_firmware_setup, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SetRebootToFirmwareSetup", ++ "b", ++ SD_BUS_PARAM(enable), ++ NULL,, ++ method_set_reboot_to_firmware_setup, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD_WITH_NAMES("SetWallMessage", ++ "sb", ++ SD_BUS_PARAM(wall_message) ++ SD_BUS_PARAM(enable), ++ NULL,, ++ method_set_wall_message, ++ SD_BUS_VTABLE_UNPRIVILEGED), ++ ++ SD_BUS_SIGNAL_WITH_NAMES("SessionNew", ++ "so", ++ SD_BUS_PARAM(session_id) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("SessionRemoved", ++ "so", ++ SD_BUS_PARAM(session_id) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("UserNew", ++ "uo", ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("UserRemoved", ++ "uo", ++ SD_BUS_PARAM(uid) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("SeatNew", ++ "so", ++ SD_BUS_PARAM(seat_id) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("SeatRemoved", ++ "so", ++ SD_BUS_PARAM(seat_id) ++ SD_BUS_PARAM(object_path), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("PrepareForShutdown", ++ "b", ++ SD_BUS_PARAM(start), ++ 0), ++ SD_BUS_SIGNAL_WITH_NAMES("PrepareForSleep", ++ "b", ++ SD_BUS_PARAM(start), ++ 0), + + SD_BUS_VTABLE_END + }; +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 8bcbf6bf4b..3dd7c1522f 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -50,6 +50,7 @@ + #include "list.h" + #include "locale-util.h" + #include "log.h" ++#include "login-util.h" + #include "logs-show.h" + #include "macro.h" + #include "mkdir.h" +@@ -3266,6 +3267,8 @@ static int logind_reboot(enum action a) { + }; + + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ const char *method_with_flags; ++ uint64_t flags = 0; + sd_bus *bus; + int r; + +@@ -3284,6 +3287,29 @@ static int logind_reboot(enum action a) { + if (arg_dry_run) + return 0; + ++ SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0); ++ ++ method_with_flags = strjoina(actions[a].method, "WithFlags"); ++ ++ r = sd_bus_call_method( ++ bus, ++ "org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ method_with_flags, ++ &error, ++ NULL, ++ "t", flags); ++ if (r >= 0) ++ return 0; ++ ++ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) ++ return log_error_errno(r, "Failed to %s via logind: %s", actions[a].description, bus_error_message(&error, r)); ++ ++ /* Fallback to original methods in case there is older version of systemd-logind */ ++ log_debug("Method %s not available: %s. Falling back to %s", method_with_flags, bus_error_message(&error, r), actions[a].method); ++ sd_bus_error_free(&error); ++ + r = sd_bus_call_method( + bus, + "org.freedesktop.login1", +diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h +index 1268085498..8805e19477 100644 +--- a/src/systemd/sd-bus-vtable.h ++++ b/src/systemd/sd-bus-vtable.h +@@ -65,10 +65,12 @@ struct sd_bus_vtable { + const char *result; + sd_bus_message_handler_t handler; + size_t offset; ++ const char *names; + } method; + struct { + const char *member; + const char *signature; ++ const char *names; + } signal; + struct { + const char *member; +@@ -91,7 +93,10 @@ struct sd_bus_vtable { + }, \ + } + +-#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \ ++/* helper macro to format method and signal parameters, one at a time */ ++#define SD_BUS_PARAM(x) #x "\0" ++ ++#define SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, _offset, _flags) \ + { \ + .type = _SD_BUS_VTABLE_METHOD, \ + .flags = _flags, \ +@@ -102,13 +107,18 @@ struct sd_bus_vtable { + .result = _result, \ + .handler = _handler, \ + .offset = _offset, \ ++ .names = _in_names _out_names, \ + }, \ + }, \ + } ++#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \ ++ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, _offset, _flags) ++#define SD_BUS_METHOD_WITH_NAMES(_member, _signature, _in_names, _result, _out_names, _handler, _flags) \ ++ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, 0, _flags) + #define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \ +- SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, 0, _flags) ++ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, 0, _flags) + +-#define SD_BUS_SIGNAL(_member, _signature, _flags) \ ++#define SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, _out_names, _flags) \ + { \ + .type = _SD_BUS_VTABLE_SIGNAL, \ + .flags = _flags, \ +@@ -116,9 +126,12 @@ struct sd_bus_vtable { + .signal = { \ + .member = _member, \ + .signature = _signature, \ ++ .names = _out_names, \ + }, \ + }, \ + } ++#define SD_BUS_SIGNAL(_member, _signature, _flags) \ ++ SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, "", _flags) + + #define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \ + { \ diff --git a/SOURCES/0613-logind-add-WithFlags-methods-to-policy.patch b/SOURCES/0613-logind-add-WithFlags-methods-to-policy.patch new file mode 100644 index 0000000..753c9d9 --- /dev/null +++ b/SOURCES/0613-logind-add-WithFlags-methods-to-policy.patch @@ -0,0 +1,85 @@ +From e1b18ab36b2457a4896e531f03713b198725c919 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 9 Mar 2021 09:03:58 +0100 +Subject: [PATCH] =?UTF-8?q?logind:=20add=20=E2=80=A6WithFlags=20methods=20?= + =?UTF-8?q?to=20policy?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Without this, privilege escalation through polkit does not work, because all +methods fail with permission errors. + +Forgotten in 8885fed4e3a52cf1bf105e42043203c485ed9d92. +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1933335. + +(cherry picked from commit 2280db756eaff795091871feee8e47d4f6989a58) + +Related: #1269726 +--- + src/login/org.freedesktop.login1.conf | 28 +++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf +index f880f3e2da..dcde0c22c6 100644 +--- a/src/login/org.freedesktop.login1.conf ++++ b/src/login/org.freedesktop.login1.conf +@@ -130,30 +130,58 @@ + send_interface="org.freedesktop.login1.Manager" + send_member="PowerOff"/> + ++ ++ + + ++ ++ + + ++ ++ + + ++ ++ + + ++ ++ + + ++ ++ + + ++ ++ + diff --git a/SOURCES/0614-logind-simplify-flags-handling-a-bit.patch b/SOURCES/0614-logind-simplify-flags-handling-a-bit.patch new file mode 100644 index 0000000..fb61d3c --- /dev/null +++ b/SOURCES/0614-logind-simplify-flags-handling-a-bit.patch @@ -0,0 +1,72 @@ +From 6751217a032dd1a8e8ee324332f29786265f0ebe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 2 Feb 2021 15:27:30 +0100 +Subject: [PATCH] logind: simplify flags handling a bit + +Let's split out the two codepaths a bit, and emphasize which ones it the +new-style and which the old-style codepath, and let's clearly convert +the params of the old-stye into the new style for further processing, so +that the old style path is brief and isolated. + +No change in behaviour. + +Follow-up for: 8885fed4e3a52cf1bf105e42043203c485ed9d92 + +(cherry picked from commit d3e99bc0c7f785dcf4e73cfed12f74002e73be5f) + +Related: #1269726 +--- + src/login/logind-dbus.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 0c43fbb3e0..ae9abc9bce 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -1776,8 +1776,8 @@ static int method_do_shutdown_or_sleep( + bool with_flags, + sd_bus_error *error) { + +- int interactive = false, r; +- uint64_t flags = 0; ++ uint64_t flags; ++ int r; + + assert(m); + assert(message); +@@ -1785,19 +1785,25 @@ static int method_do_shutdown_or_sleep( + assert(w >= 0); + assert(w <= _INHIBIT_WHAT_MAX); + +- if (with_flags) ++ if (with_flags) { ++ /* New style method: with flags parameter (and interactive bool in the bus message header) */ + r = sd_bus_message_read(message, "t", &flags); +- else +- r = sd_bus_message_read(message, "b", &interactive); +- +- if (r < 0) +- return r; ++ if (r < 0) ++ return r; ++ if ((flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC) != 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); ++ } else { ++ /* Old style method: no flags parameter, but interactive bool passed as boolean in ++ * payload. Let's convert this argument to the new-style flags parameter for our internal ++ * use. */ ++ int interactive; + +- if (with_flags && (flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC)) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, +- "Invalid flags parameter"); ++ r = sd_bus_message_read(message, "b", &interactive); ++ if (r < 0) ++ return r; + +- SET_FLAG(flags, SD_LOGIND_INTERACTIVE, interactive); ++ flags = interactive ? SD_LOGIND_INTERACTIVE : 0; ++ } + + /* Don't allow multiple jobs being executed at the same time */ + if (m->action_what) diff --git a/SOURCES/0615-Update-link-to-RHEL-documentation.patch b/SOURCES/0615-Update-link-to-RHEL-documentation.patch new file mode 100644 index 0000000..922b826 --- /dev/null +++ b/SOURCES/0615-Update-link-to-RHEL-documentation.patch @@ -0,0 +1,25 @@ +From 48b893c770aed3214586d529ddaba14267818c33 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 15 Jul 2021 10:35:08 +0200 +Subject: [PATCH] Update link to RHEL documentation + +RHEL-only + +Resolves: #1982584 +--- + man/systemctl.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 9f0f4d46ea..a71e6c7c4f 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2017,7 +2017,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + For examples how to use systemctl in comparsion + with old service and chkconfig command please see: +- ++ + Managing System Services + + diff --git a/SOURCES/0616-Set-default-core-ulimit-to-0-but-keep-the-hard-limit.patch b/SOURCES/0616-Set-default-core-ulimit-to-0-but-keep-the-hard-limit.patch new file mode 100644 index 0000000..a1893a2 --- /dev/null +++ b/SOURCES/0616-Set-default-core-ulimit-to-0-but-keep-the-hard-limit.patch @@ -0,0 +1,29 @@ +From e2f5e8ccb27f48717b50339f58582d70ad5f59b1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 3 Aug 2021 11:52:36 +0200 +Subject: [PATCH] Set default core ulimit to 0, but keep the hard limit + ulimited + +so users can change it later. + +Follow-up to 830bd662276ee117e65a4b3d541f77e8b172eafd. + +rhel-only +Resolves: #1905582 +--- + src/core/system.conf.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index b4d6dfa15a..84246c0e36 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -52,7 +52,7 @@ + #DefaultLimitFSIZE= + #DefaultLimitDATA= + #DefaultLimitSTACK= +-DefaultLimitCORE=0 ++DefaultLimitCORE=0:infinity + #DefaultLimitRSS= + #DefaultLimitNOFILE= + #DefaultLimitAS= diff --git a/SOURCES/0617-shared-seccomp-util-address-family-filtering-is-brok.patch b/SOURCES/0617-shared-seccomp-util-address-family-filtering-is-brok.patch new file mode 100644 index 0000000..f3f13ad --- /dev/null +++ b/SOURCES/0617-shared-seccomp-util-address-family-filtering-is-brok.patch @@ -0,0 +1,76 @@ +From 3cf73fa4599116da350a0100378e749bbcbcad37 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 26 Nov 2020 11:23:54 +0100 +Subject: [PATCH] shared/seccomp-util: address family filtering is broken on + ppc + +This reverts the gist of da1921a5c396547261c8c7fcd94173346eb3b718 and +0d9fca76bb69e162265b2d25cb79f1890c0da31b (for ppc). + +Quoting #17559: +> libseccomp 2.5 added socket syscall multiplexing on ppc64(el): +> https://github.com/seccomp/libseccomp/pull/229 +> +> Like with i386, s390 and s390x this breaks socket argument filtering, so +> RestrictAddressFamilies doesn't work. +> +> This causes the unit test to fail: +> /* test_restrict_address_families */ +> Operating on architecture: ppc +> Failed to install socket family rules for architecture ppc, skipping: Operation canceled +> Operating on architecture: ppc64 +> Failed to add socket() rule for architecture ppc64, skipping: Invalid argument +> Operating on architecture: ppc64-le +> Failed to add socket() rule for architecture ppc64-le, skipping: Invalid argument +> Assertion 'fd < 0' failed at src/test/test-seccomp.c:424, function test_restrict_address_families(). Aborting. +> +> The socket filters can't be added so `socket(AF_UNIX, SOCK_DGRAM, 0);` still +> works, triggering the assertion. + +Fixes #17559. + +(cherry picked from commit d5923e38bc0e6cf9d7620ed5f1f8606fe7fe1168) + +Resolves: #1982650 +--- + src/shared/seccomp-util.c | 6 +++--- + src/test/test-seccomp.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index e903512d45..c57c409433 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -1251,9 +1251,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + case SCMP_ARCH_X32: + case SCMP_ARCH_ARM: + case SCMP_ARCH_AARCH64: +- case SCMP_ARCH_PPC: +- case SCMP_ARCH_PPC64: +- case SCMP_ARCH_PPC64LE: + case SCMP_ARCH_MIPSEL64N32: + case SCMP_ARCH_MIPS64N32: + case SCMP_ARCH_MIPSEL64: +@@ -1267,6 +1264,9 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + case SCMP_ARCH_X86: + case SCMP_ARCH_MIPSEL: + case SCMP_ARCH_MIPS: ++ case SCMP_ARCH_PPC: ++ case SCMP_ARCH_PPC64: ++ case SCMP_ARCH_PPC64LE: + default: + /* These we either know we don't support (i.e. are the ones that do use socketcall()), or we + * don't know */ +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 009a2e1922..5eb1c78b8b 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -25,7 +25,7 @@ + #include "util.h" + #include "virt.h" + +-#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__) ++#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__) + /* On these archs, socket() is implemented via the socketcall() syscall multiplexer, + * and we can't restrict it hence via seccomp. */ + # define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1 diff --git a/SOURCES/0618-logind-rework-Seat-Session-User-object-allocation-an.patch b/SOURCES/0618-logind-rework-Seat-Session-User-object-allocation-an.patch new file mode 100644 index 0000000..bddc651 --- /dev/null +++ b/SOURCES/0618-logind-rework-Seat-Session-User-object-allocation-an.patch @@ -0,0 +1,341 @@ +From 019b3a5d7530c51aa8f7f1e5f5cb5eb81113d4db Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 18:53:09 +0200 +Subject: [PATCH] logind: rework Seat/Session/User object allocation and + freeing a bit + +Let's update things a bit to follow current practices: + +- User structure initialization rather than zero-initialized allocation + +- Always propagate proper errors from allocation functions + +- Use _cleanup_ for freeing objects when allocation fails half-way + +- Make destructors return NULL + +(cherry picked from commit 8c29a4570993105fecc12288596d2ee77c7f82b8) + +Related: #1642460 +--- + src/login/logind-core.c | 14 ++++++---- + src/login/logind-seat.c | 38 +++++++++++++++---------- + src/login/logind-seat.h | 6 ++-- + src/login/logind-session.c | 57 +++++++++++++++++++++----------------- + src/login/logind-session.h | 7 +++-- + src/login/logind-user.c | 21 +++++++------- + 6 files changed, 83 insertions(+), 60 deletions(-) + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index cff5536ac0..f598bbaa1c 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -88,15 +88,16 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev + + int manager_add_seat(Manager *m, const char *id, Seat **_seat) { + Seat *s; ++ int r; + + assert(m); + assert(id); + + s = hashmap_get(m->seats, id); + if (!s) { +- s = seat_new(m, id); +- if (!s) +- return -ENOMEM; ++ r = seat_new(&s, m, id); ++ if (r < 0) ++ return r; + } + + if (_seat) +@@ -107,15 +108,16 @@ int manager_add_seat(Manager *m, const char *id, Seat **_seat) { + + int manager_add_session(Manager *m, const char *id, Session **_session) { + Session *s; ++ int r; + + assert(m); + assert(id); + + s = hashmap_get(m->sessions, id); + if (!s) { +- s = session_new(m, id); +- if (!s) +- return -ENOMEM; ++ r = session_new(&s, m, id); ++ if (r < 0) ++ return r; + } + + if (_session) +diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c +index 63253db5bf..f68fc0ceaa 100644 +--- a/src/login/logind-seat.c ++++ b/src/login/logind-seat.c +@@ -21,33 +21,42 @@ + #include "terminal-util.h" + #include "util.h" + +-Seat *seat_new(Manager *m, const char *id) { +- Seat *s; ++int seat_new(Seat** ret, Manager *m, const char *id) { ++ _cleanup_(seat_freep) Seat *s = NULL; ++ int r; + ++ assert(ret); + assert(m); + assert(id); + +- s = new0(Seat, 1); ++ if (!seat_name_is_valid(id)) ++ return -EINVAL; ++ ++ s = new(Seat, 1); + if (!s) +- return NULL; ++ return -ENOMEM; ++ ++ *s = (Seat) { ++ .manager = m, ++ }; + + s->state_file = strappend("/run/systemd/seats/", id); + if (!s->state_file) +- return mfree(s); ++ return -ENOMEM; + + s->id = basename(s->state_file); +- s->manager = m; + +- if (hashmap_put(m->seats, s->id, s) < 0) { +- free(s->state_file); +- return mfree(s); +- } ++ r = hashmap_put(m->seats, s->id, s); ++ if (r < 0) ++ return r; + +- return s; ++ *ret = TAKE_PTR(s); ++ return 0; + } + +-void seat_free(Seat *s) { +- assert(s); ++Seat* seat_free(Seat *s) { ++ if (!s) ++ return NULL; + + if (s->in_gc_queue) + LIST_REMOVE(gc_queue, s->manager->seat_gc_queue, s); +@@ -64,7 +73,8 @@ void seat_free(Seat *s) { + + free(s->positions); + free(s->state_file); +- free(s); ++ ++ return mfree(s); + } + + int seat_save(Seat *s) { +diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h +index 70878bbe52..51cd468e26 100644 +--- a/src/login/logind-seat.h ++++ b/src/login/logind-seat.h +@@ -27,8 +27,10 @@ struct Seat { + LIST_FIELDS(Seat, gc_queue); + }; + +-Seat *seat_new(Manager *m, const char *id); +-void seat_free(Seat *s); ++int seat_new(Seat **ret, Manager *m, const char *id); ++Seat* seat_free(Seat *s); ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Seat *, seat_free); + + int seat_save(Seat *s); + int seat_load(Seat *s); +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 69d5a10319..5621d59a41 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -24,57 +24,61 @@ + #include "mkdir.h" + #include "parse-util.h" + #include "path-util.h" ++#include "process-util.h" + #include "string-table.h" + #include "terminal-util.h" + #include "user-util.h" + #include "util.h" +-#include "process-util.h" + + #define RELEASE_USEC (20*USEC_PER_SEC) + + static void session_remove_fifo(Session *s); + +-Session* session_new(Manager *m, const char *id) { +- Session *s; ++int session_new(Session **ret, Manager *m, const char *id) { ++ _cleanup_(session_freep) Session *s = NULL; ++ int r; + ++ assert(ret); + assert(m); + assert(id); +- assert(session_id_valid(id)); + +- s = new0(Session, 1); ++ if (!session_id_valid(id)) ++ return -EINVAL; ++ ++ s = new(Session, 1); + if (!s) +- return NULL; ++ return -ENOMEM; ++ ++ *s = (Session) { ++ .manager = m, ++ .fifo_fd = -1, ++ .vtfd = -1, ++ .audit_id = AUDIT_SESSION_INVALID, ++ }; + + s->state_file = strappend("/run/systemd/sessions/", id); + if (!s->state_file) +- return mfree(s); +- +- s->devices = hashmap_new(&devt_hash_ops); +- if (!s->devices) { +- free(s->state_file); +- return mfree(s); +- } ++ return -ENOMEM; + + s->id = basename(s->state_file); + +- if (hashmap_put(m->sessions, s->id, s) < 0) { +- hashmap_free(s->devices); +- free(s->state_file); +- return mfree(s); +- } ++ s->devices = hashmap_new(&devt_hash_ops); ++ if (!s->devices) ++ return -ENOMEM; + +- s->manager = m; +- s->fifo_fd = -1; +- s->vtfd = -1; +- s->audit_id = AUDIT_SESSION_INVALID; ++ r = hashmap_put(m->sessions, s->id, s); ++ if (r < 0) ++ return r; + +- return s; ++ *ret = TAKE_PTR(s); ++ return 0; + } + +-void session_free(Session *s) { ++Session* session_free(Session *s) { + SessionDevice *sd; + +- assert(s); ++ if (!s) ++ return NULL; + + if (s->in_gc_queue) + LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s); +@@ -126,7 +130,8 @@ void session_free(Session *s) { + hashmap_remove(s->manager->sessions, s->id); + + free(s->state_file); +- free(s); ++ ++ return mfree(s); + } + + void session_set_user(Session *s, User *u) { +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 29ca399daf..572f2545c1 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -109,8 +109,11 @@ struct Session { + LIST_FIELDS(Session, gc_queue); + }; + +-Session *session_new(Manager *m, const char *id); +-void session_free(Session *s); ++int session_new(Session **ret, Manager *m, const char *id); ++Session* session_free(Session *s); ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free); ++ + void session_set_user(Session *s, User *u); + bool session_may_gc(Session *s, bool drop_not_started); + void session_add_to_gc_queue(Session *s); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 56b8066f12..60ccd62abb 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -30,23 +30,24 @@ + #include "user-util.h" + #include "util.h" + +-int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) { ++int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { + _cleanup_(user_freep) User *u = NULL; + char lu[DECIMAL_STR_MAX(uid_t) + 1]; + int r; + +- assert(out); ++ assert(ret); + assert(m); + assert(name); + +- u = new0(User, 1); ++ u = new(User, 1); + if (!u) + return -ENOMEM; + +- u->manager = m; +- u->uid = uid; +- u->gid = gid; +- xsprintf(lu, UID_FMT, uid); ++ *u = (User) { ++ .manager = m, ++ .uid = uid, ++ .gid = gid, ++ }; + + u->name = strdup(name); + if (!u->name) +@@ -58,6 +59,7 @@ int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) { + if (asprintf(&u->runtime_path, "/run/user/"UID_FMT, uid) < 0) + return -ENOMEM; + ++ xsprintf(lu, UID_FMT, uid); + r = slice_build_subslice(SPECIAL_USER_SLICE, lu, &u->slice); + if (r < 0) + return r; +@@ -78,8 +80,7 @@ int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) { + if (r < 0) + return r; + +- *out = TAKE_PTR(u); +- ++ *ret = TAKE_PTR(u); + return 0; + } + +@@ -272,7 +273,7 @@ int user_save(User *u) { + if (!u->started) + return 0; + +- return user_save_internal (u); ++ return user_save_internal(u); + } + + int user_load(User *u) { diff --git a/SOURCES/0619-logind-fix-serialization-deserialization-of-user-s-d.patch b/SOURCES/0619-logind-fix-serialization-deserialization-of-user-s-d.patch new file mode 100644 index 0000000..7639b30 --- /dev/null +++ b/SOURCES/0619-logind-fix-serialization-deserialization-of-user-s-d.patch @@ -0,0 +1,116 @@ +From 0314e68fe961cec941b1b0eb1cbcca4546cfdfdb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 19:04:35 +0200 +Subject: [PATCH] logind: fix serialization/deserialization of user's "display + session" + +Previously this was serialized as part of the user object. This didn't +work however, as we load users first, and sessions seconds and hence +referencing a session from the user load logic cannot work. + +Fix this by storing an IS_DISPLAY property along with each session, and +make the session with this set display session when it is loaded. + +(cherry picked from commit 1c8280fd47b6561d35b15b3b6d49bdeacf891bfd) + +Related: #1642460 +--- + src/login/logind-session.c | 18 +++++++++++++++++- + src/login/logind-user.c | 18 ++++-------------- + 2 files changed, 21 insertions(+), 15 deletions(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 5621d59a41..0afb065b2b 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -184,11 +184,13 @@ int session_save(Session *s) { + "UID="UID_FMT"\n" + "USER=%s\n" + "ACTIVE=%i\n" ++ "IS_DISPLAY=%i\n" + "STATE=%s\n" + "REMOTE=%i\n", + s->user->uid, + s->user->name, + session_is_active(s), ++ s->user->display == s, + session_state_to_string(session_get_state(s)), + s->remote); + +@@ -359,7 +361,8 @@ int session_load(Session *s) { + *monotonic = NULL, + *controller = NULL, + *active = NULL, +- *devices = NULL; ++ *devices = NULL, ++ *is_display = NULL; + + int k, r; + +@@ -389,6 +392,7 @@ int session_load(Session *s) { + "CONTROLLER", &controller, + "ACTIVE", &active, + "DEVICES", &devices, ++ "IS_DISPLAY", &is_display, + NULL); + + if (r < 0) +@@ -496,6 +500,18 @@ int session_load(Session *s) { + s->was_active = k; + } + ++ if (is_display) { ++ /* Note that when enumerating users are loaded before sessions, hence the display session to use is ++ * something we have to store along with the session and not the user, as in that case we couldn't ++ * apply it at the time we load the user. */ ++ ++ k = parse_boolean(is_display); ++ if (k < 0) ++ log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m"); ++ else if (k > 0) ++ s->user->display = s; ++ } ++ + if (controller) { + if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) { + session_set_controller(s, controller, false, false); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 60ccd62abb..17ed361411 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -277,8 +277,7 @@ int user_save(User *u) { + } + + int user_load(User *u) { +- _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL; +- Session *s = NULL; ++ _cleanup_free_ char *realtime = NULL, *monotonic = NULL; + int r; + + assert(u); +@@ -286,22 +285,13 @@ int user_load(User *u) { + r = parse_env_file(NULL, u->state_file, NEWLINE, + "SERVICE_JOB", &u->service_job, + "SLICE_JOB", &u->slice_job, +- "DISPLAY", &display, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, + NULL); +- if (r < 0) { +- if (r == -ENOENT) +- return 0; +- ++ if (r == -ENOENT) ++ return 0; ++ if (r < 0) + return log_error_errno(r, "Failed to read %s: %m", u->state_file); +- } +- +- if (display) +- s = hashmap_get(u->manager->sessions, display); +- +- if (s && s->display && display_is_local(s->display)) +- u->display = s; + + if (realtime) + timestamp_deserialize(realtime, &u->timestamp.realtime); diff --git a/SOURCES/0620-logind-turn-of-stdio-locking-when-writing-session-fi.patch b/SOURCES/0620-logind-turn-of-stdio-locking-when-writing-session-fi.patch new file mode 100644 index 0000000..93c7244 --- /dev/null +++ b/SOURCES/0620-logind-turn-of-stdio-locking-when-writing-session-fi.patch @@ -0,0 +1,39 @@ +From 3eab0f1b64477792bd01ca52c3eb26ce64c5c7ba Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 20:18:55 +0200 +Subject: [PATCH] logind: turn of stdio locking when writing session files too + +This just copies what we already do for user and seat files to session +files. + +(cherry picked from commit 44176400138e18d9087e0864ca97041416a90d47) + +Related: #1642460 +--- + src/login/logind-session.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 0afb065b2b..960a24d1a7 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -175,9 +176,8 @@ int session_save(Session *s) { + if (r < 0) + goto fail; + +- assert(s->user); +- +- fchmod(fileno(f), 0644); ++ (void) __fsetlocking(f, FSETLOCKING_BYCALLER); ++ (void) fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" diff --git a/SOURCES/0621-units-set-StopWhenUnneeded-for-the-user-slice-units-.patch b/SOURCES/0621-units-set-StopWhenUnneeded-for-the-user-slice-units-.patch new file mode 100644 index 0000000..4b9bb79 --- /dev/null +++ b/SOURCES/0621-units-set-StopWhenUnneeded-for-the-user-slice-units-.patch @@ -0,0 +1,27 @@ +From f94c1bbec9e2c3efcbafd61ea1fdf8dbc3245d1b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 20:19:38 +0200 +Subject: [PATCH] units: set StopWhenUnneeded= for the user slice units too + +We'd like them to go away, just like the user-runtime-dir@.service when +they aren't needed anymore. + +(cherry picked from commit 1007473b49b5aaeef0e53cd4a15f4ed8cf721926) + +Related: #1642460 +--- + units/user-.slice.d/10-defaults.conf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/user-.slice.d/10-defaults.conf b/units/user-.slice.d/10-defaults.conf +index efc9d37c8e..1147e7aed9 100644 +--- a/units/user-.slice.d/10-defaults.conf ++++ b/units/user-.slice.d/10-defaults.conf +@@ -10,6 +10,7 @@ + [Unit] + Description=User Slice of UID %j + After=systemd-user-sessions.service ++StopWhenUnneeded=yes + + [Slice] + TasksMax=80% diff --git a/SOURCES/0622-units-improve-Description-string-a-bit.patch b/SOURCES/0622-units-improve-Description-string-a-bit.patch new file mode 100644 index 0000000..dff8053 --- /dev/null +++ b/SOURCES/0622-units-improve-Description-string-a-bit.patch @@ -0,0 +1,29 @@ +From 50a4e03d2da89df32f2f63eb56051d789508ae75 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 18:15:07 +0200 +Subject: [PATCH] units: improve Description= string a bit + +Let's not use the word "wrapper", as it's not clear what that is, and in +some way any unit file is a "wrapper"... let's simply say that it's +about the runtime directory. + +(cherry picked from commit 14df094a51e87013d96ac697ae4f14593cbcad39) + +Related: #1642460 +--- + units/user-runtime-dir@.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in +index bfd6488d61..63db1cca6a 100644 +--- a/units/user-runtime-dir@.service.in ++++ b/units/user-runtime-dir@.service.in +@@ -8,7 +8,7 @@ + # (at your option) any later version. + + [Unit] +-Description=/run/user/%i mount wrapper ++Description=User runtime directory /run/user/%i + After=systemd-user-sessions.service + StopWhenUnneeded=yes + diff --git a/SOURCES/0623-logind-improve-logging-in-manager_connect_console.patch b/SOURCES/0623-logind-improve-logging-in-manager_connect_console.patch new file mode 100644 index 0000000..6a30f47 --- /dev/null +++ b/SOURCES/0623-logind-improve-logging-in-manager_connect_console.patch @@ -0,0 +1,77 @@ +From 9e9c6cbbdd60f4538cee041ffe3f9cd831c5de17 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 3 Aug 2018 20:21:27 +0200 +Subject: [PATCH] logind: improve logging in manager_connect_console() + +let's make sure we log about every failure + +Also, complain about systems where /dev/tty0 exists but +/sys/class/tty/tty0/active does not. Such systems (usually container +environments) are pretty broken as they mount something that is not a VC +to /dev/tty0 and they really shouldn't. + +Systems should either have a VC or not, but not badly fake one by +mounting things wildly. + +This just adds a warning message, as before we'll simply turn off VC +handling in this case. + +(cherry picked from commit 0b6d55cae9b8adc507fbea95d1b2874729a77386) + +Related: #1642460 +--- + src/login/logind.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/login/logind.c b/src/login/logind.c +index 52fcee933c..1b366cd55f 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -815,28 +815,28 @@ static int manager_connect_console(Manager *m) { + assert(m); + assert(m->console_active_fd < 0); + +- /* On certain architectures (S390 and Xen, and containers), +- /dev/tty0 does not exist, so don't fail if we can't open +- it. */ ++ /* On certain systems (such as S390, Xen, and containers) /dev/tty0 does not exist (as there is no VC), so ++ * don't fail if we can't open it. */ ++ + if (access("/dev/tty0", F_OK) < 0) + return 0; + + m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (m->console_active_fd < 0) { + +- /* On some systems the device node /dev/tty0 may exist +- * even though /sys/class/tty/tty0 does not. */ +- if (errno == ENOENT) ++ /* On some systems /dev/tty0 may exist even though /sys/class/tty/tty0 does not. These are broken, but ++ * common. Let's complain but continue anyway. */ ++ if (errno == ENOENT) { ++ log_warning_errno(errno, "System has /dev/tty0 but not /sys/class/tty/tty0/active which is broken, ignoring: %m"); + return 0; ++ } + + return log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m"); + } + + r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m); +- if (r < 0) { +- log_error("Failed to watch foreground console"); +- return r; +- } ++ if (r < 0) ++ return log_error_errno(r, "Failed to watch foreground console: %m"); + + /* + * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used +@@ -855,7 +855,7 @@ static int manager_connect_console(Manager *m) { + + r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m); + if (r < 0) +- return r; ++ return log_error_errno(r, "Failed to subscribe to signal: %m"); + + return 0; + } diff --git a/SOURCES/0624-logind-save-restore-User-object-s-stopping-field-dur.patch b/SOURCES/0624-logind-save-restore-User-object-s-stopping-field-dur.patch new file mode 100644 index 0000000..d640d09 --- /dev/null +++ b/SOURCES/0624-logind-save-restore-User-object-s-stopping-field-dur.patch @@ -0,0 +1,90 @@ +From 4703c08fe3a8bfa1bc9b893e8bde365b1cbeffd9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 18:14:11 +0200 +Subject: [PATCH] logind: save/restore User object's "stopping" field during + restarts + +Whether we are stopping or not is highly relevant, hence don't forget it +across restarts. + +(cherry picked from commit d865bc024bf28c17120d7322a81e9a99997a59f6) + +Related: #1642460 +--- + src/login/logind-user.c | 20 +++++++++++++++----- + src/login/logind-user.h | 5 +++-- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 17ed361411..35b2ca5489 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -136,9 +136,11 @@ static int user_save_internal(User *u) { + fprintf(f, + "# This is private data. Do not parse.\n" + "NAME=%s\n" +- "STATE=%s\n", ++ "STATE=%s\n" /* friendly user-facing state */ ++ "STOPPING=%s\n", /* low-level state */ + u->name, +- user_state_to_string(user_get_state(u))); ++ user_state_to_string(user_get_state(u)), ++ yes_no(u->stopping)); + + /* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */ + if (u->runtime_path) +@@ -277,14 +279,14 @@ int user_save(User *u) { + } + + int user_load(User *u) { +- _cleanup_free_ char *realtime = NULL, *monotonic = NULL; ++ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL; + int r; + + assert(u); + + r = parse_env_file(NULL, u->state_file, NEWLINE, + "SERVICE_JOB", &u->service_job, +- "SLICE_JOB", &u->slice_job, ++ "STOPPING", &stopping, + "REALTIME", &realtime, + "MONOTONIC", &monotonic, + NULL); +@@ -293,12 +295,20 @@ int user_load(User *u) { + if (r < 0) + return log_error_errno(r, "Failed to read %s: %m", u->state_file); + ++ if (stopping) { ++ r = parse_boolean(stopping); ++ if (r < 0) ++ log_debug_errno(r, "Failed to parse 'STOPPING' boolean: %s", stopping); ++ else ++ u->stopping = r; ++ } ++ + if (realtime) + timestamp_deserialize(realtime, &u->timestamp.realtime); + if (monotonic) + timestamp_deserialize(monotonic, &u->timestamp.monotonic); + +- return r; ++ return 0; + } + + static int user_start_service(User *u) { +diff --git a/src/login/logind-user.h b/src/login/logind-user.h +index eba2325284..03e020b870 100644 +--- a/src/login/logind-user.h ++++ b/src/login/logind-user.h +@@ -36,8 +36,9 @@ struct User { + dual_timestamp timestamp; + + bool in_gc_queue:1; +- bool started:1; +- bool stopping:1; ++ ++ bool started:1; /* Whenever the user being started, has been started or is being stopped again. */ ++ bool stopping:1; /* Whenever the user is being stopped or has been stopped. */ + + LIST_HEAD(Session, sessions); + LIST_FIELDS(User, gc_queue); diff --git a/SOURCES/0625-logind-correct-bad-clean-up-path.patch b/SOURCES/0625-logind-correct-bad-clean-up-path.patch new file mode 100644 index 0000000..90740cc --- /dev/null +++ b/SOURCES/0625-logind-correct-bad-clean-up-path.patch @@ -0,0 +1,25 @@ +From eebbeada76b0fa4e252ecf4e25b088733636fe89 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 18:19:45 +0200 +Subject: [PATCH] logind: correct bad clean-up path + +(cherry picked from commit d88ffeeeefda4c3447223fd36f8e30f23c931e48) + +Related: #1642460 +--- + src/login/logind-dbus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index ae9abc9bce..4b2c418453 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -845,7 +845,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + + r = sd_bus_message_enter_container(message, 'a', "(sv)"); + if (r < 0) +- return r; ++ goto fail; + + r = session_start(session, message); + if (r < 0) diff --git a/SOURCES/0626-logind-fix-bad-error-propagation.patch b/SOURCES/0626-logind-fix-bad-error-propagation.patch new file mode 100644 index 0000000..1a07e78 --- /dev/null +++ b/SOURCES/0626-logind-fix-bad-error-propagation.patch @@ -0,0 +1,25 @@ +From 7662d7c86d1fbb01693d4eb008fa27bf1e0030a9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 18:21:37 +0200 +Subject: [PATCH] logind: fix bad error propagation + +(cherry picked from commit cce08496e7353e3e9903b42695aba3f9d259b90a) + +Related: #1642460 +--- + src/login/logind-seat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c +index f68fc0ceaa..9e4f009643 100644 +--- a/src/login/logind-seat.c ++++ b/src/login/logind-seat.c +@@ -175,7 +175,7 @@ static int vt_allocate(unsigned int vtnr) { + xsprintf(p, "/dev/tty%u", vtnr); + fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) +- return -errno; ++ return fd; + + return 0; + } diff --git a/SOURCES/0627-logind-never-elect-a-session-that-is-stopping-as-dis.patch b/SOURCES/0627-logind-never-elect-a-session-that-is-stopping-as-dis.patch new file mode 100644 index 0000000..145c425 --- /dev/null +++ b/SOURCES/0627-logind-never-elect-a-session-that-is-stopping-as-dis.patch @@ -0,0 +1,42 @@ +From 35f9a7f8f4e8917725349fe764706658c02537ca Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 19:02:29 +0200 +Subject: [PATCH] logind: never elect a session that is stopping as display + +(cherry picked from commit 04857cd801022d9f9933efb484c6253572f09870) + +Related: #1642460 +--- + src/login/logind-user.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 35b2ca5489..3e4c99bdbd 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -613,11 +613,10 @@ int user_kill(User *u, int signo) { + } + + static bool elect_display_filter(Session *s) { +- /* Return true if the session is a candidate for the user’s ‘primary +- * session’ or ‘display’. */ ++ /* Return true if the session is a candidate for the user’s ‘primary session’ or ‘display’. */ + assert(s); + +- return (s->class == SESSION_USER && !s->stopping); ++ return s->class == SESSION_USER && s->started && !s->stopping; + } + + static int elect_display_compare(Session *s1, Session *s2) { +@@ -663,9 +662,8 @@ void user_elect_display(User *u) { + + assert(u); + +- /* This elects a primary session for each user, which we call +- * the "display". We try to keep the assignment stable, but we +- * "upgrade" to better choices. */ ++ /* This elects a primary session for each user, which we call the "display". We try to keep the assignment ++ * stable, but we "upgrade" to better choices. */ + log_debug("Electing new display for user %s", u->name); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { diff --git a/SOURCES/0628-logind-introduce-little-helper-that-checks-whether-a.patch b/SOURCES/0628-logind-introduce-little-helper-that-checks-whether-a.patch new file mode 100644 index 0000000..d50750b --- /dev/null +++ b/SOURCES/0628-logind-introduce-little-helper-that-checks-whether-a.patch @@ -0,0 +1,60 @@ +From 83c49a5e54dffc3dfa85b79f6375cd0a42a4ff76 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 19:34:39 +0200 +Subject: [PATCH] logind: introduce little helper that checks whether a session + is ready + +(cherry picked from commit b1951bc83ffbbb92ba4de7b9cba845421c2f35b1) + +Related: #1642460 +--- + src/login/logind-session-dbus.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index 88a2d33dc8..03585b7f8e 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -704,6 +704,15 @@ int session_send_lock_all(Manager *m, bool lock) { + return r; + } + ++static bool session_ready(Session *s) { ++ assert(s); ++ ++ /* Returns true when the session is ready, i.e. all jobs we enqueued for it are done (regardless if successful or not) */ ++ ++ return !s->scope_job && ++ !s->user->service_job; ++} ++ + int session_send_create_reply(Session *s, sd_bus_error *error) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *c = NULL; + _cleanup_close_ int fifo_fd = -1; +@@ -711,14 +720,13 @@ int session_send_create_reply(Session *s, sd_bus_error *error) { + + assert(s); + +- /* This is called after the session scope and the user service +- * were successfully created, and finishes where ++ /* This is called after the session scope and the user service were successfully created, and finishes where + * bus_manager_create_session() left off. */ + + if (!s->create_message) + return 0; + +- if (!sd_bus_error_is_set(error) && (s->scope_job || s->user->service_job)) ++ if (!sd_bus_error_is_set(error) && !session_ready(s)) + return 0; + + c = s->create_message; +@@ -731,8 +739,7 @@ int session_send_create_reply(Session *s, sd_bus_error *error) { + if (fifo_fd < 0) + return fifo_fd; + +- /* Update the session state file before we notify the client +- * about the result. */ ++ /* Update the session state file before we notify the client about the result. */ + session_save(s); + + p = session_bus_path(s); diff --git a/SOURCES/0629-logind-propagate-session-stop-errors.patch b/SOURCES/0629-logind-propagate-session-stop-errors.patch new file mode 100644 index 0000000..feed8cb --- /dev/null +++ b/SOURCES/0629-logind-propagate-session-stop-errors.patch @@ -0,0 +1,40 @@ +From 31aa21a13f9b91486b1a95c5b73fa088af77fcb4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 19:35:44 +0200 +Subject: [PATCH] logind: propagate session stop errors + +Let's propagate errors from stopping sessions via seat_stop(). This is +similar to how we propagate such errors in user_stop() for all sessions +associated with a user. + +Note that we propagate these errors, but we don't abort the function. + +(cherry picked from commit e6958b7ea33813b085966ac25817a957c0dad7f9) + +Related: #1642460 +--- + src/login/logind-seat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c +index 9e4f009643..96c34a6c9e 100644 +--- a/src/login/logind-seat.c ++++ b/src/login/logind-seat.c +@@ -431,7 +431,7 @@ int seat_start(Seat *s) { + } + + int seat_stop(Seat *s, bool force) { +- int r = 0; ++ int r; + + assert(s); + +@@ -441,7 +441,7 @@ int seat_stop(Seat *s, bool force) { + "SEAT_ID=%s", s->id, + LOG_MESSAGE("Removed seat %s.", s->id)); + +- seat_stop_sessions(s, force); ++ r = seat_stop_sessions(s, force); + + unlink(s->state_file); + seat_add_to_gc_queue(s); diff --git a/SOURCES/0630-logind-rework-how-we-manage-the-slice-and-user-runti.patch b/SOURCES/0630-logind-rework-how-we-manage-the-slice-and-user-runti.patch new file mode 100644 index 0000000..7880086 --- /dev/null +++ b/SOURCES/0630-logind-rework-how-we-manage-the-slice-and-user-runti.patch @@ -0,0 +1,618 @@ +From a05c1077911652954c8b9e82cfdc0fc643eca782 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 6 Aug 2018 21:44:45 +0200 +Subject: [PATCH] logind: rework how we manage the slice and + user-runtime-dir@.service unit for each user + +Instead of managing it explicitly, let's simplify things and rely on +regular Wants=/Requires= dependencies to pull in these units from +user@.service and the session scope, and StopWhenUneeded= to stop these +auxiliary units again. This way, they can be pulled in easily by +unrelated units too. + +This simplifies things quite a bit: for each session we now only need to +manage the session scope, and for each user the user@.service, the other +units are not something we need to manage anymore. + +This patch also makes sure that if user@.service of a user is masked we +will continue to work, and user-runtime-dir@.service will still be +correctly pulled in, as it is now a dependency of the scope unit. + +Fixes: #9461 +Replaces: #5546 +(cherry picked from commit 25a1ab4ed48b72e974f77a68dcbe3521014787bb) + +Related: #1642460 +--- + src/login/logind-dbus.c | 58 ++++++++-------- + src/login/logind-session.c | 64 ++++++++++-------- + src/login/logind-session.h | 2 +- + src/login/logind-user.c | 134 ++++++++++++++----------------------- + src/login/logind-user.h | 7 +- + src/login/logind.c | 2 +- + src/login/logind.h | 2 +- + 7 files changed, 123 insertions(+), 146 deletions(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 4b2c418453..7eba617fff 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -847,7 +847,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + if (r < 0) + goto fail; + +- r = session_start(session, message); ++ r = session_start(session, message, error); + if (r < 0) + goto fail; + +@@ -3110,24 +3110,20 @@ const sd_bus_vtable manager_vtable[] = { + }; + + static int session_jobs_reply(Session *s, const char *unit, const char *result) { +- int r = 0; +- + assert(s); + assert(unit); + + if (!s->started) +- return r; ++ return 0; + +- if (streq(result, "done")) +- r = session_send_create_reply(s, NULL); +- else { ++ if (result && !streq(result, "done")) { + _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; + +- sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); +- r = session_send_create_reply(s, &e); ++ sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit '%s' failed with '%s'", unit, result); ++ return session_send_create_reply(s, &e); + } + +- return r; ++ return session_send_create_reply(s, NULL); + } + + int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) { +@@ -3160,30 +3156,29 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err + } + + session = hashmap_get(m->session_units, unit); +- if (session && streq_ptr(path, session->scope_job)) { +- session->scope_job = mfree(session->scope_job); +- session_jobs_reply(session, unit, result); ++ if (session) { ++ if (streq_ptr(path, session->scope_job)) { ++ session->scope_job = mfree(session->scope_job); ++ (void) session_jobs_reply(session, unit, result); ++ ++ session_save(session); ++ user_save(session->user); ++ } + +- session_save(session); +- user_save(session->user); + session_add_to_gc_queue(session); + } + + user = hashmap_get(m->user_units, unit); +- if (user && +- (streq_ptr(path, user->service_job) || +- streq_ptr(path, user->slice_job))) { +- +- if (streq_ptr(path, user->service_job)) ++ if (user) { ++ if (streq_ptr(path, user->service_job)) { + user->service_job = mfree(user->service_job); + +- if (streq_ptr(path, user->slice_job)) +- user->slice_job = mfree(user->slice_job); ++ LIST_FOREACH(sessions_by_user, session, user->sessions) ++ (void) session_jobs_reply(session, unit, NULL /* don't propagate user service failures to the client */); + +- LIST_FOREACH(sessions_by_user, session, user->sessions) +- session_jobs_reply(session, unit, result); ++ user_save(user); ++ } + +- user_save(user); + user_add_to_gc_queue(user); + } + +@@ -3315,13 +3310,14 @@ int manager_start_scope( + pid_t pid, + const char *slice, + const char *description, +- const char *after, +- const char *after2, ++ char **wants, ++ char **after, + sd_bus_message *more_properties, + sd_bus_error *error, + char **job) { + + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; ++ char **i; + int r; + + assert(manager); +@@ -3359,14 +3355,14 @@ int manager_start_scope( + return r; + } + +- if (!isempty(after)) { +- r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after); ++ STRV_FOREACH(i, wants) { ++ r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i); + if (r < 0) + return r; + } + +- if (!isempty(after2)) { +- r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2); ++ STRV_FOREACH(i, after) { ++ r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i); + if (r < 0) + return r; + } +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 960a24d1a7..d56b48a732 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -27,6 +27,7 @@ + #include "path-util.h" + #include "process-util.h" + #include "string-table.h" ++#include "strv.h" + #include "terminal-util.h" + #include "user-util.h" + #include "util.h" +@@ -560,17 +561,18 @@ int session_activate(Session *s) { + return 0; + } + +-static int session_start_scope(Session *s, sd_bus_message *properties) { ++static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_error *error) { + int r; + + assert(s); + assert(s->user); + + if (!s->scope) { +- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- char *scope, *job = NULL; ++ _cleanup_free_ char *scope = NULL; + const char *description; + ++ s->scope_job = mfree(s->scope_job); ++ + scope = strjoin("session-", s->id, ".scope"); + if (!scope) + return log_oom(); +@@ -583,21 +585,15 @@ static int session_start_scope(Session *s, sd_bus_message *properties) { + s->leader, + s->user->slice, + description, +- "systemd-logind.service", +- "systemd-user-sessions.service", ++ STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */ ++ STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */ + properties, +- &error, +- &job); +- if (r < 0) { +- log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(&error, r)); +- free(scope); +- return r; +- } else { +- s->scope = scope; ++ error, ++ &s->scope_job); ++ if (r < 0) ++ return log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(error, r)); + +- free(s->scope_job); +- s->scope_job = job; +- } ++ s->scope = TAKE_PTR(scope); + } + + if (s->scope) +@@ -606,7 +602,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties) { + return 0; + } + +-int session_start(Session *s, sd_bus_message *properties) { ++int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) { + int r; + + assert(s); +@@ -614,6 +610,9 @@ int session_start(Session *s, sd_bus_message *properties) { + if (!s->user) + return -ESTALE; + ++ if (s->stopping) ++ return -EINVAL; ++ + if (s->started) + return 0; + +@@ -621,8 +620,7 @@ int session_start(Session *s, sd_bus_message *properties) { + if (r < 0) + return r; + +- /* Create cgroup */ +- r = session_start_scope(s, properties); ++ r = session_start_scope(s, properties, error); + if (r < 0) + return r; + +@@ -673,21 +671,24 @@ static int session_stop_scope(Session *s, bool force) { + * that is left in the scope is "left-over". Informing systemd about this has the benefit that it will log + * when killing any processes left after this point. */ + r = manager_abandon_scope(s->manager, s->scope, &error); +- if (r < 0) ++ if (r < 0) { + log_warning_errno(r, "Failed to abandon session scope, ignoring: %s", bus_error_message(&error, r)); ++ sd_bus_error_free(&error); ++ } ++ ++ s->scope_job = mfree(s->scope_job); + + /* Optionally, let's kill everything that's left now. */ + if (force || manager_shall_kill(s->manager, s->user->name)) { +- char *job = NULL; + +- r = manager_stop_unit(s->manager, s->scope, &error, &job); +- if (r < 0) +- return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r)); ++ r = manager_stop_unit(s->manager, s->scope, &error, &s->scope_job); ++ if (r < 0) { ++ if (force) ++ return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r)); + +- free(s->scope_job); +- s->scope_job = job; ++ log_warning_errno(r, "Failed to stop session scope, ignoring: %s", bus_error_message(&error, r)); ++ } + } else { +- s->scope_job = mfree(s->scope_job); + + /* With no killing, this session is allowed to persist in "closing" state indefinitely. + * Therefore session stop and session removal may be two distinct events. +@@ -707,8 +708,17 @@ int session_stop(Session *s, bool force) { + + assert(s); + ++ /* This is called whenever we begin with tearing down a session record. It's called in four cases: explicit API ++ * request via the bus (either directly for the session object or for the seat or user object this session ++ * belongs to; 'force' is true), or due to automatic GC (i.e. scope vanished; 'force' is false), or because the ++ * session FIFO saw an EOF ('force' is false), or because the release timer hit ('force' is false). */ ++ + if (!s->user) + return -ESTALE; ++ if (!s->started) ++ return 0; ++ if (s->stopping) ++ return 0; + + s->timer_event_source = sd_event_source_unref(s->timer_event_source); + +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 572f2545c1..7d17d9a25f 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -124,7 +124,7 @@ void session_set_idle_hint(Session *s, bool b); + int session_get_locked_hint(Session *s); + void session_set_locked_hint(Session *s, bool b); + int session_create_fifo(Session *s); +-int session_start(Session *s, sd_bus_message *properties); ++int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); + int session_stop(Session *s, bool force); + int session_finalize(Session *s); + int session_release(Session *s); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 3e4c99bdbd..39fc76f4dc 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -68,6 +68,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { + if (r < 0) + return r; + ++ r = unit_name_build("user-runtime-dir", lu, ".service", &u->runtime_dir_service); ++ if (r < 0) ++ return r; ++ + r = hashmap_put(m->users, UID_TO_PTR(uid), u); + if (r < 0) + return r; +@@ -80,6 +84,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { + if (r < 0) + return r; + ++ r = hashmap_put(m->user_units, u->runtime_dir_service, u); ++ if (r < 0) ++ return r; ++ + *ret = TAKE_PTR(u); + return 0; + } +@@ -97,15 +105,18 @@ User *user_free(User *u) { + if (u->service) + hashmap_remove_value(u->manager->user_units, u->service, u); + ++ if (u->runtime_dir_service) ++ hashmap_remove_value(u->manager->user_units, u->runtime_dir_service, u); ++ + if (u->slice) + hashmap_remove_value(u->manager->user_units, u->slice, u); + + hashmap_remove_value(u->manager->users, UID_TO_PTR(u->uid), u); + +- u->slice_job = mfree(u->slice_job); + u->service_job = mfree(u->service_job); + + u->service = mfree(u->service); ++ u->runtime_dir_service = mfree(u->runtime_dir_service); + u->slice = mfree(u->slice); + u->runtime_path = mfree(u->runtime_path); + u->state_file = mfree(u->state_file); +@@ -149,9 +160,6 @@ static int user_save_internal(User *u) { + if (u->service_job) + fprintf(f, "SERVICE_JOB=%s\n", u->service_job); + +- if (u->slice_job) +- fprintf(f, "SLICE_JOB=%s\n", u->slice_job); +- + if (u->display) + fprintf(f, "DISPLAY=%s\n", u->display->id); + +@@ -311,66 +319,46 @@ int user_load(User *u) { + return 0; + } + +-static int user_start_service(User *u) { ++static void user_start_service(User *u) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- char *job; + int r; + + assert(u); + ++ /* Start the service containing the "systemd --user" instance (user@.service). Note that we don't explicitly ++ * start the per-user slice or the systemd-runtime-dir@.service instance, as those are pulled in both by ++ * user@.service and the session scopes as dependencies. */ ++ + u->service_job = mfree(u->service_job); + +- r = manager_start_unit( +- u->manager, +- u->service, +- &error, +- &job); ++ r = manager_start_unit(u->manager, u->service, &error, &u->service_job); + if (r < 0) + /* we don't fail due to this, let's try to continue */ + log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_UNIT_MASKED) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to start user service '%s', ignoring: %s", u->service, bus_error_message(&error, r)); +- else +- u->service_job = job; +- +- return 0; + } + + int user_start(User *u) { +- int r; +- + assert(u); + + if (u->started && !u->stopping) + return 0; + +- /* +- * If u->stopping is set, the user is marked for removal and the slice +- * and service stop-jobs are queued. We have to clear that flag before +- * queing the start-jobs again. If they succeed, the user object can be +- * re-used just fine (pid1 takes care of job-ordering and proper +- * restart), but if they fail, we want to force another user_stop() so +- * possibly pending units are stopped. +- * Note that we don't clear u->started, as we have no clue what state +- * the user is in on failure here. Hence, we pretend the user is +- * running so it will be properly taken down by GC. However, we clearly +- * return an error from user_start() in that case, so no further +- * reference to the user is taken. +- */ ++ /* If u->stopping is set, the user is marked for removal and service stop-jobs are queued. We have to clear ++ * that flag before queing the start-jobs again. If they succeed, the user object can be re-used just fine ++ * (pid1 takes care of job-ordering and proper restart), but if they fail, we want to force another user_stop() ++ * so possibly pending units are stopped. */ + u->stopping = false; + + if (!u->started) + log_debug("Starting services for new user %s.", u->name); + +- /* Save the user data so far, because pam_systemd will read the +- * XDG_RUNTIME_DIR out of it while starting up systemd --user. +- * We need to do user_save_internal() because we have not +- * "officially" started yet. */ ++ /* Save the user data so far, because pam_systemd will read the XDG_RUNTIME_DIR out of it while starting up ++ * systemd --user. We need to do user_save_internal() because we have not "officially" started yet. */ + user_save_internal(u); + +- /* Spawn user systemd */ +- r = user_start_service(u); +- if (r < 0) +- return r; ++ /* Start user@UID.service */ ++ user_start_service(u); + + if (!u->started) { + if (!dual_timestamp_is_set(&u->timestamp)) +@@ -385,68 +373,50 @@ int user_start(User *u) { + return 0; + } + +-static int user_stop_slice(User *u) { ++static void user_stop_service(User *u) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- char *job; + int r; + + assert(u); ++ assert(u->service); + +- r = manager_stop_unit(u->manager, u->slice, &error, &job); +- if (r < 0) { +- log_error("Failed to stop user slice: %s", bus_error_message(&error, r)); +- return r; +- } ++ /* The reverse of user_start_service(). Note that we only stop user@UID.service here, and let StopWhenUnneeded= ++ * deal with the slice and the user-runtime-dir@.service instance. */ + +- free(u->slice_job); +- u->slice_job = job; +- +- return r; +-} +- +-static int user_stop_service(User *u) { +- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- char *job; +- int r; +- +- assert(u); +- +- r = manager_stop_unit(u->manager, u->service, &error, &job); +- if (r < 0) { +- log_error("Failed to stop user service: %s", bus_error_message(&error, r)); +- return r; +- } ++ u->service_job = mfree(u->service_job); + +- free_and_replace(u->service_job, job); +- return r; ++ r = manager_stop_unit(u->manager, u->service, &error, &u->service_job); ++ if (r < 0) ++ log_warning_errno(r, "Failed to stop user service '%s', ignoring: %s", u->service, bus_error_message(&error, r)); + } + + int user_stop(User *u, bool force) { + Session *s; +- int r = 0, k; ++ int r = 0; + assert(u); + +- /* Stop jobs have already been queued */ +- if (u->stopping) { ++ /* This is called whenever we begin with tearing down a user record. It's called in two cases: explicit API ++ * request to do so via the bus (in which case 'force' is true) and automatically due to GC, if there's no ++ * session left pinning it (in which case 'force' is false). Note that this just initiates tearing down of the ++ * user, the User object will remain in memory until user_finalize() is called, see below. */ ++ ++ if (!u->started) ++ return 0; ++ ++ if (u->stopping) { /* Stop jobs have already been queued */ + user_save(u); +- return r; ++ return 0; + } + + LIST_FOREACH(sessions_by_user, s, u->sessions) { ++ int k; ++ + k = session_stop(s, force); + if (k < 0) + r = k; + } + +- /* Kill systemd */ +- k = user_stop_service(u); +- if (k < 0) +- r = k; +- +- /* Kill cgroup */ +- k = user_stop_slice(u); +- if (k < 0) +- r = k; ++ user_stop_service(u); + + u->stopping = true; + +@@ -461,6 +431,9 @@ int user_finalize(User *u) { + + assert(u); + ++ /* Called when the user is really ready to be freed, i.e. when all unit stop jobs and suchlike for it are ++ * done. This is called as a result of an earlier user_done() when all jobs are completed. */ ++ + if (u->started) + log_debug("User %s logged out.", u->name); + +@@ -554,9 +527,6 @@ bool user_may_gc(User *u, bool drop_not_started) { + if (user_check_linger_file(u) > 0) + return false; + +- if (u->slice_job && manager_job_is_active(u->manager, u->slice_job)) +- return false; +- + if (u->service_job && manager_job_is_active(u->manager, u->service_job)) + return false; + +@@ -581,7 +551,7 @@ UserState user_get_state(User *u) { + if (u->stopping) + return USER_CLOSING; + +- if (!u->started || u->slice_job || u->service_job) ++ if (!u->started || u->service_job) + return USER_OPENING; + + if (u->sessions) { +diff --git a/src/login/logind-user.h b/src/login/logind-user.h +index 03e020b870..5e1f7b813a 100644 +--- a/src/login/logind-user.h ++++ b/src/login/logind-user.h +@@ -25,11 +25,12 @@ struct User { + char *name; + char *state_file; + char *runtime_path; +- char *slice; +- char *service; ++ ++ char *slice; /* user-UID.slice */ ++ char *service; /* user@UID.service */ ++ char *runtime_dir_service; /* user-runtime-dir@UID.service */ + + char *service_job; +- char *slice_job; + + Session *display; + +diff --git a/src/login/logind.c b/src/login/logind.c +index 1b366cd55f..6c208c8e89 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -1158,7 +1158,7 @@ static int manager_startup(Manager *m) { + user_start(user); + + HASHMAP_FOREACH(session, m->sessions, i) +- session_start(session, NULL); ++ (void) session_start(session, NULL, NULL); + + HASHMAP_FOREACH(inhibitor, m->inhibitors, i) + inhibitor_start(inhibitor); +diff --git a/src/login/logind.h b/src/login/logind.h +index a6ebc9e152..ae4d74076b 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -161,7 +161,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name + + int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_; + +-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *after2, sd_bus_message *more_properties, sd_bus_error *error, char **job); ++int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, sd_bus_message *more_properties, sd_bus_error *error, char **job); + int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job); + int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job); + int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error); diff --git a/SOURCES/0631-logind-optionally-keep-the-user-.service-instance-fo.patch b/SOURCES/0631-logind-optionally-keep-the-user-.service-instance-fo.patch new file mode 100644 index 0000000..63f6a56 --- /dev/null +++ b/SOURCES/0631-logind-optionally-keep-the-user-.service-instance-fo.patch @@ -0,0 +1,291 @@ +From 35455408393cb29a5e49fd769c4823b6a6f886b4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 7 Aug 2018 11:02:00 +0200 +Subject: [PATCH] logind: optionally, keep the user@.service instance for + eached logged in user around for a while + +This should speed up rapid logout/login cycles a bit. + +By default this timeout is now set to 10s. + +Fixes: #8410 +Replaces: #4434 +(cherry picked from commit 9afe9efb9340588db553950727a2a9672dc3db24) + +Resolves: #1642460 +--- + man/logind.conf.xml | 11 +++++ + src/login/logind-core.c | 2 + + src/login/logind-dbus.c | 1 + + src/login/logind-gperf.gperf | 1 + + src/login/logind-session.c | 4 ++ + src/login/logind-user.c | 88 +++++++++++++++++++++++++++++++++--- + src/login/logind-user.h | 7 ++- + src/login/logind.h | 1 + + 8 files changed, 107 insertions(+), 8 deletions(-) + +diff --git a/man/logind.conf.xml b/man/logind.conf.xml +index 7d7e869a26..0cf8a7d1f2 100644 +--- a/man/logind.conf.xml ++++ b/man/logind.conf.xml +@@ -184,6 +184,17 @@ + 5. + + ++ ++ UserStopDelaySec= ++ ++ Specifies how long to keep the user record and per-user service ++ user@.service around for a user after they logged out fully. If set to zero, the per-user ++ service is terminated immediately when the last session of the user has ended. If this option is configured to ++ non-zero rapid logout/login cycles are sped up, as the user's service manager is not constantly restarted. If ++ set to infinity the per-user service for a user is never terminated again after first login, ++ and continues to run until system shutdown. Defaults to 10s. ++ ++ + + HandlePowerKey= + HandleSuspendKey= +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index f598bbaa1c..678c708df1 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -27,6 +27,8 @@ void manager_reset_config(Manager *m) { + m->reserve_vt = 6; + m->remove_ipc = false; + m->inhibit_delay_max = 5 * USEC_PER_SEC; ++ m->user_stop_delay = 10 * USEC_PER_SEC; ++ + m->handle_power_key = HANDLE_POWEROFF; + m->handle_suspend_key = HANDLE_SUSPEND; + m->handle_hibernate_key = HANDLE_HIBERNATE; +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 7eba617fff..6586280269 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -2695,6 +2695,7 @@ const sd_bus_vtable manager_vtable[] = { + SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("UserStopDelayUSec", "t", NULL, offsetof(Manager, user_stop_delay), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST), +diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf +index c85339dcd3..8829ce7d85 100644 +--- a/src/login/logind-gperf.gperf ++++ b/src/login/logind-gperf.gperf +@@ -23,6 +23,7 @@ Login.KillUserProcesses, config_parse_bool, 0, offse + Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users) + Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users) + Login.InhibitDelayMaxSec, config_parse_sec, 0, offsetof(Manager, inhibit_delay_max) ++Login.UserStopDelaySec, config_parse_sec, 0, offsetof(Manager, user_stop_delay) + Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key) + Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key) + Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key) +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index d56b48a732..dd4ac9482a 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -101,6 +101,8 @@ Session* session_free(Session *s) { + + if (s->user->display == s) + s->user->display = NULL; ++ ++ user_update_last_session_timer(s->user); + } + + if (s->seat) { +@@ -142,6 +144,8 @@ void session_set_user(Session *s, User *u) { + + s->user = u; + LIST_PREPEND(sessions_by_user, u->sessions, s); ++ ++ user_update_last_session_timer(u); + } + + static void session_save_devices(Session *s, FILE *f) { +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 39fc76f4dc..f23fcbe674 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -47,6 +47,7 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { + .manager = m, + .uid = uid, + .gid = gid, ++ .last_session_timestamp = USEC_INFINITY, + }; + + u->name = strdup(name); +@@ -113,6 +114,8 @@ User *user_free(User *u) { + + hashmap_remove_value(u->manager->users, UID_TO_PTR(u->uid), u); + ++ (void) sd_event_source_unref(u->timer_event_source); ++ + u->service_job = mfree(u->service_job); + + u->service = mfree(u->service); +@@ -170,6 +173,10 @@ static int user_save_internal(User *u) { + u->timestamp.realtime, + u->timestamp.monotonic); + ++ if (u->last_session_timestamp != USEC_INFINITY) ++ fprintf(f, "LAST_SESSION_TIMESTAMP=" USEC_FMT "\n", ++ u->last_session_timestamp); ++ + if (u->sessions) { + Session *i; + bool first; +@@ -287,16 +294,17 @@ int user_save(User *u) { + } + + int user_load(User *u) { +- _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL; ++ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL, *last_session_timestamp = NULL; + int r; + + assert(u); + + r = parse_env_file(NULL, u->state_file, NEWLINE, +- "SERVICE_JOB", &u->service_job, +- "STOPPING", &stopping, +- "REALTIME", &realtime, +- "MONOTONIC", &monotonic, ++ "SERVICE_JOB", &u->service_job, ++ "STOPPING", &stopping, ++ "REALTIME", &realtime, ++ "MONOTONIC", &monotonic, ++ "LAST_SESSION_TIMESTAMP", &last_session_timestamp, + NULL); + if (r == -ENOENT) + return 0; +@@ -312,9 +320,11 @@ int user_load(User *u) { + } + + if (realtime) +- timestamp_deserialize(realtime, &u->timestamp.realtime); ++ (void) timestamp_deserialize(realtime, &u->timestamp.realtime); + if (monotonic) +- timestamp_deserialize(monotonic, &u->timestamp.monotonic); ++ (void) timestamp_deserialize(monotonic, &u->timestamp.monotonic); ++ if (last_session_timestamp) ++ (void) timestamp_deserialize(last_session_timestamp, &u->last_session_timestamp); + + return 0; + } +@@ -524,6 +534,17 @@ bool user_may_gc(User *u, bool drop_not_started) { + if (u->sessions) + return false; + ++ if (u->last_session_timestamp != USEC_INFINITY) { ++ /* All sessions have been closed. Let's see if we shall leave the user record around for a bit */ ++ ++ if (u->manager->user_stop_delay == USEC_INFINITY) ++ return false; /* Leave it around forever! */ ++ if (u->manager->user_stop_delay > 0 && ++ now(CLOCK_MONOTONIC) < usec_add(u->last_session_timestamp, u->manager->user_stop_delay)) ++ return false; /* Leave it around for a bit longer. */ ++ } ++ ++ /* Is this a user that shall stay around forever? */ + if (user_check_linger_file(u) > 0) + return false; + +@@ -649,6 +670,59 @@ void user_elect_display(User *u) { + } + } + ++static int user_stop_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) { ++ User *u = userdata; ++ ++ assert(u); ++ user_add_to_gc_queue(u); ++ ++ return 0; ++} ++ ++void user_update_last_session_timer(User *u) { ++ int r; ++ ++ assert(u); ++ ++ if (u->sessions) { ++ /* There are sessions, turn off the timer */ ++ u->last_session_timestamp = USEC_INFINITY; ++ u->timer_event_source = sd_event_source_unref(u->timer_event_source); ++ return; ++ } ++ ++ if (u->last_session_timestamp != USEC_INFINITY) ++ return; /* Timer already started */ ++ ++ u->last_session_timestamp = now(CLOCK_MONOTONIC); ++ ++ assert(!u->timer_event_source); ++ ++ if (u->manager->user_stop_delay == 0 || u->manager->user_stop_delay == USEC_INFINITY) ++ return; ++ ++ if (sd_event_get_state(u->manager->event) == SD_EVENT_FINISHED) { ++ log_debug("Not allocating user stop timeout, since we are already exiting."); ++ return; ++ } ++ ++ r = sd_event_add_time(u->manager->event, ++ &u->timer_event_source, ++ CLOCK_MONOTONIC, ++ usec_add(u->last_session_timestamp, u->manager->user_stop_delay), 0, ++ user_stop_timeout_callback, u); ++ if (r < 0) ++ log_warning_errno(r, "Failed to enqueue user stop event source, ignoring: %m"); ++ ++ if (DEBUG_LOGGING) { ++ char s[FORMAT_TIMESPAN_MAX]; ++ ++ log_debug("Last session of user '%s' logged out, terminating user context in %s.", ++ u->name, ++ format_timespan(s, sizeof(s), u->manager->user_stop_delay, USEC_PER_MSEC)); ++ } ++} ++ + static const char* const user_state_table[_USER_STATE_MAX] = { + [USER_OFFLINE] = "offline", + [USER_OPENING] = "opening", +diff --git a/src/login/logind-user.h b/src/login/logind-user.h +index 5e1f7b813a..e05646adc9 100644 +--- a/src/login/logind-user.h ++++ b/src/login/logind-user.h +@@ -34,7 +34,11 @@ struct User { + + Session *display; + +- dual_timestamp timestamp; ++ dual_timestamp timestamp; /* When this User object was 'started' the first time */ ++ usec_t last_session_timestamp; /* When the number of sessions of this user went from 1 to 0 the last time */ ++ ++ /* Set up when the last session of the user logs out */ ++ sd_event_source *timer_event_source; + + bool in_gc_queue:1; + +@@ -62,6 +66,7 @@ int user_load(User *u); + int user_kill(User *u, int signo); + int user_check_linger_file(User *u); + void user_elect_display(User *u); ++void user_update_last_session_timer(User *u); + + extern const sd_bus_vtable user_vtable[]; + int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); +diff --git a/src/login/logind.h b/src/login/logind.h +index ae4d74076b..7288dd7445 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -62,6 +62,7 @@ struct Manager { + Hashmap *user_units; + + usec_t inhibit_delay_max; ++ usec_t user_stop_delay; + + /* If an action is currently being executed or is delayed, + * this is != 0 and encodes what is being done */ diff --git a/SOURCES/0632-logind-add-a-RequiresMountsFor-dependency-from-the-s.patch b/SOURCES/0632-logind-add-a-RequiresMountsFor-dependency-from-the-s.patch new file mode 100644 index 0000000..93f6a2c --- /dev/null +++ b/SOURCES/0632-logind-add-a-RequiresMountsFor-dependency-from-the-s.patch @@ -0,0 +1,210 @@ +From e9a187ea6abf1e7034ee3113355b282743a98f39 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Aug 2018 15:27:49 +0200 +Subject: [PATCH] logind: add a RequiresMountsFor= dependency from the session + scope unit to the home directory of the user + +This is useful so that during shutdown scope units are always terminated +before the mounts necessary for the home directory. + +(Ideally we'd also add a similar dependency from the user@.service +instance to the home directory, but this isn't as easy as that service +is defined statically and not dynamically, and hence not easy to modify +dynamically, in particular when it comes to deps) + +(cherry picked from commit d5ac9d060267820aabdf9af509a54a1830b27b7d) + +Related: #1642460 +--- + src/login/logind-core.c | 24 ++++++++++++++++++------ + src/login/logind-dbus.c | 7 +++++++ + src/login/logind-session.c | 1 + + src/login/logind-user.c | 13 ++++++++++++- + src/login/logind-user.h | 3 ++- + src/login/logind.h | 4 ++-- + 6 files changed, 42 insertions(+), 10 deletions(-) + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index 678c708df1..0ed812a2c8 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -128,7 +128,14 @@ int manager_add_session(Manager *m, const char *id, Session **_session) { + return 0; + } + +-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { ++int manager_add_user( ++ Manager *m, ++ uid_t uid, ++ gid_t gid, ++ const char *name, ++ const char *home, ++ User **_user) { ++ + User *u; + int r; + +@@ -137,7 +144,7 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User ** + + u = hashmap_get(m->users, UID_TO_PTR(uid)); + if (!u) { +- r = user_new(&u, m, uid, gid, name); ++ r = user_new(&u, m, uid, gid, name, home); + if (r < 0) + return r; + } +@@ -148,7 +155,12 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User ** + return 0; + } + +-int manager_add_user_by_name(Manager *m, const char *name, User **_user) { ++int manager_add_user_by_name( ++ Manager *m, ++ const char *name, ++ User **_user) { ++ ++ const char *home = NULL; + uid_t uid; + gid_t gid; + int r; +@@ -156,11 +168,11 @@ int manager_add_user_by_name(Manager *m, const char *name, User **_user) { + assert(m); + assert(name); + +- r = get_user_creds(&name, &uid, &gid, NULL, NULL); ++ r = get_user_creds(&name, &uid, &gid, &home, NULL); + if (r < 0) + return r; + +- return manager_add_user(m, uid, gid, name, _user); ++ return manager_add_user(m, uid, gid, name, home, _user); + } + + int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { +@@ -173,7 +185,7 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { + if (!p) + return errno > 0 ? -errno : -ENOENT; + +- return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user); ++ return manager_add_user(m, uid, p->pw_gid, p->pw_name, p->pw_dir, _user); + } + + int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) { +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 6586280269..1bb152bc20 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -3313,6 +3313,7 @@ int manager_start_scope( + const char *description, + char **wants, + char **after, ++ const char *requires_mounts_for, + sd_bus_message *more_properties, + sd_bus_error *error, + char **job) { +@@ -3368,6 +3369,12 @@ int manager_start_scope( + return r; + } + ++ if (!empty_or_root(requires_mounts_for)) { ++ r = sd_bus_message_append(m, "(sv)", "RequiresMountsFor", "as", 1, requires_mounts_for); ++ if (r < 0) ++ return r; ++ } ++ + /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore + * SIGTERM */ + r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true); +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index dd4ac9482a..e4c8bb36f6 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -591,6 +591,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er + description, + STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */ + STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */ ++ s->user->home, + properties, + error, + &s->scope_job); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index f23fcbe674..70f5eb9d59 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -30,7 +30,13 @@ + #include "user-util.h" + #include "util.h" + +-int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { ++int user_new(User **ret, ++ Manager *m, ++ uid_t uid, ++ gid_t gid, ++ const char *name, ++ const char *home) { ++ + _cleanup_(user_freep) User *u = NULL; + char lu[DECIMAL_STR_MAX(uid_t) + 1]; + int r; +@@ -54,6 +60,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) { + if (!u->name) + return -ENOMEM; + ++ u->home = strdup(home); ++ if (!u->home) ++ return -ENOMEM; ++ + if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0) + return -ENOMEM; + +@@ -124,6 +134,7 @@ User *user_free(User *u) { + u->runtime_path = mfree(u->runtime_path); + u->state_file = mfree(u->state_file); + u->name = mfree(u->name); ++ u->home = mfree(u->home); + + return mfree(u); + } +diff --git a/src/login/logind-user.h b/src/login/logind-user.h +index e05646adc9..c41973e27d 100644 +--- a/src/login/logind-user.h ++++ b/src/login/logind-user.h +@@ -23,6 +23,7 @@ struct User { + uid_t uid; + gid_t gid; + char *name; ++ char *home; + char *state_file; + char *runtime_path; + +@@ -49,7 +50,7 @@ struct User { + LIST_FIELDS(User, gc_queue); + }; + +-int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name); ++int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name, const char *home); + User *user_free(User *u); + + DEFINE_TRIVIAL_CLEANUP_FUNC(User *, user_free); +diff --git a/src/login/logind.h b/src/login/logind.h +index 7288dd7445..d29b01c75b 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -129,7 +129,7 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev + int manager_add_button(Manager *m, const char *name, Button **_button); + int manager_add_seat(Manager *m, const char *id, Seat **_seat); + int manager_add_session(Manager *m, const char *id, Session **_session); +-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user); ++int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, const char *home, User **_user); + int manager_add_user_by_name(Manager *m, const char *name, User **_user); + int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user); + int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor); +@@ -162,7 +162,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name + + int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_; + +-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, sd_bus_message *more_properties, sd_bus_error *error, char **job); ++int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job); + int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job); + int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job); + int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error); diff --git a/SOURCES/0633-logind-improve-error-propagation-of-user_check_linge.patch b/SOURCES/0633-logind-improve-error-propagation-of-user_check_linge.patch new file mode 100644 index 0000000..9552207 --- /dev/null +++ b/SOURCES/0633-logind-improve-error-propagation-of-user_check_linge.patch @@ -0,0 +1,39 @@ +From 117ed6bd7aa71fc79599e1d37bdb4a94b3505a38 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Aug 2018 16:03:11 +0200 +Subject: [PATCH] logind: improve error propagation of user_check_linger_file() + +Let's make this a bit prettier, and propagate unexpected access() errors +correctly. + +(The callers of this function will suppress them, but it's nicer of they +do that, rather than us doing that twice in both the callers and the +callees) + +(cherry picked from commit 6996df9b864981980f5b713dc5c7d506a7a4b9bf) + +Related: #1642460 +--- + src/login/logind-user.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 70f5eb9d59..3fd28fc66c 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -532,8 +532,14 @@ int user_check_linger_file(User *u) { + return -ENOMEM; + + p = strjoina("/var/lib/systemd/linger/", cc); ++ if (access(p, F_OK) < 0) { ++ if (errno != ENOENT) ++ return -errno; + +- return access(p, F_OK) >= 0; ++ return false; ++ } ++ ++ return true; + } + + bool user_may_gc(User *u, bool drop_not_started) { diff --git a/SOURCES/0634-logind-automatically-GC-lingering-users-for-who-now-.patch b/SOURCES/0634-logind-automatically-GC-lingering-users-for-who-now-.patch new file mode 100644 index 0000000..e299007 --- /dev/null +++ b/SOURCES/0634-logind-automatically-GC-lingering-users-for-who-now-.patch @@ -0,0 +1,82 @@ +From 89dd5e016a50da082e51129eecb3c5e04b8f0cf5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Aug 2018 16:04:40 +0200 +Subject: [PATCH] logind: automatically GC lingering users for who now + user@.service (nor slice, not runtime dir service) is running anymore + +This heavily borrows from @intelfx' PR #5546, but watches all three +units that are associated with a user now: the slice, the user@.service +and user-runtime-dir@.service. + +The logic and reasoning behind it is the same though: there's no value +in keeping lingering users around if all their three services are gone. + +Replaces: #5546 +Fixes: #4162 +(cherry picked from commit 4e5b605af202c770dfc8e3562d0f8d0440b2fe14) + +Related: #1642460 +--- + src/login/logind-user.c | 28 +++++++++++++++++++++++++--- + 1 file changed, 25 insertions(+), 3 deletions(-) + +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index 3fd28fc66c..bba3158d1a 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -26,6 +26,7 @@ + #include "special.h" + #include "stdio-util.h" + #include "string-table.h" ++#include "strv.h" + #include "unit-name.h" + #include "user-util.h" + #include "util.h" +@@ -542,6 +543,25 @@ int user_check_linger_file(User *u) { + return true; + } + ++static bool user_unit_active(User *u) { ++ const char *i; ++ int r; ++ ++ assert(u->service); ++ assert(u->runtime_dir_service); ++ assert(u->slice); ++ ++ FOREACH_STRING(i, u->service, u->runtime_dir_service, u->slice) { ++ r = manager_unit_is_active(u->manager, i); ++ if (r < 0) ++ log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring", u->service); ++ if (r != 0) ++ return true; ++ } ++ ++ return false; ++} ++ + bool user_may_gc(User *u, bool drop_not_started) { + assert(u); + +@@ -561,8 +581,10 @@ bool user_may_gc(User *u, bool drop_not_started) { + return false; /* Leave it around for a bit longer. */ + } + +- /* Is this a user that shall stay around forever? */ +- if (user_check_linger_file(u) > 0) ++ /* Is this a user that shall stay around forever ("linger")? Before we say "no" to GC'ing for lingering users, let's check ++ * if any of the three units that we maintain for this user is still around. If none of them is, ++ * there's no need to keep this user around even if lingering is enabled. */ ++ if (user_check_linger_file(u) > 0 && user_unit_active(u)) + return false; + + if (u->service_job && manager_job_is_active(u->manager, u->service_job)) +@@ -608,7 +630,7 @@ UserState user_get_state(User *u) { + return all_closing ? USER_CLOSING : USER_ONLINE; + } + +- if (user_check_linger_file(u) > 0) ++ if (user_check_linger_file(u) > 0 && user_unit_active(u)) + return USER_LINGERING; + + return USER_CLOSING; diff --git a/SOURCES/0635-pam_systemd-simplify-code-which-with-we-set-environm.patch b/SOURCES/0635-pam_systemd-simplify-code-which-with-we-set-environm.patch new file mode 100644 index 0000000..9eaff4c --- /dev/null +++ b/SOURCES/0635-pam_systemd-simplify-code-which-with-we-set-environm.patch @@ -0,0 +1,101 @@ +From 96887ddecd1e4c36d8a32411ed515ddaf0f3a0e3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 20 Jul 2018 11:27:55 +0200 +Subject: [PATCH] pam_systemd: simplify code which with we set environment + variables + +Let's shorten things a bit by splitting out common code in a new +function. + +(cherry picked from commit d6baaa6978d3eb5b8e8497021c4ba576aee936a3) + +Related: #1642460 +--- + src/login/pam_systemd.c | 46 ++++++++++++++++++++++++----------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index 78ddb7d398..b2b62540bb 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -301,6 +301,24 @@ static const char* getenv_harder(pam_handle_t *handle, const char *key, const ch + return fallback; + } + ++static int update_environment(pam_handle_t *handle, const char *key, const char *value) { ++ int r; ++ ++ assert(handle); ++ assert(key); ++ ++ /* Updates the environment, but only if there's actually a value set. Also, log about errors */ ++ ++ if (isempty(value)) ++ return PAM_SUCCESS; ++ ++ r = pam_misc_setenv(handle, key, value, 0); ++ if (r != PAM_SUCCESS) ++ pam_syslog(handle, LOG_ERR, "Failed to set environment variable %s.", key); ++ ++ return r; ++} ++ + _public_ PAM_EXTERN int pam_sm_open_session( + pam_handle_t *handle, + int flags, +@@ -555,11 +573,9 @@ _public_ PAM_EXTERN int pam_sm_open_session( + "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u original_uid=%u", + id, object_path, runtime_path, session_fd, seat, vtnr, original_uid); + +- r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set session id."); ++ r = update_environment(handle, "XDG_SESSION_ID", id); ++ if (r != PAM_SUCCESS) + return r; +- } + + if (original_uid == pw->pw_uid) { + /* Don't set $XDG_RUNTIME_DIR if the user we now +@@ -568,34 +584,26 @@ _public_ PAM_EXTERN int pam_sm_open_session( + * in privileged apps clobbering the runtime directory + * unnecessarily. */ + +- r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); ++ r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path); ++ if (r != PAM_SUCCESS) + return r; +- } + + r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path); + if (r != PAM_SUCCESS) + return r; + } + +- if (!isempty(seat)) { +- r = pam_misc_setenv(handle, "XDG_SEAT", seat, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set seat."); +- return r; +- } +- } ++ r = update_environment(handle, "XDG_SEAT", seat); ++ if (r != PAM_SUCCESS) ++ return r; + + if (vtnr > 0) { + char buf[DECIMAL_STR_MAX(vtnr)]; + sprintf(buf, "%u", vtnr); + +- r = pam_misc_setenv(handle, "XDG_VTNR", buf, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set virtual terminal number."); ++ r = update_environment(handle, "XDG_VTNR", buf); ++ if (r != PAM_SUCCESS) + return r; +- } + } + + r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL); diff --git a/SOURCES/0636-logind-validate-run-user-1000-before-we-set-it.patch b/SOURCES/0636-logind-validate-run-user-1000-before-we-set-it.patch new file mode 100644 index 0000000..e485042 --- /dev/null +++ b/SOURCES/0636-logind-validate-run-user-1000-before-we-set-it.patch @@ -0,0 +1,89 @@ +From c8b74ac5cf508c7bcec92d197880043af1d2bad7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 22:23:41 +0200 +Subject: [PATCH] logind: validate /run/user/1000 before we set it + +Let's be safe than sorry, in particular as logind doesn't set it up +anymore, but user-runtime-dir@.service does, and logind doesn't really +track success of that. + +(cherry picked from commit b92171124819305985ed292cc472f6668a027425) + +Related: #1642460 +--- + src/login/pam_systemd.c | 48 +++++++++++++++++++++++++++++++++++------ + 1 file changed, 41 insertions(+), 7 deletions(-) + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index b2b62540bb..64e1b4d1bf 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -319,6 +319,36 @@ static int update_environment(pam_handle_t *handle, const char *key, const char + return r; + } + ++static bool validate_runtime_directory(pam_handle_t *handle, const char *path, uid_t uid) { ++ struct stat st; ++ ++ assert(path); ++ ++ /* Just some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually set ++ * up properly for us. */ ++ ++ if (lstat(path, &st) < 0) { ++ pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror(errno)); ++ goto fail; ++ } ++ ++ if (!S_ISDIR(st.st_mode)) { ++ pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path); ++ goto fail; ++ } ++ ++ if (st.st_uid != uid) { ++ pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid); ++ goto fail; ++ } ++ ++ return true; ++ ++fail: ++ pam_syslog(handle, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order."); ++ return false; ++} ++ + _public_ PAM_EXTERN int pam_sm_open_session( + pam_handle_t *handle, + int flags, +@@ -377,10 +407,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( + if (asprintf(&rt, "/run/user/"UID_FMT, pw->pw_uid) < 0) + return PAM_BUF_ERR; + +- r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); +- return r; ++ if (validate_runtime_directory(handle, rt, pw->pw_uid)) { ++ r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); ++ if (r != PAM_SUCCESS) { ++ pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); ++ return r; ++ } + } + + r = export_legacy_dbus_address(handle, pw->pw_uid, rt); +@@ -584,9 +616,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( + * in privileged apps clobbering the runtime directory + * unnecessarily. */ + +- r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path); +- if (r != PAM_SUCCESS) +- return r; ++ if (validate_runtime_directory(handle, runtime_path, pw->pw_uid)) { ++ r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path); ++ if (r != PAM_SUCCESS) ++ return r; ++ } + + r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path); + if (r != PAM_SUCCESS) diff --git a/SOURCES/0637-sd-hwdb-allow-empty-properties.patch b/SOURCES/0637-sd-hwdb-allow-empty-properties.patch new file mode 100644 index 0000000..57a0575 --- /dev/null +++ b/SOURCES/0637-sd-hwdb-allow-empty-properties.patch @@ -0,0 +1,33 @@ +From 2ab6e6ae9853e410310268efc0cea7f2276979ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 20 Oct 2020 17:12:42 +0200 +Subject: [PATCH] sd-hwdb: allow empty properties + +So far we didn't allow empty properties, but it makes sense to do so, for +example to distinguish empty data from lack of data. It also makes it easy to +override properties (back to the empty) value for specific cases. + +(cherry picked from commit afe87974dd57741f74dd87165b251886f24c859f) + +Related: #2005009 +--- + src/hwdb/hwdb.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c +index 317cad8a67..af085cdb75 100644 +--- a/src/hwdb/hwdb.c ++++ b/src/hwdb/hwdb.c +@@ -462,10 +462,9 @@ static int insert_data(struct trie *trie, char **match_list, char *line, + while (isblank(line[0]) && isblank(line[1])) + line++; + +- if (isempty(line + 1) || isempty(value)) ++ if (isempty(line + 1)) + return log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL, +- "Empty %s in \"%s=%s\", ignoring", +- isempty(line + 1) ? "key" : "value", ++ "Empty key in \"%s=%s\", ignoring", + line, value); + + STRV_FOREACH(entry, match_list) diff --git a/SOURCES/0638-Update-hwdb.patch b/SOURCES/0638-Update-hwdb.patch new file mode 100644 index 0000000..f189fab --- /dev/null +++ b/SOURCES/0638-Update-hwdb.patch @@ -0,0 +1,104589 @@ +From 793dc4d9e32baba27eac1f37283a7485b0889803 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 19 Aug 2021 12:31:36 +0200 +Subject: [PATCH] Update hwdb + +Resolves: #2005009 +--- + hwdb/20-OUI.hwdb | 26574 +++++++++++++++++- + hwdb/20-acpi-vendor.hwdb | 257 +- + hwdb/20-bluetooth-vendor-product.hwdb | 3691 ++- + hwdb/20-dmi-id.hwdb | 6 + + hwdb/20-pci-classes.hwdb | 15 + + hwdb/20-pci-vendor-model.hwdb | 12830 ++++++++- + hwdb/20-sdio-classes.hwdb | 4 +- + hwdb/20-sdio-vendor-model.hwdb | 5 +- + hwdb/20-usb-vendor-model.hwdb | 11834 +++++++- + hwdb/60-autosuspend-fingerprint-reader.hwdb | 300 + + hwdb/60-autosuspend.hwdb | 71 + + hwdb/60-evdev.hwdb | 345 +- + hwdb/60-input-id.hwdb | 40 +- + hwdb/60-keyboard.hwdb | 981 +- + hwdb/60-seat.hwdb | 36 + + hwdb/60-sensor.hwdb | 648 +- + hwdb/70-mouse.hwdb | 593 +- + hwdb/70-pointingstick.hwdb | 36 +- + hwdb/70-touchpad.hwdb | 21 +- + hwdb/80-ieee1394-unit-function.hwdb | 1359 + + hwdb/meson.build | 5 + + 21 files changed, 57400 insertions(+), 2251 deletions(-) + create mode 100644 hwdb/20-dmi-id.hwdb + create mode 100644 hwdb/60-autosuspend-fingerprint-reader.hwdb + create mode 100644 hwdb/60-autosuspend.hwdb + create mode 100644 hwdb/60-seat.hwdb + create mode 100644 hwdb/80-ieee1394-unit-function.hwdb + +diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb +index 1f24cd6016..5befc978e0 100644 +--- a/hwdb/20-OUI.hwdb ++++ b/hwdb/20-OUI.hwdb +@@ -234,7 +234,7 @@ OUI:00004B* + ID_OUI_FROM_DATABASE=ICL DATA OY + + OUI:00004C* +- ID_OUI_FROM_DATABASE=NEC CORPORATION ++ ID_OUI_FROM_DATABASE=NEC Corporation + + OUI:00004D* + ID_OUI_FROM_DATABASE=DCI CORPORATION +@@ -291,10 +291,10 @@ OUI:00005E* + ID_OUI_FROM_DATABASE=ICANN, IANA Department + + OUI:00005F* +- ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd + + OUI:000060* +- ID_OUI_FROM_DATABASE=KONTRON ELEKTRONIK GMBH ++ ID_OUI_FROM_DATABASE=Kontron Europe GmbH + + OUI:000061* + ID_OUI_FROM_DATABASE=GATEWAY COMMUNICATIONS +@@ -327,7 +327,7 @@ OUI:00006A* + ID_OUI_FROM_DATABASE=COMPUTER CONSOLES INC. + + OUI:00006B* +- ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC./MIPS ++ ID_OUI_FROM_DATABASE=Silicon Graphics + + OUI:00006C* + ID_OUI_FROM_DATABASE=Private +@@ -414,7 +414,7 @@ OUI:000087* + ID_OUI_FROM_DATABASE=HITACHI, LTD. + + OUI:000088* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:000089* + ID_OUI_FROM_DATABASE=CAYMAN SYSTEMS INC. +@@ -573,7 +573,7 @@ OUI:0000BC* + ID_OUI_FROM_DATABASE=Rockwell Automation + + OUI:0000BD* +- ID_OUI_FROM_DATABASE=MITSUBISHI CABLE COMPANY ++ ID_OUI_FROM_DATABASE=Mitsubishi Cable Industries, Ltd. / Ryosei Systems + + OUI:0000BE* + ID_OUI_FROM_DATABASE=THE NTI GROUP +@@ -819,7 +819,7 @@ OUI:00010E* + ID_OUI_FROM_DATABASE=Bri-Link Technologies Co., Ltd + + OUI:00010F* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:000110* + ID_OUI_FROM_DATABASE=Gotham Networks +@@ -2130,7 +2130,7 @@ OUI:0002C3* + ID_OUI_FROM_DATABASE=Arelnet Ltd. + + OUI:0002C4* +- ID_OUI_FROM_DATABASE=Vector International BVBA ++ ID_OUI_FROM_DATABASE=OPT Machine Vision Tech Co., Ltd + + OUI:0002C5* + ID_OUI_FROM_DATABASE=Evertz Microsystems Ltd. +@@ -2139,7 +2139,7 @@ OUI:0002C6* + ID_OUI_FROM_DATABASE=Data Track Technology PLC + + OUI:0002C7* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0002C8* + ID_OUI_FROM_DATABASE=Technocom Communications Technology (pte) Ltd +@@ -2364,7 +2364,7 @@ OUI:000311* + ID_OUI_FROM_DATABASE=Micro Technology Co., Ltd. + + OUI:000312* +- ID_OUI_FROM_DATABASE=TR-Systemtechnik GmbH ++ ID_OUI_FROM_DATABASE=TRsystems GmbH + + OUI:000313* + ID_OUI_FROM_DATABASE=Access Media SPA +@@ -2418,7 +2418,7 @@ OUI:000323* + ID_OUI_FROM_DATABASE=Cornet Technology, Inc. + + OUI:000324* +- ID_OUI_FROM_DATABASE=SANYO Consumer Electronics Co., Ltd. ++ ID_OUI_FROM_DATABASE=SANYO Techno Solutions Tottori Co., Ltd. + + OUI:000325* + ID_OUI_FROM_DATABASE=Arima Computer Corp. +@@ -2466,7 +2466,7 @@ OUI:000333* + ID_OUI_FROM_DATABASE=Digitel Co., Ltd. + + OUI:000334* +- ID_OUI_FROM_DATABASE=Newport Electronics ++ ID_OUI_FROM_DATABASE=Omega Engineering Inc. + + OUI:000335* + ID_OUI_FROM_DATABASE=Mirae Technology +@@ -2919,7 +2919,7 @@ OUI:0003CA* + ID_OUI_FROM_DATABASE=MTS Systems Corp. + + OUI:0003CB* +- ID_OUI_FROM_DATABASE=Nippon Systems Development Co., Ltd. ++ ID_OUI_FROM_DATABASE=SystemGear Co., Ltd. + + OUI:0003CC* + ID_OUI_FROM_DATABASE=Momentum Computer, Inc. +@@ -3006,7 +3006,7 @@ OUI:0003E7* + ID_OUI_FROM_DATABASE=Logostek Co. Ltd. + + OUI:0003E8* +- ID_OUI_FROM_DATABASE=Wavelength Digital Limited ++ ID_OUI_FROM_DATABASE=Wavesight Limited + + OUI:0003E9* + ID_OUI_FROM_DATABASE=Akara Canada, Inc. +@@ -3453,7 +3453,7 @@ OUI:00047C* + ID_OUI_FROM_DATABASE=Skidata AG + + OUI:00047D* +- ID_OUI_FROM_DATABASE=Pelco ++ ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + + OUI:00047E* + ID_OUI_FROM_DATABASE=Siqura B.V. +@@ -3462,7 +3462,7 @@ OUI:00047F* + ID_OUI_FROM_DATABASE=Chr. Mayr GmbH & Co. KG + + OUI:000480* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:000481* + ID_OUI_FROM_DATABASE=Econolite Control Products, Inc. +@@ -3591,7 +3591,7 @@ OUI:0004AA* + ID_OUI_FROM_DATABASE=Jetstream Communications + + OUI:0004AB* +- ID_OUI_FROM_DATABASE=Comverse Network Systems, Inc. ++ ID_OUI_FROM_DATABASE=Mavenir Inc. + + OUI:0004AC* + ID_OUI_FROM_DATABASE=IBM Corp +@@ -3666,7 +3666,7 @@ OUI:0004C3* + ID_OUI_FROM_DATABASE=CASTOR Informatique + + OUI:0004C4* +- ID_OUI_FROM_DATABASE=Allen & Heath Limited ++ ID_OUI_FROM_DATABASE=Audiotonix Group Limited + + OUI:0004C5* + ID_OUI_FROM_DATABASE=ASE Technologies, USA +@@ -3747,7 +3747,7 @@ OUI:0004DE* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0004DF* +- ID_OUI_FROM_DATABASE=Teracom Telematica Ltda. ++ ID_OUI_FROM_DATABASE=TERACOM TELEMATICA S.A + + OUI:0004E0* + ID_OUI_FROM_DATABASE=Procket Networks +@@ -3936,7 +3936,7 @@ OUI:00051D* + ID_OUI_FROM_DATABASE=Airocon, Inc. + + OUI:00051E* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:00051F* + ID_OUI_FROM_DATABASE=Taijin Media Co., Ltd. +@@ -3999,7 +3999,7 @@ OUI:000532* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:000533* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:000534* + ID_OUI_FROM_DATABASE=Northstar Engineering Ltd. +@@ -4449,7 +4449,7 @@ OUI:0005C8* + ID_OUI_FROM_DATABASE=VERYTECH + + OUI:0005C9* +- ID_OUI_FROM_DATABASE=LG Innotek Co., Ltd. ++ ID_OUI_FROM_DATABASE=LG Innotek + + OUI:0005CA* + ID_OUI_FROM_DATABASE=Hitron Technology, Inc. +@@ -5349,13 +5349,13 @@ OUI:0006F4* + ID_OUI_FROM_DATABASE=Prime Electronics & Satellitics Inc. + + OUI:0006F5* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0006F6* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0006F7* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0006F8* + ID_OUI_FROM_DATABASE=The Boeing Company +@@ -5388,13 +5388,13 @@ OUI:000701* + ID_OUI_FROM_DATABASE=RACAL-DATACOM + + OUI:000702* +- ID_OUI_FROM_DATABASE=Varian Medical Systems ++ ID_OUI_FROM_DATABASE=Varex Imaging + + OUI:000703* + ID_OUI_FROM_DATABASE=CSEE Transport + + OUI:000704* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:000705* + ID_OUI_FROM_DATABASE=Endress & Hauser GmbH & Co +@@ -5646,7 +5646,7 @@ OUI:000757* + ID_OUI_FROM_DATABASE=Topcall International AG + + OUI:000758* +- ID_OUI_FROM_DATABASE=Dragonwave ++ ID_OUI_FROM_DATABASE=DragonWave Inc. + + OUI:000759* + ID_OUI_FROM_DATABASE=Boris Manufacturing Corp. +@@ -5754,7 +5754,7 @@ OUI:00077B* + ID_OUI_FROM_DATABASE=Millimetrix Broadband Networks + + OUI:00077C* +- ID_OUI_FROM_DATABASE=Westermo Teleindustri AB ++ ID_OUI_FROM_DATABASE=Westermo Network Technologies AB + + OUI:00077D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -5793,7 +5793,7 @@ OUI:000788* + ID_OUI_FROM_DATABASE=Clipcomm, Inc. + + OUI:000789* +- ID_OUI_FROM_DATABASE=DONGWON SYSTEMS ++ ID_OUI_FROM_DATABASE=Allradio Co., Ltd + + OUI:00078A* + ID_OUI_FROM_DATABASE=Mentor Data System Inc. +@@ -5808,7 +5808,7 @@ OUI:00078D* + ID_OUI_FROM_DATABASE=NetEngines Ltd. + + OUI:00078E* +- ID_OUI_FROM_DATABASE=Garz & Friche GmbH ++ ID_OUI_FROM_DATABASE=Garz & Fricke GmbH + + OUI:00078F* + ID_OUI_FROM_DATABASE=Emkay Innovative Products +@@ -6186,7 +6186,7 @@ OUI:00080B* + ID_OUI_FROM_DATABASE=Birka BPA Informationssystem AB + + OUI:00080C* +- ID_OUI_FROM_DATABASE=VDA Elettronica spa ++ ID_OUI_FROM_DATABASE=VDA Group S.p.a. + + OUI:00080D* + ID_OUI_FROM_DATABASE=Toshiba +@@ -6273,7 +6273,7 @@ OUI:000828* + ID_OUI_FROM_DATABASE=Koei Engineering Ltd. + + OUI:000829* +- ID_OUI_FROM_DATABASE=Aval Nagasaki Corporation ++ ID_OUI_FROM_DATABASE=TOKYO ELECTRON DEVICE NAGASAKI LIMITED + + OUI:00082A* + ID_OUI_FROM_DATABASE=Powerwallz Network Security +@@ -6348,7 +6348,7 @@ OUI:00085C* + ID_OUI_FROM_DATABASE=Shanghai Dare Technologies Co. Ltd. + + OUI:00085D* +- ID_OUI_FROM_DATABASE=Aastra ++ ID_OUI_FROM_DATABASE=Mitel Corporation + + OUI:00085E* + ID_OUI_FROM_DATABASE=PCO AG +@@ -6585,7 +6585,7 @@ OUI:0008AB* + ID_OUI_FROM_DATABASE=EnerLinx.com, Inc. + + OUI:0008AC* +- ID_OUI_FROM_DATABASE=Eltromat GmbH ++ ID_OUI_FROM_DATABASE=BST GmbH + + OUI:0008AD* + ID_OUI_FROM_DATABASE=Toyo-Linx Co., Ltd. +@@ -6597,7 +6597,7 @@ OUI:0008AF* + ID_OUI_FROM_DATABASE=Novatec Corporation + + OUI:0008B0* +- ID_OUI_FROM_DATABASE=BKtel communications GmbH ++ ID_OUI_FROM_DATABASE=HUBER+SUHNER BKtel GmbH + + OUI:0008B1* + ID_OUI_FROM_DATABASE=ProQuent Systems +@@ -6807,7 +6807,7 @@ OUI:0008F5* + ID_OUI_FROM_DATABASE=YESTECHNOLOGY Co.,Ltd. + + OUI:0008F6* +- ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd + + OUI:0008F7* + ID_OUI_FROM_DATABASE=Hitachi Ltd, Semiconductor & Integrated Circuits Gr +@@ -7011,7 +7011,7 @@ OUI:000939* + ID_OUI_FROM_DATABASE=ShibaSoku Co.,Ltd. + + OUI:00093A* +- ID_OUI_FROM_DATABASE=Molex ++ ID_OUI_FROM_DATABASE=Molex CMS + + OUI:00093B* + ID_OUI_FROM_DATABASE=HYUNDAI NETWORKS INC. +@@ -7272,7 +7272,7 @@ OUI:000990* + ID_OUI_FROM_DATABASE=ACKSYS Communications & systems + + OUI:000991* +- ID_OUI_FROM_DATABASE=GE Fanuc Automation Manufacturing, Inc. ++ ID_OUI_FROM_DATABASE=Intelligent Platforms, LLC. + + OUI:000992* + ID_OUI_FROM_DATABASE=InterEpoch Technology,INC. +@@ -7641,7 +7641,7 @@ OUI:000A0C* + ID_OUI_FROM_DATABASE=Scientific Research Corporation + + OUI:000A0D* +- ID_OUI_FROM_DATABASE=FCI Deutschland GmbH ++ ID_OUI_FROM_DATABASE=Amphenol + + OUI:000A0E* + ID_OUI_FROM_DATABASE=Invivo Research Inc. +@@ -7914,7 +7914,7 @@ OUI:000A67* + ID_OUI_FROM_DATABASE=OngCorp + + OUI:000A68* +- ID_OUI_FROM_DATABASE=Solarflare Communications Inc ++ ID_OUI_FROM_DATABASE=Solarflare Communications Inc. + + OUI:000A69* + ID_OUI_FROM_DATABASE=SUNNY bell Technology Co., Ltd. +@@ -8253,7 +8253,7 @@ OUI:000AD8* + ID_OUI_FROM_DATABASE=IPCserv Technology Corp. + + OUI:000AD9* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:000ADA* + ID_OUI_FROM_DATABASE=Vindicator Technologies +@@ -8544,7 +8544,7 @@ OUI:000B39* + ID_OUI_FROM_DATABASE=Keisoku Giken Co.,Ltd. + + OUI:000B3A* +- ID_OUI_FROM_DATABASE=QuStream Corporation ++ ID_OUI_FROM_DATABASE=PESA + + OUI:000B3B* + ID_OUI_FROM_DATABASE=devolo AG +@@ -8562,7 +8562,7 @@ OUI:000B3F* + ID_OUI_FROM_DATABASE=Anthology Solutions Inc. + + OUI:000B40* +- ID_OUI_FROM_DATABASE=Oclaro ++ ID_OUI_FROM_DATABASE=Cambridge Industries Group (CIG) + + OUI:000B41* + ID_OUI_FROM_DATABASE=Ing. Büro Dr. Beutlhauser +@@ -8604,7 +8604,7 @@ OUI:000B4D* + ID_OUI_FROM_DATABASE=Emuzed + + OUI:000B4E* +- ID_OUI_FROM_DATABASE=VertexRSI, General Dynamics SatCOM Technologies, Inc. ++ ID_OUI_FROM_DATABASE=Communications & Power Industries + + OUI:000B4F* + ID_OUI_FROM_DATABASE=Verifone +@@ -8772,7 +8772,7 @@ OUI:000B85* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:000B86* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:000B87* + ID_OUI_FROM_DATABASE=American Reliance Inc. +@@ -8856,7 +8856,7 @@ OUI:000BA1* + ID_OUI_FROM_DATABASE=Fujikura Solutions Ltd. + + OUI:000BA2* +- ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd + + OUI:000BA3* + ID_OUI_FROM_DATABASE=Siemens AG +@@ -9288,7 +9288,7 @@ OUI:000C31* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:000C32* +- ID_OUI_FROM_DATABASE=Avionic Design Development GmbH ++ ID_OUI_FROM_DATABASE=Avionic Design GmbH + + OUI:000C33* + ID_OUI_FROM_DATABASE=Compucase Enterprise Co. Ltd. +@@ -9462,7 +9462,7 @@ OUI:000C6B* + ID_OUI_FROM_DATABASE=Kurz Industrie-Elektronik GmbH + + OUI:000C6C* +- ID_OUI_FROM_DATABASE=Elgato Systems LLC ++ ID_OUI_FROM_DATABASE=Eve Systems GmbH + + OUI:000C6D* + ID_OUI_FROM_DATABASE=Edwards Ltd. +@@ -9795,7 +9795,7 @@ OUI:000CDA* + ID_OUI_FROM_DATABASE=FreeHand Systems, Inc. + + OUI:000CDB* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:000CDC* + ID_OUI_FROM_DATABASE=BECS Technology, Inc +@@ -9807,7 +9807,7 @@ OUI:000CDE* + ID_OUI_FROM_DATABASE=ABB STOTZ-KONTAKT GmbH + + OUI:000CDF* +- ID_OUI_FROM_DATABASE=PULNiX America, Inc ++ ID_OUI_FROM_DATABASE=JAI Manufacturing + + OUI:000CE0* + ID_OUI_FROM_DATABASE=Trek Diagnostics Inc. +@@ -9828,7 +9828,7 @@ OUI:000CE5* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:000CE6* +- ID_OUI_FROM_DATABASE=Meru Networks Inc ++ ID_OUI_FROM_DATABASE=Fortinet Inc. + + OUI:000CE7* + ID_OUI_FROM_DATABASE=MediaTek Inc. +@@ -9846,7 +9846,7 @@ OUI:000CEB* + ID_OUI_FROM_DATABASE=CNMP Networks, Inc. + + OUI:000CEC* +- ID_OUI_FROM_DATABASE=Spectracom Corp. ++ ID_OUI_FROM_DATABASE=Orolia USA + + OUI:000CED* + ID_OUI_FROM_DATABASE=Real Digital Media +@@ -9903,7 +9903,7 @@ OUI:000CFE* + ID_OUI_FROM_DATABASE=Grand Electronic Co., Ltd + + OUI:000CFF* +- ID_OUI_FROM_DATABASE=MRO-TEK LIMITED ++ ID_OUI_FROM_DATABASE=MRO-TEK Realty Limited + + OUI:000D00* + ID_OUI_FROM_DATABASE=Seaway Networks Inc. +@@ -9936,7 +9936,7 @@ OUI:000D09* + ID_OUI_FROM_DATABASE=Yuehua(Zhuhai) Electronic CO. LTD + + OUI:000D0A* +- ID_OUI_FROM_DATABASE=Projectiondesign as ++ ID_OUI_FROM_DATABASE=Barco Projection Systems NV + + OUI:000D0B* + ID_OUI_FROM_DATABASE=BUFFALO.INC +@@ -10296,7 +10296,7 @@ OUI:000D81* + ID_OUI_FROM_DATABASE=Pepperl+Fuchs GmbH + + OUI:000D82* +- ID_OUI_FROM_DATABASE=PHSNET SRLS ++ ID_OUI_FROM_DATABASE=PHSNET + + OUI:000D83* + ID_OUI_FROM_DATABASE=Sanmina-SCI Hungary Ltd. +@@ -10446,7 +10446,7 @@ OUI:000DB3* + ID_OUI_FROM_DATABASE=SDO Communication Corperation + + OUI:000DB4* +- ID_OUI_FROM_DATABASE=NETASQ ++ ID_OUI_FROM_DATABASE=Stormshield + + OUI:000DB5* + ID_OUI_FROM_DATABASE=GLOBALSAT TECHNOLOGY CORPORATION +@@ -10695,7 +10695,7 @@ OUI:000E06* + ID_OUI_FROM_DATABASE=Team Simoco Ltd + + OUI:000E07* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:000E08* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC +@@ -11064,7 +11064,7 @@ OUI:000E81* + ID_OUI_FROM_DATABASE=Devicescape Software, Inc. + + OUI:000E82* +- ID_OUI_FROM_DATABASE=Commtech Wireless ++ ID_OUI_FROM_DATABASE=Infinity Tech + + OUI:000E83* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -11094,7 +11094,7 @@ OUI:000E8B* + ID_OUI_FROM_DATABASE=Astarte Technology Co, Ltd. + + OUI:000E8C* +- ID_OUI_FROM_DATABASE=Siemens AG A&D ET ++ ID_OUI_FROM_DATABASE=Siemens AG + + OUI:000E8D* + ID_OUI_FROM_DATABASE=Systems in Progress Holding GmbH +@@ -11166,7 +11166,7 @@ OUI:000EA3* + ID_OUI_FROM_DATABASE=CNCR-IT CO.,LTD,HangZhou P.R.CHINA + + OUI:000EA4* +- ID_OUI_FROM_DATABASE=Certance Inc. ++ ID_OUI_FROM_DATABASE=Quantum Corp. + + OUI:000EA5* + ID_OUI_FROM_DATABASE=BLIP Systems +@@ -11403,7 +11403,7 @@ OUI:000EF2* + ID_OUI_FROM_DATABASE=Infinico Corporation + + OUI:000EF3* +- ID_OUI_FROM_DATABASE=Smarthome ++ ID_OUI_FROM_DATABASE=Smartlabs, Inc. + + OUI:000EF4* + ID_OUI_FROM_DATABASE=Kasda Networks Inc +@@ -11691,7 +11691,7 @@ OUI:000F52* + ID_OUI_FROM_DATABASE=YORK Refrigeration, Marine & Controls + + OUI:000F53* +- ID_OUI_FROM_DATABASE=Solarflare Communications Inc ++ ID_OUI_FROM_DATABASE=Solarflare Communications Inc. + + OUI:000F54* + ID_OUI_FROM_DATABASE=Entrelogic Corporation +@@ -12108,7 +12108,7 @@ OUI:000FDD* + ID_OUI_FROM_DATABASE=SORDIN AB + + OUI:000FDE* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:000FDF* + ID_OUI_FROM_DATABASE=SOLOMON Technology Corp. +@@ -12378,7 +12378,7 @@ OUI:001037* + ID_OUI_FROM_DATABASE=CYQ've Technology Co., Ltd. + + OUI:001038* +- ID_OUI_FROM_DATABASE=MICRO RESEARCH INSTITUTE, INC. ++ ID_OUI_FROM_DATABASE=Micro Research Ltd. + + OUI:001039* + ID_OUI_FROM_DATABASE=Vectron Systems AG +@@ -13518,7 +13518,7 @@ OUI:0011B3* + ID_OUI_FROM_DATABASE=YOSHIMIYA CO.,LTD. + + OUI:0011B4* +- ID_OUI_FROM_DATABASE=Westermo Teleindustri AB ++ ID_OUI_FROM_DATABASE=Westermo Network Technologies AB + + OUI:0011B5* + ID_OUI_FROM_DATABASE=Shenzhen Powercom Co.,Ltd +@@ -14010,7 +14010,7 @@ OUI:001257* + ID_OUI_FROM_DATABASE=LeapComm Communication Technologies Inc. + + OUI:001258* +- ID_OUI_FROM_DATABASE=Activis Polska ++ ID_OUI_FROM_DATABASE=TechVoIP Sp z o.o. + + OUI:001259* + ID_OUI_FROM_DATABASE=THERMO ELECTRON KARLSRUHE +@@ -14187,7 +14187,7 @@ OUI:001292* + ID_OUI_FROM_DATABASE=Griffin Technology + + OUI:001293* +- ID_OUI_FROM_DATABASE=GE Energy ++ ID_OUI_FROM_DATABASE=ABB Power Protection (CH) + + OUI:001294* + ID_OUI_FROM_DATABASE=SUMITOMO ELECTRIC DEVICE INNOVATIONS, INC +@@ -14265,7 +14265,7 @@ OUI:0012AC* + ID_OUI_FROM_DATABASE=ONTIMETEK INC. + + OUI:0012AD* +- ID_OUI_FROM_DATABASE=IDS GmbH ++ ID_OUI_FROM_DATABASE=VIVAVIS AG + + OUI:0012AE* + ID_OUI_FROM_DATABASE=HLS HARD-LINE Solutions Inc. +@@ -14427,7 +14427,7 @@ OUI:0012E2* + ID_OUI_FROM_DATABASE=ALAXALA Networks Corporation + + OUI:0012E3* +- ID_OUI_FROM_DATABASE=Agat-RT, Ltd. ++ ID_OUI_FROM_DATABASE=Agat Soft LLC + + OUI:0012E4* + ID_OUI_FROM_DATABASE=ZIEHL industrie-electronik GmbH + Co KG +@@ -14460,7 +14460,7 @@ OUI:0012ED* + ID_OUI_FROM_DATABASE=AVG Advanced Technologies + + OUI:0012EE* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:0012EF* + ID_OUI_FROM_DATABASE=OneAccess SA +@@ -14472,7 +14472,7 @@ OUI:0012F1* + ID_OUI_FROM_DATABASE=IFOTEC + + OUI:0012F2* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:0012F3* + ID_OUI_FROM_DATABASE=connectBlue AB +@@ -14604,7 +14604,7 @@ OUI:00131D* + ID_OUI_FROM_DATABASE=Scanvaegt International A/S + + OUI:00131E* +- ID_OUI_FROM_DATABASE=Peiker acustic GmbH & Co. KG ++ ID_OUI_FROM_DATABASE=peiker acustic GmbH + + OUI:00131F* + ID_OUI_FROM_DATABASE=NxtPhase T&D, Corp. +@@ -15369,7 +15369,7 @@ OUI:00141C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:00141D* +- ID_OUI_FROM_DATABASE=LTi DRIVES GmbH ++ ID_OUI_FROM_DATABASE=KEBA Industrial Automation Germany GmbH + + OUI:00141E* + ID_OUI_FROM_DATABASE=P.A. Semi, Inc. +@@ -15552,7 +15552,7 @@ OUI:001459* + ID_OUI_FROM_DATABASE=Moram Co., Ltd. + + OUI:00145A* +- ID_OUI_FROM_DATABASE=Neratec Solutions AG ++ ID_OUI_FROM_DATABASE=Westermo Neratec AG + + OUI:00145B* + ID_OUI_FROM_DATABASE=SeekerNet Inc. +@@ -15885,7 +15885,7 @@ OUI:0014C8* + ID_OUI_FROM_DATABASE=Contemporary Research Corp + + OUI:0014C9* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:0014CA* + ID_OUI_FROM_DATABASE=Key Radio Systems Limited +@@ -16914,7 +16914,7 @@ OUI:00161F* + ID_OUI_FROM_DATABASE=SUNWAVETEC Co., Ltd. + + OUI:001620* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001621* + ID_OUI_FROM_DATABASE=Colorado Vnet +@@ -16980,7 +16980,7 @@ OUI:001635* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:001636* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:001637* + ID_OUI_FROM_DATABASE=CITEL SpA +@@ -16995,7 +16995,7 @@ OUI:00163A* + ID_OUI_FROM_DATABASE=YVES TECHNOLOGY CO., LTD. + + OUI:00163B* +- ID_OUI_FROM_DATABASE=VertexRSI/General Dynamics ++ ID_OUI_FROM_DATABASE=Communications & Power Industries + + OUI:00163C* + ID_OUI_FROM_DATABASE=Rebox B.V. +@@ -17370,7 +17370,7 @@ OUI:0016B7* + ID_OUI_FROM_DATABASE=Seoul Commtech + + OUI:0016B8* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:0016B9* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP +@@ -17514,7 +17514,7 @@ OUI:0016E7* + ID_OUI_FROM_DATABASE=Dynamix Promotions Limited + + OUI:0016E8* +- ID_OUI_FROM_DATABASE=Sigma Designs, Inc. ++ ID_OUI_FROM_DATABASE=Lumissil Microsystems + + OUI:0016E9* + ID_OUI_FROM_DATABASE=Tiba Medical Inc +@@ -17580,7 +17580,7 @@ OUI:0016FD* + ID_OUI_FROM_DATABASE=Jaty Electronics + + OUI:0016FE* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0016FF* + ID_OUI_FROM_DATABASE=Wamin Optocomm Mfg Corp +@@ -17637,7 +17637,7 @@ OUI:001710* + ID_OUI_FROM_DATABASE=Casa Systems Inc. + + OUI:001711* +- ID_OUI_FROM_DATABASE=GE Healthcare Bio-Sciences AB ++ ID_OUI_FROM_DATABASE=Cytiva Sweden AB + + OUI:001712* + ID_OUI_FROM_DATABASE=ISCO International +@@ -18411,7 +18411,7 @@ OUI:001812* + ID_OUI_FROM_DATABASE=Beijing Xinwei Telecom Technology Co., Ltd. + + OUI:001813* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001814* + ID_OUI_FROM_DATABASE=Mitutoyo Corporation +@@ -18516,7 +18516,7 @@ OUI:001835* + ID_OUI_FROM_DATABASE=Thoratec / ITC + + OUI:001836* +- ID_OUI_FROM_DATABASE=Reliance Electric Limited ++ ID_OUI_FROM_DATABASE=REJ Co.,Ltd + + OUI:001837* + ID_OUI_FROM_DATABASE=Universal ABIT Co., Ltd. +@@ -18753,7 +18753,7 @@ OUI:001884* + ID_OUI_FROM_DATABASE=Fon Technology S.L. + + OUI:001885* +- ID_OUI_FROM_DATABASE=Avigilon Corporation ++ ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + + OUI:001886* + ID_OUI_FROM_DATABASE=EL-TECH, INC. +@@ -19008,7 +19008,7 @@ OUI:0018D9* + ID_OUI_FROM_DATABASE=Santosha Internatonal, Inc + + OUI:0018DA* +- ID_OUI_FROM_DATABASE=AMBER wireless GmbH ++ ID_OUI_FROM_DATABASE=Würth Elektronik eiSos GmbH & Co. KG + + OUI:0018DB* + ID_OUI_FROM_DATABASE=EPL Technology Ltd +@@ -19272,7 +19272,7 @@ OUI:001931* + ID_OUI_FROM_DATABASE=Balluff GmbH + + OUI:001932* +- ID_OUI_FROM_DATABASE=Gude Analog- und Digialsysteme GmbH ++ ID_OUI_FROM_DATABASE=Gude Systems GmbH + + OUI:001933* + ID_OUI_FROM_DATABASE=Strix Systems, Inc. +@@ -19299,7 +19299,7 @@ OUI:00193A* + ID_OUI_FROM_DATABASE=OESOLUTIONS + + OUI:00193B* +- ID_OUI_FROM_DATABASE=Wilibox Deliberant Group LLC ++ ID_OUI_FROM_DATABASE=LigoWave + + OUI:00193C* + ID_OUI_FROM_DATABASE=HighPoint Technologies Incorporated +@@ -19419,7 +19419,7 @@ OUI:001962* + ID_OUI_FROM_DATABASE=Commerciant, LP + + OUI:001963* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001964* + ID_OUI_FROM_DATABASE=Doorking Inc. +@@ -19479,7 +19479,7 @@ OUI:001976* + ID_OUI_FROM_DATABASE=Xipher Technologies, LLC + + OUI:001977* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:001978* + ID_OUI_FROM_DATABASE=Datum Systems, Inc. +@@ -19551,7 +19551,7 @@ OUI:00198E* + ID_OUI_FROM_DATABASE=Oticon A/S + + OUI:00198F* +- ID_OUI_FROM_DATABASE=Alcatel Bell N.V. ++ ID_OUI_FROM_DATABASE=Nokia Bell N.V. + + OUI:001990* + ID_OUI_FROM_DATABASE=ELM DATA Co., Ltd. +@@ -19701,7 +19701,7 @@ OUI:0019C0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:0019C1* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0019C2* + ID_OUI_FROM_DATABASE=Equustek Solutions, Inc. +@@ -19980,7 +19980,7 @@ OUI:001A1D* + ID_OUI_FROM_DATABASE=PChome Online Inc. + + OUI:001A1E* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:001A1F* + ID_OUI_FROM_DATABASE=Coastal Environmental Systems +@@ -20079,7 +20079,7 @@ OUI:001A3E* + ID_OUI_FROM_DATABASE=Faster Technology LLC + + OUI:001A3F* +- ID_OUI_FROM_DATABASE=intelbras ++ ID_OUI_FROM_DATABASE=Intelbras + + OUI:001A40* + ID_OUI_FROM_DATABASE=A-FOUR TECH CO., LTD. +@@ -20241,7 +20241,7 @@ OUI:001A74* + ID_OUI_FROM_DATABASE=Procare International Co + + OUI:001A75* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001A76* + ID_OUI_FROM_DATABASE=SDT information Technology Co.,LTD. +@@ -20292,7 +20292,7 @@ OUI:001A85* + ID_OUI_FROM_DATABASE=NV Michel Van de Wiele + + OUI:001A86* +- ID_OUI_FROM_DATABASE=AdvancedIO Systems Inc ++ ID_OUI_FROM_DATABASE=New Wave Design & Verification + + OUI:001A87* + ID_OUI_FROM_DATABASE=Canhold International Limited +@@ -20766,7 +20766,7 @@ OUI:001B23* + ID_OUI_FROM_DATABASE=SimpleComTools + + OUI:001B24* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:001B25* + ID_OUI_FROM_DATABASE=Nortel Networks +@@ -20925,7 +20925,7 @@ OUI:001B58* + ID_OUI_FROM_DATABASE=ACE CAD Enterprise Co., Ltd. + + OUI:001B59* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001B5A* + ID_OUI_FROM_DATABASE=Apollo Imaging Technologies, Inc. +@@ -21057,7 +21057,7 @@ OUI:001B84* + ID_OUI_FROM_DATABASE=Scan Engineering Telecom + + OUI:001B85* +- ID_OUI_FROM_DATABASE=MAN Diesel SE ++ ID_OUI_FROM_DATABASE=MAN Energy Solutions + + OUI:001B86* + ID_OUI_FROM_DATABASE=Bosch Access Systems GmbH +@@ -21186,7 +21186,7 @@ OUI:001BAF* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + + OUI:001BB0* +- ID_OUI_FROM_DATABASE=BHARAT ELECTRONICS ++ ID_OUI_FROM_DATABASE=Bharat Electronics Limited + + OUI:001BB1* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation +@@ -21312,7 +21312,7 @@ OUI:001BC5014* + ID_OUI_FROM_DATABASE=Private + + OUI:001BC5015* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Corporate Systems Engineering + + OUI:001BC5016* + ID_OUI_FROM_DATABASE=Energotechnica OOO NPP Ltd +@@ -21390,7 +21390,7 @@ OUI:001BC502F* + ID_OUI_FROM_DATABASE=Fibrain Co. Ltd. + + OUI:001BC5030* +- ID_OUI_FROM_DATABASE=OctoGate it Security Systems GmbH ++ ID_OUI_FROM_DATABASE=OctoGate IT Security Systems GmbH + + OUI:001BC5031* + ID_OUI_FROM_DATABASE=ADIXEIN LIMITED +@@ -21726,7 +21726,7 @@ OUI:001BC509F* + ID_OUI_FROM_DATABASE=ENTE Sp. z o.o. + + OUI:001BC50A0* +- ID_OUI_FROM_DATABASE=HomerSoft sp. z o.o. ++ ID_OUI_FROM_DATABASE=Silvair + + OUI:001BC50A1* + ID_OUI_FROM_DATABASE=Hangzhou Zhiping Technology Co., Ltd. +@@ -21759,7 +21759,7 @@ OUI:001BC50AA* + ID_OUI_FROM_DATABASE=Senceive Ltd + + OUI:001BC50AB* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Evondos Oy + + OUI:001BC50AC* + ID_OUI_FROM_DATABASE=AVnu Alliance +@@ -21792,7 +21792,7 @@ OUI:001BC50B5* + ID_OUI_FROM_DATABASE=Exibea AB + + OUI:001BC50B6* +- ID_OUI_FROM_DATABASE=Veilux inc. ++ ID_OUI_FROM_DATABASE=VEILUX INC. + + OUI:001BC50B7* + ID_OUI_FROM_DATABASE=Autelis, LLC +@@ -21969,7 +21969,7 @@ OUI:001BEC* + ID_OUI_FROM_DATABASE=Netio Technologies Co., Ltd + + OUI:001BED* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:001BEE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S +@@ -22011,7 +22011,7 @@ OUI:001BFA* + ID_OUI_FROM_DATABASE=G.i.N. mbH + + OUI:001BFB* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:001BFC* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. +@@ -22461,7 +22461,7 @@ OUI:001C90* + ID_OUI_FROM_DATABASE=Empacket Corporation + + OUI:001C91* +- ID_OUI_FROM_DATABASE=Gefen Inc. ++ ID_OUI_FROM_DATABASE=Gefen LLC + + OUI:001C92* + ID_OUI_FROM_DATABASE=Tervela +@@ -22518,7 +22518,7 @@ OUI:001CA3* + ID_OUI_FROM_DATABASE=Terra + + OUI:001CA4* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001CA5* + ID_OUI_FROM_DATABASE=Zygo Corporation +@@ -22782,7 +22782,7 @@ OUI:001CFB* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:001CFC* +- ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd + + OUI:001CFD* + ID_OUI_FROM_DATABASE=Universal Electronics, Inc. +@@ -22809,7 +22809,7 @@ OUI:001D04* + ID_OUI_FROM_DATABASE=Zipit Wireless, Inc. + + OUI:001D05* +- ID_OUI_FROM_DATABASE=Eaton Corporation ++ ID_OUI_FROM_DATABASE=Cooper Lighting Solutions + + OUI:001D06* + ID_OUI_FROM_DATABASE=HM Electronics, Inc. +@@ -22914,7 +22914,7 @@ OUI:001D27* + ID_OUI_FROM_DATABASE=NAC-INTERCOM + + OUI:001D28* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001D29* + ID_OUI_FROM_DATABASE=Doro AB +@@ -23217,7 +23217,7 @@ OUI:001D8C* + ID_OUI_FROM_DATABASE=La Crosse Technology LTD + + OUI:001D8D* +- ID_OUI_FROM_DATABASE=Raytek GmbH ++ ID_OUI_FROM_DATABASE=Fluke Process Instruments GmbH + + OUI:001D8E* + ID_OUI_FROM_DATABASE=Alereon, Inc. +@@ -23463,7 +23463,7 @@ OUI:001DDE* + ID_OUI_FROM_DATABASE=Zhejiang Broadcast&Television Technology Co.,Ltd. + + OUI:001DDF* +- ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd. ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd + + OUI:001DE0* + ID_OUI_FROM_DATABASE=Intel Corporate +@@ -23709,7 +23709,7 @@ OUI:001E30* + ID_OUI_FROM_DATABASE=Shireen Inc + + OUI:001E31* +- ID_OUI_FROM_DATABASE=INFOMARK CO.,LTD. ++ ID_OUI_FROM_DATABASE=infomark + + OUI:001E32* + ID_OUI_FROM_DATABASE=Zensys +@@ -23745,7 +23745,7 @@ OUI:001E3C* + ID_OUI_FROM_DATABASE=Lyngbox Media AB + + OUI:001E3D* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:001E3E* + ID_OUI_FROM_DATABASE=KMW Inc. +@@ -23769,7 +23769,7 @@ OUI:001E44* + ID_OUI_FROM_DATABASE=SANTEC + + OUI:001E45* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001E46* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. +@@ -23874,7 +23874,7 @@ OUI:001E67* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:001E68* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:001E69* + ID_OUI_FROM_DATABASE=Thomson Inc. +@@ -23898,7 +23898,7 @@ OUI:001E6F* + ID_OUI_FROM_DATABASE=Magna-Power Electronics, Inc. + + OUI:001E70* +- ID_OUI_FROM_DATABASE=Cobham Defence Communications Ltd ++ ID_OUI_FROM_DATABASE=Cobham Antenna Systems + + OUI:001E71* + ID_OUI_FROM_DATABASE=MIrcom Group of Companies +@@ -24096,7 +24096,7 @@ OUI:001EB1* + ID_OUI_FROM_DATABASE=Cryptsoft Pty Ltd + + OUI:001EB2* +- ID_OUI_FROM_DATABASE=LG innotek ++ ID_OUI_FROM_DATABASE=LG Innotek + + OUI:001EB3* + ID_OUI_FROM_DATABASE=Primex Wireless +@@ -24114,7 +24114,7 @@ OUI:001EB7* + ID_OUI_FROM_DATABASE=TBTech, Co., Ltd. + + OUI:001EB8* +- ID_OUI_FROM_DATABASE=Fortis, Inc. ++ ID_OUI_FROM_DATABASE=Aloys, Inc + + OUI:001EB9* + ID_OUI_FROM_DATABASE=Sing Fai Technology Limited +@@ -24222,7 +24222,7 @@ OUI:001EDB* + ID_OUI_FROM_DATABASE=Giken Trastem Co., Ltd. + + OUI:001EDC* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001EDD* + ID_OUI_FROM_DATABASE=WASKO S.A. +@@ -24234,7 +24234,7 @@ OUI:001EDF* + ID_OUI_FROM_DATABASE=Master Industrialization Center Kista + + OUI:001EE0* +- ID_OUI_FROM_DATABASE=Urmet Domus SpA ++ ID_OUI_FROM_DATABASE=Urmet SpA + + OUI:001EE1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -24579,7 +24579,7 @@ OUI:001F52* + ID_OUI_FROM_DATABASE=UVT Unternehmensberatung fur Verkehr und Technik GmbH + + OUI:001F53* +- ID_OUI_FROM_DATABASE=GEMAC Gesellschaft für Mikroelektronikanwendung Chemnitz mbH ++ ID_OUI_FROM_DATABASE=GEMAC Chemnitz GmbH + + OUI:001F54* + ID_OUI_FROM_DATABASE=Lorex Technology Inc. +@@ -24768,7 +24768,7 @@ OUI:001F91* + ID_OUI_FROM_DATABASE=DBS Lodging Technologies, LLC + + OUI:001F92* +- ID_OUI_FROM_DATABASE=Avigilon Corporation ++ ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + + OUI:001F93* + ID_OUI_FROM_DATABASE=Xiotech Corporation +@@ -25014,7 +25014,7 @@ OUI:001FE3* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + + OUI:001FE4* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:001FE5* + ID_OUI_FROM_DATABASE=In-Circuit GmbH +@@ -26052,7 +26052,7 @@ OUI:00213D* + ID_OUI_FROM_DATABASE=Cermetek Microelectronics, Inc. + + OUI:00213E* +- ID_OUI_FROM_DATABASE=TomTom ++ ID_OUI_FROM_DATABASE=TomTom International BV + + OUI:00213F* + ID_OUI_FROM_DATABASE=A-Team Technology Ltd. +@@ -26103,7 +26103,7 @@ OUI:00214E* + ID_OUI_FROM_DATABASE=GS Yuasa Power Supply Ltd. + + OUI:00214F* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:002150* + ID_OUI_FROM_DATABASE=EYEVIEW ELECTRONICS +@@ -26340,7 +26340,7 @@ OUI:00219D* + ID_OUI_FROM_DATABASE=Adesys BV + + OUI:00219E* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:00219F* + ID_OUI_FROM_DATABASE=SATEL OY +@@ -26415,7 +26415,7 @@ OUI:0021B6* + ID_OUI_FROM_DATABASE=Triacta Power Technologies Inc. + + OUI:0021B7* +- ID_OUI_FROM_DATABASE=Lexmark International Inc. ++ ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC. + + OUI:0021B8* + ID_OUI_FROM_DATABASE=Inphi Corporation +@@ -27045,7 +27045,7 @@ OUI:002288* + ID_OUI_FROM_DATABASE=Sagrad, Inc. + + OUI:002289* +- ID_OUI_FROM_DATABASE=Optosecurity Inc. ++ ID_OUI_FROM_DATABASE=Vanderlande APC inc. + + OUI:00228A* + ID_OUI_FROM_DATABASE=Teratronik elektronische systeme gmbh +@@ -27090,7 +27090,7 @@ OUI:002297* + ID_OUI_FROM_DATABASE=XMOS Semiconductor + + OUI:002298* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:002299* + ID_OUI_FROM_DATABASE=SeaMicro Inc. +@@ -27114,7 +27114,7 @@ OUI:00229F* + ID_OUI_FROM_DATABASE=Sensys Traffic AB + + OUI:0022A0* +- ID_OUI_FROM_DATABASE=Delphi Corporation ++ ID_OUI_FROM_DATABASE=APTIV SERVICES US, LLC + + OUI:0022A1* + ID_OUI_FROM_DATABASE=Huawei Symantec Technologies Co.,Ltd. +@@ -27159,7 +27159,7 @@ OUI:0022AE* + ID_OUI_FROM_DATABASE=Mattel Inc. + + OUI:0022AF* +- ID_OUI_FROM_DATABASE=Safety Vision ++ ID_OUI_FROM_DATABASE=Safety Vision, LLC + + OUI:0022B0* + ID_OUI_FROM_DATABASE=D-Link Corporation +@@ -27420,7 +27420,7 @@ OUI:002305* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:002306* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:002307* + ID_OUI_FROM_DATABASE=FUTURE INNOVATION TECH CO.,LTD +@@ -27609,7 +27609,7 @@ OUI:002344* + ID_OUI_FROM_DATABASE=Objective Interface Systems, Inc. + + OUI:002345* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:002346* + ID_OUI_FROM_DATABASE=Vestac +@@ -27642,7 +27642,7 @@ OUI:00234F* + ID_OUI_FROM_DATABASE=Luminous Power Technologies Pvt. Ltd. + + OUI:002350* +- ID_OUI_FROM_DATABASE=LynTec ++ ID_OUI_FROM_DATABASE=RDC, Inc. dba LynTec + + OUI:002351* + ID_OUI_FROM_DATABASE=2Wire Inc +@@ -27804,7 +27804,7 @@ OUI:002385* + ID_OUI_FROM_DATABASE=ANTIPODE + + OUI:002386* +- ID_OUI_FROM_DATABASE=Tour & Andersson AB ++ ID_OUI_FROM_DATABASE=IMI Hydronic Engineering international SA + + OUI:002387* + ID_OUI_FROM_DATABASE=ThinkFlood, Inc. +@@ -27819,7 +27819,7 @@ OUI:00238A* + ID_OUI_FROM_DATABASE=Ciena Corporation + + OUI:00238B* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:00238C* + ID_OUI_FROM_DATABASE=Private +@@ -27963,7 +27963,7 @@ OUI:0023BA* + ID_OUI_FROM_DATABASE=Chroma + + OUI:0023BB* +- ID_OUI_FROM_DATABASE=Schmitt Industries ++ ID_OUI_FROM_DATABASE=Accretech SBS, Inc. + + OUI:0023BC* + ID_OUI_FROM_DATABASE=EQ-SYS GmbH +@@ -28092,7 +28092,7 @@ OUI:0023E5* + ID_OUI_FROM_DATABASE=IPaXiom Networks + + OUI:0023E6* +- ID_OUI_FROM_DATABASE=Pirkus, Inc. ++ ID_OUI_FROM_DATABASE=Innovation Farm, Inc. + + OUI:0023E7* + ID_OUI_FROM_DATABASE=Hinke A/S +@@ -28125,7 +28125,7 @@ OUI:0023F0* + ID_OUI_FROM_DATABASE=Shanghai Jinghan Weighing Apparatus Co. Ltd. + + OUI:0023F1* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:0023F2* + ID_OUI_FROM_DATABASE=TVLogic +@@ -28320,7 +28320,7 @@ OUI:002432* + ID_OUI_FROM_DATABASE=Neostar Technology Co.,LTD + + OUI:002433* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:002434* + ID_OUI_FROM_DATABASE=Lectrosonics, Inc. +@@ -28335,7 +28335,7 @@ OUI:002437* + ID_OUI_FROM_DATABASE=Motorola - BSG + + OUI:002438* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:002439* + ID_OUI_FROM_DATABASE=Digital Barriers Advanced Technologies +@@ -28485,7 +28485,7 @@ OUI:00246B* + ID_OUI_FROM_DATABASE=Covia, Inc. + + OUI:00246C* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:00246D* + ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH +@@ -28566,7 +28566,7 @@ OUI:002486* + ID_OUI_FROM_DATABASE=DesignArt Networks + + OUI:002487* +- ID_OUI_FROM_DATABASE=Blackboard Inc. ++ ID_OUI_FROM_DATABASE=Transact Campus, Inc. + + OUI:002488* + ID_OUI_FROM_DATABASE=Centre For Development Of Telematics +@@ -28878,7 +28878,7 @@ OUI:0024EE* + ID_OUI_FROM_DATABASE=Wynmax Inc. + + OUI:0024EF* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:0024F0* + ID_OUI_FROM_DATABASE=Seanodes +@@ -29301,7 +29301,7 @@ OUI:00257D* + ID_OUI_FROM_DATABASE=PointRed Telecom Private Ltd. + + OUI:00257E* +- ID_OUI_FROM_DATABASE=NEW POS Technology Limited ++ ID_OUI_FROM_DATABASE=NEW POS TECHNOLOGY LIMITED + + OUI:00257F* + ID_OUI_FROM_DATABASE=CallTechSolution Co.,Ltd +@@ -29424,7 +29424,7 @@ OUI:0025A6* + ID_OUI_FROM_DATABASE=Central Network Solution Co., Ltd. + + OUI:0025A7* +- ID_OUI_FROM_DATABASE=Comverge, Inc. ++ ID_OUI_FROM_DATABASE=itron + + OUI:0025A8* + ID_OUI_FROM_DATABASE=Kontron (BeiJing) Technology Co.,Ltd +@@ -29583,7 +29583,7 @@ OUI:0025DB* + ID_OUI_FROM_DATABASE=ATI Electronics(Shenzhen) Co., LTD + + OUI:0025DC* +- ID_OUI_FROM_DATABASE=Sumitomo Electric Industries,Ltd ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd + + OUI:0025DD* + ID_OUI_FROM_DATABASE=SUNNYTEK INFORMATION CO., LTD. +@@ -29616,7 +29616,7 @@ OUI:0025E6* + ID_OUI_FROM_DATABASE=Belgian Monitoring Systems bvba + + OUI:0025E7* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:0025E8* + ID_OUI_FROM_DATABASE=Idaho Technology +@@ -29889,7 +29889,7 @@ OUI:002642* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:002643* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:002644* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium +@@ -29916,7 +29916,7 @@ OUI:00264D* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + + OUI:00264E* +- ID_OUI_FROM_DATABASE=Rail & Road Protec GmbH ++ ID_OUI_FROM_DATABASE=r2p GmbH + + OUI:00264F* + ID_OUI_FROM_DATABASE=Krüger &Gothe GmbH +@@ -30030,7 +30030,7 @@ OUI:002673* + ID_OUI_FROM_DATABASE=RICOH COMPANY,LTD. + + OUI:002674* +- ID_OUI_FROM_DATABASE=Electronic Solutions, Inc. ++ ID_OUI_FROM_DATABASE=Hunter Douglas + + OUI:002675* + ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd +@@ -30156,7 +30156,7 @@ OUI:00269D* + ID_OUI_FROM_DATABASE=M2Mnet Co., Ltd. + + OUI:00269E* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:00269F* + ID_OUI_FROM_DATABASE=Private +@@ -30561,7 +30561,7 @@ OUI:0027E3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0027F8* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:00289F* + ID_OUI_FROM_DATABASE=Semptian Co., Ltd. +@@ -30572,6 +30572,9 @@ OUI:0028F8* + OUI:002926* + ID_OUI_FROM_DATABASE=Applied Optoelectronics, Inc Taiwan Branch + ++OUI:0029C2* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:002A10* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -30581,15 +30584,24 @@ OUI:002A6A* + OUI:002AAF* + ID_OUI_FROM_DATABASE=LARsys-Automation GmbH + ++OUI:002B67* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ + OUI:002CC8* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:002D76* + ID_OUI_FROM_DATABASE=TITECH GmbH + ++OUI:002DB3* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:002EC7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:002F5C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:002FD9* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -30846,13 +30858,13 @@ OUI:003053* + ID_OUI_FROM_DATABASE=Basler AG + + OUI:003054* +- ID_OUI_FROM_DATABASE=CASTLENET TECHNOLOGY, INC. ++ ID_OUI_FROM_DATABASE=Castlenet Technology Inc. + + OUI:003055* + ID_OUI_FROM_DATABASE=Renesas Technology America, Inc. + + OUI:003056* +- ID_OUI_FROM_DATABASE=Beck IPC GmbH ++ ID_OUI_FROM_DATABASE=HMS Industrial Networks + + OUI:003057* + ID_OUI_FROM_DATABASE=QTelNet, Inc. +@@ -30861,7 +30873,7 @@ OUI:003058* + ID_OUI_FROM_DATABASE=API MOTION + + OUI:003059* +- ID_OUI_FROM_DATABASE=KONTRON COMPACT COMPUTERS AG ++ ID_OUI_FROM_DATABASE=Kontron Europe GmbH + + OUI:00305A* + ID_OUI_FROM_DATABASE=TELGEN CORPORATION +@@ -31032,7 +31044,7 @@ OUI:003091* + ID_OUI_FROM_DATABASE=TAIWAN FIRST LINE ELEC. CORP. + + OUI:003092* +- ID_OUI_FROM_DATABASE=ModuNORM GmbH ++ ID_OUI_FROM_DATABASE=Kontron Electronics AG + + OUI:003093* + ID_OUI_FROM_DATABASE=Sonnet Technologies, Inc +@@ -31364,12 +31376,21 @@ OUI:0030FF* + OUI:003146* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:003192* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ ++OUI:003217* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00323A* + ID_OUI_FROM_DATABASE=so-logic + + OUI:00336C* + ID_OUI_FROM_DATABASE=SynapSense Corporation + ++OUI:0034A1* ++ ID_OUI_FROM_DATABASE=RF-LAMBDA USA INC. ++ + OUI:0034DA* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -31388,9 +31409,15 @@ OUI:003532* + OUI:003560* + ID_OUI_FROM_DATABASE=Rosen Aviation + ++OUI:0035FF* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:003676* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:0036BE* ++ ID_OUI_FROM_DATABASE=Northwest Towers ++ + OUI:0036F8* + ID_OUI_FROM_DATABASE=Conti Temic microelectronic GmbH + +@@ -31439,6 +31466,9 @@ OUI:003CC5* + OUI:003D41* + ID_OUI_FROM_DATABASE=Hatteland Computer AS + ++OUI:003DE1* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:003DE8* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -31689,7 +31719,7 @@ OUI:004050* + ID_OUI_FROM_DATABASE=IRONICS, INCORPORATED + + OUI:004051* +- ID_OUI_FROM_DATABASE=GRACILIS, INC. ++ ID_OUI_FROM_DATABASE=Garbee and Garbee + + OUI:004052* + ID_OUI_FROM_DATABASE=STAR TECHNOLOGIES, INC. +@@ -32219,6 +32249,9 @@ OUI:0041B4* + OUI:0041D2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:004238* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:004252* + ID_OUI_FROM_DATABASE=RLX Technologies + +@@ -32228,15 +32261,21 @@ OUI:00425A* + OUI:004268* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:004279* ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd ++ + OUI:0043FF* + ID_OUI_FROM_DATABASE=KETRON S.R.L. + + OUI:004501* +- ID_OUI_FROM_DATABASE=Versus Technology, Inc. ++ ID_OUI_FROM_DATABASE=Midmark RTLS + + OUI:00451D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:0045E2* ++ ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. ++ + OUI:00464B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -32249,6 +32288,12 @@ OUI:004BF3* + OUI:004D32* + ID_OUI_FROM_DATABASE=Andon Health Co.,Ltd. + ++OUI:004E01* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:004E35* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:005000* + ID_OUI_FROM_DATABASE=NEXO COMMUNICATIONS, INC. + +@@ -32619,7 +32664,7 @@ OUI:005083* + ID_OUI_FROM_DATABASE=GILBARCO, INC. + + OUI:005084* +- ID_OUI_FROM_DATABASE=ATL PRODUCTS ++ ID_OUI_FROM_DATABASE=Quantum Corp. + + OUI:005086* + ID_OUI_FROM_DATABASE=TELKOM SA, LTD. +@@ -32928,7 +32973,7 @@ OUI:0050F0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0050F1* +- ID_OUI_FROM_DATABASE=Intel Corporation ++ ID_OUI_FROM_DATABASE=Maxlinear, Inc + + OUI:0050F2* + ID_OUI_FROM_DATABASE=MICROSOFT CORP. +@@ -32975,6 +33020,9 @@ OUI:0051ED* + OUI:005218* + ID_OUI_FROM_DATABASE=Wuxi Keboda Electron Co.Ltd + ++OUI:0052C2* ++ ID_OUI_FROM_DATABASE=peiker acustic GmbH ++ + OUI:00549F* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -32984,6 +33032,9 @@ OUI:0054AF* + OUI:0054BD* + ID_OUI_FROM_DATABASE=Swelaser AB + ++OUI:0055B1* ++ ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd. ++ + OUI:0055DA0* + ID_OUI_FROM_DATABASE=Shinko Technos co.,ltd. + +@@ -33065,6 +33116,9 @@ OUI:005A13* + OUI:005A39* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD + ++OUI:005B94* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:005BA1* + ID_OUI_FROM_DATABASE=shanghai huayuan chuangxin software CO., LTD. + +@@ -33080,6 +33134,12 @@ OUI:005D03* + OUI:005D73* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:005E0C* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:005F67* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:005F86* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -33387,7 +33447,7 @@ OUI:006064* + ID_OUI_FROM_DATABASE=NETCOMM LIMITED + + OUI:006065* +- ID_OUI_FROM_DATABASE=BERNECKER & RAINER INDUSTRIE-ELEKTRONIC GmbH ++ ID_OUI_FROM_DATABASE=B&R Industrial Automation GmbH + + OUI:006066* + ID_OUI_FROM_DATABASE=LACROIX Trafic +@@ -33399,7 +33459,7 @@ OUI:006068* + ID_OUI_FROM_DATABASE=Dialogic Corporation + + OUI:006069* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:00606A* + ID_OUI_FROM_DATABASE=MITSUBISHI WIRELESS COMMUNICATIONS. INC. +@@ -33753,7 +33813,7 @@ OUI:0060DE* + ID_OUI_FROM_DATABASE=Kayser-Threde GmbH + + OUI:0060DF* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:0060E0* + ID_OUI_FROM_DATABASE=AXIOM TECHNOLOGY CO., LTD. +@@ -33851,21 +33911,93 @@ OUI:0060FE* + OUI:0060FF* + ID_OUI_FROM_DATABASE=QuVis, Inc. + ++OUI:006151* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:006171* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:0062EC* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:0063DE* ++ ID_OUI_FROM_DATABASE=CLOUDWALK TECHNOLOGY CO.,LTD ++ + OUI:006440* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0064A6* + ID_OUI_FROM_DATABASE=Maquet CardioVascular + ++OUI:0064AF* ++ ID_OUI_FROM_DATABASE=Dish Technologies Corp ++ ++OUI:006619* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:00664B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:006762* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:00682B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:0068EB* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ ++OUI:00692D* ++ ID_OUI_FROM_DATABASE=Sunnovo International Limited ++ ++OUI:0069670* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:0069671* ++ ID_OUI_FROM_DATABASE=miliwave ++ ++OUI:0069672* ++ ID_OUI_FROM_DATABASE=Ningbo Shen Link Communication Technology Co.,Ltd ++ ++OUI:0069673* ++ ID_OUI_FROM_DATABASE=Suzhou Radiant Lighting Technology Co.,Ltd ++ ++OUI:0069674* ++ ID_OUI_FROM_DATABASE=Command Alkon, Inc ++ ++OUI:0069675* ++ ID_OUI_FROM_DATABASE=Shenzhen Xiao Bi En Culture Education Technology Co.,Ltd. ++ ++OUI:0069676* ++ ID_OUI_FROM_DATABASE=Comcast-SRL ++ ++OUI:0069677* ++ ID_OUI_FROM_DATABASE=PANGAEA SOLUTION INC ++ ++OUI:0069678* ++ ID_OUI_FROM_DATABASE=Ambient-System sp. z o.o. ++ ++OUI:0069679* ++ ID_OUI_FROM_DATABASE=Hangzhou Wise IOT Technology Co.,Ltd ++ ++OUI:006967A* ++ ID_OUI_FROM_DATABASE=Zhejiang Holip Electronic Technology Co.,Ltd ++ ++OUI:006967B* ++ ID_OUI_FROM_DATABASE=Datapan d.o.o. ++ ++OUI:006967C* ++ ID_OUI_FROM_DATABASE=Desird Design R&D ++ ++OUI:006967D* ++ ID_OUI_FROM_DATABASE=aversix ++ ++OUI:006967E* ++ ID_OUI_FROM_DATABASE=Tianjin Lianwu Technology Co., Ltd. ++ ++OUI:006B6F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:006B8E* + ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd. + +@@ -33887,12 +34019,21 @@ OUI:006CFD* + OUI:006D52* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:006D61* ++ ID_OUI_FROM_DATABASE=Guangzhou V-SOLUTION Electronic Technology Co., Ltd. ++ + OUI:006DFB* + ID_OUI_FROM_DATABASE=Vutrix Technologies Ltd + ++OUI:006E02* ++ ID_OUI_FROM_DATABASE=Xovis AG ++ + OUI:006F64* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:006FF2* ++ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD. ++ + OUI:0070B0* + ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES + +@@ -33932,12 +34073,21 @@ OUI:007532* + OUI:0075E1* + ID_OUI_FROM_DATABASE=Ampt, LLC + ++OUI:00763D* ++ ID_OUI_FROM_DATABASE=Veea ++ + OUI:007686* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:0076B1* + ID_OUI_FROM_DATABASE=Somfy-Protect By Myfox SAS + ++OUI:00778D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:0077E4* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:007888* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -33950,6 +34100,12 @@ OUI:0078CD* + OUI:007B18* + ID_OUI_FROM_DATABASE=SENTRY Co., LTD. + ++OUI:007C2D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:007D60* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:007DFA* + ID_OUI_FROM_DATABASE=Volkswagen Group of America + +@@ -34383,7 +34539,7 @@ OUI:00808B* + ID_OUI_FROM_DATABASE=DACOLL LIMITED + + OUI:00808C* +- ID_OUI_FROM_DATABASE=NetScout Systems, Inc. ++ ID_OUI_FROM_DATABASE=NETSCOUT SYSTEMS INC + + OUI:00808D* + ID_OUI_FROM_DATABASE=WESTCOAST TECHNOLOGY B.V. +@@ -34656,7 +34812,7 @@ OUI:0080E6* + ID_OUI_FROM_DATABASE=PEER NETWORKS, INC. + + OUI:0080E7* +- ID_OUI_FROM_DATABASE=Leonardo Tactical Systems. ++ ID_OUI_FROM_DATABASE=Leonardo UK Ltd + + OUI:0080E8* + ID_OUI_FROM_DATABASE=CUMULUS CORPORATIION +@@ -34751,9 +34907,21 @@ OUI:008701* + OUI:008731* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:008764* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:008865* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:0088BA* ++ ID_OUI_FROM_DATABASE=NC&C ++ ++OUI:008A55* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:008A76* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:008A96* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -35415,7 +35583,7 @@ OUI:0090D1* + ID_OUI_FROM_DATABASE=LEICHU ENTERPRISE CO., LTD. + + OUI:0090D2* +- ID_OUI_FROM_DATABASE=ARTEL VIDEO SYSTEMS ++ ID_OUI_FROM_DATABASE=Artel Video Systems + + OUI:0090D3* + ID_OUI_FROM_DATABASE=GIESECKE & DEVRIENT GmbH +@@ -35552,12 +35720,21 @@ OUI:0090FE* + OUI:0090FF* + ID_OUI_FROM_DATABASE=TELLUS TECHNOLOGY INC. + ++OUI:00919E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:0091D6* + ID_OUI_FROM_DATABASE=Crystal Group, Inc. + ++OUI:0091EB* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:0091FA* + ID_OUI_FROM_DATABASE=Synapse Product Development + ++OUI:00927D* ++ ID_OUI_FROM_DATABASE=Ficosa Internationa(Taicang) C0.,Ltd. ++ + OUI:0092FA* + ID_OUI_FROM_DATABASE=SHENZHEN WISKY TECHNOLOGY CO.,LTD + +@@ -35567,6 +35744,9 @@ OUI:009363* + OUI:0094A1* + ID_OUI_FROM_DATABASE=F5 Networks, Inc. + ++OUI:0094EC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:009569* + ID_OUI_FROM_DATABASE=LSD Science and Technology Co.,Ltd. + +@@ -35594,6 +35774,9 @@ OUI:009E1E* + OUI:009EC8* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:009EEE* ++ ID_OUI_FROM_DATABASE=Positivo Tecnologia S.A. ++ + OUI:00A000* + ID_OUI_FROM_DATABASE=CENTILLION NETWORKS, INC. + +@@ -35637,7 +35820,7 @@ OUI:00A00D* + ID_OUI_FROM_DATABASE=THE PANDA PROJECT + + OUI:00A00E* +- ID_OUI_FROM_DATABASE=NetScout Systems, Inc. ++ ID_OUI_FROM_DATABASE=NETSCOUT SYSTEMS INC + + OUI:00A00F* + ID_OUI_FROM_DATABASE=Broadband Technologies +@@ -36123,7 +36306,7 @@ OUI:00A0AF* + ID_OUI_FROM_DATABASE=WMS INDUSTRIES + + OUI:00A0B0* +- ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC. ++ ID_OUI_FROM_DATABASE=I-O DATA DEVICE,INC. + + OUI:00A0B1* + ID_OUI_FROM_DATABASE=FIRST VIRTUAL CORPORATION +@@ -36234,7 +36417,7 @@ OUI:00A0D4* + ID_OUI_FROM_DATABASE=RADIOLAN, INC. + + OUI:00A0D5* +- ID_OUI_FROM_DATABASE=Sierra Wireless Inc ++ ID_OUI_FROM_DATABASE=Sierra Wireless + + OUI:00A0D6* + ID_OUI_FROM_DATABASE=SBE, Inc. +@@ -36348,7 +36531,7 @@ OUI:00A0FA* + ID_OUI_FROM_DATABASE=Marconi Communication GmbH + + OUI:00A0FB* +- ID_OUI_FROM_DATABASE=TORAY ENGINEERING CO., LTD. ++ ID_OUI_FROM_DATABASE=Toray Engineering D Solutions Co., Ltd. + + OUI:00A0FC* + ID_OUI_FROM_DATABASE=IMAGE SCIENCES, INC. +@@ -36380,6 +36563,9 @@ OUI:00A2F5* + OUI:00A2FF* + ID_OUI_FROM_DATABASE=abatec group AG + ++OUI:00A388* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:00A38E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -36419,9 +36605,21 @@ OUI:00AA6E* + OUI:00AA70* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:00AB48* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:00ACE0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:00AD24* ++ ID_OUI_FROM_DATABASE=D-Link International ++ ++OUI:00AD63* ++ ID_OUI_FROM_DATABASE=Dedicated Micros Malta LTD ++ ++OUI:00ADD5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:00AECD* + ID_OUI_FROM_DATABASE=Pensando Systems + +@@ -36542,6 +36740,9 @@ OUI:00B0F0* + OUI:00B0F5* + ID_OUI_FROM_DATABASE=NetWorth Technologies, Inc. + ++OUI:00B1E3* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00B338* + ID_OUI_FROM_DATABASE=Kontron Asia Pacific Design Sdn. Bhd + +@@ -36551,6 +36752,9 @@ OUI:00B342* + OUI:00B362* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:00B4F5* ++ ID_OUI_FROM_DATABASE=DongGuan Siyoto Electronics Co., Ltd ++ + OUI:00B56D* + ID_OUI_FROM_DATABASE=David Electronics Co., LTD. + +@@ -36560,15 +36764,36 @@ OUI:00B5D0* + OUI:00B5D6* + ID_OUI_FROM_DATABASE=Omnibit Inc. + ++OUI:00B600* ++ ID_OUI_FROM_DATABASE=VOIM Co., Ltd. ++ + OUI:00B670* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:00B69F* + ID_OUI_FROM_DATABASE=Latch + ++OUI:00B771* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00B78D* + ID_OUI_FROM_DATABASE=Nanjing Shining Electric Automation Co., Ltd + ++OUI:00B7A8* ++ ID_OUI_FROM_DATABASE=Heinzinger electronic GmbH ++ ++OUI:00B810* ++ ID_OUI_FROM_DATABASE=Yichip Microelectronics (Hangzhou) Co.,Ltd ++ ++OUI:00B881* ++ ID_OUI_FROM_DATABASE=New platforms LLC ++ ++OUI:00B8B3* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:00B8B6* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:00B8C2* + ID_OUI_FROM_DATABASE=Heights Telecom T ltd + +@@ -36581,6 +36806,9 @@ OUI:00BAC0* + OUI:00BB01* + ID_OUI_FROM_DATABASE=OCTOTHORPE CORP. + ++OUI:00BB1C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:00BB3A* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -36605,6 +36833,9 @@ OUI:00BD27* + OUI:00BD3A* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:00BD3E* ++ ID_OUI_FROM_DATABASE=Vizio, Inc ++ + OUI:00BD82* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + +@@ -36617,6 +36848,9 @@ OUI:00BE75* + OUI:00BE9E* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:00BED5* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:00BF15* + ID_OUI_FROM_DATABASE=Genetec Inc. + +@@ -36626,6 +36860,9 @@ OUI:00BF61* + OUI:00BF77* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:00BFAF* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:00C000* + ID_OUI_FROM_DATABASE=LANOPTICS, LTD. + +@@ -36696,7 +36933,7 @@ OUI:00C016* + ID_OUI_FROM_DATABASE=ELECTRONIC THEATRE CONTROLS + + OUI:00C017* +- ID_OUI_FROM_DATABASE=NetScout Systems, Inc. ++ ID_OUI_FROM_DATABASE=NetAlly + + OUI:00C018* + ID_OUI_FROM_DATABASE=LANART CORPORATION +@@ -36945,7 +37182,7 @@ OUI:00C069* + ID_OUI_FROM_DATABASE=Axxcelera Broadband Wireless + + OUI:00C06A* +- ID_OUI_FROM_DATABASE=ZAHNER-ELEKTRIK GMBH & CO. KG ++ ID_OUI_FROM_DATABASE=Zahner-Elektrik Ingeborg Zahner-Schiller GmbH & Co. KG. + + OUI:00C06B* + ID_OUI_FROM_DATABASE=OSI PLUS CORPORATION +@@ -37104,7 +37341,7 @@ OUI:00C09E* + ID_OUI_FROM_DATABASE=CACHE COMPUTERS, INC. + + OUI:00C09F* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:00C0A0* + ID_OUI_FROM_DATABASE=ADVANCE MICRO RESEARCH, INC. +@@ -37173,7 +37410,7 @@ OUI:00C0B5* + ID_OUI_FROM_DATABASE=CORPORATE NETWORK SYSTEMS,INC. + + OUI:00C0B6* +- ID_OUI_FROM_DATABASE=Overland Storage, Inc. ++ ID_OUI_FROM_DATABASE=HVE, Inc. + + OUI:00C0B7* + ID_OUI_FROM_DATABASE=AMERICAN POWER CONVERSION CORP +@@ -37406,9 +37643,15 @@ OUI:00C1B1* + OUI:00C2C6* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:00C343* ++ ID_OUI_FROM_DATABASE=E-T-A Circuit Breakers Ltd ++ + OUI:00C3F4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:00C52C* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:00C5DB* + ID_OUI_FROM_DATABASE=Datatech Sistemas Digitales Avanzados SL + +@@ -37424,11 +37667,17 @@ OUI:00CAE5* + OUI:00CB00* + ID_OUI_FROM_DATABASE=Private + ++OUI:00CB51* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:00CBB4* + ID_OUI_FROM_DATABASE=SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD + + OUI:00CBBD* +- ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Ltd. ++ ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Group ++ ++OUI:00CC34* ++ ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:00CC3F* + ID_OUI_FROM_DATABASE=Universal Electronics, Inc. +@@ -37442,6 +37691,9 @@ OUI:00CD90* + OUI:00CDFE* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:00CE30* ++ ID_OUI_FROM_DATABASE=Express LUCK Industrial Ltd. ++ + OUI:00CF1C* + ID_OUI_FROM_DATABASE=Communication Machinery Corporation + +@@ -37584,7 +37836,7 @@ OUI:00D02C* + ID_OUI_FROM_DATABASE=CAMPBELL SCIENTIFIC, INC. + + OUI:00D02D* +- ID_OUI_FROM_DATABASE=ADEMCO ++ ID_OUI_FROM_DATABASE=Resideo + + OUI:00D02E* + ID_OUI_FROM_DATABASE=COMMUNICATION AUTOMATION CORP. +@@ -37689,7 +37941,7 @@ OUI:00D04F* + ID_OUI_FROM_DATABASE=BITRONICS, INC. + + OUI:00D050* +- ID_OUI_FROM_DATABASE=ISKRATEL ++ ID_OUI_FROM_DATABASE=Iskratel d.o.o. + + OUI:00D051* + ID_OUI_FROM_DATABASE=O2 MICRO, INC. +@@ -38219,6 +38471,12 @@ OUI:00D0FF* + OUI:00D11C* + ID_OUI_FROM_DATABASE=ACETEL + ++OUI:00D279* ++ ID_OUI_FROM_DATABASE=VINGROUP JOINT STOCK COMPANY ++ ++OUI:00D2B1* ++ ID_OUI_FROM_DATABASE=TPV Display Technology (Xiamen) Co.,Ltd. ++ + OUI:00D318* + ID_OUI_FROM_DATABASE=SPG Controls + +@@ -38228,9 +38486,18 @@ OUI:00D38D* + OUI:00D632* + ID_OUI_FROM_DATABASE=GE Energy + ++OUI:00D6FE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:00D76D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:00D78F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:00D861* ++ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. ++ + OUI:00D9D1* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + +@@ -38249,6 +38516,9 @@ OUI:00DB70* + OUI:00DBDF* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:00DCB2* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:00DD00* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +@@ -38297,6 +38567,9 @@ OUI:00DD0E* + OUI:00DD0F* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + ++OUI:00DD25* ++ ID_OUI_FROM_DATABASE=Shenzhen hechengdong Technology Co., Ltd ++ + OUI:00DEFB* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -38547,7 +38820,7 @@ OUI:00E051* + ID_OUI_FROM_DATABASE=TALX CORPORATION + + OUI:00E052* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:00E053* + ID_OUI_FROM_DATABASE=CELLPORT LABS, INC. +@@ -38850,7 +39123,7 @@ OUI:00E0B6* + ID_OUI_FROM_DATABASE=Entrada Networks + + OUI:00E0B7* +- ID_OUI_FROM_DATABASE=PI GROUP, LTD. ++ ID_OUI_FROM_DATABASE=Cosworth Electronics Ltd + + OUI:00E0B8* + ID_OUI_FROM_DATABASE=GATEWAY 2000 +@@ -38970,7 +39243,7 @@ OUI:00E0DE* + ID_OUI_FROM_DATABASE=DATAX NV + + OUI:00E0DF* +- ID_OUI_FROM_DATABASE=KEYMILE GmbH ++ ID_OUI_FROM_DATABASE=DZS GmbH + + OUI:00E0E0* + ID_OUI_FROM_DATABASE=SI ELECTRONICS, LTD. +@@ -39077,12 +39350,24 @@ OUI:00E175* + OUI:00E18C* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:00E22C* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:00E3B2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:00E400* + ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. + ++OUI:00E406* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:00E421* ++ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. ++ ++OUI:00E5E4* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:00E666* + ID_OUI_FROM_DATABASE=ARIMA Communications Corp. + +@@ -39092,11 +39377,20 @@ OUI:00E6D3* + OUI:00E6E8* + ID_OUI_FROM_DATABASE=Netzin Technology Corporation,.Ltd. + ++OUI:00E7E3* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:00E8AB* + ID_OUI_FROM_DATABASE=Meggitt Training Systems, Inc. + ++OUI:00E93A* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ ++OUI:00EABD* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00EB2D* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:00EBD5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -39104,6 +39398,12 @@ OUI:00EBD5* + OUI:00EC0A* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:00EDB8* ++ ID_OUI_FROM_DATABASE=KYOCERA Corporation ++ ++OUI:00EEAB* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00EEBD* + ID_OUI_FROM_DATABASE=HTC Corporation + +@@ -39116,6 +39416,12 @@ OUI:00F22C* + OUI:00F28B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:00F361* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:00F39F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:00F3DB* + ID_OUI_FROM_DATABASE=WOO Sports + +@@ -39125,9 +39431,15 @@ OUI:00F403* + OUI:00F46F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:00F48D* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:00F4B9* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:00F620* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:00F663* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -39146,9 +39458,15 @@ OUI:00F860* + OUI:00F871* + ID_OUI_FROM_DATABASE=DGS Denmark A/S + ++OUI:00FA21* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:00FA3B* + ID_OUI_FROM_DATABASE=CLOOS ELECTRONIC GMBH + ++OUI:00FAB6* ++ ID_OUI_FROM_DATABASE=Kontakt Micro-Location Sp z o.o. ++ + OUI:00FC58* + ID_OUI_FROM_DATABASE=WebSilicon Ltd. + +@@ -39164,6 +39482,9 @@ OUI:00FC8D* + OUI:00FCBA* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:00FD22* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:00FD45* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -39224,6 +39545,12 @@ OUI:0403D6* + OUI:0404EA* + ID_OUI_FROM_DATABASE=Valens Semiconductor Ltd. + ++OUI:0405DD* ++ ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co., Ltd ++ ++OUI:04072E* ++ ID_OUI_FROM_DATABASE=VTech Electronics Ltd. ++ + OUI:040973* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -39239,9 +39566,57 @@ OUI:040AE0* + OUI:040CCE* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:040E3C* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:040EC2* + ID_OUI_FROM_DATABASE=ViewSonic Mobile China Limited + ++OUI:0411190* ++ ID_OUI_FROM_DATABASE=FORT Robotics Inc. ++ ++OUI:0411191* ++ ID_OUI_FROM_DATABASE=Acentury ++ ++OUI:0411192* ++ ID_OUI_FROM_DATABASE=Alethea Communications Technologies Pvt. Ltd. ++ ++OUI:0411193* ++ ID_OUI_FROM_DATABASE=SUZHOU RIBAO TECHNOLOGY CO.,LTD. ++ ++OUI:0411194* ++ ID_OUI_FROM_DATABASE=Bolicom Innovation Technology (BeiJing) Co.,LTD. ++ ++OUI:0411195* ++ ID_OUI_FROM_DATABASE=CEITA COMMUNICATION TECHNOLOGY CO.,LTD ++ ++OUI:0411196* ++ ID_OUI_FROM_DATABASE=ZPD technology Co., Ltd ++ ++OUI:0411197* ++ ID_OUI_FROM_DATABASE=Herrick Tech Labs ++ ++OUI:0411198* ++ ID_OUI_FROM_DATABASE=Shenzhen YIZHENG Technology Co.,Ltd ++ ++OUI:0411199* ++ ID_OUI_FROM_DATABASE=AC Power Distribution / ACT Entmt. ++ ++OUI:041119A* ++ ID_OUI_FROM_DATABASE=CyOne Security AG ++ ++OUI:041119B* ++ ID_OUI_FROM_DATABASE=Hubei Baobao Intelligent Technology Co.,LTD ++ ++OUI:041119C* ++ ID_OUI_FROM_DATABASE=Haerbin Donglin Technology Co., Ltd. ++ ++OUI:041119D* ++ ID_OUI_FROM_DATABASE=Nuance Hearing Ltd. ++ ++OUI:041119E* ++ ID_OUI_FROM_DATABASE=JULIDA LIMITED ++ + OUI:041552* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -39275,15 +39650,24 @@ OUI:041BBA* + OUI:041D10* + ID_OUI_FROM_DATABASE=Dream Ware Inc. + ++OUI:041DC7* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:041E64* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:041E7A* + ID_OUI_FROM_DATABASE=DSPWorks + ++OUI:041EFA* ++ ID_OUI_FROM_DATABASE=BISSELL Homecare, Inc. ++ + OUI:04209A* + ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company + ++OUI:042144* ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd ++ + OUI:04214C* + ID_OUI_FROM_DATABASE=Insight Energy Ventures LLC + +@@ -39293,12 +39677,18 @@ OUI:042234* + OUI:0425C5* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:0425E0* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:042605* + ID_OUI_FROM_DATABASE=GFR Gesellschaft für Regelungstechnik und Energieeinsparung mbH + + OUI:042665* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:042728* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:042758* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -39320,36 +39710,69 @@ OUI:043110* + OUI:0432F4* + ID_OUI_FROM_DATABASE=Partron + ++OUI:043385* ++ ID_OUI_FROM_DATABASE=Nanchang BlackShark Co.,Ltd. ++ + OUI:043389* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:0433C2* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:043604* + ID_OUI_FROM_DATABASE=Gyeyoung I&T + ++OUI:043926* ++ ID_OUI_FROM_DATABASE=China Dragon Technology Limited ++ + OUI:043A0D* + ID_OUI_FROM_DATABASE=SM Optics S.r.l. + + OUI:043D98* + ID_OUI_FROM_DATABASE=ChongQing QingJia Electronics CO.,LTD + ++OUI:043F72* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ + OUI:0440A9* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + + OUI:044169* + ID_OUI_FROM_DATABASE=GoPro + ++OUI:04421A* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:0444A1* + ID_OUI_FROM_DATABASE=TELECON GALICIA,S.A. + ++OUI:044562* ++ ID_OUI_FROM_DATABASE=ANDRA Sp. z o. o. ++ ++OUI:0445A1* ++ ID_OUI_FROM_DATABASE=NIRIT- Xinwei Telecom Technology Co., Ltd. ++ + OUI:044665* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:0446CF* ++ ID_OUI_FROM_DATABASE=Beijing Venustech Cybervision Co.,Ltd. ++ + OUI:04489A* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:04495D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:044A50* + ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company + ++OUI:044A6C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:044AC6* ++ ID_OUI_FROM_DATABASE=Aipon Electronics Co., Ltd ++ + OUI:044BED* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -39401,6 +39824,9 @@ OUI:0455CA* + OUI:045604* + ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co.,Ltd. + ++OUI:0456E5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:04572F* + ID_OUI_FROM_DATABASE=Sertel Electronics UK Ltd + +@@ -39413,6 +39839,9 @@ OUI:045A95* + OUI:045C06* + ID_OUI_FROM_DATABASE=Zmodo Technology Corporation + ++OUI:045C6C* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:045C8E* + ID_OUI_FROM_DATABASE=gosund GROUP CO.,LTD + +@@ -39422,9 +39851,15 @@ OUI:045D4B* + OUI:045D56* + ID_OUI_FROM_DATABASE=camtron industrial inc. + ++OUI:045EA4* ++ ID_OUI_FROM_DATABASE=SHENZHEN NETIS TECHNOLOGY CO.,LTD ++ + OUI:045FA7* + ID_OUI_FROM_DATABASE=Shenzhen Yichen Technology Development Co.,LTD + ++OUI:045FB9* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:046169* + ID_OUI_FROM_DATABASE=MEDIA GLOBAL LINKS CO., LTD. + +@@ -39449,6 +39884,12 @@ OUI:0469F8* + OUI:046B1B* + ID_OUI_FROM_DATABASE=SYSDINE Co., Ltd. + ++OUI:046B25* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:046C59* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:046C9D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -39509,6 +39950,12 @@ OUI:04714BD* + OUI:04714BE* + ID_OUI_FROM_DATABASE=Gimso Mobile Ltd + ++OUI:047153* ++ ID_OUI_FROM_DATABASE=SERNET (SUZHOU) TECHNOLOGIES CORPORATION ++ ++OUI:047295* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:0474A1* + ID_OUI_FROM_DATABASE=Aligera Equipamentos Digitais Ltda + +@@ -39519,7 +39966,10 @@ OUI:0475F5* + ID_OUI_FROM_DATABASE=CSST + + OUI:04766E* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ ++OUI:0476B0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:047863* + ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd. +@@ -39527,24 +39977,48 @@ OUI:047863* + OUI:047970* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:047975* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:0479B7* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:047A0B* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ ++OUI:047AAE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:047BCB* ++ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. ++ + OUI:047D50* + ID_OUI_FROM_DATABASE=Shenzhen Kang Ying Technology Co.Ltd. + + OUI:047D7B* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. ++ ++OUI:047E23* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited + + OUI:047E4A* + ID_OUI_FROM_DATABASE=moobox CO., Ltd. + ++OUI:047F0E* ++ ID_OUI_FROM_DATABASE=Barrot Technology Limited ++ ++OUI:04819B* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:0481AE* + ID_OUI_FROM_DATABASE=Clack Corporation + + OUI:04848A* + ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED + ++OUI:04885F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:04888C* + ID_OUI_FROM_DATABASE=Eifelwerk Butler Systeme GmbH + +@@ -39563,9 +40037,24 @@ OUI:048B42* + OUI:048C03* + ID_OUI_FROM_DATABASE=ThinPAD Technology (Shenzhen)CO.,LTD + ++OUI:048C16* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:048C9A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:048D38* + ID_OUI_FROM_DATABASE=Netcore Technology Inc. + ++OUI:049081* ++ ID_OUI_FROM_DATABASE=Pensando Systems, Inc. ++ ++OUI:049162* ++ ID_OUI_FROM_DATABASE=Microchip Technology Inc. ++ ++OUI:049226* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:0492EE* + ID_OUI_FROM_DATABASE=iway AG + +@@ -39588,7 +40077,7 @@ OUI:049790* + ID_OUI_FROM_DATABASE=Lartech telecom LLC + + OUI:0498F3* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:0499E6* + ID_OUI_FROM_DATABASE=Shenzhen Yoostar Technology Co., Ltd +@@ -39599,11 +40088,14 @@ OUI:049B9C* + OUI:049C62* + ID_OUI_FROM_DATABASE=BMT Medical Technology s.r.o. + ++OUI:049DFE* ++ ID_OUI_FROM_DATABASE=Hivesystem ++ + OUI:049F06* + ID_OUI_FROM_DATABASE=Smobile Co., Ltd. + + OUI:049F81* +- ID_OUI_FROM_DATABASE=NetScout Systems, Inc. ++ ID_OUI_FROM_DATABASE=NETSCOUT SYSTEMS INC + + OUI:049FCA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -39611,6 +40103,12 @@ OUI:049FCA* + OUI:04A151* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:04A222* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ ++OUI:04A2F3* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:04A316* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -39620,9 +40118,15 @@ OUI:04A3F3* + OUI:04A82A* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:04AAE1* ++ ID_OUI_FROM_DATABASE=BEIJING MICROVISION TECHNOLOGY CO.,LTD ++ + OUI:04AB18* + ID_OUI_FROM_DATABASE=ELECOM CO.,LTD. + ++OUI:04AB6A* ++ ID_OUI_FROM_DATABASE=Chun-il Co.,Ltd. ++ + OUI:04AC44* + ID_OUI_FROM_DATABASE=Holtek Semiconductor Inc. + +@@ -39632,18 +40136,36 @@ OUI:04B0E7* + OUI:04B167* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:04B1A1* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:04B3B6* + ID_OUI_FROM_DATABASE=Seamap (UK) Ltd + ++OUI:04B429* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:04B466* + ID_OUI_FROM_DATABASE=BSP Co., Ltd. + + OUI:04B648* + ID_OUI_FROM_DATABASE=ZENNER + ++OUI:04B86A* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:04B9E3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:04BA1C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:04BA36* + ID_OUI_FROM_DATABASE=Li Seng Technology Ltd + ++OUI:04BA8D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:04BBF9* + ID_OUI_FROM_DATABASE=Pavilion Data Systems Inc + +@@ -39654,7 +40176,10 @@ OUI:04BD70* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:04BD88* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:04BDBF* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:04BF6D* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation +@@ -39677,12 +40202,18 @@ OUI:04C103* + OUI:04C1B9* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:04C1D8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:04C23E* + ID_OUI_FROM_DATABASE=HTC Corporation + + OUI:04C241* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:04C29B* ++ ID_OUI_FROM_DATABASE=Aura Home, Inc. ++ + OUI:04C3E60* + ID_OUI_FROM_DATABASE=DREAMKAS LLC + +@@ -39731,6 +40262,9 @@ OUI:04C3E6E* + OUI:04C5A4* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:04C807* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:04C880* + ID_OUI_FROM_DATABASE=Samtec Inc + +@@ -39743,30 +40277,117 @@ OUI:04C9D9* + OUI:04CB1D* + ID_OUI_FROM_DATABASE=Traka plc + ++OUI:04CB88* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ ++OUI:04CD15* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:04CE14* + ID_OUI_FROM_DATABASE=Wilocity LTD. + ++OUI:04CE7E* ++ ID_OUI_FROM_DATABASE=NXP France Semiconductors France ++ + OUI:04CF25* + ID_OUI_FROM_DATABASE=MANYCOLORS, INC. + ++OUI:04CF8C* ++ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD ++ + OUI:04D13A* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:04D16E0* ++ ID_OUI_FROM_DATABASE=INTRIPLE, a.s. ++ ++OUI:04D16E1* ++ ID_OUI_FROM_DATABASE=Launch Tech Co., Ltd. ++ ++OUI:04D16E2* ++ ID_OUI_FROM_DATABASE=s.d.i. s.p.a. ++ ++OUI:04D16E3* ++ ID_OUI_FROM_DATABASE=Beijing Huaxia Qixin Technology Co., Ltd. ++ ++OUI:04D16E4* ++ ID_OUI_FROM_DATABASE=ShenZhen Huafu Information technology Co.?Ltd ++ ++OUI:04D16E5* ++ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc. ++ ++OUI:04D16E6* ++ ID_OUI_FROM_DATABASE=ETL Elektrotechnik Lauter GmbH ++ ++OUI:04D16E7* ++ ID_OUI_FROM_DATABASE=Envision Energy ++ ++OUI:04D16E8* ++ ID_OUI_FROM_DATABASE=CHENGDU INTERLINK SCIENCE AND TECHNOLOGY CO.,LTD ++ ++OUI:04D16E9* ++ ID_OUI_FROM_DATABASE=FUZHOU ZHUOYI ELECTRONIC CO.,LTD ++ ++OUI:04D16EA* ++ ID_OUI_FROM_DATABASE=Metra Electronics ++ ++OUI:04D16EB* ++ ID_OUI_FROM_DATABASE=National Radio & Telecommunication Corporation - NRTC ++ ++OUI:04D16EC* ++ ID_OUI_FROM_DATABASE=PacPort Corporation ++ ++OUI:04D16ED* ++ ID_OUI_FROM_DATABASE=Elotec Fischer Elektronik GmbH ++ ++OUI:04D16EE* ++ ID_OUI_FROM_DATABASE=Evolute Systems Private Limited ++ ++OUI:04D320* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ ++OUI:04D395* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:04D3B0* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:04D3B5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:04D3CF* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:04D437* + ID_OUI_FROM_DATABASE=ZNV + ++OUI:04D442* ++ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO., LTD. ++ ++OUI:04D4C4* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ ++OUI:04D590* ++ ID_OUI_FROM_DATABASE=Fortinet, Inc. ++ ++OUI:04D60E* ++ ID_OUI_FROM_DATABASE=FUNAI ELECTRIC CO., LTD. ++ + OUI:04D6AA* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:04D6F4* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ + OUI:04D783* + ID_OUI_FROM_DATABASE=Y&H E&C Co.,LTD. + ++OUI:04D7A5* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:04D9F5* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:04DAD2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -39812,45 +40433,96 @@ OUI:04E536* + OUI:04E548* + ID_OUI_FROM_DATABASE=Cohda Wireless Pty Ltd + ++OUI:04E56E* ++ ID_OUI_FROM_DATABASE=THUB Co., ltd. ++ ++OUI:04E598* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:04E662* + ID_OUI_FROM_DATABASE=Acroname Inc. + + OUI:04E676* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + ++OUI:04E77E* ++ ID_OUI_FROM_DATABASE=We Corporation Inc. ++ ++OUI:04E795* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:04E9E5* + ID_OUI_FROM_DATABASE=PJRC.COM, LLC + ++OUI:04EA56* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:04EB40* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:04ECBB* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:04ECD8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:04ED33* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:04EE03* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:04EE91* + ID_OUI_FROM_DATABASE=x-fabric GmbH + ++OUI:04EEEE* ++ ID_OUI_FROM_DATABASE=Laplace System Co., Ltd. ++ + OUI:04F021* + ID_OUI_FROM_DATABASE=Compex Systems Pte Ltd + ++OUI:04F03E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:04F128* + ID_OUI_FROM_DATABASE=HMD Global Oy + + OUI:04F13E* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:04F169* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:04F17D* + ID_OUI_FROM_DATABASE=Tarana Wireless + ++OUI:04F352* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:04F4BC* + ID_OUI_FROM_DATABASE=Xena Networks + ++OUI:04F5F4* ++ ID_OUI_FROM_DATABASE=Proxim Wireless ++ + OUI:04F7E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:04F8C2* + ID_OUI_FROM_DATABASE=Flaircomm Microelectronics, Inc. + ++OUI:04F8F8* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:04F938* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:04F993* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ ++OUI:04F9D9* ++ ID_OUI_FROM_DATABASE=Speaker Electronic(Jiashan) Co.,Ltd ++ + OUI:04FA3F* + ID_OUI_FROM_DATABASE=Opticore Inc. + +@@ -40032,7 +40704,7 @@ OUI:080036* + ID_OUI_FROM_DATABASE=INTERGRAPH CORPORATION + + OUI:080037* +- ID_OUI_FROM_DATABASE=FUJI-XEROX CO. LTD. ++ ID_OUI_FROM_DATABASE=FUJIFILM Business Innovation Corp. + + OUI:080038* + ID_OUI_FROM_DATABASE=BULL S.A.S. +@@ -40065,7 +40737,7 @@ OUI:080041* + ID_OUI_FROM_DATABASE=RACAL-MILGO INFORMATION SYS.. + + OUI:080042* +- ID_OUI_FROM_DATABASE=JAPAN MACNICS CORP. ++ ID_OUI_FROM_DATABASE=MACNICA, Inc. + + OUI:080043* + ID_OUI_FROM_DATABASE=PIXEL COMPUTER INC. +@@ -40179,7 +40851,7 @@ OUI:080068* + ID_OUI_FROM_DATABASE=RIDGE COMPUTERS + + OUI:080069* +- ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC. ++ ID_OUI_FROM_DATABASE=Silicon Graphics + + OUI:08006A* + ID_OUI_FROM_DATABASE=AT&T +@@ -40269,7 +40941,7 @@ OUI:080087* + ID_OUI_FROM_DATABASE=Xyplex, Inc. + + OUI:080088* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:080089* + ID_OUI_FROM_DATABASE=Kinetics +@@ -40296,11 +40968,14 @@ OUI:080090* + ID_OUI_FROM_DATABASE=SONOMA SYSTEMS + + OUI:08010F* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:08028E* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:080342* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ + OUI:080371* + ID_OUI_FROM_DATABASE=KRG CORPORATE + +@@ -40310,6 +40985,9 @@ OUI:080581* + OUI:0805CD* + ID_OUI_FROM_DATABASE=DongGuang EnMai Electronic Product Co.Ltd. + ++OUI:0805E2* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:0808C2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -40319,6 +40997,9 @@ OUI:0808EA* + OUI:0809B6* + ID_OUI_FROM_DATABASE=Masimo Corp + ++OUI:0809C7* ++ ID_OUI_FROM_DATABASE=Zhuhai Unitech Power Technology Co., Ltd. ++ + OUI:080A4E* + ID_OUI_FROM_DATABASE=Planet Bingo® — 3rd Rock Gaming® + +@@ -40337,18 +41018,27 @@ OUI:080EA8* + OUI:080FFA* + ID_OUI_FROM_DATABASE=KSP INC. + ++OUI:081086* ++ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. ++ + OUI:08115E* + ID_OUI_FROM_DATABASE=Bitel Co., Ltd. + + OUI:081196* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:0812A5* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:081443* + ID_OUI_FROM_DATABASE=UNIBRAIN S.A. + + OUI:08152F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK + ++OUI:081605* ++ ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. ++ + OUI:081651* + ID_OUI_FROM_DATABASE=SHENZHEN SEA STAR TECHNOLOGY CO.,LTD + +@@ -40367,6 +41057,9 @@ OUI:08184C* + OUI:0819A6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:081C6E* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:081DC4* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific Messtechnik GmbH + +@@ -40397,6 +41090,9 @@ OUI:082522* + OUI:082525* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:082697* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:082719* + ID_OUI_FROM_DATABASE=APS systems/electronic AG + +@@ -40409,33 +41105,75 @@ OUI:082AD0* + OUI:082CB0* + ID_OUI_FROM_DATABASE=Network Instruments + ++OUI:082CB6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:082CED* ++ ID_OUI_FROM_DATABASE=Technity Solutions Inc. ++ ++OUI:082E36* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:082E5F* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:082FE9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:08306B* + ID_OUI_FROM_DATABASE=Palo Alto Networks + ++OUI:08318B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:0831A4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:08351B* ++ ID_OUI_FROM_DATABASE=Shenzhen Jialihua Electronic Technology Co., Ltd ++ + OUI:083571* + ID_OUI_FROM_DATABASE=CASwell INC. + + OUI:0835B2* + ID_OUI_FROM_DATABASE=CoreEdge Networks Co., Ltd + ++OUI:0836C9* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:08373D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:08379C* + ID_OUI_FROM_DATABASE=Topaz Co. LTD. + ++OUI:083869* ++ ID_OUI_FROM_DATABASE=Hong Kong AMobile Intelligent Corp. Limited Taiwan Branch ++ + OUI:0838A5* + ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH + ++OUI:0838E6* ++ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. ++ ++OUI:083A2F* ++ ID_OUI_FROM_DATABASE=Guangzhou Juan Intelligent Tech Joint Stock Co.,Ltd ++ ++OUI:083A38* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:083A5C* + ID_OUI_FROM_DATABASE=Junilab, Inc. + ++OUI:083A88* ++ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. ++ + OUI:083AB8* + ID_OUI_FROM_DATABASE=Shinoda Plasma Co., Ltd. + ++OUI:083AF2* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:083D88* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -40463,11 +41201,20 @@ OUI:084027* + OUI:0840F3* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + ++OUI:084296* ++ ID_OUI_FROM_DATABASE=Mobile Technology Solutions LLC ++ ++OUI:0845D1* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:084656* + ID_OUI_FROM_DATABASE=VEO-LABS + ++OUI:08474C* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:0847D0* +- ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co. Ltd.) ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. + + OUI:08482C* + ID_OUI_FROM_DATABASE=Raycore Taiwan Co., LTD. +@@ -40479,7 +41226,16 @@ OUI:084E1C* + ID_OUI_FROM_DATABASE=H2A Systems, LLC + + OUI:084EBF* +- ID_OUI_FROM_DATABASE=Broad Net Mux Corporation ++ ID_OUI_FROM_DATABASE=Sumitomo Electric Industries, Ltd ++ ++OUI:084F0A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:084FA9* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:084FF9* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:085114* + ID_OUI_FROM_DATABASE=QINGDAO TOPSCOMM COMMUNICATION CO., LTD +@@ -40490,30 +41246,57 @@ OUI:08512E* + OUI:085240* + ID_OUI_FROM_DATABASE=EbV Elektronikbau- und Vertriebs GmbH + ++OUI:0854BB* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ ++OUI:085531* ++ ID_OUI_FROM_DATABASE=Routerboard.com ++ + OUI:085700* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:0858A5* ++ ID_OUI_FROM_DATABASE=Beijing Vrv Software Corpoaration Limited. ++ ++OUI:085A11* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:085AE0* + ID_OUI_FROM_DATABASE=Recovision Technology Co., Ltd. + + OUI:085B0E* + ID_OUI_FROM_DATABASE=Fortinet, Inc. + ++OUI:085BD6* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:085BDA* + ID_OUI_FROM_DATABASE=CliniCare LTD + ++OUI:085C1B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:085DDD* + ID_OUI_FROM_DATABASE=MERCURY CORPORATION + + OUI:08606E* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:086083* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:086195* ++ ID_OUI_FROM_DATABASE=Rockwell Automation ++ + OUI:086266* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:086361* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:0865F0* ++ ID_OUI_FROM_DATABASE=JM Zengge Co., Ltd ++ + OUI:08661F* + ID_OUI_FROM_DATABASE=Palo Alto Networks + +@@ -40523,6 +41306,9 @@ OUI:086698* + OUI:08674E* + ID_OUI_FROM_DATABASE=Hisense broadband multimedia technology Co.,Ltd + ++OUI:08688D* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:0868D0* + ID_OUI_FROM_DATABASE=Japan System Design + +@@ -40532,6 +41318,15 @@ OUI:0868EA* + OUI:086A0A* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + ++OUI:086AC5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:086BD1* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ ++OUI:086BD7* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:086D41* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -40541,6 +41336,9 @@ OUI:086DF2* + OUI:087045* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:087190* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:087402* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -40562,6 +41360,9 @@ OUI:0876FF* + OUI:087808* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:08798C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:087999* + ID_OUI_FROM_DATABASE=AIM GmbH + +@@ -40571,15 +41372,27 @@ OUI:087A4C* + OUI:087BAA* + ID_OUI_FROM_DATABASE=SVYAZKOMPLEKTSERVICE, LLC + ++OUI:087C39* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:087CBE* + ID_OUI_FROM_DATABASE=Quintic Corp. + + OUI:087D21* + ID_OUI_FROM_DATABASE=Altasec technology corporation + ++OUI:087E64* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:087F98* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:088039* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:0881B2* ++ ID_OUI_FROM_DATABASE=Logitech (China) Technology Co., Ltd ++ + OUI:0881BC* + ID_OUI_FROM_DATABASE=HongKong Ipro Technology Co., Limited + +@@ -40589,12 +41402,24 @@ OUI:0881F4* + OUI:088466* + ID_OUI_FROM_DATABASE=Novartis Pharma AG + ++OUI:08849D* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:08855B* ++ ID_OUI_FROM_DATABASE=Kontron Europe GmbH ++ + OUI:088620* + ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + + OUI:08863B* + ID_OUI_FROM_DATABASE=Belkin International Inc. + ++OUI:0887C6* ++ ID_OUI_FROM_DATABASE=INGRAM MICRO SERVICES ++ ++OUI:0887C7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:088C2C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -40604,12 +41429,18 @@ OUI:088DC8* + OUI:088E4F* + ID_OUI_FROM_DATABASE=SF Software Solutions + ++OUI:088EDC* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:088F2C* +- ID_OUI_FROM_DATABASE=Hills Sound Vision & Lighting ++ ID_OUI_FROM_DATABASE=Amber Technology Ltd. + + OUI:0890BA* + ID_OUI_FROM_DATABASE=Danlaw Inc + ++OUI:089356* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:0894EF* + ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation + +@@ -40628,45 +41459,99 @@ OUI:089734* + OUI:089758* + ID_OUI_FROM_DATABASE=Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary + ++OUI:089798* ++ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. ++ ++OUI:0899E8* ++ ID_OUI_FROM_DATABASE=KEMAS GmbH ++ ++OUI:089AC7* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:089B4B* + ID_OUI_FROM_DATABASE=iKuai Networks + ++OUI:089BB9* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ ++OUI:089BF1* ++ ID_OUI_FROM_DATABASE=eero inc. ++ ++OUI:089C86* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:089E01* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:089E08* + ID_OUI_FROM_DATABASE=Google, Inc. + ++OUI:089E84* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:089F97* + ID_OUI_FROM_DATABASE=LEROY AUTOMATION + + OUI:08A12B* + ID_OUI_FROM_DATABASE=ShenZhen EZL Technology Co., Ltd + ++OUI:08A189* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:08A5C8* + ID_OUI_FROM_DATABASE=Sunnovo International Limited + ++OUI:08A6BC* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:08A7C0* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:08A842* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:08A8A1* + ID_OUI_FROM_DATABASE=Cyclotronics Power Concepts, Inc + + OUI:08A95A* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:08AA55* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:08AA89* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:08ACA5* + ID_OUI_FROM_DATABASE=Benu Video, Inc. + ++OUI:08ACC4* ++ ID_OUI_FROM_DATABASE=FMTech ++ + OUI:08AED6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:08AF78* + ID_OUI_FROM_DATABASE=Totus Solutions, Inc. + ++OUI:08B055* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ ++OUI:08B0A7* ++ ID_OUI_FROM_DATABASE=Truebeyond Co., Ltd ++ + OUI:08B258* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:08B2A3* + ID_OUI_FROM_DATABASE=Cynny Italia S.r.L. + ++OUI:08B3AF* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:08B4B1* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:08B4CF* + ID_OUI_FROM_DATABASE=Abicom International + +@@ -40679,6 +41564,12 @@ OUI:08B7EC* + OUI:08BA22* + ID_OUI_FROM_DATABASE=Swaive Corporation + ++OUI:08BA5F* ++ ID_OUI_FROM_DATABASE=Qingdao Hisense Electronics Co.,Ltd. ++ ++OUI:08BB3C* ++ ID_OUI_FROM_DATABASE=Flextronics Tech.(Ind) Pvt Ltd ++ + OUI:08BBCC* + ID_OUI_FROM_DATABASE=AK-NORD EDV VERTRIEBSGES. mbH + +@@ -40697,18 +41588,33 @@ OUI:08BE77* + OUI:08BEAC* + ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd. + ++OUI:08BFA0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:08C021* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:08C0EB* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ + OUI:08C5E1* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + + OUI:08C6B3* + ID_OUI_FROM_DATABASE=QTECH LLC + ++OUI:08C729* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:08CA45* + ID_OUI_FROM_DATABASE=Toyou Feiji Electronics Co., Ltd. + ++OUI:08CBE5* ++ ID_OUI_FROM_DATABASE=R3 - Reliable Realtime Radio Communications GmbH ++ ++OUI:08CC27* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:08CC68* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -40724,6 +41630,9 @@ OUI:08D09F* + OUI:08D0B7* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd. + ++OUI:08D23E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:08D29A* + ID_OUI_FROM_DATABASE=Proformatique + +@@ -40754,6 +41663,9 @@ OUI:08DF1F* + OUI:08DFCB* + ID_OUI_FROM_DATABASE=Systrome Networks + ++OUI:08E4DF* ++ ID_OUI_FROM_DATABASE=Shenzhen Sande Dacom Electronics Co., Ltd ++ + OUI:08E5DA* + ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD. + +@@ -40763,14 +41675,20 @@ OUI:08E672* + OUI:08E689* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:08E7E5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:08E84F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:08E9F6* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:08EA40* + ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD + + OUI:08EA44* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:08EB29* + ID_OUI_FROM_DATABASE=Jiangsu Huitong Group Co.,Ltd. +@@ -40784,6 +41702,9 @@ OUI:08EBED* + OUI:08ECA9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:08ECF5* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:08ED020* + ID_OUI_FROM_DATABASE=D2SLink Systems + +@@ -40829,9 +41750,15 @@ OUI:08ED02D* + OUI:08ED02E* + ID_OUI_FROM_DATABASE=Telstra Corporation Limited + ++OUI:08ED9D* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:08EDB9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:08EDED* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:08EE8B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -40844,12 +41771,21 @@ OUI:08EFAB* + OUI:08F1B7* + ID_OUI_FROM_DATABASE=Towerstream Corpration + ++OUI:08F1EA* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:08F2F4* + ID_OUI_FROM_DATABASE=Net One Partners Co.,Ltd. + ++OUI:08F458* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:08F4AB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:08F606* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:08F69C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -40859,9 +41795,24 @@ OUI:08F6F8* + OUI:08F728* + ID_OUI_FROM_DATABASE=GLOBO Multimedia Sp. z o.o. Sp.k. + ++OUI:08F7E9* ++ ID_OUI_FROM_DATABASE=HRCP Research and Development Partnership ++ ++OUI:08F8BC* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:08FA28* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:08FA79* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:08FAE0* + ID_OUI_FROM_DATABASE=Fohhn Audio AG + ++OUI:08FBEA* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:08FC52* + ID_OUI_FROM_DATABASE=OpenXS BV + +@@ -40871,6 +41822,12 @@ OUI:08FC88* + OUI:08FD0E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:08FF24* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ ++OUI:08FF44* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:0C01DB* + ID_OUI_FROM_DATABASE=Infinix mobility limited + +@@ -40886,8 +41843,11 @@ OUI:0C0535* + OUI:0C08B4* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:0C0E76* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:0C1105* +- ID_OUI_FROM_DATABASE=Ringslink (Xiamen) Network Communication Technologies Co., Ltd ++ ID_OUI_FROM_DATABASE=AKUVOX (XIAMEN) NETWORKS CO., LTD + + OUI:0C1167* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -40901,21 +41861,33 @@ OUI:0C130B* + OUI:0C1420* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:0C14D2* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:0C1539* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:0C15C5* + ID_OUI_FROM_DATABASE=SDTEC Co., Ltd. + ++OUI:0C1773* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:0C17F1* + ID_OUI_FROM_DATABASE=TELECSYS + + OUI:0C191F* + ID_OUI_FROM_DATABASE=Inform Electronik + ++OUI:0C19F8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:0C1A10* + ID_OUI_FROM_DATABASE=Acoustic Stream + ++OUI:0C1C19* ++ ID_OUI_FROM_DATABASE=LONGCONN ELECTRONICS(SHENZHEN) CO.,LTD ++ + OUI:0C1C20* + ID_OUI_FROM_DATABASE=Kakao Corp + +@@ -40931,6 +41903,9 @@ OUI:0C1DC2* + OUI:0C2026* + ID_OUI_FROM_DATABASE=noax Technologies AG + ++OUI:0C20D3* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:0C2138* + ID_OUI_FROM_DATABASE=Hengstler GmbH + +@@ -40946,6 +41921,9 @@ OUI:0C2724* + OUI:0C2755* + ID_OUI_FROM_DATABASE=Valuable Techologies Limited + ++OUI:0C29EF* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:0C2A69* + ID_OUI_FROM_DATABASE=electric imp, incorporated + +@@ -40961,12 +41939,27 @@ OUI:0C2C54* + OUI:0C2D89* + ID_OUI_FROM_DATABASE=QiiQ Communications Inc. + ++OUI:0C2FB0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:0C3021* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:0C31DC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:0C354F* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:0C35FE* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:0C3747* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:0C3796* ++ ID_OUI_FROM_DATABASE=BIZLINK TECHNOLOGY, INC. ++ + OUI:0C37DC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -40976,6 +41969,12 @@ OUI:0C383E* + OUI:0C3956* + ID_OUI_FROM_DATABASE=Observator instruments + ++OUI:0C3AFA* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:0C3B50* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:0C3C65* + ID_OUI_FROM_DATABASE=Dome Imaging Inc + +@@ -40985,12 +41984,24 @@ OUI:0C3CCD* + OUI:0C3E9F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:0C4101* ++ ID_OUI_FROM_DATABASE=Ruichi Auto Technology (Guangzhou) Co., Ltd. ++ + OUI:0C413E* + ID_OUI_FROM_DATABASE=Microsoft Corporation + + OUI:0C41E9* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:0C42A1* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ ++OUI:0C4314* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:0C43F9* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:0C45BA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -41006,6 +42017,9 @@ OUI:0C47C9* + OUI:0C4885* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:0C48C6* ++ ID_OUI_FROM_DATABASE=CELESTICA INC. ++ + OUI:0C4933* + ID_OUI_FROM_DATABASE=Sichuan Jiuzhou Electronic Technology Co., Ltd. + +@@ -41054,18 +42068,69 @@ OUI:0C57EB* + OUI:0C5842* + ID_OUI_FROM_DATABASE=DME Micro + ++OUI:0C599C* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:0C5A19* + ID_OUI_FROM_DATABASE=Axtion Sdn Bhd + + OUI:0C5A9E* + ID_OUI_FROM_DATABASE=Wi-SUN Alliance + ++OUI:0C5CB50* ++ ID_OUI_FROM_DATABASE=Yamasei ++ ++OUI:0C5CB51* ++ ID_OUI_FROM_DATABASE=avxav Electronic Trading LLC ++ ++OUI:0C5CB52* ++ ID_OUI_FROM_DATABASE=HongKong Blossom Limited ++ ++OUI:0C5CB53* ++ ID_OUI_FROM_DATABASE=iH&S Technology Limited ++ ++OUI:0C5CB54* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:0C5CB55* ++ ID_OUI_FROM_DATABASE=The Raymond Corporation ++ ++OUI:0C5CB56* ++ ID_OUI_FROM_DATABASE=S2C limited ++ ++OUI:0C5CB57* ++ ID_OUI_FROM_DATABASE=Energybox Limited ++ ++OUI:0C5CB58* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ ++OUI:0C5CB59* ++ ID_OUI_FROM_DATABASE=Colordeve International ++ ++OUI:0C5CB5A* ++ ID_OUI_FROM_DATABASE=Zhengzhou coal machinery hydraulic electric control Co.,Ltd ++ ++OUI:0C5CB5B* ++ ID_OUI_FROM_DATABASE=ADI ++ ++OUI:0C5CB5C* ++ ID_OUI_FROM_DATABASE=Hunan Newman Car NetworKing Technology Co.,Ltd ++ ++OUI:0C5CB5D* ++ ID_OUI_FROM_DATABASE=BSU Inc ++ ++OUI:0C5CB5E* ++ ID_OUI_FROM_DATABASE=Munters Europe AB ++ + OUI:0C5CD8* + ID_OUI_FROM_DATABASE=DOLI Elektronik GmbH + + OUI:0C5F35* + ID_OUI_FROM_DATABASE=Niagara Video Corporation + ++OUI:0C6046* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:0C6076* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -41105,12 +42170,18 @@ OUI:0C704A* + OUI:0C715D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:0C718C* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:0C722C* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:0C72D9* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:0C7329* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:0C73BE* + ID_OUI_FROM_DATABASE=Dongguan Haimai Electronie Technology Co.,Ltd + +@@ -41162,6 +42233,9 @@ OUI:0C73EBE* + OUI:0C74C2* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:0C7512* ++ ID_OUI_FROM_DATABASE=Shenzhen Kunlun TongTai Technology Co.,Ltd. ++ + OUI:0C7523* + ID_OUI_FROM_DATABASE=BEIJING GEHUA CATV NETWORK CO.,LTD + +@@ -41174,8 +42248,11 @@ OUI:0C75BD* + OUI:0C771A* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:0C7A15* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:0C7C28* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:0C7D7C* + ID_OUI_FROM_DATABASE=Kexiang Information Technology Co, Ltd. +@@ -41186,6 +42263,12 @@ OUI:0C8063* + OUI:0C8112* + ID_OUI_FROM_DATABASE=Private + ++OUI:0C8126* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:0C817D* ++ ID_OUI_FROM_DATABASE=EEP Elektro-Elektronik Pranjic GmbH ++ + OUI:0C8230* + ID_OUI_FROM_DATABASE=SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD + +@@ -41195,9 +42278,21 @@ OUI:0C8268* + OUI:0C826A* + ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd + ++OUI:0C839A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:0C83CC* ++ ID_OUI_FROM_DATABASE=Alpha Networks Inc. ++ ++OUI:0C8408* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:0C8411* + ID_OUI_FROM_DATABASE=A.O. Smith Water Products + ++OUI:0C8447* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:0C8484* + ID_OUI_FROM_DATABASE=Zenovia Electronics Inc. + +@@ -41216,6 +42311,9 @@ OUI:0C8910* + OUI:0C8A87* + ID_OUI_FROM_DATABASE=AgLogica Holdings, Inc + ++OUI:0C8B7D* ++ ID_OUI_FROM_DATABASE=Vizio, Inc ++ + OUI:0C8BD3* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + +@@ -41225,6 +42323,9 @@ OUI:0C8BFD* + OUI:0C8C24* + ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD + ++OUI:0C8C69* ++ ID_OUI_FROM_DATABASE=Shenzhen elink smart Co., ltd ++ + OUI:0C8C8F* + ID_OUI_FROM_DATABASE=Kamo Technology Limited + +@@ -41234,9 +42335,15 @@ OUI:0C8CDC* + OUI:0C8D98* + ID_OUI_FROM_DATABASE=TOP EIGHT IND CORP + ++OUI:0C8DCA* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:0C8DDB* + ID_OUI_FROM_DATABASE=Cisco Meraki + ++OUI:0C8E29* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:0C8FFF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -41249,18 +42356,30 @@ OUI:0C924E* + OUI:0C9301* + ID_OUI_FROM_DATABASE=PT. Prasimax Inovasi Teknologi + ++OUI:0C938F* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:0C93FB* + ID_OUI_FROM_DATABASE=BNS Solutions + ++OUI:0C9541* ++ ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. ++ + OUI:0C96BF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:0C96CD* ++ ID_OUI_FROM_DATABASE=MERCURY CORPORATION ++ + OUI:0C96E6* + ID_OUI_FROM_DATABASE=Cloud Network Technology (Samoa) Limited + + OUI:0C9838* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:0C9A3C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:0C9A42* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + +@@ -41276,6 +42395,9 @@ OUI:0C9D92* + OUI:0C9E91* + ID_OUI_FROM_DATABASE=Sankosha Corporation + ++OUI:0CA06C* ++ ID_OUI_FROM_DATABASE=Industrial Cyber Sensing Inc. ++ + OUI:0CA138* + ID_OUI_FROM_DATABASE=Blinq Wireless Inc. + +@@ -41294,6 +42416,9 @@ OUI:0CA694* + OUI:0CA8A7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:0CAAEE* ++ ID_OUI_FROM_DATABASE=Ansjer Electronics Co., Ltd. ++ + OUI:0CAC05* + ID_OUI_FROM_DATABASE=Unitend Technologies Inc. + +@@ -41315,6 +42440,9 @@ OUI:0CB34F* + OUI:0CB459* + ID_OUI_FROM_DATABASE=Marketech International Corp. + ++OUI:0CB4A4* ++ ID_OUI_FROM_DATABASE=Xintai Automobile Intelligent Network Technology ++ + OUI:0CB4EF* + ID_OUI_FROM_DATABASE=Digience Co.,Ltd. + +@@ -41327,6 +42455,12 @@ OUI:0CB5DE* + OUI:0CB6D2* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:0CB771* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:0CB789* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:0CB912* + ID_OUI_FROM_DATABASE=JM-DATA GmbH + +@@ -41345,6 +42479,9 @@ OUI:0CBF15* + OUI:0CBF3F* + ID_OUI_FROM_DATABASE=Shenzhen Lencotion Technology Co.,Ltd + ++OUI:0CBF74* ++ ID_OUI_FROM_DATABASE=Morse Micro ++ + OUI:0CC0C0* + ID_OUI_FROM_DATABASE=MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO + +@@ -41375,9 +42512,15 @@ OUI:0CC731* + OUI:0CC81F* + ID_OUI_FROM_DATABASE=Summer Infant, Inc. + ++OUI:0CC844* ++ ID_OUI_FROM_DATABASE=Cambridge Mobile Telematics, Inc. ++ + OUI:0CC9C6* + ID_OUI_FROM_DATABASE=Samwin Hong Kong Limited + ++OUI:0CCB0C* ++ ID_OUI_FROM_DATABASE=iSYS RTS GmbH ++ + OUI:0CCB85* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -41396,9 +42539,15 @@ OUI:0CCDFB* + OUI:0CCEF6* + ID_OUI_FROM_DATABASE=Guizhou Fortuneship Technology Co., Ltd + ++OUI:0CCF89* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ + OUI:0CCFD1* + ID_OUI_FROM_DATABASE=SPRINGWAVE Co., Ltd + ++OUI:0CD0F8* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:0CD292* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -41432,21 +42581,42 @@ OUI:0CD9C1* + OUI:0CDA41* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:0CDC7E* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:0CDCCC* + ID_OUI_FROM_DATABASE=Inala Technologies + ++OUI:0CDD24* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:0CDDEF* + ID_OUI_FROM_DATABASE=Nokia Corporation + + OUI:0CDFA4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:0CE041* ++ ID_OUI_FROM_DATABASE=iDruide ++ + OUI:0CE0DC* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:0CE0E4* + ID_OUI_FROM_DATABASE=PLANTRONICS, INC. + ++OUI:0CE159* ++ ID_OUI_FROM_DATABASE=Shenzhen iStartek Technology Co., Ltd. ++ ++OUI:0CE441* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:0CE4A0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:0CE5A3* ++ ID_OUI_FROM_DATABASE=SharkNinja ++ + OUI:0CE5D3* + ID_OUI_FROM_DATABASE=DH electronics GmbH + +@@ -41462,9 +42632,24 @@ OUI:0CE82F* + OUI:0CE936* + ID_OUI_FROM_DATABASE=ELIMOS srl + ++OUI:0CE99A* ++ ID_OUI_FROM_DATABASE=ATLS ALTEC ++ + OUI:0CEAC9* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:0CEC80* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:0CEC84* ++ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. ++ ++OUI:0CEC8D* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:0CEE99* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:0CEEE6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -41537,6 +42722,9 @@ OUI:0CF3EE* + OUI:0CF405* + ID_OUI_FROM_DATABASE=Beijing Signalway Technologies Co.,Ltd + ++OUI:0CF475* ++ ID_OUI_FROM_DATABASE=Zliide Technologies ApS ++ + OUI:0CF4D5* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -41558,9 +42746,57 @@ OUI:0CFD37* + OUI:0CFE45* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + ++OUI:0CFE5D0* ++ ID_OUI_FROM_DATABASE=Chengdu Ledong Information & Technology Co., Ltd. ++ ++OUI:0CFE5D1* ++ ID_OUI_FROM_DATABASE=Fender Musical Instrument ++ ++OUI:0CFE5D2* ++ ID_OUI_FROM_DATABASE=Dspread International Co.,Limited ++ ++OUI:0CFE5D3* ++ ID_OUI_FROM_DATABASE=Beijing WayClouds Technology Co., Ltd. ++ ++OUI:0CFE5D4* ++ ID_OUI_FROM_DATABASE=Yantai Dongfang Wisdom Electic Co.,Ltd. ++ ++OUI:0CFE5D5* ++ ID_OUI_FROM_DATABASE=SELECTRIC Nachrichten-Systeme GmbH ++ ++OUI:0CFE5D6* ++ ID_OUI_FROM_DATABASE=Antailiye Technology Co.,Ltd ++ ++OUI:0CFE5D7* ++ ID_OUI_FROM_DATABASE=Vermes Microdispensing GmbH ++ ++OUI:0CFE5D8* ++ ID_OUI_FROM_DATABASE=CTK Contact Electronics co., Ltd. ++ ++OUI:0CFE5D9* ++ ID_OUI_FROM_DATABASE=Celerway Communication AS ++ ++OUI:0CFE5DA* ++ ID_OUI_FROM_DATABASE=Fujian Jieyu Computer Technology Co., Ltd. ++ ++OUI:0CFE5DB* ++ ID_OUI_FROM_DATABASE=YINUO-LINK LIMITED ++ ++OUI:0CFE5DC* ++ ID_OUI_FROM_DATABASE=Bepal Technology Co.,Ltd. ++ ++OUI:0CFE5DD* ++ ID_OUI_FROM_DATABASE=Maksat Technologies P Ltd ++ ++OUI:0CFE5DE* ++ ID_OUI_FROM_DATABASE=NEWGREEN TECH CO., LTD. ++ + OUI:100000* + ID_OUI_FROM_DATABASE=Private + ++OUI:100020* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:10005A* + ID_OUI_FROM_DATABASE=IBM Corp + +@@ -41570,6 +42806,9 @@ OUI:1000E8* + OUI:1000FD* + ID_OUI_FROM_DATABASE=LaonPeople + ++OUI:100177* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1001CA* + ID_OUI_FROM_DATABASE=Ashley Butterworth + +@@ -41585,6 +42824,15 @@ OUI:1005B1* + OUI:1005CA* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:1005E1* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:100645* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:1006ED* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:1007230* + ID_OUI_FROM_DATABASE=RippleTek Tech Ltd + +@@ -41633,18 +42881,30 @@ OUI:100723F* + OUI:1007B6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:10082C* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:1008B1* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:10090C* + ID_OUI_FROM_DATABASE=Janome Sewing Machine Co., Ltd. + ++OUI:1009F9* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:100BA9* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:100C24* + ID_OUI_FROM_DATABASE=pomdevices, LLC + ++OUI:100C29* ++ ID_OUI_FROM_DATABASE=Shenzhen NORCO lntelligent Technology Co.,Ltd ++ ++OUI:100C6B* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:100D2F* + ID_OUI_FROM_DATABASE=Online Security Pty. Ltd. + +@@ -41663,6 +42923,9 @@ OUI:100E7E* + OUI:100F18* + ID_OUI_FROM_DATABASE=Fu Gang Electronic(KunShan)CO.,LTD + ++OUI:101081* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:1010B6* + ID_OUI_FROM_DATABASE=McCain Inc + +@@ -41678,8 +42941,14 @@ OUI:101248* + OUI:101250* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:1012B4* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:1012FB* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:101331* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:1013EE* + ID_OUI_FROM_DATABASE=Justec International Technology INC. +@@ -41687,6 +42956,9 @@ OUI:1013EE* + OUI:10189E* + ID_OUI_FROM_DATABASE=Elmo Motion Control + ++OUI:101965* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:101B54* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -41699,24 +42971,54 @@ OUI:101D51* + OUI:101DC0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:101EDA* ++ ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS ++ + OUI:101F74* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:102279* + ID_OUI_FROM_DATABASE=ZeroDesktop, Inc. + ++OUI:102779* ++ ID_OUI_FROM_DATABASE=Sadel S.p.A. ++ + OUI:1027BE* + ID_OUI_FROM_DATABASE=TVIP + ++OUI:1027F5* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:102831* + ID_OUI_FROM_DATABASE=Morion Inc. + ++OUI:102959* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:1029AB* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:102AB3* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:102B41* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:102C6B* ++ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. ++ + OUI:102C83* + ID_OUI_FROM_DATABASE=XIMEA + ++OUI:102CEF* ++ ID_OUI_FROM_DATABASE=EMU Electronic AG ++ ++OUI:102D31* ++ ID_OUI_FROM_DATABASE=Shenzhen Americas Trading Company LLC ++ ++OUI:102D41* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:102D96* + ID_OUI_FROM_DATABASE=Looxcie Inc. + +@@ -41726,27 +43028,75 @@ OUI:102EAF* + OUI:102F6B* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:102FA3* ++ ID_OUI_FROM_DATABASE=Shenzhen Uvision-tech Technology Co.Ltd ++ ++OUI:103025* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:103034* + ID_OUI_FROM_DATABASE=Cara Systems + + OUI:103047* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:10321D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:10327E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:103378* + ID_OUI_FROM_DATABASE=FLECTRON Co., LTD + ++OUI:1033BF* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:10341B* ++ ID_OUI_FROM_DATABASE=Spacelink ++ ++OUI:10364A* ++ ID_OUI_FROM_DATABASE=Boston Dynamics ++ + OUI:103711* + ID_OUI_FROM_DATABASE=Simlink AS + ++OUI:10381F* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ ++OUI:103917* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:10394E* ++ ID_OUI_FROM_DATABASE=Hisense broadband multimedia technology Co.,Ltd ++ ++OUI:1039E9* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:103B59* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:103D0A* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ ++OUI:103D1C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:103D3E* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:103DEA* + ID_OUI_FROM_DATABASE=HFC Technology (Beijing) Ltd. Co. + ++OUI:103F44* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:1040F3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:104121* ++ ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO ++ + OUI:10417F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -41768,6 +43118,9 @@ OUI:1045F8* + OUI:1046B4* + ID_OUI_FROM_DATABASE=FormericaOE + ++OUI:104738* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:104780* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -41792,12 +43145,30 @@ OUI:104E07* + OUI:104E89* + ID_OUI_FROM_DATABASE=Garmin International + ++OUI:104F58* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:104FA8* + ID_OUI_FROM_DATABASE=Sony Corporation + ++OUI:105072* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:105107* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:105172* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:10521C* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:105403* ++ ID_OUI_FROM_DATABASE=INTARSO GmbH ++ ++OUI:1055E4* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:105611* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -41810,21 +43181,36 @@ OUI:105887* + OUI:105917* + ID_OUI_FROM_DATABASE=Tonal + ++OUI:105932* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ ++OUI:105A17* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:105AF7* + ID_OUI_FROM_DATABASE=ADB Italia + ++OUI:105BAD* ++ ID_OUI_FROM_DATABASE=Mega Well Limited ++ + OUI:105C3B* + ID_OUI_FROM_DATABASE=Perma-Pipe, Inc. + + OUI:105CBF* + ID_OUI_FROM_DATABASE=DuroByte Inc + ++OUI:105DDC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:105F06* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + + OUI:105F49* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:105FD4* ++ ID_OUI_FROM_DATABASE=Tendyron Corporation ++ + OUI:10604B* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -41840,6 +43226,9 @@ OUI:1062E5* + OUI:1062EB* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:1063C8* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:1064E2* + ID_OUI_FROM_DATABASE=ADFweb.com s.r.l. + +@@ -41847,7 +43236,7 @@ OUI:106530* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:1065A3* +- ID_OUI_FROM_DATABASE=Core Brands LLC ++ ID_OUI_FROM_DATABASE=Panamax LLC + + OUI:1065CF* + ID_OUI_FROM_DATABASE=IQSIM +@@ -41861,18 +43250,33 @@ OUI:10683F* + OUI:106F3F* + ID_OUI_FROM_DATABASE=BUFFALO.INC + ++OUI:106FD9* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:106FEF* + ID_OUI_FROM_DATABASE=Ad-Sol Nissin Corp + ++OUI:1070FD* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ ++OUI:107100* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:1071F9* + ID_OUI_FROM_DATABASE=Cloud Telecomputers, LLC + + OUI:107223* + ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO + ++OUI:10746F* ++ ID_OUI_FROM_DATABASE=MOTOROLA SOLUTIONS MALAYSIA SDN. BHD. ++ + OUI:10768A* + ID_OUI_FROM_DATABASE=EoCell + ++OUI:107717* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ + OUI:1077B0* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -41900,12 +43304,24 @@ OUI:107B44* + OUI:107BA4* + ID_OUI_FROM_DATABASE=Olive & Dove Co.,Ltd. + ++OUI:107BCE* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:107BEF* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + + OUI:107D1A* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:1081B4* ++ ID_OUI_FROM_DATABASE=Hunan Greatwall Galaxy Science and Technology Co.,Ltd. ++ ++OUI:108286* ++ ID_OUI_FROM_DATABASE=Luxshare Precision Industry Co.,Ltd ++ ++OUI:1082D7* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:1083D2* + ID_OUI_FROM_DATABASE=Microseven Systems, LLC + +@@ -41918,36 +43334,69 @@ OUI:10880F* + OUI:1088CE* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:1089FB* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:108A1B* + ID_OUI_FROM_DATABASE=RAONIX Inc. + ++OUI:108B6A* ++ ID_OUI_FROM_DATABASE=Antailiye Technology Co.,Ltd ++ + OUI:108CCF* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:108EBA* ++ ID_OUI_FROM_DATABASE=Molekule ++ + OUI:108EE0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:108FFE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:109266* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:109397* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:1093E9* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:109497* ++ ID_OUI_FROM_DATABASE=Logitech Hong Kong ++ + OUI:1094BB* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:10954B* + ID_OUI_FROM_DATABASE=Megabyte Ltd. + ++OUI:109693* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:109836* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:1098C3* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:109AB9* + ID_OUI_FROM_DATABASE=Tosibox Oy + + OUI:109ADD* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:109C70* ++ ID_OUI_FROM_DATABASE=Prusa Research s.r.o. ++ ++OUI:109D7A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:109E3A* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:109FA9* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +@@ -41957,12 +43406,18 @@ OUI:10A13B* + OUI:10A24E* + ID_OUI_FROM_DATABASE=GOLD3LINK ELECTRONICS CO., LTD + ++OUI:10A3B8* ++ ID_OUI_FROM_DATABASE=Iskratel d.o.o. ++ + OUI:10A4B9* + ID_OUI_FROM_DATABASE=Baidu Online Network Technology (Beijing) Co., Ltd + + OUI:10A4BE* + ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD + ++OUI:10A4DA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:10A5D0* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +@@ -41990,18 +43445,36 @@ OUI:10B26B* + OUI:10B36F* + ID_OUI_FROM_DATABASE=Bowei Technology Company Limited + ++OUI:10B3C6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:10B3D5* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:10B3D6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:10B713* + ID_OUI_FROM_DATABASE=Private + ++OUI:10B7A8* ++ ID_OUI_FROM_DATABASE=CableFree Networks Limited ++ + OUI:10B7F6* + ID_OUI_FROM_DATABASE=Plastoform Industries Ltd. + ++OUI:10B9F7* ++ ID_OUI_FROM_DATABASE=Niko-Servodan ++ + OUI:10B9FE* + ID_OUI_FROM_DATABASE=Lika srl + + OUI:10BAA5* + ID_OUI_FROM_DATABASE=GANA I&C CO., LTD + ++OUI:10BC97* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:10BD18* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -42020,6 +43493,9 @@ OUI:10C07C* + OUI:10C172* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:10C22F* ++ ID_OUI_FROM_DATABASE=China Entropy Co., Ltd. ++ + OUI:10C25A* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + +@@ -42029,15 +43505,24 @@ OUI:10C2BA* + OUI:10C37B* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:10C3AB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:10C586* + ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD. + ++OUI:10C595* ++ ID_OUI_FROM_DATABASE=Lenovo ++ + OUI:10C60C* + ID_OUI_FROM_DATABASE=Domino UK Ltd + + OUI:10C61F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:10C65E* ++ ID_OUI_FROM_DATABASE=Adapt-IP ++ + OUI:10C67E* + ID_OUI_FROM_DATABASE=SHENZHEN JUCHIN TECHNOLOGY CO., LTD + +@@ -42047,6 +43532,12 @@ OUI:10C6FC* + OUI:10C73F* + ID_OUI_FROM_DATABASE=Midas Klark Teknik Ltd + ++OUI:10C753* ++ ID_OUI_FROM_DATABASE=Qingdao Intelligent&Precise Electronics Co.,Ltd. ++ ++OUI:10C9CA* ++ ID_OUI_FROM_DATABASE=Ace Technology Corp. ++ + OUI:10CA81* + ID_OUI_FROM_DATABASE=PRECIA + +@@ -42065,9 +43556,15 @@ OUI:10CDAE* + OUI:10CDB6* + ID_OUI_FROM_DATABASE=Essential Products, Inc. + ++OUI:10CE45* ++ ID_OUI_FROM_DATABASE=Miromico AG ++ + OUI:10CEA9* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:10CEE9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:10D07A* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + +@@ -42083,9 +43580,63 @@ OUI:10D38A* + OUI:10D542* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:10D561* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ ++OUI:10D7B0* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:10DA43* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:10DC4A* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:10DCB60* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:10DCB61* ++ ID_OUI_FROM_DATABASE=ABB Switzerland Ltd. ++ ++OUI:10DCB62* ++ ID_OUI_FROM_DATABASE=CAL-COMP INDUSTRIA E COMERCIO DE ELETRONICOS E INFORMATICA LTDA ++ ++OUI:10DCB63* ++ ID_OUI_FROM_DATABASE=HANACNS ++ ++OUI:10DCB64* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:10DCB65* ++ ID_OUI_FROM_DATABASE=Milesight Taiwan ++ ++OUI:10DCB66* ++ ID_OUI_FROM_DATABASE=Prolan Zrt. ++ ++OUI:10DCB67* ++ ID_OUI_FROM_DATABASE=Moya Commumication Technology (Shenzhen) Co.,Ltd. ++ ++OUI:10DCB68* ++ ID_OUI_FROM_DATABASE=Sanofi (Beijing) Pharmaceutical Co., Ltd. ++ ++OUI:10DCB69* ++ ID_OUI_FROM_DATABASE=Fuzhou Rockchip Electronics Co.,Ltd ++ ++OUI:10DCB6A* ++ ID_OUI_FROM_DATABASE=Pickering Interfaces Ltd ++ ++OUI:10DCB6B* ++ ID_OUI_FROM_DATABASE=Eyeball Fintech Company ++ ++OUI:10DCB6C* ++ ID_OUI_FROM_DATABASE=BBPOS International Limited ++ ++OUI:10DCB6D* ++ ID_OUI_FROM_DATABASE=LeoLabs ++ ++OUI:10DCB6E* ++ ID_OUI_FROM_DATABASE=Shenzhen Sunwoda intelligent hardware Co.,Ltd ++ + OUI:10DDB1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -42098,6 +43649,9 @@ OUI:10DEE4* + OUI:10DF8B* + ID_OUI_FROM_DATABASE=Shenzhen CareDear Communication Technology Co.,Ltd + ++OUI:10DFFC* ++ ID_OUI_FROM_DATABASE=Siemens AG ++ + OUI:10E2D5* + ID_OUI_FROM_DATABASE=Qi Hardware Inc. + +@@ -42107,12 +43661,18 @@ OUI:10E3C7* + OUI:10E4AF* + ID_OUI_FROM_DATABASE=APR, LLC + ++OUI:10E4C2* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:10E68F* + ID_OUI_FROM_DATABASE=KWANGSUNG ELECTRONICS KOREA CO.,LTD. + + OUI:10E6AE* + ID_OUI_FROM_DATABASE=Source Technologies, LLC + ++OUI:10E77A* ++ ID_OUI_FROM_DATABASE=STMicrolectronics International NV ++ + OUI:10E7C6* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -42122,9 +43682,15 @@ OUI:10E878* + OUI:10E8EE* + ID_OUI_FROM_DATABASE=PhaseSpace + ++OUI:10E953* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:10EA59* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:10EC81* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:10EED9* + ID_OUI_FROM_DATABASE=Canoga Perkins Corporation + +@@ -42146,9 +43712,15 @@ OUI:10F3DB* + OUI:10F49A* + ID_OUI_FROM_DATABASE=T3 Innovation + ++OUI:10F605* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:10F681* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:10F920* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:10F96F* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -42179,6 +43751,15 @@ OUI:1100AA* + OUI:111111* + ID_OUI_FROM_DATABASE=Private + ++OUI:140020* ++ ID_OUI_FROM_DATABASE=LongSung Technology (Shanghai) Co.,Ltd. ++ ++OUI:14007D* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:140152* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:1402EC* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -42191,9 +43772,15 @@ OUI:140708* + OUI:1407E0* + ID_OUI_FROM_DATABASE=Abrantix AG + ++OUI:1409B4* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:1409DC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:140AC5* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:140C5B* + ID_OUI_FROM_DATABASE=PLNetworks + +@@ -42203,36 +43790,69 @@ OUI:140C76* + OUI:140D4F* + ID_OUI_FROM_DATABASE=Flextronics International + ++OUI:140F42* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:14109F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:141114* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ ++OUI:14115D* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:141330* + ID_OUI_FROM_DATABASE=Anakreon UK LLP + ++OUI:141333* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ ++OUI:141346* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:141357* + ID_OUI_FROM_DATABASE=ATP Electronics, Inc. + ++OUI:1413FB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:14144B* + ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD + ++OUI:141459* ++ ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. ++ + OUI:1414E6* + ID_OUI_FROM_DATABASE=Ningbo Sanhe Digital Co.,Ltd + + OUI:14157C* + ID_OUI_FROM_DATABASE=TOKYO COSMOS ELECTRIC CO.,LTD. + ++OUI:14169D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:14169E* + ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited + + OUI:141877* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:1418C3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:141973* ++ ID_OUI_FROM_DATABASE=Beijing Yunyi Times Technology Co.,Ltd ++ + OUI:141A51* + ID_OUI_FROM_DATABASE=Treetech Sistemas Digitais + + OUI:141AA3* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:141B30* ++ ID_OUI_FROM_DATABASE=Shenzhen Yipingfang Network Technology Co., Ltd. ++ + OUI:141BBD* + ID_OUI_FROM_DATABASE=Volex Inc. + +@@ -42296,24 +43916,39 @@ OUI:14205E* + OUI:142233* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:14223B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:1422DB* + ID_OUI_FROM_DATABASE=eero inc. + ++OUI:14230A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1423D7* + ID_OUI_FROM_DATABASE=EUTRONIX CO., LTD. + ++OUI:142475* ++ ID_OUI_FROM_DATABASE=4DReplay, Inc ++ + OUI:142882* + ID_OUI_FROM_DATABASE=MIDICOM ELECTRONICS CO.LTD + + OUI:142971* + ID_OUI_FROM_DATABASE=NEMOA ELECTRONICS (HK) CO. LTD + ++OUI:142A14* ++ ID_OUI_FROM_DATABASE=ShenZhen Selenview Digital Technology Co.,Ltd ++ + OUI:142BD2* + ID_OUI_FROM_DATABASE=Armtel Ltd. + + OUI:142BD6* + ID_OUI_FROM_DATABASE=Guangdong Appscomm Co.,Ltd + ++OUI:142C78* ++ ID_OUI_FROM_DATABASE=GooWi Wireless Technology Co., Limited ++ + OUI:142D27* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -42323,6 +43958,9 @@ OUI:142D8B* + OUI:142DF5* + ID_OUI_FROM_DATABASE=Amphitech + ++OUI:142E5E* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:142FFD* + ID_OUI_FROM_DATABASE=LT SECURITY INC + +@@ -42362,6 +44000,12 @@ OUI:14373B* + OUI:143AEA* + ID_OUI_FROM_DATABASE=Dynapower Company LLC + ++OUI:143B42* ++ ID_OUI_FROM_DATABASE=Realfit(Shenzhen) Intelligent Technology Co., Ltd ++ ++OUI:143CC3* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:143DF2* + ID_OUI_FROM_DATABASE=Beijing Shidai Hongyuan Network Communication Co.,Ltd + +@@ -42374,21 +44018,36 @@ OUI:143EBF* + OUI:143F27* + ID_OUI_FROM_DATABASE=Noccela Oy + ++OUI:143FA6* ++ ID_OUI_FROM_DATABASE=Sony Home Entertainment&Sound Products Inc ++ ++OUI:143FC3* ++ ID_OUI_FROM_DATABASE=SnapAV ++ + OUI:144146* + ID_OUI_FROM_DATABASE=Honeywell (China) Co., LTD + + OUI:1441E2* + ID_OUI_FROM_DATABASE=Monaco Enterprises, Inc. + ++OUI:1442FC* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:144319* + ID_OUI_FROM_DATABASE=Creative&Link Technology Limited + + OUI:14444A* + ID_OUI_FROM_DATABASE=Apollo Seiko Ltd. + ++OUI:144658* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1446E4* + ID_OUI_FROM_DATABASE=AVISTEL + ++OUI:14472D* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:144802* + ID_OUI_FROM_DATABASE=THE YEOLRIM Co.,Ltd. + +@@ -42398,6 +44057,9 @@ OUI:14488B* + OUI:144978* + ID_OUI_FROM_DATABASE=Digital Control Incorporated + ++OUI:1449BC* ++ ID_OUI_FROM_DATABASE=DrayTek Corp. ++ + OUI:1449E0* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + +@@ -42407,6 +44069,9 @@ OUI:144C1A* + OUI:144D67* + ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. + ++OUI:144E2A* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ + OUI:144E34* + ID_OUI_FROM_DATABASE=Remote Solution + +@@ -42414,7 +44079,7 @@ OUI:144F8A* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:144FD70* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:144FD71* + ID_OUI_FROM_DATABASE=Zehnder Group AG +@@ -42458,9 +44123,24 @@ OUI:144FD7D* + OUI:144FD7E* + ID_OUI_FROM_DATABASE=Edan Instruments, Inc. + ++OUI:145051* ++ ID_OUI_FROM_DATABASE=SHARP Corporation ++ ++OUI:145120* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:14517E* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:145290* ++ ID_OUI_FROM_DATABASE=KNS Group LLC (YADRO Company) ++ + OUI:145412* + ID_OUI_FROM_DATABASE=Entis Co., Ltd. + ++OUI:14563A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:145645* + ID_OUI_FROM_DATABASE=Savitech Corp. + +@@ -42470,18 +44150,27 @@ OUI:14568E* + OUI:14579F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:145808* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:1458D0* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:1459C0* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:1459C3* ++ ID_OUI_FROM_DATABASE=Creative Chips GmbH ++ + OUI:145A05* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:145A83* + ID_OUI_FROM_DATABASE=Logi-D inc + ++OUI:145AFC* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:145BD1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -42489,7 +44178,10 @@ OUI:145BE1* + ID_OUI_FROM_DATABASE=nyantec GmbH + + OUI:145E45* +- ID_OUI_FROM_DATABASE=Kaleao Limited ++ ID_OUI_FROM_DATABASE=Bamboo Systems Group ++ ++OUI:145E69* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + + OUI:145F94* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -42497,6 +44189,9 @@ OUI:145F94* + OUI:146080* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:1460CB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:146102* + ID_OUI_FROM_DATABASE=Alpine Electronics, Inc. + +@@ -42506,12 +44201,18 @@ OUI:14612F* + OUI:146308* + ID_OUI_FROM_DATABASE=JABIL CIRCUIT (SHANGHAI) LTD. + ++OUI:1469A2* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:146A0B* + ID_OUI_FROM_DATABASE=Cypress Electronics Limited + + OUI:146B72* + ID_OUI_FROM_DATABASE=Shenzhen Fortune Ship Technology Co., Ltd. + ++OUI:146B9A* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:146B9C* + ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD + +@@ -42527,29 +44228,56 @@ OUI:147411* + OUI:147590* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:147740* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:14780B* + ID_OUI_FROM_DATABASE=Varex Imaging Deutschland AG + + OUI:1479F3* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + ++OUI:147BAC* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:147D05* ++ ID_OUI_FROM_DATABASE=SERCOMM PHILIPPINES INC ++ + OUI:147DB3* + ID_OUI_FROM_DATABASE=JOA TELECOM.CO.,LTD + + OUI:147DC5* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:147DDA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14825B* + ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd + ++OUI:148430* ++ ID_OUI_FROM_DATABASE=MITAC COMPUTING TECHNOLOGY CORPORATION ++ ++OUI:14857F* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:148692* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:14876A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:1488E6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:148919* ++ ID_OUI_FROM_DATABASE=2bps ++ + OUI:14893E* + ID_OUI_FROM_DATABASE=VIXTEL TECHNOLOGIES LIMTED + +-OUI:148951* +- ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++OUI:1489CB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:1489FD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -42557,6 +44285,9 @@ OUI:1489FD* + OUI:148A70* + ID_OUI_FROM_DATABASE=ADS GmbH + ++OUI:148C4A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:148F21* + ID_OUI_FROM_DATABASE=Garmin International + +@@ -42566,6 +44297,9 @@ OUI:148FC6* + OUI:149090* + ID_OUI_FROM_DATABASE=KongTop industrial(shen zhen)CO.,LTD + ++OUI:149138* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:149182* + ID_OUI_FROM_DATABASE=Belkin International Inc. + +@@ -42578,9 +44312,15 @@ OUI:14942F* + OUI:149448* + ID_OUI_FROM_DATABASE=BLU CASTLE S.A. + ++OUI:1495CE* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:1496E5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:149877* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14987D* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + +@@ -42596,6 +44336,9 @@ OUI:149B2F* + OUI:149D09* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:149D99* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:149ECF* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -42603,7 +44346,7 @@ OUI:149F3C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:149FB6* +- ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO.,LTD. ++ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO., LTD. + + OUI:149FE8* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. +@@ -42611,9 +44354,21 @@ OUI:149FE8* + OUI:14A0F8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:14A1BF* ++ ID_OUI_FROM_DATABASE=ASSA ABLOY Korea Co., Ltd Unilock ++ ++OUI:14A2A0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:14A32F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:14A364* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:14A3B4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:14A51A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -42629,15 +44384,72 @@ OUI:14A78B* + OUI:14A86B* + ID_OUI_FROM_DATABASE=ShenZhen Telacom Science&Technology Co., Ltd + ++OUI:14A9D0* ++ ID_OUI_FROM_DATABASE=F5 Networks, Inc. ++ + OUI:14A9E3* + ID_OUI_FROM_DATABASE=MST CORPORATION + ++OUI:14AB02* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:14AB56* ++ ID_OUI_FROM_DATABASE=WUXI FUNIDE DIGITAL CO.,LTD ++ + OUI:14ABC5* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:14ABF0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:14ADCA* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ ++OUI:14AE850* ++ ID_OUI_FROM_DATABASE=Kayamatics Limited ++ ++OUI:14AE851* ++ ID_OUI_FROM_DATABASE=Henfred Technology Co., Ltd. ++ ++OUI:14AE852* ++ ID_OUI_FROM_DATABASE=Qingdao iTechene Technologies Co., Ltd. ++ ++OUI:14AE853* ++ ID_OUI_FROM_DATABASE=IFLYTEK CO.,LTD. ++ ++OUI:14AE854* ++ ID_OUI_FROM_DATABASE=CENTERVUE SPA ++ ++OUI:14AE855* ++ ID_OUI_FROM_DATABASE=AZ-TECHNOLOGY SDN BHD ++ ++OUI:14AE856* ++ ID_OUI_FROM_DATABASE=TMG TE GmbH ++ ++OUI:14AE857* ++ ID_OUI_FROM_DATABASE=SHENZHEN HONOR ELECTRONIC CO.,LTD ++ ++OUI:14AE858* ++ ID_OUI_FROM_DATABASE=Trimble LEM ++ ++OUI:14AE859* ++ ID_OUI_FROM_DATABASE=Veo Technologies ++ ++OUI:14AE85A* ++ ID_OUI_FROM_DATABASE=MTA Systems ++ ++OUI:14AE85B* ++ ID_OUI_FROM_DATABASE=NTC SOFT ++ ++OUI:14AE85C* ++ ID_OUI_FROM_DATABASE=IO Industries Inc. ++ ++OUI:14AE85D* ++ ID_OUI_FROM_DATABASE=iSolution Technologies Co.,Ltd. ++ ++OUI:14AE85E* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:14AEDB* + ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd. + +@@ -42647,12 +44459,18 @@ OUI:14B126* + OUI:14B1C8* + ID_OUI_FROM_DATABASE=InfiniWing, Inc. + ++OUI:14B2E5* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ + OUI:14B31F* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:14B370* + ID_OUI_FROM_DATABASE=Gigaset Digital Technology (Shenzhen) Co., Ltd. + ++OUI:14B457* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:14B484* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -42674,15 +44492,24 @@ OUI:14BB6E* + OUI:14BD61* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:14C03E* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:14C089* + ID_OUI_FROM_DATABASE=DUNE HD LTD + + OUI:14C126* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:14C14E* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:14C1FF* + ID_OUI_FROM_DATABASE=ShenZhen QianHai Comlan communication Co.,LTD + ++OUI:14C213* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14C21D* + ID_OUI_FROM_DATABASE=Sabtech Industries + +@@ -42692,15 +44519,24 @@ OUI:14C3C2* + OUI:14C697* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:14C88B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14C913* + ID_OUI_FROM_DATABASE=LG Electronics + + OUI:14CAA0* + ID_OUI_FROM_DATABASE=Hu&Co + ++OUI:14CB19* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:14CC20* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:14CCB3* ++ ID_OUI_FROM_DATABASE=AO GK NATEKS ++ + OUI:14CF8D* + ID_OUI_FROM_DATABASE=OHSUNG + +@@ -42710,12 +44546,18 @@ OUI:14CF92* + OUI:14CFE2* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:14D00D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14D11F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:14D169* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:14D19E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:14D4FE* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -42731,12 +44573,18 @@ OUI:14DAE9* + OUI:14DB85* + ID_OUI_FROM_DATABASE=S NET MEDIA + ++OUI:14DD9C* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:14DDA9* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:14DDE5* + ID_OUI_FROM_DATABASE=MPMKVVCL + ++OUI:14DE39* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:14E4EC* + ID_OUI_FROM_DATABASE=mLogic LLC + +@@ -42749,6 +44597,9 @@ OUI:14E7C8* + OUI:14E9B2* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:14EB08* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:14EB33* + ID_OUI_FROM_DATABASE=BSMediasoft Co., Ltd. + +@@ -42764,6 +44615,9 @@ OUI:14EDE4* + OUI:14EE9D* + ID_OUI_FROM_DATABASE=AirNav Systems LLC + ++OUI:14EFCF* ++ ID_OUI_FROM_DATABASE=SCHREDER ++ + OUI:14F0C5* + ID_OUI_FROM_DATABASE=Xtremio Ltd. + +@@ -42776,6 +44630,9 @@ OUI:14F42A* + OUI:14F65A* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:14F6D8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:14F893* + ID_OUI_FROM_DATABASE=Wuhan FiberHome Digital Technology Co.,Ltd. + +@@ -42786,7 +44643,7 @@ OUI:14FEB5* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:18002D* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:1800DB* + ID_OUI_FROM_DATABASE=Fitbit Inc. +@@ -42797,18 +44654,36 @@ OUI:18017D* + OUI:1801E3* + ID_OUI_FROM_DATABASE=Bittium Wireless Ltd + ++OUI:1801F1* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:18022D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:1802AE* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:180373* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:1803FA* + ID_OUI_FROM_DATABASE=IBT Interfaces + ++OUI:1804ED* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:180675* + ID_OUI_FROM_DATABASE=Dilax Intelcom GmbH + ++OUI:1806F5* ++ ID_OUI_FROM_DATABASE=RAD Data Communications, Ltd. ++ + OUI:1806FF* + ID_OUI_FROM_DATABASE=Acer Computer(Shanghai) Limited. + ++OUI:180712* ++ ID_OUI_FROM_DATABASE=Shenzhen Dazoo Technologies CO.,Ltd ++ + OUI:180B52* + ID_OUI_FROM_DATABASE=Nanotron Technologies GmbH + +@@ -42821,21 +44696,33 @@ OUI:180C77* + OUI:180CAC* + ID_OUI_FROM_DATABASE=CANON INC. + ++OUI:180D2C* ++ ID_OUI_FROM_DATABASE=Intelbras ++ + OUI:180F76* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:18104E* + ID_OUI_FROM_DATABASE=CEDINT-UPM + ++OUI:181171* ++ ID_OUI_FROM_DATABASE=Guangzhou Doctorpai Education & Technology Co.,Ltd ++ + OUI:181212* + ID_OUI_FROM_DATABASE=Cepton Technologies + ++OUI:18132D* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:181420* + ID_OUI_FROM_DATABASE=TEB SAS + + OUI:181456* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:18146C* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:1816C9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -42845,9 +44732,15 @@ OUI:181714* + OUI:181725* + ID_OUI_FROM_DATABASE=Cameo Communications, Inc. + ++OUI:18188B* ++ ID_OUI_FROM_DATABASE=FUJITSU CONNECTED TECHNOLOGIES LIMITED ++ + OUI:18193F* + ID_OUI_FROM_DATABASE=Tamtron Oy + ++OUI:1819D6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:181BEB* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +@@ -42857,6 +44750,9 @@ OUI:181DEA* + OUI:181E78* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:181E95* ++ ID_OUI_FROM_DATABASE=AuVerte ++ + OUI:181EB0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -42872,21 +44768,36 @@ OUI:18204C* + OUI:1820A6* + ID_OUI_FROM_DATABASE=Sage Co., Ltd. + ++OUI:1820D5* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:182195* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:18227E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:182649* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:182666* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:182861* + ID_OUI_FROM_DATABASE=AirTies Wireless Networks + ++OUI:182A44* ++ ID_OUI_FROM_DATABASE=HIROSE ELECTRONIC SYSTEM ++ ++OUI:182A57* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:182A7B* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:182AD3* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:182B05* + ID_OUI_FROM_DATABASE=8D Technologies + +@@ -42902,9 +44813,15 @@ OUI:182D98* + OUI:183009* + ID_OUI_FROM_DATABASE=Woojin Industrial Systems Co., Ltd. + ++OUI:18300C* ++ ID_OUI_FROM_DATABASE=Hisense Electric Co.,Ltd ++ + OUI:1831BF* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:183219* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:1832A2* + ID_OUI_FROM_DATABASE=LAON TECHNOLOGY CO., LTD. + +@@ -42917,6 +44834,9 @@ OUI:183451* + OUI:1835D1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:183672* ++ ID_OUI_FROM_DATABASE=Shaoxing ShunChuang Technology CO.,LTD ++ + OUI:1836FC* + ID_OUI_FROM_DATABASE=Elecsys International Corporation + +@@ -42926,12 +44846,18 @@ OUI:183825* + OUI:183864* + ID_OUI_FROM_DATABASE=CAP-TECH INTERNATIONAL CO., LTD. + ++OUI:1838AE* ++ ID_OUI_FROM_DATABASE=CONSPIN SOLUTION ++ + OUI:183919* + ID_OUI_FROM_DATABASE=Unicoi Systems + + OUI:18396E* + ID_OUI_FROM_DATABASE=SUNSEA TELECOMMUNICATIONS CO.,LTD. + ++OUI:18399C* ++ ID_OUI_FROM_DATABASE=Skorpios Technologies ++ + OUI:183A2D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -42941,50 +44867,101 @@ OUI:183A48* + OUI:183BD2* + ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd. + ++OUI:183CB7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:183D5E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:183DA2* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:183EEF* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:183F47* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:1840A4* + ID_OUI_FROM_DATABASE=Shenzhen Trylong Smart Science and Technology Co., Ltd. + ++OUI:1841FE* ++ ID_OUI_FROM_DATABASE=Digital 14 ++ + OUI:18421D* + ID_OUI_FROM_DATABASE=Private + + OUI:18422F* + ID_OUI_FROM_DATABASE=Alcatel Lucent + ++OUI:1842D4* ++ ID_OUI_FROM_DATABASE=Wuhan Hosan Telecommunication Technology Co.,Ltd ++ + OUI:184462* + ID_OUI_FROM_DATABASE=Riava Networks, Inc. + + OUI:1844E6* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:184516* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:184593* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:184617* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:184644* ++ ID_OUI_FROM_DATABASE=Home Control Singapore Pte Ltd ++ ++OUI:18473D* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:184859* ++ ID_OUI_FROM_DATABASE=Castlenet Technology Inc. ++ ++OUI:1848CA* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:1848D8* + ID_OUI_FROM_DATABASE=Fastback Networks + + OUI:184A6F* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + ++OUI:184B0D* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ ++OUI:184BDF* ++ ID_OUI_FROM_DATABASE=Caavo Inc ++ + OUI:184C08* + ID_OUI_FROM_DATABASE=Rockwell Automation + ++OUI:184CAE* ++ ID_OUI_FROM_DATABASE=CONTINENTAL ++ ++OUI:184E16* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:184E94* + ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC. + ++OUI:184ECB* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:184F32* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:184F5D* ++ ID_OUI_FROM_DATABASE=JRC Mobility Inc. ++ + OUI:18502A* + ID_OUI_FROM_DATABASE=SOARNEX + + OUI:185207* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:185253* + ID_OUI_FROM_DATABASE=Pixord Corporation +@@ -42995,21 +44972,42 @@ OUI:185282* + OUI:1853E0* + ID_OUI_FROM_DATABASE=Hanyang Digitech Co.Ltd + ++OUI:1854CF* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:18550F* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:1855E3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:185644* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:185680* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:1856C3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:185869* ++ ID_OUI_FROM_DATABASE=Sailer Electronic Co., Ltd ++ + OUI:185933* + ID_OUI_FROM_DATABASE=Cisco SPVTG + + OUI:185936* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:185A58* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:185AE8* + ID_OUI_FROM_DATABASE=Zenotech.Co.,Ltd + ++OUI:185BB3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:185D9A* + ID_OUI_FROM_DATABASE=BobjGear LLC + +@@ -43029,7 +45027,7 @@ OUI:1862E4* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:186472* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:186571* + ID_OUI_FROM_DATABASE=Top Victory Electronics (Taiwan) Co., Ltd. +@@ -43064,20 +45062,83 @@ OUI:186882* + OUI:1868CB* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + ++OUI:1869D8* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:1869DA* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + + OUI:186D99* + ID_OUI_FROM_DATABASE=Adanis Inc. + ++OUI:186F2D* ++ ID_OUI_FROM_DATABASE=Shenzhen Sundray Technologies Company Limited ++ ++OUI:18703B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:187117* + ID_OUI_FROM_DATABASE=eta plus electronic gmbh + ++OUI:1871D5* ++ ID_OUI_FROM_DATABASE=Hazens Automotive Electronics(SZ)Co.,Ltd. ++ + OUI:18742E* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:1874E20* ++ ID_OUI_FROM_DATABASE=Ensor AG ++ ++OUI:1874E21* ++ ID_OUI_FROM_DATABASE=Sartorius Lab Instruments GmbH & Co. KG ++ ++OUI:1874E22* ++ ID_OUI_FROM_DATABASE=Shenzhen WITSTECH Co.,Ltd. ++ ++OUI:1874E23* ++ ID_OUI_FROM_DATABASE=CT Company ++ ++OUI:1874E24* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:1874E25* ++ ID_OUI_FROM_DATABASE=HANGZHOU ZHOUJU ELECTRONIC TECHNOLOGICAL CO.,LTD ++ ++OUI:1874E26* ++ ID_OUI_FROM_DATABASE=Beijing Jrunion Technology Co., Ltd. ++ ++OUI:1874E27* ++ ID_OUI_FROM_DATABASE=Sansec Technology Co.,Ltd ++ ++OUI:1874E28* ++ ID_OUI_FROM_DATABASE=Kano Computing Limited ++ ++OUI:1874E29* ++ ID_OUI_FROM_DATABASE=SHENZHEN AORO COMMUNICATION EQUIPMENT CO., LTD ++ ++OUI:1874E2A* ++ ID_OUI_FROM_DATABASE=Linux Automation GmbH ++ ++OUI:1874E2B* ++ ID_OUI_FROM_DATABASE=Shenzhen Jooan Technology Co., Ltd ++ ++OUI:1874E2C* ++ ID_OUI_FROM_DATABASE=NextGen RF Design, Inc. ++ ++OUI:1874E2D* ++ ID_OUI_FROM_DATABASE=Samriddi Automations Pvt. Ltd. ++ ++OUI:1874E2E* ++ ID_OUI_FROM_DATABASE=G&O Audio Co.,LTD ++ + OUI:187532* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:187758* ++ ID_OUI_FROM_DATABASE=Audoo Limited (UK) ++ ++OUI:1878D4* ++ ID_OUI_FROM_DATABASE=Verizon + + OUI:1879A2* + ID_OUI_FROM_DATABASE=GMJ ELECTRIC LIMITED +@@ -43085,9 +45146,15 @@ OUI:1879A2* + OUI:187A93* + ID_OUI_FROM_DATABASE=AMICCOM Electronics Corporation + ++OUI:187C0B* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:187C81* + ID_OUI_FROM_DATABASE=Valeo Vision Systems + ++OUI:187EB9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:187ED5* + ID_OUI_FROM_DATABASE=shenzhen kaism technology Co. Ltd + +@@ -43100,9 +45167,15 @@ OUI:1880CE* + OUI:1880F5* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + ++OUI:18810E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:188219* + ID_OUI_FROM_DATABASE=Alibaba Cloud Computing Ltd. + ++OUI:18828C* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:188331* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -43118,6 +45191,9 @@ OUI:18863A* + OUI:1886AC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + ++OUI:188740* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:188796* + ID_OUI_FROM_DATABASE=HTC Corporation + +@@ -43133,6 +45209,9 @@ OUI:1889A0* + OUI:1889DF* + ID_OUI_FROM_DATABASE=CerebrEX Inc. + ++OUI:188A6A* ++ ID_OUI_FROM_DATABASE=AVPro Global Hldgs ++ + OUI:188B15* + ID_OUI_FROM_DATABASE=ShenZhen ZhongRuiJing Technology co.,LTD + +@@ -43148,12 +45227,18 @@ OUI:188ED5* + OUI:188EF9* + ID_OUI_FROM_DATABASE=G2C Co. Ltd. + ++OUI:189088* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:1890D8* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + + OUI:18922C* + ID_OUI_FROM_DATABASE=Virtual Instruments + ++OUI:1892A4* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ + OUI:18937F* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + +@@ -43163,6 +45248,9 @@ OUI:1893D7* + OUI:1894C6* + ID_OUI_FROM_DATABASE=ShenZhen Chenyee Technology Co., Ltd. + ++OUI:189552* ++ ID_OUI_FROM_DATABASE=1MORE ++ + OUI:1897FF* + ID_OUI_FROM_DATABASE=TechFaith Wireless Technology Limited + +@@ -43223,6 +45311,9 @@ OUI:189C27* + OUI:189C5D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:189E2C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:189EFC* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -43232,9 +45323,15 @@ OUI:18A28A* + OUI:18A3E8* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:18A4A9* ++ ID_OUI_FROM_DATABASE=Vanu Inc. ++ + OUI:18A6F7* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:18A7F1* ++ ID_OUI_FROM_DATABASE=Qingdao Haier Technology Co.,Ltd ++ + OUI:18A905* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -43244,9 +45341,18 @@ OUI:18A958* + OUI:18A99B* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:18AA0F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:18AA45* + ID_OUI_FROM_DATABASE=Fon Technology + ++OUI:18AACA* ++ ID_OUI_FROM_DATABASE=Sichuan tianyi kanghe communications co., LTD ++ ++OUI:18AB1D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:18ABF5* + ID_OUI_FROM_DATABASE=Ultra Electronics Electrics + +@@ -43283,24 +45389,54 @@ OUI:18B430* + OUI:18B591* + ID_OUI_FROM_DATABASE=I-Storm + ++OUI:18B6CC* ++ ID_OUI_FROM_DATABASE=We Corporation Inc. ++ ++OUI:18B6F7* ++ ID_OUI_FROM_DATABASE=NEW POS TECHNOLOGY LIMITED ++ + OUI:18B79E* + ID_OUI_FROM_DATABASE=Invoxia + + OUI:18B81F* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:18B905* ++ ID_OUI_FROM_DATABASE=Hong Kong Bouffalo Lab Limited ++ ++OUI:18BB26* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ ++OUI:18BB41* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:18BC5A* + ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. + + OUI:18BDAD* + ID_OUI_FROM_DATABASE=L-TECH CORPORATION + ++OUI:18BE92* ++ ID_OUI_FROM_DATABASE=Delta Networks, Inc. ++ ++OUI:18BF1C* ++ ID_OUI_FROM_DATABASE=Jiangsu Huitong Group Co.,Ltd. ++ ++OUI:18BFB3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Memory Division ++ ++OUI:18C04D* ++ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. ++ + OUI:18C086* + ID_OUI_FROM_DATABASE=Broadcom + + OUI:18C19D* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:18C241* ++ ID_OUI_FROM_DATABASE=SonicWall ++ + OUI:18C2BF* + ID_OUI_FROM_DATABASE=BUFFALO.INC + +@@ -43316,18 +45452,30 @@ OUI:18C58A* + OUI:18C8E7* + ID_OUI_FROM_DATABASE=Shenzhen Hualistone Technology Co.,Ltd + ++OUI:18CC18* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:18CC23* + ID_OUI_FROM_DATABASE=Philio Technology Corporation + + OUI:18CC88* + ID_OUI_FROM_DATABASE=Hitachi Johnson Controls Air + ++OUI:18CE94* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:18CF24* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:18CF5E* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + + OUI:18D071* + ID_OUI_FROM_DATABASE=DASAN CO., LTD. + ++OUI:18D0C5* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:18D225* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -43337,6 +45485,9 @@ OUI:18D276* + OUI:18D5B6* + ID_OUI_FROM_DATABASE=SMG Holdings LLC + ++OUI:18D61C* ++ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. ++ + OUI:18D66A* + ID_OUI_FROM_DATABASE=Inmarsat + +@@ -43352,6 +45503,12 @@ OUI:18D717* + OUI:18D949* + ID_OUI_FROM_DATABASE=Qvis Labs, LLC + ++OUI:18D98F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:18D9EF* ++ ID_OUI_FROM_DATABASE=Shuttle Inc. ++ + OUI:18DBF2* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -43361,6 +45518,21 @@ OUI:18DC56* + OUI:18DED7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:18DFB4* ++ ID_OUI_FROM_DATABASE=BOSUNG POWERTEC CO.,LTD. ++ ++OUI:18DFC1* ++ ID_OUI_FROM_DATABASE=Aetheros ++ ++OUI:18E1CA* ++ ID_OUI_FROM_DATABASE=wanze ++ ++OUI:18E1DE* ++ ID_OUI_FROM_DATABASE=Chengdu ChipIntelli Technology Co., Ltd ++ ++OUI:18E215* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:18E288* + ID_OUI_FROM_DATABASE=STT Condigi + +@@ -43376,6 +45548,9 @@ OUI:18E3BC* + OUI:18E728* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:18E777* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:18E7F4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -43388,9 +45563,18 @@ OUI:18E829* + OUI:18E8DD* + ID_OUI_FROM_DATABASE=MODULETEK + ++OUI:18ECE7* ++ ID_OUI_FROM_DATABASE=BUFFALO.INC ++ + OUI:18EE69* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:18EE86* ++ ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc. ++ ++OUI:18EF3A* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:18EF63* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -43400,6 +45584,9 @@ OUI:18F0E4* + OUI:18F145* + ID_OUI_FROM_DATABASE=NetComm Wireless Limited + ++OUI:18F18E* ++ ID_OUI_FROM_DATABASE=ChipER Technology co. ltd ++ + OUI:18F1D8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -43421,15 +45608,69 @@ OUI:18F76B* + OUI:18F87A* + ID_OUI_FROM_DATABASE=i3 International Inc. + ++OUI:18F87F* ++ ID_OUI_FROM_DATABASE=Wha Yu Industrial Co., Ltd. ++ ++OUI:18F9C4* ++ ID_OUI_FROM_DATABASE=BAE Systems ++ + OUI:18FA6F* + ID_OUI_FROM_DATABASE=ISC applied systems corp + + OUI:18FB7B* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:18FC26* ++ ID_OUI_FROM_DATABASE=Qorvo International Pte. Ltd. ++ + OUI:18FC9F* + ID_OUI_FROM_DATABASE=Changhe Electronics Co., Ltd. + ++OUI:18FDCB0* ++ ID_OUI_FROM_DATABASE=Shenzhen Rui jiali Electronic Technology Co. Ltd. ++ ++OUI:18FDCB1* ++ ID_OUI_FROM_DATABASE=SOTHIS CIC TEC (Shanghai) Co., Ltd ++ ++OUI:18FDCB2* ++ ID_OUI_FROM_DATABASE=Cabtronix AG ++ ++OUI:18FDCB3* ++ ID_OUI_FROM_DATABASE=Staclar, Inc. ++ ++OUI:18FDCB4* ++ ID_OUI_FROM_DATABASE=Gosuncn Technology Group Co.,LTD. ++ ++OUI:18FDCB5* ++ ID_OUI_FROM_DATABASE=Accel Robotics ++ ++OUI:18FDCB6* ++ ID_OUI_FROM_DATABASE=SKA Organisation ++ ++OUI:18FDCB7* ++ ID_OUI_FROM_DATABASE=ENERGIE IP ++ ++OUI:18FDCB8* ++ ID_OUI_FROM_DATABASE=CISTECH Solutions ++ ++OUI:18FDCB9* ++ ID_OUI_FROM_DATABASE=CreyNox GmbH ++ ++OUI:18FDCBA* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:18FDCBB* ++ ID_OUI_FROM_DATABASE=TRANSLITE GLOBAL LLC ++ ++OUI:18FDCBC* ++ ID_OUI_FROM_DATABASE=Ark Vision Systems GmbH & Co. KG ++ ++OUI:18FDCBD* ++ ID_OUI_FROM_DATABASE=StreamLocator ++ ++OUI:18FDCBE* ++ ID_OUI_FROM_DATABASE=KWANG YANG MOTOR CO.,LTD ++ + OUI:18FE34* + ID_OUI_FROM_DATABASE=Espressif Inc. + +@@ -43442,11 +45683,20 @@ OUI:18FF2E* + OUI:1C0042* + ID_OUI_FROM_DATABASE=NARI Technology Co., Ltd. + ++OUI:1C012D* ++ ID_OUI_FROM_DATABASE=Ficer Technology ++ ++OUI:1C0219* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:1C05B7* ++ ID_OUI_FROM_DATABASE=Chongqing Trantor Technology Co., Ltd. ++ + OUI:1C0656* + ID_OUI_FROM_DATABASE=IDY Corporation + + OUI:1C08C1* +- ID_OUI_FROM_DATABASE=Lg Innotek ++ ID_OUI_FROM_DATABASE=LG Innotek + + OUI:1C0B52* + ID_OUI_FROM_DATABASE=EPICOM S.A +@@ -43466,6 +45716,15 @@ OUI:1C11E1* + OUI:1C129D* + ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB + ++OUI:1C12B0* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:1C1338* ++ ID_OUI_FROM_DATABASE=Kimball Electronics Group, LLC ++ ++OUI:1C1386* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:1C1448* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -43487,6 +45746,9 @@ OUI:1C19DE* + OUI:1C1AC0* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:1C1ADF* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:1C1B0D* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +@@ -43505,12 +45767,21 @@ OUI:1C1D67* + OUI:1C1D86* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:1C1E38* ++ ID_OUI_FROM_DATABASE=PCCW Global, Inc. ++ + OUI:1C1EE3* + ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD + + OUI:1C1FD4* + ID_OUI_FROM_DATABASE=LifeBEAM Technologies LTD + ++OUI:1C1FF1* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:1C20DB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1C21D10* + ID_OUI_FROM_DATABASE=Toyo System CO.,LTD. + +@@ -43565,12 +45836,39 @@ OUI:1C232C* + OUI:1C234F* + ID_OUI_FROM_DATABASE=EDMI Europe Ltd + ++OUI:1C24CD* ++ ID_OUI_FROM_DATABASE=Askey Computer Corp. ++ ++OUI:1C24EB* ++ ID_OUI_FROM_DATABASE=Burlywood ++ + OUI:1C25E1* + ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited + ++OUI:1C2704* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:1C27DD* + ID_OUI_FROM_DATABASE=Datang Gohighsec(zhejiang)Information Technology Co.,Ltd. + ++OUI:1C28AF* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:1C2A8B* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:1C2AA3* ++ ID_OUI_FROM_DATABASE=Shenzhen HongRui Optical Technology Co., Ltd. ++ ++OUI:1C2CE0* ++ ID_OUI_FROM_DATABASE=Shanghai Mountain View Silicon ++ ++OUI:1C2E1B* ++ ID_OUI_FROM_DATABASE=Suzhou Tremenet Communication Technology Co., Ltd. ++ ++OUI:1C3008* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:1C330E* + ID_OUI_FROM_DATABASE=PernixData + +@@ -43580,6 +45878,9 @@ OUI:1C334D* + OUI:1C3477* + ID_OUI_FROM_DATABASE=Innovation Wireless + ++OUI:1C34DA* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ + OUI:1C35F1* + ID_OUI_FROM_DATABASE=NEW Lift Neue Elektronische Wege Steuerungsbau GmbH + +@@ -43589,6 +45890,9 @@ OUI:1C36BB* + OUI:1C37BF* + ID_OUI_FROM_DATABASE=Cloudium Systems Ltd. + ++OUI:1C3929* ++ ID_OUI_FROM_DATABASE=OHSUNG ++ + OUI:1C3947* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +@@ -43598,9 +45902,24 @@ OUI:1C398A* + OUI:1C3A4F* + ID_OUI_FROM_DATABASE=AccuSpec Electronics, LLC + ++OUI:1C3A60* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:1C3ADE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:1C3B8F* ++ ID_OUI_FROM_DATABASE=Selve GmbH & Co. KG ++ ++OUI:1C3BF3* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:1C3CD4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:1C3D2F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1C3DE7* + ID_OUI_FROM_DATABASE=Sigma Koki Co.,Ltd. + +@@ -43616,15 +45935,36 @@ OUI:1C40E8* + OUI:1C4158* + ID_OUI_FROM_DATABASE=Gemalto M2M GmbH + ++OUI:1C4176* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:1C4190* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ ++OUI:1C427D* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:1C4363* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1C43EC* + ID_OUI_FROM_DATABASE=JAPAN CIRCUIT CO.,LTD + + OUI:1C4419* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:1C4455* ++ ID_OUI_FROM_DATABASE=Sieb & Meyer AG ++ + OUI:1C4593* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:1C45C2* ++ ID_OUI_FROM_DATABASE=Huizhou City Sunsin lntelligent Technology Co.,Ltd ++ ++OUI:1C472F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:1C4840* + ID_OUI_FROM_DATABASE=IMS Messsysteme GmbH + +@@ -43646,9 +45986,18 @@ OUI:1C4BB9* + OUI:1C4BD6* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:1C4C48* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ ++OUI:1C4D66* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:1C4D70* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:1C501E* ++ ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd. ++ + OUI:1C51B5* + ID_OUI_FROM_DATABASE=Techaya LTD + +@@ -43658,15 +46007,27 @@ OUI:1C5216* + OUI:1C52D6* + ID_OUI_FROM_DATABASE=FLAT DISPLAY TECHNOLOGY CORPORATION + ++OUI:1C53F9* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:1C549E* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:1C553A* + ID_OUI_FROM_DATABASE=QianGua Corp. + + OUI:1C56FE* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:1C573E* ++ ID_OUI_FROM_DATABASE=Altice Labs S.A. ++ + OUI:1C57D8* + ID_OUI_FROM_DATABASE=Kraftway Corporation PLC + ++OUI:1C599B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1C5A0B* + ID_OUI_FROM_DATABASE=Tegile Systems + +@@ -43685,12 +46046,18 @@ OUI:1C5C60* + OUI:1C5CF2* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:1C5D80* ++ ID_OUI_FROM_DATABASE=Mitubishi Hitachi Power Systems Industries Co., Ltd. ++ + OUI:1C5F2B* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:1C5FFF* + ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch + ++OUI:1C60D2* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:1C60DE* + ID_OUI_FROM_DATABASE=MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + +@@ -43700,6 +46067,12 @@ OUI:1C62B8* + OUI:1C63B7* + ID_OUI_FROM_DATABASE=OpenProducts 237 AB + ++OUI:1C63BF* ++ ID_OUI_FROM_DATABASE=SHENZHEN BROADTEL TELECOM CO.,LTD ++ ++OUI:1C6499* ++ ID_OUI_FROM_DATABASE=Comtrend Corporation ++ + OUI:1C659D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -43712,6 +46085,12 @@ OUI:1C66AA* + OUI:1C6758* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:1C687E* ++ ID_OUI_FROM_DATABASE=Shenzhen Qihu Intelligent Technology Company Limited ++ ++OUI:1C697A* ++ ID_OUI_FROM_DATABASE=EliteGroup Computer Systems Co., LTD ++ + OUI:1C69A5* + ID_OUI_FROM_DATABASE=BlackBerry RTS + +@@ -43727,12 +46106,18 @@ OUI:1C6E4C* + OUI:1C6E76* + ID_OUI_FROM_DATABASE=Quarion Technology Inc + ++OUI:1C6EE6* ++ ID_OUI_FROM_DATABASE=NHNETWORKS ++ + OUI:1C6F65* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + + OUI:1C7022* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:1C721D* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:1C7328* + ID_OUI_FROM_DATABASE=Connected Home + +@@ -43754,8 +46139,11 @@ OUI:1C77F6* + OUI:1C7839* + ID_OUI_FROM_DATABASE=Shenzhen Tencent Computer System Co., Ltd. + ++OUI:1C784E* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ + OUI:1C7B21* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:1C7B23* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd. +@@ -43770,7 +46158,7 @@ OUI:1C7CC7* + ID_OUI_FROM_DATABASE=Coriant GmbH + + OUI:1C7D22* +- ID_OUI_FROM_DATABASE=Fuji Xerox Co., Ltd. ++ ID_OUI_FROM_DATABASE=FUJIFILM Business Innovation Corp. + + OUI:1C7E51* + ID_OUI_FROM_DATABASE=3bumen.com +@@ -43778,6 +46166,54 @@ OUI:1C7E51* + OUI:1C7EE5* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:1C7F2C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:1C82590* ++ ID_OUI_FROM_DATABASE=Shandong Luneng Intelligence Technology CO., Ltd ++ ++OUI:1C82591* ++ ID_OUI_FROM_DATABASE=3xLOGIC Inc. ++ ++OUI:1C82592* ++ ID_OUI_FROM_DATABASE=Diatrend Corporation ++ ++OUI:1C82593* ++ ID_OUI_FROM_DATABASE=C&A Marketing, INC. ++ ++OUI:1C82594* ++ ID_OUI_FROM_DATABASE=winsun AG ++ ++OUI:1C82595* ++ ID_OUI_FROM_DATABASE=Fagus-GreCon Greten GmbH & Co. KG ++ ++OUI:1C82596* ++ ID_OUI_FROM_DATABASE=CGI IT UK LIMITED ++ ++OUI:1C82597* ++ ID_OUI_FROM_DATABASE=Jump Trading ++ ++OUI:1C82598* ++ ID_OUI_FROM_DATABASE=SHENZHEN AOA TECHNOLOGY CO.,LTD ++ ++OUI:1C82599* ++ ID_OUI_FROM_DATABASE=Shanghai Xiaoyan Technology Co., Ltd. ++ ++OUI:1C8259A* ++ ID_OUI_FROM_DATABASE=ESTec Corporation ++ ++OUI:1C8259B* ++ ID_OUI_FROM_DATABASE=KeyWest Networks, Inc ++ ++OUI:1C8259C* ++ ID_OUI_FROM_DATABASE=Evondos Oy ++ ++OUI:1C8259D* ++ ID_OUI_FROM_DATABASE=Applied Concepts, Inc. ++ ++OUI:1C8259E* ++ ID_OUI_FROM_DATABASE=Microtronics Engineering GmbH ++ + OUI:1C8341* + ID_OUI_FROM_DATABASE=Hefei Bitland Information Technology Co.Ltd + +@@ -43928,11 +46364,17 @@ OUI:1C8779D* + OUI:1C8779E* + ID_OUI_FROM_DATABASE=ASSYSTEM France + ++OUI:1C87E3* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ ++OUI:1C880C* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:1C88790* + ID_OUI_FROM_DATABASE=Newps co.,ltd + + OUI:1C88791* +- ID_OUI_FROM_DATABASE=ANDRA Sp. z o.o. ++ ID_OUI_FROM_DATABASE=ANDRA Sp. z o. o. + + OUI:1C88792* + ID_OUI_FROM_DATABASE=Airsmart System Co.,Ltd +@@ -43982,12 +46424,27 @@ OUI:1C8E8E* + OUI:1C8F8A* + ID_OUI_FROM_DATABASE=Phase Motion Control SpA + ++OUI:1C90BE* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ + OUI:1C9148* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:1C9179* + ID_OUI_FROM_DATABASE=Integrated System Technologies Ltd + ++OUI:1C9180* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:1C919D* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co., Ltd. ++ ++OUI:1C937C* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:1C93C4* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:1C9492* + ID_OUI_FROM_DATABASE=RUAG Schweiz AG + +@@ -44003,24 +46460,45 @@ OUI:1C965A* + OUI:1C973D* + ID_OUI_FROM_DATABASE=PRICOM Design + ++OUI:1C97C5* ++ ID_OUI_FROM_DATABASE=Ynomia Pty Ltd ++ ++OUI:1C98C1* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:1C98EC* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:1C994C* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:1C9957* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:1C9C26* + ID_OUI_FROM_DATABASE=Zoovel Technologies + ++OUI:1C9C8C* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:1C9D3E* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:1C9DC2* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:1C9E46* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:1C9ECB* + ID_OUI_FROM_DATABASE=Beijing Nari Smartchip Microelectronics Company Limited + ++OUI:1C9ECC* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:1C9F4E* ++ ID_OUI_FROM_DATABASE=COOSEA GROUP (HK) COMPANY LIMITED ++ + OUI:1CA0B8* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +@@ -44069,15 +46547,66 @@ OUI:1CA0D3D* + OUI:1CA0D3E* + ID_OUI_FROM_DATABASE=Exicom Tele-Systems Ltd. + ++OUI:1CA0EF0* ++ ID_OUI_FROM_DATABASE=Tangshan Liulin Automation Equipment Co., Ltd. ++ ++OUI:1CA0EF1* ++ ID_OUI_FROM_DATABASE=Wisnu and Supak Co.,Ltd. ++ ++OUI:1CA0EF2* ++ ID_OUI_FROM_DATABASE=Schneider-Electric(China)Co.Ltd,Shenzhen Branch ++ ++OUI:1CA0EF3* ++ ID_OUI_FROM_DATABASE=Sequent AG ++ ++OUI:1CA0EF4* ++ ID_OUI_FROM_DATABASE=Leviathan Solutions Ltd. ++ ++OUI:1CA0EF5* ++ ID_OUI_FROM_DATABASE=Nanjing Bilin Intelligent Identification Technology Co.,Ltd ++ ++OUI:1CA0EF6* ++ ID_OUI_FROM_DATABASE=HANJEN.CHIN CO., LTD. ++ ++OUI:1CA0EF7* ++ ID_OUI_FROM_DATABASE=tec5AG ++ ++OUI:1CA0EF8* ++ ID_OUI_FROM_DATABASE=Zillnk ++ ++OUI:1CA0EF9* ++ ID_OUI_FROM_DATABASE=Atlas Aerospace ++ ++OUI:1CA0EFA* ++ ID_OUI_FROM_DATABASE=Henrich Electronics Corporation ++ ++OUI:1CA0EFB* ++ ID_OUI_FROM_DATABASE=BMK professional electronics GmbH ++ ++OUI:1CA0EFC* ++ ID_OUI_FROM_DATABASE=LLC Gagar.In ++ ++OUI:1CA0EFD* ++ ID_OUI_FROM_DATABASE=Shenzhen Liandian Communication Technology Co.LTD ++ ++OUI:1CA0EFE* ++ ID_OUI_FROM_DATABASE=RDA Microelectronics Technologies (Shanghai) Co. , Ltd ++ + OUI:1CA2B1* + ID_OUI_FROM_DATABASE=ruwido austria gmbh + + OUI:1CA532* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:1CA681* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1CA770* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD + ++OUI:1CA852* ++ ID_OUI_FROM_DATABASE=SENSAIO PTE LTD ++ + OUI:1CAA07* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -44096,6 +46625,9 @@ OUI:1CABC0* + OUI:1CADD1* + ID_OUI_FROM_DATABASE=Bosung Electronics Co., Ltd. + ++OUI:1CAECB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1CAF05* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -44114,9 +46646,15 @@ OUI:1CB17F* + OUI:1CB243* + ID_OUI_FROM_DATABASE=TDC A/S + ++OUI:1CB3E9* ++ ID_OUI_FROM_DATABASE=Shenzhen Zhongke United Communication Technology ++ + OUI:1CB72C* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:1CB796* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:1CB857* + ID_OUI_FROM_DATABASE=Becon Technologies Co,.Ltd. + +@@ -44135,6 +46673,12 @@ OUI:1CBD0E* + OUI:1CBDB9* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:1CBFC0* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:1CBFCE* ++ ID_OUI_FROM_DATABASE=Shenzhen Century Xinyang Technology Co., Ltd ++ + OUI:1CC035* + ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. + +@@ -44183,9 +46727,15 @@ OUI:1CC0E1D* + OUI:1CC0E1E* + ID_OUI_FROM_DATABASE=Yun Yang Fire Safety Equipment Co.,Ltd. + ++OUI:1CC10C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:1CC11A* + ID_OUI_FROM_DATABASE=Wavetronix + ++OUI:1CC1BC* ++ ID_OUI_FROM_DATABASE=Yichip Microelectronics (Hangzhou) Co.,Ltd ++ + OUI:1CC1DE* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -44255,21 +46805,42 @@ OUI:1CCAE3F* + OUI:1CCB99* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:1CCCD6* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:1CCDE5* + ID_OUI_FROM_DATABASE=Shanghai Wind Technologies Co.,Ltd + ++OUI:1CD107* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ ++OUI:1CD1BA* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:1CD1E0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:1CD40C* + ID_OUI_FROM_DATABASE=Kriwan Industrie-Elektronik GmbH + ++OUI:1CD5E2* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:1CD6BD* + ID_OUI_FROM_DATABASE=LEEDARSON LIGHTING CO., LTD. + ++OUI:1CD6BE* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:1CDA27* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:1CDDEA* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:1CDE57* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:1CDEA7* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -44288,18 +46859,39 @@ OUI:1CE192* + OUI:1CE2CC* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:1CE57F* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:1CE61D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:1CE62B* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:1CE639* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:1CE6AD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:1CE6C7* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:1CE85D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:1CEA0B* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:1CEA1B* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:1CEC72* ++ ID_OUI_FROM_DATABASE=Allradio Co., Ltd ++ ++OUI:1CED6F* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:1CEEC9* + ID_OUI_FROM_DATABASE=Elo touch solutions + +@@ -44315,6 +46907,9 @@ OUI:1CF03E* + OUI:1CF061* + ID_OUI_FROM_DATABASE=SCAPS GmbH + ++OUI:1CF29A* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:1CF4CA* + ID_OUI_FROM_DATABASE=Private + +@@ -44327,9 +46922,60 @@ OUI:1CFA68* + OUI:1CFCBB* + ID_OUI_FROM_DATABASE=Realfiction ApS + ++OUI:1CFD080* ++ ID_OUI_FROM_DATABASE=InSeat Solutions, LLC ++ ++OUI:1CFD081* ++ ID_OUI_FROM_DATABASE=Shenzhen SEWO Technology Co.,Ltd. ++ ++OUI:1CFD082* ++ ID_OUI_FROM_DATABASE=HiHi Ltd ++ ++OUI:1CFD083* ++ ID_OUI_FROM_DATABASE=Umeox Innovations Co.,Ltd ++ ++OUI:1CFD084* ++ ID_OUI_FROM_DATABASE=SABIK Offshore GmbH ++ ++OUI:1CFD085* ++ ID_OUI_FROM_DATABASE=Beijing Hengxin Rainbow Information Technology Co.,Ltd ++ ++OUI:1CFD086* ++ ID_OUI_FROM_DATABASE=A&B Technology ++ ++OUI:1CFD087* ++ ID_OUI_FROM_DATABASE=sunweit industrial limited ++ ++OUI:1CFD088* ++ ID_OUI_FROM_DATABASE=ShenZhen DeLippo Technology Co., LTD ++ ++OUI:1CFD089* ++ ID_OUI_FROM_DATABASE=Cobham Slip Rings ++ ++OUI:1CFD08A* ++ ID_OUI_FROM_DATABASE=Banmak Technogies Co.,Ltd ++ ++OUI:1CFD08B* ++ ID_OUI_FROM_DATABASE=guangzhou huiqun intelligent technology co. LTD ++ ++OUI:1CFD08C* ++ ID_OUI_FROM_DATABASE=Shanghai YottaTech Co Ltd (上海尧它科技有限公司) ++ ++OUI:1CFD08D* ++ ID_OUI_FROM_DATABASE=Tianjin Keyvia Electric Co.,Ltd ++ ++OUI:1CFD08E* ++ ID_OUI_FROM_DATABASE=MESHBOX FOUNDATION PTE. LTD. ++ ++OUI:1CFE2B* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:1CFEA7* + ID_OUI_FROM_DATABASE=IDentytech Solutins Ltd. + ++OUI:1CFF59* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:20014F* + ID_OUI_FROM_DATABASE=Linea Research Ltd + +@@ -44348,15 +46994,66 @@ OUI:2005E8* + OUI:2008ED* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:200A0D0* ++ ID_OUI_FROM_DATABASE=halstrup-walcher GmbH ++ ++OUI:200A0D1* ++ ID_OUI_FROM_DATABASE=Wideband Systems, Inc. ++ ++OUI:200A0D2* ++ ID_OUI_FROM_DATABASE=Netinovo Technologies(Shenzhen) Ltd ++ ++OUI:200A0D3* ++ ID_OUI_FROM_DATABASE=Clearly IP Inc ++ ++OUI:200A0D4* ++ ID_OUI_FROM_DATABASE=Virtium ++ ++OUI:200A0D5* ++ ID_OUI_FROM_DATABASE=Shenzhen Zhangyue Technology Co.,Ltd ++ ++OUI:200A0D6* ++ ID_OUI_FROM_DATABASE=Austin Hughes Electronics Ltd. ++ ++OUI:200A0D7* ++ ID_OUI_FROM_DATABASE=Tecnint HTE SRL ++ ++OUI:200A0D8* ++ ID_OUI_FROM_DATABASE=bcheck NV ++ ++OUI:200A0D9* ++ ID_OUI_FROM_DATABASE=Welzek (Beijing) Technologies Co, Ltd ++ ++OUI:200A0DA* ++ ID_OUI_FROM_DATABASE=IRSAP ++ ++OUI:200A0DB* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:200A0DC* ++ ID_OUI_FROM_DATABASE=sehwa ++ ++OUI:200A0DD* ++ ID_OUI_FROM_DATABASE=Bently & EL Co. Ltd. ++ ++OUI:200A0DE* ++ ID_OUI_FROM_DATABASE=HANGZHOU DANGBEI NETWORK TECH.Co.,Ltd ++ + OUI:200A5E* + ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing Co., Ltd. + + OUI:200BC7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:200BCF* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:200CC8* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:200DB0* ++ ID_OUI_FROM_DATABASE=Shenzhen Four Seas Global Link Network Technology Co., Ltd. ++ + OUI:200E95* + ID_OUI_FROM_DATABASE=IEC – TC9 WG43 + +@@ -44366,6 +47063,9 @@ OUI:200F70* + OUI:20107A* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + ++OUI:20114E* ++ ID_OUI_FROM_DATABASE=MeteRSit S.R.L. ++ + OUI:201257* + ID_OUI_FROM_DATABASE=Most Lucky Trading Ltd + +@@ -44384,15 +47084,33 @@ OUI:2016B9* + OUI:2016D8* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:201742* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:20180E* + ID_OUI_FROM_DATABASE=Shenzhen Sunchip Technology Co., Ltd + + OUI:201A06* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:201B88* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co., Ltd. ++ ++OUI:201BC9* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:201D03* + ID_OUI_FROM_DATABASE=Elatec GmbH + ++OUI:201E88* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:201F31* ++ ID_OUI_FROM_DATABASE=Inteno Broadband Technology AB ++ ++OUI:201F3B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:2021A5* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -44402,9 +47120,21 @@ OUI:202564* + OUI:202598* + ID_OUI_FROM_DATABASE=Teleview + ++OUI:2025D2* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:202681* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ ++OUI:20283E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:2028BC* + ID_OUI_FROM_DATABASE=Visionscape Co,. Ltd. + ++OUI:202AC5* ++ ID_OUI_FROM_DATABASE=Petite-En ++ + OUI:202BC1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -44420,15 +47150,36 @@ OUI:202D23* + OUI:202DF8* + ID_OUI_FROM_DATABASE=Digital Media Cartridge Ltd. + ++OUI:20311C* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:2031EB* + ID_OUI_FROM_DATABASE=HDSN + ++OUI:203233* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ ++OUI:20326C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:2032C6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:2034FB* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:20365B* + ID_OUI_FROM_DATABASE=Megafone Limited + ++OUI:2036D7* ++ ID_OUI_FROM_DATABASE=Shanghai Reacheng Communication Technology Co.,Ltd ++ + OUI:203706* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:2037A5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:2037BC* + ID_OUI_FROM_DATABASE=Kuipers Electronic Engineering BV + +@@ -44441,9 +47192,15 @@ OUI:203A07* + OUI:203AEF* + ID_OUI_FROM_DATABASE=Sivantos GmbH + ++OUI:203B69* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:203CAE* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:203CC0* ++ ID_OUI_FROM_DATABASE=Beijing Tosee Technology Co., Ltd. ++ + OUI:203D66* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -44459,9 +47216,15 @@ OUI:204005* + OUI:20415A* + ID_OUI_FROM_DATABASE=Smarteh d.o.o. + ++OUI:204181* ++ ID_OUI_FROM_DATABASE=ESYSE GmbH Embedded Systems Engineering ++ + OUI:20443A* + ID_OUI_FROM_DATABASE=Schneider Electric Asia Pacific Ltd + ++OUI:204441* ++ ID_OUI_FROM_DATABASE=Remote Solution ++ + OUI:2046A1* + ID_OUI_FROM_DATABASE=VECOW Co., Ltd + +@@ -44480,8 +47243,11 @@ OUI:2047ED* + OUI:204AAA* + ID_OUI_FROM_DATABASE=Hanscan Spain S.A. + ++OUI:204B22* ++ ID_OUI_FROM_DATABASE=Sunnovo International Limited ++ + OUI:204C03* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:204C6D* + ID_OUI_FROM_DATABASE=Hugo Brennenstuhl Gmbh & Co. KG. +@@ -44498,11 +47264,20 @@ OUI:204E71* + OUI:204E7F* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:204EF6* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ ++OUI:2050E7* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ ++OUI:205383* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:2053CA* + ID_OUI_FROM_DATABASE=Risk Technology Ltd + + OUI:205476* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:2054FA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -44516,9 +47291,15 @@ OUI:205532* + OUI:205721* + ID_OUI_FROM_DATABASE=Salix Technology CO., Ltd. + ++OUI:20579E* ++ ID_OUI_FROM_DATABASE=HUNAN FN-LINK TECHNOLOGY LIMITED ++ + OUI:2057AF* + ID_OUI_FROM_DATABASE=Shenzhen FH-NET OPTOELECTRONICS CO.,LTD + ++OUI:205869* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:2059A0* + ID_OUI_FROM_DATABASE=Paragon Technologies Inc. + +@@ -44537,9 +47318,15 @@ OUI:205CFA* + OUI:205D47* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:205E64* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:205EF7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:205F3D* ++ ID_OUI_FROM_DATABASE=Cambridge Communication Systems Ltd ++ + OUI:206274* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +@@ -44549,6 +47336,15 @@ OUI:20635F* + OUI:206432* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + ++OUI:2064CB* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:20658E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:2066CF* ++ ID_OUI_FROM_DATABASE=FREEBOX SAS ++ + OUI:20677C* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -44558,9 +47354,15 @@ OUI:2067B1* + OUI:20689D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:206980* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:206A8A* + ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation + ++OUI:206A94* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:206AFF* + ID_OUI_FROM_DATABASE=Atlas Elektronik UK Limited + +@@ -44568,7 +47370,10 @@ OUI:206BE7* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:206C8A* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:206D31* ++ ID_OUI_FROM_DATABASE=FIREWALLA INC + + OUI:206E9C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -44582,6 +47387,9 @@ OUI:20719E* + OUI:207355* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:207454* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:2074CF* + ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co.,Ltd + +@@ -44594,33 +47402,99 @@ OUI:20768F* + OUI:207693* + ID_OUI_FROM_DATABASE=Lenovo (Beijing) Limited. + ++OUI:207759* ++ ID_OUI_FROM_DATABASE=OPTICAL NETWORK VIDEO TECHNOLOGIES (SHENZHEN) CO., LTD. ++ + OUI:20780B* + ID_OUI_FROM_DATABASE=Delta Faucet Company + + OUI:207852* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:2078F0* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:207918* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:207C14* ++ ID_OUI_FROM_DATABASE=Qotom ++ + OUI:207C8F* + ID_OUI_FROM_DATABASE=Quanta Microsystems,Inc. + + OUI:207D74* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:208058* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ ++OUI:20826A* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:2082C0* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:2083F8* ++ ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA ++ + OUI:20858C* + ID_OUI_FROM_DATABASE=Assa + ++OUI:2085930* ++ ID_OUI_FROM_DATABASE=Hemina Spa ++ ++OUI:2085931* ++ ID_OUI_FROM_DATABASE=Networking Services Corp ++ ++OUI:2085932* ++ ID_OUI_FROM_DATABASE=Mid Continent Controls, Inc. ++ ++OUI:2085933* ++ ID_OUI_FROM_DATABASE=UNILUMIN GROUP CO.,LTD ++ ++OUI:2085934* ++ ID_OUI_FROM_DATABASE=Kloudspot Inc ++ ++OUI:2085935* ++ ID_OUI_FROM_DATABASE=Wave-In Communication ++ ++OUI:2085936* ++ ID_OUI_FROM_DATABASE=Eilersen Electric A/S ++ ++OUI:2085937* ++ ID_OUI_FROM_DATABASE=Great Lite International ++ ++OUI:2085938* ++ ID_OUI_FROM_DATABASE=AASSET SECURITY ++ ++OUI:2085939* ++ ID_OUI_FROM_DATABASE=Mastodon Design ++ ++OUI:208593A* ++ ID_OUI_FROM_DATABASE=H3 Industries, Inc. ++ ++OUI:208593B* ++ ID_OUI_FROM_DATABASE=IOG Products LLC ++ ++OUI:208593C* ++ ID_OUI_FROM_DATABASE=Regloplas AG ++ ++OUI:208593D* ++ ID_OUI_FROM_DATABASE=Shanghai Kenmyond Industrial Network Equipment Co.,Ltd ++ ++OUI:208593E* ++ ID_OUI_FROM_DATABASE=Dynaudio ++ + OUI:208756* + ID_OUI_FROM_DATABASE=SIEMENS AG + + OUI:2087AC* + ID_OUI_FROM_DATABASE=AES motomation + ++OUI:2087EC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:20896F* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -44633,6 +47507,9 @@ OUI:208986* + OUI:208B37* + ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd + ++OUI:208C47* ++ ID_OUI_FROM_DATABASE=Tenstorrent Inc ++ + OUI:20906F* + ID_OUI_FROM_DATABASE=Shenzhen Tencent Computer System Co., Ltd. + +@@ -44648,6 +47525,15 @@ OUI:2091D9* + OUI:20934D* + ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD + ++OUI:20968A* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ ++OUI:2098D8* ++ ID_OUI_FROM_DATABASE=Shenzhen Yingdakang Technology CO., LTD ++ ++OUI:209A7D* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:209AE9* + ID_OUI_FROM_DATABASE=Volacomm Co., Ltd + +@@ -44657,6 +47543,15 @@ OUI:209BA5* + OUI:209BCD* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:209E79* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ ++OUI:209EF7* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:20A171* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:20A2E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -44678,6 +47573,9 @@ OUI:20A783* + OUI:20A787* + ID_OUI_FROM_DATABASE=Bointec Taiwan Corporation Limited + ++OUI:20A7F9* ++ ID_OUI_FROM_DATABASE=SHENZHEN OLANBOA TECHNOLOGY CO., LTD ++ + OUI:20A8B9* + ID_OUI_FROM_DATABASE=SIEMENS AG + +@@ -44696,6 +47594,18 @@ OUI:20AA4B* + OUI:20AB37* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:20AB48* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:20AC9C* ++ ID_OUI_FROM_DATABASE=China Telecom Corporation Limited ++ ++OUI:20AD56* ++ ID_OUI_FROM_DATABASE=Continental Automotive Systems Inc. ++ ++OUI:20B001* ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV ++ + OUI:20B0F7* + ID_OUI_FROM_DATABASE=Enclustra GmbH + +@@ -44705,9 +47615,18 @@ OUI:20B399* + OUI:20B5C6* + ID_OUI_FROM_DATABASE=Mimosa Networks + ++OUI:20B730* ++ ID_OUI_FROM_DATABASE=TeconGroup, Inc ++ ++OUI:20B780* ++ ID_OUI_FROM_DATABASE=Toshiba Visual Solutions Corporation Co.,Ltd ++ + OUI:20B7C0* + ID_OUI_FROM_DATABASE=OMICRON electronics GmbH + ++OUI:20B868* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:20BB76* + ID_OUI_FROM_DATABASE=COL GIOVANNI PAOLO SpA + +@@ -44717,6 +47636,9 @@ OUI:20BBC0* + OUI:20BBC6* + ID_OUI_FROM_DATABASE=Jabil Circuit Hungary Ltd. + ++OUI:20BECD* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:20BFDB* + ID_OUI_FROM_DATABASE=DVL + +@@ -44726,6 +47648,9 @@ OUI:20C047* + OUI:20C06D* + ID_OUI_FROM_DATABASE=SHENZHEN SPACETEK TECHNOLOGY CO.,LTD + ++OUI:20C19B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:20C1AF* + ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited + +@@ -44741,6 +47666,9 @@ OUI:20C60D* + OUI:20C6EB* + ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company + ++OUI:20C74F* ++ ID_OUI_FROM_DATABASE=SensorPush ++ + OUI:20C8B3* + ID_OUI_FROM_DATABASE=SHENZHEN BUL-TECH CO.,LTD. + +@@ -44750,12 +47678,63 @@ OUI:20C9D0* + OUI:20CD39* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:20CD6E* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ ++OUI:20CE2A0* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:20CE2A1* ++ ID_OUI_FROM_DATABASE=Shanghai Digicube Info&Tech Co.,Ltd. ++ ++OUI:20CE2A2* ++ ID_OUI_FROM_DATABASE=Jabil ++ ++OUI:20CE2A3* ++ ID_OUI_FROM_DATABASE=Cuculus GmbH ++ ++OUI:20CE2A4* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:20CE2A5* ++ ID_OUI_FROM_DATABASE=Zaber Technologies Inc. ++ ++OUI:20CE2A6* ++ ID_OUI_FROM_DATABASE=Radarxense BV ++ ++OUI:20CE2A7* ++ ID_OUI_FROM_DATABASE=Beijing Huadianzhongxin Tech.Co.,Ltd ++ ++OUI:20CE2A8* ++ ID_OUI_FROM_DATABASE=Intelligraphics ++ ++OUI:20CE2A9* ++ ID_OUI_FROM_DATABASE=Rugged Monitoring ++ ++OUI:20CE2AA* ++ ID_OUI_FROM_DATABASE=MeshPlusPlus, Inc. ++ ++OUI:20CE2AB* ++ ID_OUI_FROM_DATABASE=Swarovski Optik KG ++ ++OUI:20CE2AC* ++ ID_OUI_FROM_DATABASE=Ariston Thermo s.p.a. ++ ++OUI:20CE2AD* ++ ID_OUI_FROM_DATABASE=LAUDA DR R WOBSER GMBH & CO KG ++ ++OUI:20CE2AE* ++ ID_OUI_FROM_DATABASE=Funkwerk Systems GmbH ++ + OUI:20CEC4* + ID_OUI_FROM_DATABASE=Peraso Technologies + + OUI:20CF30* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:20CFAE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:20D160* + ID_OUI_FROM_DATABASE=Private + +@@ -44765,6 +47744,9 @@ OUI:20D21F* + OUI:20D25F* + ID_OUI_FROM_DATABASE=SmartCap Technologies + ++OUI:20D276* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:20D390* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -44780,12 +47762,18 @@ OUI:20D607* + OUI:20D75A* + ID_OUI_FROM_DATABASE=Posh Mobile Limited + ++OUI:20D778* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:20D80B* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:20D906* + ID_OUI_FROM_DATABASE=Iota, Inc. + ++OUI:20DA22* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:20DBAB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +@@ -44795,6 +47783,9 @@ OUI:20DC93* + OUI:20DCE6* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:20DCFD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:20DE88* + ID_OUI_FROM_DATABASE=IC Realtime LLC + +@@ -44807,6 +47798,9 @@ OUI:20DFB9* + OUI:20E09C* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:20E2A8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:20E407* + ID_OUI_FROM_DATABASE=Spark srl + +@@ -44819,6 +47813,12 @@ OUI:20E564* + OUI:20E791* + ID_OUI_FROM_DATABASE=Siemens Healthcare Diagnostics, Inc + ++OUI:20E7B6* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ ++OUI:20E874* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:20E882* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -44834,6 +47834,9 @@ OUI:20EE28* + OUI:20EEC6* + ID_OUI_FROM_DATABASE=Elefirst Science & Tech Co ., ltd + ++OUI:20EFBD* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:20F002* + ID_OUI_FROM_DATABASE=MTData Developments Pty. Ltd. + +@@ -44843,15 +47846,24 @@ OUI:20F17C* + OUI:20F19E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:20F375* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:20F3A3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:20F41B* + ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD + ++OUI:20F44F* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:20F452* + ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd + ++OUI:20F478* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:20F510* + ID_OUI_FROM_DATABASE=Codex Digital Limited + +@@ -44876,9 +47888,18 @@ OUI:20FECD* + OUI:20FEDB* + ID_OUI_FROM_DATABASE=M2M Solution S.A.S. + ++OUI:20FF36* ++ ID_OUI_FROM_DATABASE=IFLYTEK CO.,LTD. ++ + OUI:2400BA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:2400FA* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd ++ ++OUI:24016F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2401C7* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -44891,6 +47912,12 @@ OUI:240588* + OUI:2405F5* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:2406AA* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:24085D* ++ ID_OUI_FROM_DATABASE=Continental Aftermarket & Services GmbH ++ + OUI:240917* + ID_OUI_FROM_DATABASE=Devlin Electronics Limited + +@@ -44915,6 +47942,9 @@ OUI:240B0A* + OUI:240B2A* + ID_OUI_FROM_DATABASE=Viettel Group + ++OUI:240B88* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:240BB1* + ID_OUI_FROM_DATABASE=KOSTAL Industrie Elektrik GmbH + +@@ -44933,27 +47963,96 @@ OUI:241064* + OUI:241125* + ID_OUI_FROM_DATABASE=Hutek Co., Ltd. + ++OUI:241145* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:241148* + ID_OUI_FROM_DATABASE=Entropix, LLC + + OUI:2411D0* + ID_OUI_FROM_DATABASE=Chongqing Ehs Science and Technology Development Co.,Ltd. + ++OUI:241407* ++ ID_OUI_FROM_DATABASE=Xiamen Sigmastar Technology Ltd. ++ ++OUI:2415100* ++ ID_OUI_FROM_DATABASE=Safetrust Inc ++ ++OUI:2415101* ++ ID_OUI_FROM_DATABASE=SMaBiT GmbH ++ ++OUI:2415102* ++ ID_OUI_FROM_DATABASE=Nile Global Inc ++ ++OUI:2415103* ++ ID_OUI_FROM_DATABASE=Kaiyun ++ ++OUI:2415104* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:2415105* ++ ID_OUI_FROM_DATABASE=GANZHOU DEHUIDA TECHNOLOGY CO., LTD ++ ++OUI:2415106* ++ ID_OUI_FROM_DATABASE=SHANDONG KEHUI POWER AUTOMATION CO. LTD. ++ ++OUI:2415107* ++ ID_OUI_FROM_DATABASE=SuZhou A-rack Information Technology Co.,Ltd ++ ++OUI:2415108* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:2415109* ++ ID_OUI_FROM_DATABASE=Topgolf Sweden AB ++ ++OUI:241510A* ++ ID_OUI_FROM_DATABASE=Unitronux(Shenzhen) Intelligence Technology Co.,Ltd ++ ++OUI:241510B* ++ ID_OUI_FROM_DATABASE=Teknic, Inc. ++ ++OUI:241510C* ++ ID_OUI_FROM_DATABASE=Shenzhen Xtooltech Co., Ltd ++ ++OUI:241510D* ++ ID_OUI_FROM_DATABASE=Helen of Troy ++ ++OUI:241510E* ++ ID_OUI_FROM_DATABASE=Satellite Link Technology CO.,LTD ++ ++OUI:24166D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:24169D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:24181D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:2418C6* ++ ID_OUI_FROM_DATABASE=HUNAN FN-LINK TECHNOLOGY LIMITED ++ + OUI:241A8C* + ID_OUI_FROM_DATABASE=Squarehead Technology AS + ++OUI:241AE6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:241B13* + ID_OUI_FROM_DATABASE=Shanghai Nutshell Electronic Co., Ltd. + + OUI:241B44* + ID_OUI_FROM_DATABASE=Hangzhou Tuners Electronics Co., Ltd + ++OUI:241B7A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:241C04* + ID_OUI_FROM_DATABASE=SHENZHEN JEHE TECHNOLOGY DEVELOPMENT CO., LTD. + ++OUI:241D48* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:241EEB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -44970,7 +48069,7 @@ OUI:242124* + ID_OUI_FROM_DATABASE=Nokia + + OUI:2421AB* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:24240E* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -44978,6 +48077,9 @@ OUI:24240E* + OUI:242642* + ID_OUI_FROM_DATABASE=SHARP Corporation. + ++OUI:2428FD* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:2429FE* + ID_OUI_FROM_DATABASE=KYOCERA Corporation + +@@ -44990,6 +48092,12 @@ OUI:242E90* + OUI:242FFA* + ID_OUI_FROM_DATABASE=Toshiba Global Commerce Solutions + ++OUI:2430F8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:243154* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:243184* + ID_OUI_FROM_DATABASE=SHARP Corporation + +@@ -44999,6 +48107,9 @@ OUI:24336C* + OUI:2435CC* + ID_OUI_FROM_DATABASE=Zhongshan Scinan Internet of Things Co.,Ltd. + ++OUI:2436DA* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:24374C* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +@@ -45011,15 +48122,39 @@ OUI:243A82* + OUI:243C20* + ID_OUI_FROM_DATABASE=Dynamode Group + ++OUI:243F30* ++ ID_OUI_FROM_DATABASE=Oxygen Broadband s.a. ++ ++OUI:243FAA* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:2440AE* ++ ID_OUI_FROM_DATABASE=NIIC Technology Co., Ltd. ++ ++OUI:24418C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:2442BC* + ID_OUI_FROM_DATABASE=Alinco,incorporated + ++OUI:2443E2* ++ ID_OUI_FROM_DATABASE=DASAN Network Solutions ++ + OUI:244427* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:24456B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:244597* + ID_OUI_FROM_DATABASE=GEMUE Gebr. Mueller Apparatebau + ++OUI:2446C8* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:2446E4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:24470E* + ID_OUI_FROM_DATABASE=PentronicAB + +@@ -45032,6 +48167,9 @@ OUI:244B03* + OUI:244B81* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:244BFE* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:244C07* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -45078,7 +48216,7 @@ OUI:244E7BC* + ID_OUI_FROM_DATABASE=CHUNGHSIN TECHNOLOGY GROUP CO.,LTD + + OUI:244E7BD* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Church & Dwight Co., Inc. + + OUI:244E7BE* + ID_OUI_FROM_DATABASE=WithWin Technology ShenZhen CO.,LTD +@@ -45086,12 +48224,30 @@ OUI:244E7BE* + OUI:244F1D* + ID_OUI_FROM_DATABASE=iRule LLC + ++OUI:24526A* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ ++OUI:2453BF* ++ ID_OUI_FROM_DATABASE=Enernet ++ ++OUI:24586E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:245880* + ID_OUI_FROM_DATABASE=VIZEO + + OUI:24590B* + ID_OUI_FROM_DATABASE=White Sky Inc. Limited + ++OUI:245A4C* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ ++OUI:245AB5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:245B83* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:245BA7* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -45104,9 +48260,60 @@ OUI:245CBF* + OUI:245CCB* + ID_OUI_FROM_DATABASE=AXIe Consortium, Inc. + ++OUI:245DFC0* ++ ID_OUI_FROM_DATABASE=CompanyDeep ++ ++OUI:245DFC1* ++ ID_OUI_FROM_DATABASE=ARTICONA - Bechtle Logistik & Service GmbH ++ ++OUI:245DFC2* ++ ID_OUI_FROM_DATABASE=Blue Iris Labs ++ ++OUI:245DFC3* ++ ID_OUI_FROM_DATABASE=Shenzhen Hailuck Electronic Technology CO.,LTD ++ ++OUI:245DFC4* ++ ID_OUI_FROM_DATABASE=Suzhou Jiangzhi electronic technology co., Ltd ++ ++OUI:245DFC5* ++ ID_OUI_FROM_DATABASE=ContactProximity Inc ++ ++OUI:245DFC6* ++ ID_OUI_FROM_DATABASE=Guangzhou Lango Electronics Technology Co.,Ltd. ++ ++OUI:245DFC7* ++ ID_OUI_FROM_DATABASE=LTY LLC ++ ++OUI:245DFC8* ++ ID_OUI_FROM_DATABASE=Cosmicnode ++ ++OUI:245DFC9* ++ ID_OUI_FROM_DATABASE=TORGOVYY DOM TEHNOLOGIY LLC ++ ++OUI:245DFCA* ++ ID_OUI_FROM_DATABASE=Tata Sky Limited ++ ++OUI:245DFCB* ++ ID_OUI_FROM_DATABASE=ONLY ++ ++OUI:245DFCC* ++ ID_OUI_FROM_DATABASE=Senix Corporation ++ ++OUI:245DFCD* ++ ID_OUI_FROM_DATABASE=Hunan Honestone lntelligence Technology Co.,Ltd ++ ++OUI:245DFCE* ++ ID_OUI_FROM_DATABASE=Dodge ++ ++OUI:245E48* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:245EBE* + ID_OUI_FROM_DATABASE=QNAP Systems, Inc. + ++OUI:245F9F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:245FDF* + ID_OUI_FROM_DATABASE=KYOCERA CORPORATION + +@@ -45119,6 +48326,15 @@ OUI:24615A* + OUI:246278* + ID_OUI_FROM_DATABASE=sysmocom - systems for mobile communications GmbH + ++OUI:2462AB* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:2462CE* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:24649F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2464EF* + ID_OUI_FROM_DATABASE=CYG SUNRI CO.,LTD. + +@@ -45128,6 +48344,9 @@ OUI:246511* + OUI:246880* + ID_OUI_FROM_DATABASE=Braveridge.co.,ltd. + ++OUI:2468B0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:24693E* + ID_OUI_FROM_DATABASE=innodisk Corporation + +@@ -45149,12 +48368,27 @@ OUI:246C8A* + OUI:246E96* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:246F28* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:246F8C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:247152* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:247189* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:247260* + ID_OUI_FROM_DATABASE=IOTTECH Corp + ++OUI:2474F7* ++ ID_OUI_FROM_DATABASE=GoPro ++ ++OUI:247625* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:247656* + ID_OUI_FROM_DATABASE=Shanghai Net Miles Fiber Optics Technology Co., LTD. + +@@ -45167,9 +48401,21 @@ OUI:247703* + OUI:24792A* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:2479EF* ++ ID_OUI_FROM_DATABASE=Greenpacket Berhad, Taiwan ++ ++OUI:2479F3* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:2479F8* ++ ID_OUI_FROM_DATABASE=KUPSON spol. s r.o. ++ + OUI:247C4C* + ID_OUI_FROM_DATABASE=Herman Miller + ++OUI:247D4D* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:247E12* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -45188,9 +48434,15 @@ OUI:248000* + OUI:2481AA* + ID_OUI_FROM_DATABASE=KSH International Co., Ltd. + ++OUI:2481C7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:24828A* + ID_OUI_FROM_DATABASE=Prowave Technologies Ltd. + ++OUI:248498* ++ ID_OUI_FROM_DATABASE=Beijing Jiaoda Microunion Tech.Co.,Ltd. ++ + OUI:2486F4* + ID_OUI_FROM_DATABASE=Ctek, Inc. + +@@ -45204,29 +48456,53 @@ OUI:248A07* + ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. + + OUI:248BE0* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:2491BB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:24920E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:2493CA* +- ID_OUI_FROM_DATABASE=Voxtronic Technology Computer-Systeme GmbH ++ ID_OUI_FROM_DATABASE=Voxtronic Austria + + OUI:249442* + ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC. + ++OUI:249493* ++ ID_OUI_FROM_DATABASE=FibRSol Global Network Limited ++ ++OUI:249494* ++ ID_OUI_FROM_DATABASE=Hong Kong Bouffalo Lab Limited ++ ++OUI:2494CB* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:249504* + ID_OUI_FROM_DATABASE=SFR + + OUI:2497ED* + ID_OUI_FROM_DATABASE=Techvision Intelligent Technology Limited + ++OUI:249AC8* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ ++OUI:249AD8* ++ ID_OUI_FROM_DATABASE=YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD. ++ + OUI:249EAB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:249F89* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:24A074* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:24A160* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:24A2E1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -45236,12 +48512,24 @@ OUI:24A42C* + OUI:24A43C* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + ++OUI:24A487* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:24A495* + ID_OUI_FROM_DATABASE=Thales Canada Inc. + ++OUI:24A52C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:24A534* + ID_OUI_FROM_DATABASE=SynTrust Tech International Ltd. + ++OUI:24A65E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:24A799* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:24A7DC* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +@@ -45263,6 +48551,9 @@ OUI:24AF54* + OUI:24B0A9* + ID_OUI_FROM_DATABASE=Shanghai Mobiletek Communication Ltd. + ++OUI:24B105* ++ ID_OUI_FROM_DATABASE=Prama Hikvision India Private Limited ++ + OUI:24B209* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -45302,12 +48593,18 @@ OUI:24BCF8* + OUI:24BE05* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:24BE18* ++ ID_OUI_FROM_DATABASE=DADOUTEK COMPANY LIMITED ++ + OUI:24BF74* + ID_OUI_FROM_DATABASE=Private + + OUI:24C0B3* + ID_OUI_FROM_DATABASE=RSF + ++OUI:24C17A* ++ ID_OUI_FROM_DATABASE=BEIJING IACTIVE NETWORK CO.,LTD ++ + OUI:24C1BD* + ID_OUI_FROM_DATABASE=CRRC DALIAN R&D CO.,LTD. + +@@ -45329,6 +48626,9 @@ OUI:24C848* + OUI:24C86E* + ID_OUI_FROM_DATABASE=Chaney Instrument Co. + ++OUI:24C8D3* ++ ID_OUI_FROM_DATABASE=McWane India Pvt Ltd ++ + OUI:24C9A1* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -45344,6 +48644,9 @@ OUI:24CBE7* + OUI:24CF21* + ID_OUI_FROM_DATABASE=Shenzhen State Micro Technology Co., Ltd + ++OUI:24D0DF* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:24D13F* + ID_OUI_FROM_DATABASE=MEXUS CO.,LTD + +@@ -45359,12 +48662,18 @@ OUI:24D51C* + OUI:24D76B* + ID_OUI_FROM_DATABASE=Syntronic AB + ++OUI:24D7EB* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:24D921* + ID_OUI_FROM_DATABASE=Avaya Inc + + OUI:24DA11* + ID_OUI_FROM_DATABASE=NO NDA Inc + ++OUI:24DA33* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:24DA9B* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -45381,13 +48690,16 @@ OUI:24DBED* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:24DEC6* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:24DF6A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:24DFA7* ++ ID_OUI_FROM_DATABASE=Hangzhou BroadLink Technology Co.,Ltd ++ + OUI:24E124* +- ID_OUI_FROM_DATABASE=Xiamen Ursaconn Technology Co. , Ltd. ++ ID_OUI_FROM_DATABASE=Xiamen Milesight IoT Co., Ltd. + + OUI:24E271* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd. +@@ -45398,15 +48710,27 @@ OUI:24E314* + OUI:24E43F* + ID_OUI_FROM_DATABASE=Wenzhou Kunmei Communication Technology Co.,Ltd. + ++OUI:24E4C8* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:24E5AA* + ID_OUI_FROM_DATABASE=Philips Oral Healthcare, Inc. + + OUI:24E6BA* + ID_OUI_FROM_DATABASE=JSC Zavod im. Kozitsky + ++OUI:24E853* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ ++OUI:24E927* ++ ID_OUI_FROM_DATABASE=TomTom International BV ++ + OUI:24E9B3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:24E9CA* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:24EA40* + ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG + +@@ -45422,9 +48746,15 @@ OUI:24EC99* + OUI:24ECD6* + ID_OUI_FROM_DATABASE=CSG Science & Technology Co.,Ltd.Hefei + ++OUI:24EDFD* ++ ID_OUI_FROM_DATABASE=Siemens Canada Limited ++ + OUI:24EE3A* + ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd + ++OUI:24EE9A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:24F094* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -45434,6 +48764,9 @@ OUI:24F0FF* + OUI:24F128* + ID_OUI_FROM_DATABASE=Telstra + ++OUI:24F150* ++ ID_OUI_FROM_DATABASE=Guangzhou Qi'an Technology Co., Ltd. ++ + OUI:24F27F* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -45449,6 +48782,9 @@ OUI:24F5A2* + OUI:24F5AA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:24F603* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:24F677* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -45461,6 +48797,9 @@ OUI:24FB65* + OUI:24FCE5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:24FD0D* ++ ID_OUI_FROM_DATABASE=Intelbras ++ + OUI:24FD52* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -45476,6 +48815,9 @@ OUI:2802D8* + OUI:2804E0* + ID_OUI_FROM_DATABASE=FERMAX ELECTRONICA S.A.U. + ++OUI:28052E* ++ ID_OUI_FROM_DATABASE=Dematic Corp ++ + OUI:28061E* + ID_OUI_FROM_DATABASE=NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD + +@@ -45500,6 +48842,12 @@ OUI:280DFC* + OUI:280E8B* + ID_OUI_FROM_DATABASE=Beijing Spirit Technology Development Co., Ltd. + ++OUI:280FC5* ++ ID_OUI_FROM_DATABASE=Beijing Leadsec Technology Co., Ltd. ++ ++OUI:280FEB* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:28101B* + ID_OUI_FROM_DATABASE=MagnaCom + +@@ -45509,18 +48857,30 @@ OUI:28107B* + OUI:2811A5* + ID_OUI_FROM_DATABASE=Bose Corporation + ++OUI:2811A8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:2811EC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:281471* + ID_OUI_FROM_DATABASE=Lantis co., LTD. + + OUI:28162E* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:28167F* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:2816A8* + ID_OUI_FROM_DATABASE=Microsoft Corporation + + OUI:2816AD* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:281709* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:2817CE* + ID_OUI_FROM_DATABASE=Omnisense Ltd + +@@ -45530,12 +48890,18 @@ OUI:281878* + OUI:2818FD* + ID_OUI_FROM_DATABASE=Aditya Infotech Ltd. + ++OUI:281B04* ++ ID_OUI_FROM_DATABASE=Zalliant LLC ++ + OUI:282246* + ID_OUI_FROM_DATABASE=Beijing Sinoix Communication Co., LTD + + OUI:282373* + ID_OUI_FROM_DATABASE=Digita + ++OUI:2823F5* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ + OUI:2824FF* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + +@@ -45560,6 +48926,9 @@ OUI:2829CC* + OUI:2829D9* + ID_OUI_FROM_DATABASE=GlobalBeiMing technology (Beijing)Co. Ltd + ++OUI:282B96* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:282C020* + ID_OUI_FROM_DATABASE=SAKATA DENKI Co., Ltd. + +@@ -45620,9 +48989,15 @@ OUI:283152* + OUI:283166* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:28317E* ++ ID_OUI_FROM_DATABASE=Hongkong Nano IC Technologies Co., Ltd ++ + OUI:2832C5* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:283334* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:283410* + ID_OUI_FROM_DATABASE=Enigma Diagnostics Limited + +@@ -45632,6 +49007,51 @@ OUI:2834A2* + OUI:283545* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD + ++OUI:2836130* ++ ID_OUI_FROM_DATABASE=Shandong SIASUN Industrial Software Research Institute Co., Ltd ++ ++OUI:2836131* ++ ID_OUI_FROM_DATABASE=Hi-p (Suzhou) Electronics Co,Ltd ++ ++OUI:2836132* ++ ID_OUI_FROM_DATABASE=Shenzhen HQVT TECHNOLOGY Co.,LTD ++ ++OUI:2836133* ++ ID_OUI_FROM_DATABASE=Linear Computing Inc. ++ ++OUI:2836134* ++ ID_OUI_FROM_DATABASE=Elytone Electronic Co., Ltd. ++ ++OUI:2836135* ++ ID_OUI_FROM_DATABASE=Turing Video ++ ++OUI:2836136* ++ ID_OUI_FROM_DATABASE=ESI Ventures, LLC ++ ++OUI:2836137* ++ ID_OUI_FROM_DATABASE=shenzhen technology limited ++ ++OUI:2836138* ++ ID_OUI_FROM_DATABASE=Fuzhou Lesi Intelligent Technology Co., Ltd ++ ++OUI:2836139* ++ ID_OUI_FROM_DATABASE=Qingdao Airpoint Electronics Co.,Ltd. ++ ++OUI:283613A* ++ ID_OUI_FROM_DATABASE=MAKEEN Energy ++ ++OUI:283613B* ++ ID_OUI_FROM_DATABASE=Qorvo, Inc. ++ ++OUI:283613C* ++ ID_OUI_FROM_DATABASE=midBit Technologies, LLC ++ ++OUI:283613D* ++ ID_OUI_FROM_DATABASE=AVYCON ++ ++OUI:283613E* ++ ID_OUI_FROM_DATABASE=EGMedical, s.r.o. ++ + OUI:2836380* + ID_OUI_FROM_DATABASE=Knowles Electronics LLC + +@@ -45689,6 +49109,9 @@ OUI:28385C* + OUI:2838CF* + ID_OUI_FROM_DATABASE=Gen2wave + ++OUI:283926* ++ ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. ++ + OUI:28395E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -45711,7 +49134,7 @@ OUI:283E76* + ID_OUI_FROM_DATABASE=Common Networks + + OUI:283F69* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:28401A* + ID_OUI_FROM_DATABASE=C8 MediSensors, Inc. +@@ -45719,6 +49142,12 @@ OUI:28401A* + OUI:284121* + ID_OUI_FROM_DATABASE=OptiSense Network, LLC + ++OUI:2841C6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:2841EC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:284430* + ID_OUI_FROM_DATABASE=GenesisTechnical Systems (UK) Ltd + +@@ -45728,6 +49157,9 @@ OUI:2847AA* + OUI:284846* + ID_OUI_FROM_DATABASE=GridCentric Inc. + ++OUI:2848E7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:284C53* + ID_OUI_FROM_DATABASE=Intune Networks + +@@ -45749,11 +49181,20 @@ OUI:285261* + OUI:2852E0* + ID_OUI_FROM_DATABASE=Layon international Electronic & Telecom Co.,Ltd + ++OUI:2852F9* ++ ID_OUI_FROM_DATABASE=Zhongxin Intelligent Times (Shenzhen) Co., Ltd. ++ ++OUI:28534E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:285471* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:28565A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:2856C1* +- ID_OUI_FROM_DATABASE=Harman International ++ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH + + OUI:285767* + ID_OUI_FROM_DATABASE=Dish Technologies Corp +@@ -45764,6 +49205,9 @@ OUI:2857BE* + OUI:285AEB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:285B0C* ++ ID_OUI_FROM_DATABASE=Sichuan Jiuzhou Electronic Technology Co., Ltd. ++ + OUI:285F2F* + ID_OUI_FROM_DATABASE=RNware Co.,Ltd. + +@@ -45779,12 +49223,24 @@ OUI:286094* + OUI:286336* + ID_OUI_FROM_DATABASE=Siemens AG + ++OUI:2863BD* ++ ID_OUI_FROM_DATABASE=APTIV SERVICES US, LLC ++ ++OUI:2864B0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:2864EF* ++ ID_OUI_FROM_DATABASE=Shenzhen Fsan Intelligent Technology Co.,Ltd ++ + OUI:28656B* + ID_OUI_FROM_DATABASE=Keystone Microtech Corporation + + OUI:2866E3* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:2868D2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:286AB8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -45815,12 +49271,21 @@ OUI:2872C5* + OUI:2872F0* + ID_OUI_FROM_DATABASE=ATHENA + ++OUI:2875D8* ++ ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD ++ + OUI:287610* + ID_OUI_FROM_DATABASE=IgniteNet + + OUI:2876CD* + ID_OUI_FROM_DATABASE=Funshion Online Technologies Co.,Ltd + ++OUI:287777* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:2877F1* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:287994* + ID_OUI_FROM_DATABASE=Realplay Digital Technology(Shenzhen) Co.,Ltd + +@@ -45833,9 +49298,15 @@ OUI:287B09* + OUI:287CDB* + ID_OUI_FROM_DATABASE=Hefei Toycloud Technology Co.,ltd + ++OUI:287FCF* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:288023* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:288088* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:2880A2* + ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc. + +@@ -45875,18 +49346,30 @@ OUI:28940F* + OUI:2894AF* + ID_OUI_FROM_DATABASE=Samhwa Telecom + ++OUI:2897B8* ++ ID_OUI_FROM_DATABASE=myenergi Ltd ++ + OUI:28987B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:28993A* + ID_OUI_FROM_DATABASE=Arista Networks + ++OUI:2899C7* ++ ID_OUI_FROM_DATABASE=LINDSAY BROADBAND INC ++ + OUI:289A4B* + ID_OUI_FROM_DATABASE=SteelSeries ApS + ++OUI:289AF7* ++ ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd. ++ + OUI:289AFA* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:289C6E* ++ ID_OUI_FROM_DATABASE=Shanghai High-Flying Electronics Technology Co., Ltd ++ + OUI:289E97* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -45900,7 +49383,7 @@ OUI:28A02B* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:28A183* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:28A186* + ID_OUI_FROM_DATABASE=enblink +@@ -45935,24 +49418,81 @@ OUI:28AC67* + OUI:28AC9E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:28AD18* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:28AD3E* + ID_OUI_FROM_DATABASE=Shenzhen TONG BO WEI Technology CO.,LTD + + OUI:28AF0A* + ID_OUI_FROM_DATABASE=Sirius XM Radio Inc + ++OUI:28AFFD* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:28B0CC* + ID_OUI_FROM_DATABASE=Xenya d.o.o. + + OUI:28B2BD* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:28B371* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:28B3AB* + ID_OUI_FROM_DATABASE=Genmark Automation + + OUI:28B448* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:28B4FB* ++ ID_OUI_FROM_DATABASE=Sprocomm Technologies CO.,LTD. ++ ++OUI:28B77C0* ++ ID_OUI_FROM_DATABASE=SHENZHEN EVIEW GPS TECHNOLOGY ++ ++OUI:28B77C1* ++ ID_OUI_FROM_DATABASE=SolarEdge Technologies ++ ++OUI:28B77C2* ++ ID_OUI_FROM_DATABASE=Zhuhai RongBang Electronic Technology Co., Ltd. ++ ++OUI:28B77C3* ++ ID_OUI_FROM_DATABASE=Beijing Kitten&Puppy Technology Co.,Ltd. ++ ++OUI:28B77C4* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:28B77C5* ++ ID_OUI_FROM_DATABASE=GROTHE GmbH ++ ++OUI:28B77C6* ++ ID_OUI_FROM_DATABASE=Shanghai Taiji Software Co.,Limited ++ ++OUI:28B77C7* ++ ID_OUI_FROM_DATABASE=Convertertec Deutschland GmbH ++ ++OUI:28B77C8* ++ ID_OUI_FROM_DATABASE=Shenzhen PUAS Industrial Co.,LTD ++ ++OUI:28B77C9* ++ ID_OUI_FROM_DATABASE=Anser Coding Inc. ++ ++OUI:28B77CA* ++ ID_OUI_FROM_DATABASE=Simaudio Ltd ++ ++OUI:28B77CB* ++ ID_OUI_FROM_DATABASE=Vehant Technologies Pvt Ltd. ++ ++OUI:28B77CC* ++ ID_OUI_FROM_DATABASE=AnyLink LLC ++ ++OUI:28B77CD* ++ ID_OUI_FROM_DATABASE=Enedo Finland Oy ++ ++OUI:28B77CE* ++ ID_OUI_FROM_DATABASE=Ray Pte Ltd ++ + OUI:28B9D9* + ID_OUI_FROM_DATABASE=Radisys Corporation + +@@ -45971,6 +49511,9 @@ OUI:28BC18* + OUI:28BC56* + ID_OUI_FROM_DATABASE=EMAC, Inc. + ++OUI:28BD89* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:28BE03* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -45986,6 +49529,9 @@ OUI:28C0DA* + OUI:28C13C* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + ++OUI:28C21F* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ + OUI:28C2DD* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + +@@ -45998,6 +49544,9 @@ OUI:28C671* + OUI:28C68E* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:28C709* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:28C718* + ID_OUI_FROM_DATABASE=Altierre + +@@ -46010,6 +49559,9 @@ OUI:28C825* + OUI:28C87A* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:28C87C* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:28C914* + ID_OUI_FROM_DATABASE=Taimag Corporation + +@@ -46034,6 +49586,9 @@ OUI:28CD4C* + OUI:28CD9C* + ID_OUI_FROM_DATABASE=Shenzhen Dynamax Software Development Co.,Ltd. + ++OUI:28CDC4* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:28CF08* + ID_OUI_FROM_DATABASE=ESSYS + +@@ -46043,14 +49598,29 @@ OUI:28CFDA* + OUI:28CFE9* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:28D044* ++ ID_OUI_FROM_DATABASE=Shenzhen Xinyin technology company ++ + OUI:28D0CB* + ID_OUI_FROM_DATABASE=Cambridge Communication Systems Ltd + ++OUI:28D0EA* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:28D127* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:28D1AF* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:28D1B7* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:28D244* +- ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology Co., Ltd. ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:28D3EA* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. + + OUI:28D436* + ID_OUI_FROM_DATABASE=Jiangsu dewosi electric co., LTD +@@ -46070,9 +49640,21 @@ OUI:28D997* + OUI:28DB81* + ID_OUI_FROM_DATABASE=Shanghai Guao Electronic Technology Co., Ltd + ++OUI:28DE65* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:28DEA8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:28DEE5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:28DEF6* + ID_OUI_FROM_DATABASE=bioMerieux Inc. + ++OUI:28DFEB* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:28E02C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -46088,9 +49670,15 @@ OUI:28E31F* + OUI:28E347* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:28E34E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:28E476* + ID_OUI_FROM_DATABASE=Pi-Coral + ++OUI:28E5B0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:28E608* + ID_OUI_FROM_DATABASE=Tokheim + +@@ -46103,6 +49691,15 @@ OUI:28E794* + OUI:28E7CF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:28E98E* ++ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation ++ ++OUI:28EC95* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:28EC9A* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:28ED58* + ID_OUI_FROM_DATABASE=JAG Jakob AG + +@@ -46122,7 +49719,10 @@ OUI:28EED3* + ID_OUI_FROM_DATABASE=Shenzhen Super D Technology Co., Ltd + + OUI:28EF01* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:28F033* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:28F076* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -46136,6 +49736,9 @@ OUI:28F358* + OUI:28F366* + ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD + ++OUI:28F49B* ++ ID_OUI_FROM_DATABASE=LEETEK ++ + OUI:28F532* + ID_OUI_FROM_DATABASE=ADD-Engineering BV + +@@ -46164,7 +49767,7 @@ OUI:28F5377* + ID_OUI_FROM_DATABASE=Shenzhen Modern Cowboy Technology Co.,Ltd. + + OUI:28F5378* +- ID_OUI_FROM_DATABASE=1MORE, INC. ++ ID_OUI_FROM_DATABASE=1MORE + + OUI:28F5379* + ID_OUI_FROM_DATABASE=Herbert Waldmann GmbH & Co. KG +@@ -46187,9 +49790,18 @@ OUI:28F537E* + OUI:28F606* + ID_OUI_FROM_DATABASE=Syes srl + ++OUI:28FA19* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ ++OUI:28FA7A* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:28FAA0* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:28FBAE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:28FBD3* + ID_OUI_FROM_DATABASE=Ragentek Technology Group + +@@ -46247,6 +49859,9 @@ OUI:28FD80E* + OUI:28FD80F* + ID_OUI_FROM_DATABASE=Private + ++OUI:28FE65* ++ ID_OUI_FROM_DATABASE=DongGuan Siyoto Electronics Co., Ltd ++ + OUI:28FECD* + ID_OUI_FROM_DATABASE=Lemobile Information Technology (Beijing) Co., Ltd. + +@@ -46259,30 +49874,48 @@ OUI:28FF3C* + OUI:28FF3E* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:28FFB2* ++ ID_OUI_FROM_DATABASE=Toshiba Corp. ++ + OUI:2C002C* + ID_OUI_FROM_DATABASE=UNOWHY + + OUI:2C0033* + ID_OUI_FROM_DATABASE=EControls, LLC + ++OUI:2C00AB* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:2C00F7* + ID_OUI_FROM_DATABASE=XOS + + OUI:2C010B* + ID_OUI_FROM_DATABASE=NASCENT Technology, LLC - RemKon + ++OUI:2C01B5* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2C029F* + ID_OUI_FROM_DATABASE=3ALogics + ++OUI:2C0547* ++ ID_OUI_FROM_DATABASE=Shenzhen Phaten Tech. LTD ++ + OUI:2C0623* + ID_OUI_FROM_DATABASE=Win Leader Inc. + + OUI:2C073C* + ID_OUI_FROM_DATABASE=DEVLINE LIMITED + ++OUI:2C0786* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2C081C* + ID_OUI_FROM_DATABASE=OVH + ++OUI:2C0823* ++ ID_OUI_FROM_DATABASE=Sercomm France Sarl ++ + OUI:2C088C* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + +@@ -46301,9 +49934,60 @@ OUI:2C0E3D* + OUI:2C10C1* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:2C1165* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:2C15E1* + ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd. + ++OUI:2C16BD0* ++ ID_OUI_FROM_DATABASE=Beijing Jishi Huitong Technology Co., Ltd. ++ ++OUI:2C16BD1* ++ ID_OUI_FROM_DATABASE=Curtiss-Wright Drive Technology ++ ++OUI:2C16BD2* ++ ID_OUI_FROM_DATABASE=AIMCO ++ ++OUI:2C16BD3* ++ ID_OUI_FROM_DATABASE=Saft AB ++ ++OUI:2C16BD4* ++ ID_OUI_FROM_DATABASE=Sunit Oy ++ ++OUI:2C16BD5* ++ ID_OUI_FROM_DATABASE=Beijing Zhijian Link Technology Co., Ltd. ++ ++OUI:2C16BD6* ++ ID_OUI_FROM_DATABASE=CLOUDWALK TECHNOLOGY CO.,LTD ++ ++OUI:2C16BD7* ++ ID_OUI_FROM_DATABASE=SCT OPTRONICS CO., LTD ++ ++OUI:2C16BD8* ++ ID_OUI_FROM_DATABASE=Shenzhen elink smart Co., ltd ++ ++OUI:2C16BD9* ++ ID_OUI_FROM_DATABASE=Shanghai Walktech Information Technology Co.,Ltd. ++ ++OUI:2C16BDA* ++ ID_OUI_FROM_DATABASE=Shenzhen Haiying Wire Tech Co., Ltd. ++ ++OUI:2C16BDB* ++ ID_OUI_FROM_DATABASE=LINGDONG TECHNOLOGY (BEIJING) CO. LTD ++ ++OUI:2C16BDC* ++ ID_OUI_FROM_DATABASE=Beijing CHJ Automotive Co., Ltd. ++ ++OUI:2C16BDD* ++ ID_OUI_FROM_DATABASE=Hangzhou Yanzhi Technology Co.,Ltd. ++ ++OUI:2C16BDE* ++ ID_OUI_FROM_DATABASE=Molex Incorporated ++ ++OUI:2C17E0* ++ ID_OUI_FROM_DATABASE=SYSTEMES ET TECHNOLOGIES IDENTIFICATION (STid) ++ + OUI:2C1875* + ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd + +@@ -46313,15 +49997,27 @@ OUI:2C18AE* + OUI:2C1984* + ID_OUI_FROM_DATABASE=IDN Telecom, Inc. + ++OUI:2C1A01* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:2C1A05* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2C1A31* + ID_OUI_FROM_DATABASE=Electronics Company Limited + + OUI:2C1BC8* + ID_OUI_FROM_DATABASE=Hunan Topview Network System CO.,LTD + ++OUI:2C1CF6* ++ ID_OUI_FROM_DATABASE=Alien Green LLC ++ + OUI:2C1DB8* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:2C1E4F* ++ ID_OUI_FROM_DATABASE=Chengdu Qianli Network Technology Co., Ltd. ++ + OUI:2C1EEA* + ID_OUI_FROM_DATABASE=AERODEV + +@@ -46424,6 +50120,9 @@ OUI:2C279E5* + OUI:2C279E6* + ID_OUI_FROM_DATABASE=Rutledge Omni Services Pte Ltd + ++OUI:2C279E7* ++ ID_OUI_FROM_DATABASE=FOCAL-JMLab ++ + OUI:2C279E8* + ID_OUI_FROM_DATABASE=Institut Dr. Foerster GmbH & Co. KG + +@@ -46433,6 +50132,9 @@ OUI:2C279E9* + OUI:2C279EA* + ID_OUI_FROM_DATABASE=Exegy Inc + ++OUI:2C279EB* ++ ID_OUI_FROM_DATABASE=Forties Inc. ++ + OUI:2C279EC* + ID_OUI_FROM_DATABASE=WAYCOM Technology Co.,Ltd + +@@ -46454,6 +50156,9 @@ OUI:2C28B7* + OUI:2C2997* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:2C2BF9* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:2C2D48* + ID_OUI_FROM_DATABASE=bct electronic GesmbH + +@@ -46479,7 +50184,7 @@ OUI:2C3427* + ID_OUI_FROM_DATABASE=ERCO & GENER + + OUI:2C3557* +- ID_OUI_FROM_DATABASE=ELLIY Power CO..Ltd ++ ID_OUI_FROM_DATABASE=ELIIY Power CO., Ltd. + + OUI:2C36A0* + ID_OUI_FROM_DATABASE=Capisco Limited +@@ -46505,15 +50210,24 @@ OUI:2C39C1* + OUI:2C3A28* + ID_OUI_FROM_DATABASE=Fagor Electrónica + ++OUI:2C3A91* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2C3AE8* + ID_OUI_FROM_DATABASE=Espressif Inc. + ++OUI:2C3AFD* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:2C3BFD* + ID_OUI_FROM_DATABASE=Netstor Technology Co., Ltd. + + OUI:2C3ECF* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:2C3F0B* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:2C3F38* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -46538,6 +50252,9 @@ OUI:2C4205* + OUI:2C431A* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + ++OUI:2C43BE* ++ ID_OUI_FROM_DATABASE=Sunnovo International Limited ++ + OUI:2C4401* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -46595,15 +50312,33 @@ OUI:2C4835D* + OUI:2C4835E* + ID_OUI_FROM_DATABASE=IROOTECH TECHNOLOGY CO.,LTD + ++OUI:2C4881* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:2C4A11* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ ++OUI:2C4CC6* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:2C4D54* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:2C4D79* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + ++OUI:2C4E7D* ++ ID_OUI_FROM_DATABASE=Chunghua Intelligent Network Equipment Inc. ++ ++OUI:2C4F52* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2C5089* + ID_OUI_FROM_DATABASE=Shenzhen Kaixuan Visual Technology Co.,Limited + ++OUI:2C52AF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:2C534A* + ID_OUI_FROM_DATABASE=Shenzhen Winyao Electronic Limited + +@@ -46619,6 +50354,9 @@ OUI:2C54CF* + OUI:2C553C* + ID_OUI_FROM_DATABASE=Gainspeed, Inc. + ++OUI:2C557C* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:2C55D3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -46628,9 +50366,15 @@ OUI:2C56DC* + OUI:2C5731* + ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited + ++OUI:2C5741* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2C584F* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:2C58E8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:2C598A* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -46655,6 +50399,9 @@ OUI:2C5BB8* + OUI:2C5BE1* + ID_OUI_FROM_DATABASE=Centripetal Networks, Inc + ++OUI:2C5D34* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:2C5D93* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -46662,7 +50409,10 @@ OUI:2C5FF3* + ID_OUI_FROM_DATABASE=Pertronic Industries + + OUI:2C600C* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. ++ ++OUI:2C6104* ++ ID_OUI_FROM_DATABASE=SHENZHEN FENGLIAN TECHNOLOGY CO., LTD. + + OUI:2C61F6* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -46674,7 +50424,10 @@ OUI:2C6289* + ID_OUI_FROM_DATABASE=Regenersis (Glenrothes) Ltd + + OUI:2C6373* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:2C641F* ++ ID_OUI_FROM_DATABASE=Vizio, Inc + + OUI:2C6798* + ID_OUI_FROM_DATABASE=InTalTech Ltd. +@@ -46739,27 +50492,48 @@ OUI:2C6B7D* + OUI:2C6BF5* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:2C6DC1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:2C6E85* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:2C6F51* ++ ID_OUI_FROM_DATABASE=Herospeed Digital Technology Limited ++ + OUI:2C6FC9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:2C7155* + ID_OUI_FROM_DATABASE=HiveMotion + ++OUI:2C71FF* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:2C72C3* + ID_OUI_FROM_DATABASE=Soundmatters + + OUI:2C7360* + ID_OUI_FROM_DATABASE=Earda Technologies co Ltd + ++OUI:2C73A0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2C750F* + ID_OUI_FROM_DATABASE=Shanghai Dongzhou-Lawton Communication Technology Co. Ltd. + + OUI:2C768A* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:2C780E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:2C793D* ++ ID_OUI_FROM_DATABASE=Boditech Med ++ ++OUI:2C79D7* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:2C7B5A* + ID_OUI_FROM_DATABASE=Milper Ltd + +@@ -46790,9 +50564,15 @@ OUI:2C8A72* + OUI:2C8BF2* + ID_OUI_FROM_DATABASE=Hitachi Metals America Ltd + ++OUI:2C8DB1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:2C9127* + ID_OUI_FROM_DATABASE=Eintechno Corporation + ++OUI:2C91AB* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:2C922C* + ID_OUI_FROM_DATABASE=Kishu Giken Kogyou Company Ltd,. + +@@ -46814,6 +50594,9 @@ OUI:2C9717* + OUI:2C97B1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:2C97ED* ++ ID_OUI_FROM_DATABASE=Sony Imaging Products & Solutions Inc. ++ + OUI:2C9924* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -46832,6 +50615,15 @@ OUI:2C9EEC* + OUI:2C9EFC* + ID_OUI_FROM_DATABASE=CANON INC. + ++OUI:2C9FFB* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ ++OUI:2CA02F* ++ ID_OUI_FROM_DATABASE=Veroguard Systems Pty Ltd ++ ++OUI:2CA042* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2CA157* + ID_OUI_FROM_DATABASE=acromate, Inc. + +@@ -46847,18 +50639,33 @@ OUI:2CA30E* + OUI:2CA539* + ID_OUI_FROM_DATABASE=Parallel Wireless, Inc + ++OUI:2CA59C* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:2CA780* + ID_OUI_FROM_DATABASE=True Technologies Inc. + + OUI:2CA835* + ID_OUI_FROM_DATABASE=RIM + ++OUI:2CA89C* ++ ID_OUI_FROM_DATABASE=Creatz inc. ++ ++OUI:2CA9F0* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:2CAA8E* ++ ID_OUI_FROM_DATABASE=Wyze Labs Inc ++ + OUI:2CAB00* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:2CAB25* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:2CAB33* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:2CABA4* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +@@ -46901,24 +50708,48 @@ OUI:2CB8ED* + OUI:2CBABA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:2CBC87* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:2CBE08* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:2CBE97* + ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH + ++OUI:2CBEEB* ++ ID_OUI_FROM_DATABASE=Nothing Technology Limited ++ + OUI:2CC260* + ID_OUI_FROM_DATABASE=Oracle Corporation + ++OUI:2CC407* ++ ID_OUI_FROM_DATABASE=machineQ ++ ++OUI:2CC546* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:2CC548* + ID_OUI_FROM_DATABASE=IAdea Corporation + + OUI:2CC5D3* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:2CC81B* ++ ID_OUI_FROM_DATABASE=Routerboard.com ++ ++OUI:2CCA0C* ++ ID_OUI_FROM_DATABASE=WITHUS PLANET ++ + OUI:2CCC15* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:2CCC44* ++ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. ++ ++OUI:2CCCE6* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:2CCD27* + ID_OUI_FROM_DATABASE=Precor Inc + +@@ -46928,6 +50759,9 @@ OUI:2CCD43* + OUI:2CCD69* + ID_OUI_FROM_DATABASE=Aqavi.com + ++OUI:2CCE1E* ++ ID_OUI_FROM_DATABASE=Cloudtronics Pty Ltd ++ + OUI:2CCF58* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -46937,6 +50771,9 @@ OUI:2CD02D* + OUI:2CD05A* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:2CD066* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:2CD1410* + ID_OUI_FROM_DATABASE=iCIRROUND Inc + +@@ -46977,7 +50814,7 @@ OUI:2CD141C* + ID_OUI_FROM_DATABASE=PIN SHANG LED Co., LTD. + + OUI:2CD141D* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Square Inc. + + OUI:2CD141E* + ID_OUI_FROM_DATABASE=CITA SMART SOLUTIONS LTD +@@ -46988,6 +50825,12 @@ OUI:2CD141F* + OUI:2CD1DA* + ID_OUI_FROM_DATABASE=Sanjole, Inc. + ++OUI:2CD26B* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ ++OUI:2CD2E3* ++ ID_OUI_FROM_DATABASE=Guangzhou Aoshi Electronic Co.,Ltd ++ + OUI:2CD2E7* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -46997,9 +50840,15 @@ OUI:2CD444* + OUI:2CD974* + ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD + ++OUI:2CDB07* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:2CDCAD* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + ++OUI:2CDCD7* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:2CDD0C* + ID_OUI_FROM_DATABASE=Discovergy GmbH + +@@ -47009,9 +50858,18 @@ OUI:2CDD95* + OUI:2CDDA3* + ID_OUI_FROM_DATABASE=Point Grey Research Inc. + ++OUI:2CDDE9* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ ++OUI:2CE032* ++ ID_OUI_FROM_DATABASE=TCL King Electrical Appliances(Huizhou)Co.,Ltd ++ + OUI:2CE2A8* + ID_OUI_FROM_DATABASE=DeviceDesign + ++OUI:2CE310* ++ ID_OUI_FROM_DATABASE=Stratacache ++ + OUI:2CE412* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -47021,12 +50879,21 @@ OUI:2CE6CC* + OUI:2CE871* + ID_OUI_FROM_DATABASE=Alert Metalguard ApS + ++OUI:2CEA7F* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:2CEADC* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ + OUI:2CEDEB* + ID_OUI_FROM_DATABASE=Alpheus Digital Company Limited + + OUI:2CEE26* + ID_OUI_FROM_DATABASE=Petroleum Geo-Services + ++OUI:2CF05D* ++ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. ++ + OUI:2CF0A2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -47036,12 +50903,18 @@ OUI:2CF0EE* + OUI:2CF203* + ID_OUI_FROM_DATABASE=EMKO ELEKTRONIK SAN VE TIC AS + ++OUI:2CF432* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:2CF4C5* + ID_OUI_FROM_DATABASE=Avaya Inc + + OUI:2CF7F1* + ID_OUI_FROM_DATABASE=Seeed Technology Inc. + ++OUI:2CF89B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:2CFAA2* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise + +@@ -47057,9 +50930,18 @@ OUI:2CFDA1* + OUI:2CFDAB* + ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. + ++OUI:2CFDB3* ++ ID_OUI_FROM_DATABASE=TCL Technoly Electronics(Huizhou).,Ltd ++ + OUI:2CFF65* + ID_OUI_FROM_DATABASE=Oki Electric Industry Co., Ltd. + ++OUI:2CFFEE* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:3003C8* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:30053F* + ID_OUI_FROM_DATABASE=JTI Co.,Ltd. + +@@ -47069,6 +50951,9 @@ OUI:30055C* + OUI:30074D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:3009C0* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:3009F90* + ID_OUI_FROM_DATABASE=Hurray Cloud Technology Co., Ltd. + +@@ -47114,6 +50999,51 @@ OUI:3009F9D* + OUI:3009F9E* + ID_OUI_FROM_DATABASE=ZhongLi HengFeng (Shenzhen) Technology co.,Ltd. + ++OUI:300A600* ++ ID_OUI_FROM_DATABASE=KAZUtechnica Co.,Ltd. ++ ++OUI:300A601* ++ ID_OUI_FROM_DATABASE=Beijing Ruiteng Zhongtian TECH Ltd.,Co ++ ++OUI:300A602* ++ ID_OUI_FROM_DATABASE=Advanced Electronic Designs, Inc. ++ ++OUI:300A603* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:300A604* ++ ID_OUI_FROM_DATABASE=AVIC JONHON OPTRONIC TECHNOLOGY CO., LTD. ++ ++OUI:300A605* ++ ID_OUI_FROM_DATABASE=A9 ++ ++OUI:300A606* ++ ID_OUI_FROM_DATABASE=Realtime biometrics India pvt ltd ++ ++OUI:300A607* ++ ID_OUI_FROM_DATABASE=Newtons4th Ltd ++ ++OUI:300A608* ++ ID_OUI_FROM_DATABASE=Bronkhorst High-Tech BV ++ ++OUI:300A609* ++ ID_OUI_FROM_DATABASE=WINTEK System Co., Ltd ++ ++OUI:300A60A* ++ ID_OUI_FROM_DATABASE=Ampetronic Ltd ++ ++OUI:300A60B* ++ ID_OUI_FROM_DATABASE=Giax GmbH ++ ++OUI:300A60C* ++ ID_OUI_FROM_DATABASE=Thermo Process Instruments, LP ++ ++OUI:300A60D* ++ ID_OUI_FROM_DATABASE=Sixth Energy Technologies Private Limited ++ ++OUI:300A60E* ++ ID_OUI_FROM_DATABASE=Imageo s.r.o. ++ + OUI:300AC5* + ID_OUI_FROM_DATABASE=Ruio telecommunication technologies Co., Limited + +@@ -47129,6 +51059,12 @@ OUI:300D2A* + OUI:300D43* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + ++OUI:300D9E* ++ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD ++ ++OUI:300EB8* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:300ED5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -47141,6 +51077,9 @@ OUI:3010B3* + OUI:3010E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:301389* ++ ID_OUI_FROM_DATABASE=Siemens AG, Automations & Drives, ++ + OUI:30142D* + ID_OUI_FROM_DATABASE=Piciorgros GmbH + +@@ -47154,7 +51093,7 @@ OUI:30168D* + ID_OUI_FROM_DATABASE=ProLon + + OUI:3017C8* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:3018CF* + ID_OUI_FROM_DATABASE=DEOS control systems GmbH +@@ -47165,6 +51104,9 @@ OUI:301966* + OUI:301A28* + ID_OUI_FROM_DATABASE=Mako Networks Ltd + ++OUI:301B97* ++ ID_OUI_FROM_DATABASE=Lierda Science & Technology Group Co.,Ltd ++ + OUI:301F9A0* + ID_OUI_FROM_DATABASE=ILSAN ELECTRONICS + +@@ -47219,12 +51161,30 @@ OUI:302303* + OUI:302432* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:302478* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:3024A9* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ ++OUI:3027CF* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:302952* ++ ID_OUI_FROM_DATABASE=Hillstone Networks Inc ++ + OUI:3029BE* + ID_OUI_FROM_DATABASE=Shanghai MRDcom Co.,Ltd + + OUI:302DE8* + ID_OUI_FROM_DATABASE=JDA, LLC (JDA Systems) + ++OUI:30317D* ++ ID_OUI_FROM_DATABASE=Hosiden Corporation ++ ++OUI:303235* ++ ID_OUI_FROM_DATABASE=Qingdao Intelligent&Precise Electronics Co.,Ltd. ++ + OUI:303294* + ID_OUI_FROM_DATABASE=W-IE-NE-R Plein & Baus GmbH + +@@ -47243,33 +51203,48 @@ OUI:3035AD* + OUI:3037A6* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:3037B3* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:303855* + ID_OUI_FROM_DATABASE=Nokia Corporation + + OUI:303926* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:303955* + ID_OUI_FROM_DATABASE=Shenzhen Jinhengjia Electronic Co., Ltd. + ++OUI:3039A9* ++ ID_OUI_FROM_DATABASE=Hongshan Information Science and Technology (HangZhou) Co.,Ltd. ++ + OUI:3039F2* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + + OUI:303A64* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:303ABA* ++ ID_OUI_FROM_DATABASE=Guangzhou BaoLun Electronics Co., Ltd ++ + OUI:303D08* + ID_OUI_FROM_DATABASE=GLINTT TES S.A. + + OUI:303EAD* + ID_OUI_FROM_DATABASE=Sonavox Canada Inc + ++OUI:303FBB* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:304174* + ID_OUI_FROM_DATABASE=ALTEC LANSING LLC + + OUI:304225* + ID_OUI_FROM_DATABASE=BURG-WÄCHTER KG + ++OUI:304240* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:3042A1* + ID_OUI_FROM_DATABASE=ilumisys Inc. DBA Toggled + +@@ -47294,15 +51269,75 @@ OUI:30469A* + OUI:30493B* + ID_OUI_FROM_DATABASE=Nanjing Z-Com Wireless Co.,Ltd + ++OUI:3049500* ++ ID_OUI_FROM_DATABASE=Guangzhou Lian-med Technology Co.,Ltd. ++ ++OUI:3049501* ++ ID_OUI_FROM_DATABASE=ATLI WORLD LIMITED ++ ++OUI:3049502* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:3049503* ++ ID_OUI_FROM_DATABASE=Morgan Schaffer Inc. ++ ++OUI:3049504* ++ ID_OUI_FROM_DATABASE=ADVANCED MICROWAVE ENGINEERING SRL ++ ++OUI:3049505* ++ ID_OUI_FROM_DATABASE=IK Elektronik GmbH ++ ++OUI:3049506* ++ ID_OUI_FROM_DATABASE=Curb, Inc. ++ ++OUI:3049507* ++ ID_OUI_FROM_DATABASE=Shenzhen iTG robot Co.,Ltd. ++ ++OUI:3049508* ++ ID_OUI_FROM_DATABASE=SHENZHEN LDROBOT CO., LTD. ++ ++OUI:3049509* ++ ID_OUI_FROM_DATABASE=Shanghai gatang technology CO.,LTD ++ ++OUI:304950A* ++ ID_OUI_FROM_DATABASE=Ledworks SRL ++ ++OUI:304950B* ++ ID_OUI_FROM_DATABASE=HANGZHOU EV-TECH CO.,LTD ++ ++OUI:304950C* ++ ID_OUI_FROM_DATABASE=Anacove LLC ++ ++OUI:304950D* ++ ID_OUI_FROM_DATABASE=Merlyn Mind, Inc. ++ ++OUI:304950E* ++ ID_OUI_FROM_DATABASE=IoTmaxx GmbH ++ ++OUI:304A26* ++ ID_OUI_FROM_DATABASE=Shenzhen Trolink Technology CO, LTD ++ + OUI:304B07* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + + OUI:304C7E* + ID_OUI_FROM_DATABASE=Panasonic Electric Works Automation Controls Techno Co.,Ltd. + ++OUI:304E1B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:304EC3* + ID_OUI_FROM_DATABASE=Tianjin Techua Technology Co., Ltd. + ++OUI:304F75* ++ ID_OUI_FROM_DATABASE=DASAN Network Solutions ++ ++OUI:305075* ++ ID_OUI_FROM_DATABASE=GN Audio A/S ++ ++OUI:3050FD* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:3051F8* + ID_OUI_FROM_DATABASE=BYK-Gardner GmbH + +@@ -47315,6 +51350,18 @@ OUI:3052CB* + OUI:3055ED* + ID_OUI_FROM_DATABASE=Trex Network LLC + ++OUI:305684* ++ ID_OUI_FROM_DATABASE=SHENZHEN YUNJI INTELLIGENT TECHNOLOGY CO.,LTD ++ ++OUI:305696* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ ++OUI:305714* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:30578E* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:3057AC* + ID_OUI_FROM_DATABASE=IRLAB LTD. + +@@ -47336,6 +51383,9 @@ OUI:305D38* + OUI:305DA6* + ID_OUI_FROM_DATABASE=ADVALY SYSTEM Inc. + ++OUI:305F77* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:306023* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -47351,6 +51401,9 @@ OUI:30636B* + OUI:3065EC* + ID_OUI_FROM_DATABASE=Wistron (ChongQing) + ++OUI:3066D0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:30688C* + ID_OUI_FROM_DATABASE=Reach Technology Inc. + +@@ -47366,6 +51419,9 @@ OUI:306CBE* + OUI:306E5C* + ID_OUI_FROM_DATABASE=Validus Technologies + ++OUI:306F07* ++ ID_OUI_FROM_DATABASE=Nations Technologies Inc. ++ + OUI:3071B2* + ID_OUI_FROM_DATABASE=Hangzhou Prevail Optoelectronic Equipment Co.,LTD. + +@@ -47376,7 +51432,7 @@ OUI:307496* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:307512* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:30766F* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) +@@ -47393,12 +51449,18 @@ OUI:30786B* + OUI:3078C2* + ID_OUI_FROM_DATABASE=Innowireless / QUCELL Networks + ++OUI:3078D3* ++ ID_OUI_FROM_DATABASE=Virgilant Technologies Ltd. ++ + OUI:307BAC* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + + OUI:307C30* + ID_OUI_FROM_DATABASE=RIM + ++OUI:307C4A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:307C5E* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -47408,12 +51470,24 @@ OUI:307CB2* + OUI:307ECB* + ID_OUI_FROM_DATABASE=SFR + ++OUI:30809B* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:308398* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:308454* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + + OUI:3085A9* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:3085EB* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:30862D* ++ ID_OUI_FROM_DATABASE=Arista Network, Inc. ++ + OUI:308730* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -47423,6 +51497,9 @@ OUI:3087D9* + OUI:308841* + ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. + ++OUI:308944* ++ ID_OUI_FROM_DATABASE=DEVA Broadcast Ltd. ++ + OUI:308976* + ID_OUI_FROM_DATABASE=DALIAN LAMBA TECHNOLOGY CO.,LTD + +@@ -47432,24 +51509,51 @@ OUI:308999* + OUI:3089D3* + ID_OUI_FROM_DATABASE=HONGKONG UCLOUDLINK NETWORK TECHNOLOGY LIMITED + ++OUI:308AF7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:308BB2* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:308CFB* + ID_OUI_FROM_DATABASE=Dropcam + + OUI:308D99* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:308E7A* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ ++OUI:309048* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3090AB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:309176* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:30918F* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:3092F6* + ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD + ++OUI:3093BC* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:309435* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:309587* ++ ID_OUI_FROM_DATABASE=HUNAN FN-LINK TECHNOLOGY LIMITED ++ + OUI:3095E3* + ID_OUI_FROM_DATABASE=SHANGHAI SIMCOM LIMITED + ++OUI:309610* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:3096FB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -47462,9 +51566,18 @@ OUI:309BAD* + OUI:309C23* + ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. + ++OUI:309E1D* ++ ID_OUI_FROM_DATABASE=OHSUNG ++ + OUI:309FFB* + ID_OUI_FROM_DATABASE=Ardomus Networks Corporation + ++OUI:30A023* ++ ID_OUI_FROM_DATABASE=ROCK PATH S.R.L ++ ++OUI:30A176* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:30A1FA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -47474,8 +51587,23 @@ OUI:30A220* + OUI:30A243* + ID_OUI_FROM_DATABASE=Shenzhen Prifox Innovation Technology Co., Ltd. + ++OUI:30A2C2* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:30A452* ++ ID_OUI_FROM_DATABASE=Arrival Elements BV ++ ++OUI:30A612* ++ ID_OUI_FROM_DATABASE=ShenZhen Hugsun Technology Co.,Ltd. ++ ++OUI:30A889* ++ ID_OUI_FROM_DATABASE=DECIMATOR DESIGN ++ + OUI:30A8DB* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:30A998* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. + + OUI:30A9DE* + ID_OUI_FROM_DATABASE=LG Innotek +@@ -47483,6 +51611,12 @@ OUI:30A9DE* + OUI:30AABD* + ID_OUI_FROM_DATABASE=Shanghai Reallytek Information Technology Co.,Ltd + ++OUI:30AAE4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:30AB6A* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ + OUI:30AE7B* + ID_OUI_FROM_DATABASE=Deqing Dusun Electron CO., LTD + +@@ -47492,11 +51626,26 @@ OUI:30AEA4* + OUI:30AEF6* + ID_OUI_FROM_DATABASE=Radio Mobile Access + ++OUI:30AFCE* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:30B037* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:30B164* + ID_OUI_FROM_DATABASE=Power Electronics International Inc. + ++OUI:30B1B5* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:30B216* +- ID_OUI_FROM_DATABASE=ABB AG - Power Grids - Grid Automation ++ ID_OUI_FROM_DATABASE=Hitachi ABB Power Grids – Grid Automation ++ ++OUI:30B237* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:30B346* ++ ID_OUI_FROM_DATABASE=CJSC NORSI-TRANS + + OUI:30B3A2* + ID_OUI_FROM_DATABASE=Shenzhen Heguang Measurement & Control Technology Co.,Ltd +@@ -47522,15 +51671,27 @@ OUI:30B64F* + OUI:30B7D4* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + ++OUI:30B930* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:30B9B0* ++ ID_OUI_FROM_DATABASE=Intracom Asia Co., Ltd ++ ++OUI:30BE3B* ++ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation ++ + OUI:30C01B* + ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd + + OUI:30C3D9* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:30C507* + ID_OUI_FROM_DATABASE=ECI Telecom Ltd. + ++OUI:30C50F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:30C750* + ID_OUI_FROM_DATABASE=MIC Technology Group + +@@ -47540,12 +51701,21 @@ OUI:30C7AE* + OUI:30C82A* + ID_OUI_FROM_DATABASE=WI-BIZ srl + ++OUI:30C9AB* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:30CBF8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:30CC21* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:30CDA7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:30D042* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:30D16B* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -47573,33 +51743,57 @@ OUI:30D659* + OUI:30D6C9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:30D941* ++ ID_OUI_FROM_DATABASE=Raydium Semiconductor Corp. ++ + OUI:30D9D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:30DE86* + ID_OUI_FROM_DATABASE=Cedac Software S.r.l. + ++OUI:30DF8D* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:30E090* + ID_OUI_FROM_DATABASE=Linctronix Ltd, + + OUI:30E171* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:30E283* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:30E37A* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:30E396* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:30E3D6* ++ ID_OUI_FROM_DATABASE=Spotify USA Inc. ++ + OUI:30E48E* + ID_OUI_FROM_DATABASE=Vodafone UK + + OUI:30E4DB* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:30E98E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:30EA26* ++ ID_OUI_FROM_DATABASE=Sycada BV ++ + OUI:30EB1F* + ID_OUI_FROM_DATABASE=Skylab M&C Technology Co.,Ltd + + OUI:30EB25* + ID_OUI_FROM_DATABASE=INTEK DIGITAL + ++OUI:30EB5A* ++ ID_OUI_FROM_DATABASE=LANDIS + GYR ++ + OUI:30EFD1* + ID_OUI_FROM_DATABASE=Alstom Strongwish (Shenzhen) Co., Ltd. + +@@ -47633,6 +51827,9 @@ OUI:30F7C5* + OUI:30F7D7* + ID_OUI_FROM_DATABASE=Thread Technology Co., Ltd + ++OUI:30F94B* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:30F9ED* + ID_OUI_FROM_DATABASE=Sony Corporation + +@@ -47642,15 +51839,24 @@ OUI:30FAB7* + OUI:30FB94* + ID_OUI_FROM_DATABASE=Shanghai Fangzhiwei Information Technology CO.,Ltd. + ++OUI:30FBB8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:30FC68* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:30FCEB* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:30FD11* + ID_OUI_FROM_DATABASE=MACROTECH (USA) INC. + + OUI:30FD38* + ID_OUI_FROM_DATABASE=Google, Inc. + ++OUI:30FD65* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:30FE31* + ID_OUI_FROM_DATABASE=Nokia + +@@ -47709,7 +51915,7 @@ OUI:340286* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:34029B* +- ID_OUI_FROM_DATABASE=CloudBerry Technologies Private Limited ++ ID_OUI_FROM_DATABASE=Plexonics Technologies LImited + + OUI:3403DE* + ID_OUI_FROM_DATABASE=Texas Instruments +@@ -47718,7 +51924,7 @@ OUI:34049E0* + ID_OUI_FROM_DATABASE=GoChip Inc. + + OUI:34049E1* +- ID_OUI_FROM_DATABASE=Connected IO Inc. ++ ID_OUI_FROM_DATABASE=Connected IO + + OUI:34049E2* + ID_OUI_FROM_DATABASE=EFD Induction +@@ -47742,7 +51948,7 @@ OUI:34049E8* + ID_OUI_FROM_DATABASE=Eclipse Information Technologies + + OUI:34049E9* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Church & Dwight Co., Inc. + + OUI:34049EA* + ID_OUI_FROM_DATABASE=i3 International Inc. +@@ -47751,7 +51957,7 @@ OUI:34049EB* + ID_OUI_FROM_DATABASE=Eginity, Inc. + + OUI:34049EC* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=ClearCaptions LLC + + OUI:34049ED* + ID_OUI_FROM_DATABASE=uikismart +@@ -47774,6 +51980,9 @@ OUI:3408BC* + OUI:340A22* + ID_OUI_FROM_DATABASE=TOP-ACCESS ELECTRONICS CO LTD + ++OUI:340A33* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:340A98* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -47786,6 +51995,9 @@ OUI:340B40* + OUI:340CED* + ID_OUI_FROM_DATABASE=Moduel AB + ++OUI:340F66* ++ ID_OUI_FROM_DATABASE=Web Sensing LLC ++ + OUI:341290* + ID_OUI_FROM_DATABASE=Treeview Co.,Ltd. + +@@ -47804,6 +52016,9 @@ OUI:3413E8* + OUI:34145F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:3414B5* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:341513* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -47822,12 +52037,21 @@ OUI:341A4C* + OUI:341B22* + ID_OUI_FROM_DATABASE=Grandbeing Technology Co., Ltd + ++OUI:341CF0* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:341E6B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:341FE4* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:342003* ++ ID_OUI_FROM_DATABASE=Shenzhen Feitengyun Technology Co.,LTD ++ ++OUI:3420E3* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:342109* + ID_OUI_FROM_DATABASE=Jensen Scandinavia AS + +@@ -47837,6 +52061,9 @@ OUI:342387* + OUI:3423BA* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:34243E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:34255D* + ID_OUI_FROM_DATABASE=Shenzhen Loadcom Technology Co.,Ltd + +@@ -47903,6 +52130,9 @@ OUI:3429EA* + OUI:342AF1* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:342B70* ++ ID_OUI_FROM_DATABASE=Arris ++ + OUI:342CC4* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + +@@ -47912,12 +52142,24 @@ OUI:342D0D* + OUI:342EB6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:342EB7* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:342F6E* + ID_OUI_FROM_DATABASE=Anywire corporation + ++OUI:342FBD* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:343111* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:34317F* ++ ID_OUI_FROM_DATABASE=Panasonic Appliances Company ++ ++OUI:34318F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3431C4* + ID_OUI_FROM_DATABASE=AVM GmbH + +@@ -47927,9 +52169,15 @@ OUI:3432E6* + OUI:34363B* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:343654* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:343759* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:343794* ++ ID_OUI_FROM_DATABASE=Hamee Corp. ++ + OUI:3438AF* + ID_OUI_FROM_DATABASE=Inlab Software GmbH + +@@ -47942,15 +52190,36 @@ OUI:343D98* + OUI:343DC4* + ID_OUI_FROM_DATABASE=BUFFALO.INC + ++OUI:343EA4* ++ ID_OUI_FROM_DATABASE=Ring LLC ++ + OUI:3440B5* + ID_OUI_FROM_DATABASE=IBM + + OUI:34415D* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:3441A8* ++ ID_OUI_FROM_DATABASE=ER-Telecom ++ ++OUI:344262* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:34466F* + ID_OUI_FROM_DATABASE=HiTEM Engineering + ++OUI:3446EC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:3448ED* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:34495B* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:344AC3* ++ ID_OUI_FROM_DATABASE=HuNan ZiKun Information Technology CO., Ltd ++ + OUI:344B3D* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -47978,6 +52247,12 @@ OUI:344F5C* + OUI:344F69* + ID_OUI_FROM_DATABASE=EKINOPS SAS + ++OUI:345180* ++ ID_OUI_FROM_DATABASE=TCL King Electrical Appliances (Huizhou) Co., Ltd ++ ++OUI:345184* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:3451AA* + ID_OUI_FROM_DATABASE=JID GLOBAL + +@@ -47987,12 +52262,21 @@ OUI:3451C9* + OUI:34543C* + ID_OUI_FROM_DATABASE=TAKAOKA TOKO CO.,LTD. + ++OUI:345594* ++ ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD ++ + OUI:3456FE* + ID_OUI_FROM_DATABASE=Cisco Meraki + + OUI:345760* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + ++OUI:345840* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:34587C* ++ ID_OUI_FROM_DATABASE=MIRAE INFORMATION TECHNOLOGY CO., LTD. ++ + OUI:345A06* + ID_OUI_FROM_DATABASE=SHARP Corporation + +@@ -48002,6 +52286,9 @@ OUI:345ABA* + OUI:345B11* + ID_OUI_FROM_DATABASE=EVI HEAT AB + ++OUI:345B98* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:345BBB* + ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. + +@@ -48017,6 +52304,9 @@ OUI:346178* + OUI:346288* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:3463D4* ++ ID_OUI_FROM_DATABASE=BIONIX SUPPLYCHAIN TECHNOLOGIES SLU ++ + OUI:3464A9* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -48026,6 +52316,9 @@ OUI:3466EA* + OUI:34684A* + ID_OUI_FROM_DATABASE=Teraworks Co., Ltd. + ++OUI:346893* ++ ID_OUI_FROM_DATABASE=Tecnovideo Srl ++ + OUI:346895* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -48038,12 +52331,18 @@ OUI:346AC2* + OUI:346B46* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:346B5B* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:346BD3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:346C0F* + ID_OUI_FROM_DATABASE=Pramod Telecom Pvt. Ltd + ++OUI:346D9C* ++ ID_OUI_FROM_DATABASE=Carrier Corporation ++ + OUI:346E8A* + ID_OUI_FROM_DATABASE=Ecosense + +@@ -48059,11 +52358,26 @@ OUI:346F92* + OUI:346FED* + ID_OUI_FROM_DATABASE=Enovation Controls + ++OUI:347146* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:34732D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:34735A* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:347563* ++ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. ++ + OUI:3475C7* + ID_OUI_FROM_DATABASE=Avaya Inc + + OUI:3476C5* +- ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC. ++ ID_OUI_FROM_DATABASE=I-O DATA DEVICE,INC. ++ ++OUI:347839* ++ ID_OUI_FROM_DATABASE=zte corporation + + OUI:347877* + ID_OUI_FROM_DATABASE=O-Net Communications (Shenzhen) Limited +@@ -48080,6 +52394,12 @@ OUI:347A60* + OUI:347C25* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:347DF6* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:347E00* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:347E39* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +@@ -48104,6 +52424,9 @@ OUI:3481C4* + OUI:3481F4* + ID_OUI_FROM_DATABASE=SST Taiwan Ltd. + ++OUI:3482C5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:3482DE* + ID_OUI_FROM_DATABASE=Kiio Inc + +@@ -48114,17 +52437,23 @@ OUI:348446* + ID_OUI_FROM_DATABASE=Ericsson AB + + OUI:348584* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:34862A* + ID_OUI_FROM_DATABASE=Heinz Lackmann GmbH & Co KG + ++OUI:34865D* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:34873D* +- ID_OUI_FROM_DATABASE=Quectel Wireless Solution Co.,Ltd. ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. + + OUI:34885D* + ID_OUI_FROM_DATABASE=Logitech Far East + ++OUI:348A12* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:348A7B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48137,6 +52466,12 @@ OUI:348B75* + OUI:348F27* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:34916F* ++ ID_OUI_FROM_DATABASE=UserGate Ltd. ++ ++OUI:349342* ++ ID_OUI_FROM_DATABASE=TTE Corporation ++ + OUI:3495DB* + ID_OUI_FROM_DATABASE=Logitec Corporation + +@@ -48170,6 +52505,9 @@ OUI:349D90* + OUI:349E34* + ID_OUI_FROM_DATABASE=Evervictory Electronic Co.Ltd + ++OUI:349F7B* ++ ID_OUI_FROM_DATABASE=CANON INC. ++ + OUI:34A183* + ID_OUI_FROM_DATABASE=AWare, Inc + +@@ -48203,6 +52541,9 @@ OUI:34A843* + OUI:34A84E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:34A8EB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:34AA8B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48215,21 +52556,36 @@ OUI:34AAEE* + OUI:34AB37* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:34AB95* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:34ADE4* + ID_OUI_FROM_DATABASE=Shanghai Chint Power Systems Co., Ltd. + + OUI:34AF2C* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:34AFB3* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:34B1F7* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:34B20A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:34B354* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:34B472* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:34B571* + ID_OUI_FROM_DATABASE=PLDS + ++OUI:34B5A3* ++ ID_OUI_FROM_DATABASE=CIG SHANGHAI CO LTD ++ + OUI:34B7FD* + ID_OUI_FROM_DATABASE=Guangzhou Younghead Electronic Technology Co.,Ltd + +@@ -48275,6 +52631,9 @@ OUI:34C059* + OUI:34C0F9* + ID_OUI_FROM_DATABASE=Rockwell Automation + ++OUI:34C103* ++ ID_OUI_FROM_DATABASE=Hangzhou Huamu Technology Co.,Ltd. ++ + OUI:34C3AC* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48288,17 +52647,23 @@ OUI:34C69A* + ID_OUI_FROM_DATABASE=Enecsys Ltd + + OUI:34C731* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:34C803* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:34C93D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:34C99D* + ID_OUI_FROM_DATABASE=EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD. + + OUI:34C9F0* + ID_OUI_FROM_DATABASE=LM Technologies Ltd + ++OUI:34CB1A* ++ ID_OUI_FROM_DATABASE=Procter & Gamble Company ++ + OUI:34CC28* + ID_OUI_FROM_DATABASE=Nexpring Co. LTD., + +@@ -48314,6 +52679,9 @@ OUI:34CE00* + OUI:34CE94* + ID_OUI_FROM_DATABASE=Parsec (Pty) Ltd + ++OUI:34CFF6* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:34D09B* + ID_OUI_FROM_DATABASE=MobilMAX Technology Inc. + +@@ -48362,24 +52730,45 @@ OUI:34D0B8D* + OUI:34D0B8E* + ID_OUI_FROM_DATABASE=Kongqiguanjia (Beijing)Technology co.,ltd + ++OUI:34D262* ++ ID_OUI_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD ++ + OUI:34D270* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + + OUI:34D2C4* + ID_OUI_FROM_DATABASE=RENA GmbH Print Systeme + ++OUI:34D693* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:34D712* + ID_OUI_FROM_DATABASE=Smartisan Digital Co., Ltd + ++OUI:34D772* ++ ID_OUI_FROM_DATABASE=Xiamen Yudian Automation Technology Co., Ltd ++ + OUI:34D7B4* + ID_OUI_FROM_DATABASE=Tributary Systems, Inc. + + OUI:34D954* + ID_OUI_FROM_DATABASE=WiBotic Inc. + ++OUI:34DAB7* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:34DAC1* ++ ID_OUI_FROM_DATABASE=SAE Technologies Development(Dongguan) Co., Ltd. ++ ++OUI:34DB9C* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:34DBFD* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:34DD7E* ++ ID_OUI_FROM_DATABASE=Umeox Innovations Co.,Ltd ++ + OUI:34DE1A* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -48398,12 +52787,60 @@ OUI:34E0D7* + OUI:34E12D* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:34E1D10* ++ ID_OUI_FROM_DATABASE=Tianjin Sublue Ocean Science & Technology Co., Ltd ++ ++OUI:34E1D11* ++ ID_OUI_FROM_DATABASE=SAMA NextGen PTE Limited ++ ++OUI:34E1D12* ++ ID_OUI_FROM_DATABASE=Teton Camera LLC ++ ++OUI:34E1D13* ++ ID_OUI_FROM_DATABASE=Rinco Ultrasonics AG ++ ++OUI:34E1D14* ++ ID_OUI_FROM_DATABASE=ASA Innovation & Technology Ltd. ++ ++OUI:34E1D15* ++ ID_OUI_FROM_DATABASE=Doki Technologies Limited ++ ++OUI:34E1D16* ++ ID_OUI_FROM_DATABASE=Ningbo Hua Gao Mdt Info Tech Ltd ++ ++OUI:34E1D17* ++ ID_OUI_FROM_DATABASE=Genius Pros ++ ++OUI:34E1D18* ++ ID_OUI_FROM_DATABASE=Hubitat Inc. ++ ++OUI:34E1D19* ++ ID_OUI_FROM_DATABASE=Biamp ++ ++OUI:34E1D1A* ++ ID_OUI_FROM_DATABASE=OrCam Technologies ++ ++OUI:34E1D1B* ++ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC ++ ++OUI:34E1D1C* ++ ID_OUI_FROM_DATABASE=CREW by True Rowing, Inc. ++ ++OUI:34E1D1D* ++ ID_OUI_FROM_DATABASE=HI-TECH.ORG ++ ++OUI:34E1D1E* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ + OUI:34E2FD* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:34E380* + ID_OUI_FROM_DATABASE=Genexis B.V. + ++OUI:34E3DA* ++ ID_OUI_FROM_DATABASE=Hoval Aktiengesellschaft ++ + OUI:34E42A* + ID_OUI_FROM_DATABASE=Automatic Bar Controls Inc. + +@@ -48428,21 +52865,36 @@ OUI:34E894* + OUI:34E911* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:34E9FE* ++ ID_OUI_FROM_DATABASE=Metis Co., Ltd. ++ + OUI:34EA34* + ID_OUI_FROM_DATABASE=HangZhou Gubei Electronics Technology Co.,Ltd + ++OUI:34EAE7* ++ ID_OUI_FROM_DATABASE=Shanghai High-Flying Electronics Technology Co., Ltd ++ + OUI:34ED0B* + ID_OUI_FROM_DATABASE=Shanghai XZ-COM.CO.,Ltd. + ++OUI:34ED1B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:34EF44* + ID_OUI_FROM_DATABASE=2Wire Inc + + OUI:34EF8B* + ID_OUI_FROM_DATABASE=NTT Communications Corporation + ++OUI:34EFB6* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:34F0CA* + ID_OUI_FROM_DATABASE=Shenzhen Linghangyuan Digital Technology Co.,Ltd. + ++OUI:34F150* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:34F39A* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -48458,6 +52910,12 @@ OUI:34F64B* + OUI:34F6D2* + ID_OUI_FROM_DATABASE=Panasonic Taiwan Co.,Ltd. + ++OUI:34F716* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:34F8E7* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:34F968* + ID_OUI_FROM_DATABASE=ATEK Products, LLC + +@@ -48470,12 +52928,33 @@ OUI:34FA9F* + OUI:34FC6F* + ID_OUI_FROM_DATABASE=ALCEA + ++OUI:34FCA1* ++ ID_OUI_FROM_DATABASE=Micronet union Technology(Chengdu)Co., Ltd. ++ + OUI:34FCB9* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:34FCEF* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:34FD6A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:34FE9E* ++ ID_OUI_FROM_DATABASE=Fujitsu Limited ++ ++OUI:34FEC5* ++ ID_OUI_FROM_DATABASE=Shenzhen Sunwoda intelligent hardware Co.,Ltd ++ ++OUI:380025* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:380118* ++ ID_OUI_FROM_DATABASE=ULVAC,Inc. ++ ++OUI:380146* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ + OUI:380195* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48485,6 +52964,9 @@ OUI:380197* + OUI:38019F* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD + ++OUI:3802DE* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:380546* + ID_OUI_FROM_DATABASE=Foctek Photonics, Inc. + +@@ -48512,6 +52994,9 @@ OUI:380A94* + OUI:380AAB* + ID_OUI_FROM_DATABASE=Formlabs + ++OUI:380B3C* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:380B40* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48533,9 +53018,21 @@ OUI:380FE4* + OUI:3810D5* + ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH + ++OUI:3810F0* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:381428* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:38144E* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:3816D1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:381730* ++ ID_OUI_FROM_DATABASE=Ulrich Lippert GmbH & Co KG ++ + OUI:381766* + ID_OUI_FROM_DATABASE=PROMZAKAZ LTD. + +@@ -48545,9 +53042,15 @@ OUI:3817C3* + OUI:3817E1* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:38184C* ++ ID_OUI_FROM_DATABASE=Sony Home Entertainment&Sound Products Inc ++ + OUI:38192F* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:381A52* ++ ID_OUI_FROM_DATABASE=Seiko Epson Corporation ++ + OUI:381C1A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -48557,9 +53060,18 @@ OUI:381C23* + OUI:381C4A* + ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd. + ++OUI:381D14* ++ ID_OUI_FROM_DATABASE=Skydio Inc. ++ + OUI:381DD9* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + ++OUI:381F8D* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ ++OUI:382028* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:382056* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -48569,12 +53081,18 @@ OUI:3820A8* + OUI:382187* + ID_OUI_FROM_DATABASE=Midea Group Co., Ltd. + ++OUI:3821C7* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:38229D* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + + OUI:3822D6* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:3822E2* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:38256B* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + +@@ -48593,6 +53111,9 @@ OUI:38295A* + OUI:3829DD* + ID_OUI_FROM_DATABASE=ONvocal Inc + ++OUI:382A19* ++ ID_OUI_FROM_DATABASE=Technica Engineering GmbH ++ + OUI:382B78* + ID_OUI_FROM_DATABASE=ECO PLUGS ENTERPRISE CO., LTD + +@@ -48605,6 +53126,9 @@ OUI:382DD1* + OUI:382DE8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:3830F9* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:3831AC* + ID_OUI_FROM_DATABASE=WEG + +@@ -48659,12 +53183,27 @@ OUI:383A21D* + OUI:383A21E* + ID_OUI_FROM_DATABASE=SDNware technology co.,LTD + ++OUI:383B26* ++ ID_OUI_FROM_DATABASE=Jiangsu Qinheng Co., Ltd. ++ + OUI:383BC8* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:383C9C* ++ ID_OUI_FROM_DATABASE=Fujian Newland Payment Technology Co.,Ltd. ++ ++OUI:383D5B* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:383F10* + ID_OUI_FROM_DATABASE=DBL Technology Ltd. + ++OUI:383FB3* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:38420B* ++ ID_OUI_FROM_DATABASE=Sonos, Inc. ++ + OUI:384233* + ID_OUI_FROM_DATABASE=Wildeboer Bauteile GmbH + +@@ -48677,6 +53216,12 @@ OUI:384369* + OUI:38437D* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + ++OUI:3843E5* ++ ID_OUI_FROM_DATABASE=Grotech Inc ++ ++OUI:38453B* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:38454C* + ID_OUI_FROM_DATABASE=Light Labs, Inc. + +@@ -48686,9 +53231,15 @@ OUI:38458C* + OUI:384608* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:3847BC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:38484C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:384B5B* ++ ID_OUI_FROM_DATABASE=ZTRON TECHNOLOGY LIMITED ++ + OUI:384B76* + ID_OUI_FROM_DATABASE=AIRTAME ApS + +@@ -48707,6 +53258,15 @@ OUI:384FF0* + OUI:38521A* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:385247* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:38539C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:38549B* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:385610* + ID_OUI_FROM_DATABASE=CANDY HOUSE, Inc. + +@@ -48725,6 +53285,9 @@ OUI:3859F9* + OUI:385AA8* + ID_OUI_FROM_DATABASE=Beijing Zhongdun Security Technology Development Co. + ++OUI:385C76* ++ ID_OUI_FROM_DATABASE=PLANTRONICS, INC. ++ + OUI:385F66* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +@@ -48734,12 +53297,18 @@ OUI:385FC3* + OUI:386077* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + ++OUI:3861A5* ++ ID_OUI_FROM_DATABASE=Grabango Co ++ + OUI:3863BB* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:3863F6* + ID_OUI_FROM_DATABASE=3NOD MULTIMEDIA(SHENZHEN)CO.,LTD + ++OUI:3865B2* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:386645* + ID_OUI_FROM_DATABASE=OOSIC Technology CO.,Ltd + +@@ -48749,9 +53318,18 @@ OUI:3866F0* + OUI:386793* + ID_OUI_FROM_DATABASE=Asia Optical Co., Inc. + ++OUI:386893* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:3868A4* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD ++ + OUI:3868DD* + ID_OUI_FROM_DATABASE=INVENTEC CORPORATION + ++OUI:386A77* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:386B1C* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + +@@ -48819,7 +53397,7 @@ OUI:3873EAC* + ID_OUI_FROM_DATABASE=LG Electronics + + OUI:3873EAD* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:3873EAE* + ID_OUI_FROM_DATABASE=Shenzhen Jixian Technology Co., Ltd. +@@ -48831,7 +53409,10 @@ OUI:3876D1* + ID_OUI_FROM_DATABASE=Euronda SpA + + OUI:387862* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:387A3C* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + + OUI:387B47* + ID_OUI_FROM_DATABASE=AKELA, Inc. +@@ -48839,12 +53420,27 @@ OUI:387B47* + OUI:3880DF* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:3881D7* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:388345* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:38839A* ++ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. ++ ++OUI:388479* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:388602* + ID_OUI_FROM_DATABASE=Flexoptix GmbH + ++OUI:3887D5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:38881E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:38892C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -48854,15 +53450,24 @@ OUI:3889DC* + OUI:388AB7* + ID_OUI_FROM_DATABASE=ITC Networks + ++OUI:388ABE* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:388B59* + ID_OUI_FROM_DATABASE=Google, Inc. + + OUI:388C50* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:388E7A* ++ ID_OUI_FROM_DATABASE=AUTOIT ++ + OUI:388EE7* + ID_OUI_FROM_DATABASE=Fanhattan LLC + ++OUI:389052* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:3890A5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -48878,15 +53483,24 @@ OUI:389496* + OUI:3894E0* + ID_OUI_FROM_DATABASE=Syrotech Networks. Ltd. + ++OUI:3894ED* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:389592* + ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation + ++OUI:3897A4* ++ ID_OUI_FROM_DATABASE=ELECOM CO.,LTD. ++ + OUI:3897D6* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + + OUI:3898D8* + ID_OUI_FROM_DATABASE=MERITECH CO.,LTD + ++OUI:3898E9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:389AF6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -48899,6 +53513,9 @@ OUI:389F5A* + OUI:389F83* + ID_OUI_FROM_DATABASE=OTN Systems N.V. + ++OUI:38A067* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:38A28C* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + +@@ -48911,6 +53528,9 @@ OUI:38A53C* + OUI:38A5B6* + ID_OUI_FROM_DATABASE=SHENZHEN MEGMEET ELECTRICAL CO.,LTD + ++OUI:38A659* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:38A6CE* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +@@ -48938,27 +53558,87 @@ OUI:38ADBE* + OUI:38AF29* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + ++OUI:38AFD0* ++ ID_OUI_FROM_DATABASE=Nevro ++ + OUI:38AFD7* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + + OUI:38B12D* + ID_OUI_FROM_DATABASE=Sonotronic Nagel GmbH + ++OUI:38B19E0* ++ ID_OUI_FROM_DATABASE=Triple Jump Medical ++ ++OUI:38B19E1* ++ ID_OUI_FROM_DATABASE=Freedompro Srl ++ ++OUI:38B19E2* ++ ID_OUI_FROM_DATABASE=HDANYWHERE ++ ++OUI:38B19E3* ++ ID_OUI_FROM_DATABASE=AVO DEVELOPMENT LTD ++ ++OUI:38B19E4* ++ ID_OUI_FROM_DATABASE=Basalte BVBA ++ ++OUI:38B19E5* ++ ID_OUI_FROM_DATABASE=Star Electronics GmbH & CoKG ++ ++OUI:38B19E6* ++ ID_OUI_FROM_DATABASE=Thrust Networks ++ ++OUI:38B19E7* ++ ID_OUI_FROM_DATABASE=Beijing Memblaze Technology Co Ltd ++ ++OUI:38B19E8* ++ ID_OUI_FROM_DATABASE=BoCo Inc. ++ ++OUI:38B19E9* ++ ID_OUI_FROM_DATABASE=Doepke Schaltgeräte GmbH ++ ++OUI:38B19EA* ++ ID_OUI_FROM_DATABASE=Aeroespacial Guosheng Technology Co., Ltd ++ ++OUI:38B19EB* ++ ID_OUI_FROM_DATABASE=System Q Ltd ++ ++OUI:38B19EC* ++ ID_OUI_FROM_DATABASE=Gesellschaft industrieller Technologien ++ ++OUI:38B19ED* ++ ID_OUI_FROM_DATABASE=Dallas Delta Corporation ++ ++OUI:38B19EE* ++ ID_OUI_FROM_DATABASE=ShenZhen ShuaiXian Electronic Equipment Co.Ltd ++ + OUI:38B1DB* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:38B3F7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:38B4D3* ++ ID_OUI_FROM_DATABASE=BSH Hausgeraete GmbH ++ + OUI:38B54D* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:38B5BD* + ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger + ++OUI:38B5D3* ++ ID_OUI_FROM_DATABASE=SecuWorks ++ + OUI:38B725* + ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation + + OUI:38B74D* + ID_OUI_FROM_DATABASE=Fijowave Limited + ++OUI:38B800* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:38B8EB0* + ID_OUI_FROM_DATABASE=Bumjin C&L Co., Ltd. + +@@ -48981,7 +53661,7 @@ OUI:38B8EB6* + ID_OUI_FROM_DATABASE=MATRIXSTREAM TECHNOLOGIES, INC. + + OUI:38B8EB7* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Sirin Mobile Technologies + + OUI:38B8EB8* + ID_OUI_FROM_DATABASE=CeeNex Inc +@@ -49004,6 +53684,9 @@ OUI:38B8EBD* + OUI:38B8EBE* + ID_OUI_FROM_DATABASE=Wyres SAS + ++OUI:38BAB0* ++ ID_OUI_FROM_DATABASE=Broadcom ++ + OUI:38BAF8* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -49026,7 +53709,13 @@ OUI:38BF33* + ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications + + OUI:38C096* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ ++OUI:38C2BA* ++ ID_OUI_FROM_DATABASE=CCTV NEOTECH ++ ++OUI:38C4E8* ++ ID_OUI_FROM_DATABASE=NSS Sp. z o.o. + + OUI:38C70A* + ID_OUI_FROM_DATABASE=WiFiSong +@@ -49043,6 +53732,9 @@ OUI:38C986* + OUI:38C9A9* + ID_OUI_FROM_DATABASE=SMART High Reliability Solutions, Inc. + ++OUI:38CA73* ++ ID_OUI_FROM_DATABASE=Shenzhen MiaoMing Intelligent Technology Co.,Ltd ++ + OUI:38CA97* + ID_OUI_FROM_DATABASE=Contour Design LLC + +@@ -49058,12 +53750,18 @@ OUI:38D135* + OUI:38D269* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:38D2CA* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:38D40B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:38D547* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:38D57A* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:38D620* + ID_OUI_FROM_DATABASE=Limidea Concept Pte. Ltd. + +@@ -49073,6 +53771,9 @@ OUI:38D7CA* + OUI:38D82F* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:38D9A5* ++ ID_OUI_FROM_DATABASE=Mikotek Information Inc. ++ + OUI:38DBBB* + ID_OUI_FROM_DATABASE=Sunbow Telecom Co., Ltd. + +@@ -49088,9 +53789,15 @@ OUI:38E08E* + OUI:38E1AA* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:38E26E* ++ ID_OUI_FROM_DATABASE=ShenZhen Sweet Rain Electronics Co.,Ltd. ++ + OUI:38E2DD* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:38E39F* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:38E3C5* + ID_OUI_FROM_DATABASE=Taicang T&W Electronics + +@@ -49106,12 +53813,21 @@ OUI:38E7D8* + OUI:38E8DF* + ID_OUI_FROM_DATABASE=b gmbh medien + datenbanken + ++OUI:38E8EE* ++ ID_OUI_FROM_DATABASE=Nanjing Youkuo Electric Technology Co., Ltd ++ + OUI:38E98C* + ID_OUI_FROM_DATABASE=Reco S.p.A. + + OUI:38EAA7* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:38EB47* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:38EC0D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:38EC11* + ID_OUI_FROM_DATABASE=Novatek Microelectronics Corp. + +@@ -49124,11 +53840,14 @@ OUI:38ED18* + OUI:38EE9D* + ID_OUI_FROM_DATABASE=Anedo Ltd. + ++OUI:38EFE3* ++ ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS ++ + OUI:38F098* + ID_OUI_FROM_DATABASE=Vapor Stone Rail Systems + + OUI:38F0C8* +- ID_OUI_FROM_DATABASE=Livestream ++ ID_OUI_FROM_DATABASE=Mevo Inc. + + OUI:38F135* + ID_OUI_FROM_DATABASE=SensorTec-Canada +@@ -49136,9 +53855,18 @@ OUI:38F135* + OUI:38F23E* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + ++OUI:38F32E* ++ ID_OUI_FROM_DATABASE=Skullcandy ++ + OUI:38F33F* + ID_OUI_FROM_DATABASE=TATSUNO CORPORATION + ++OUI:38F3AB* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:38F3FB* ++ ID_OUI_FROM_DATABASE=Asperiq ++ + OUI:38F554* + ID_OUI_FROM_DATABASE=HISENSE ELECTRIC CO.,LTD + +@@ -49148,6 +53876,9 @@ OUI:38F557* + OUI:38F597* + ID_OUI_FROM_DATABASE=home2net GmbH + ++OUI:38F601* ++ ID_OUI_FROM_DATABASE=Solid State Storage Technology Corporation ++ + OUI:38F708* + ID_OUI_FROM_DATABASE=National Resource Management, Inc. + +@@ -49157,6 +53888,54 @@ OUI:38F73D* + OUI:38F7B2* + ID_OUI_FROM_DATABASE=SEOJUN ELECTRIC + ++OUI:38F7CD0* ++ ID_OUI_FROM_DATABASE=Polska Fabryka Wodomierzy i Ciep?omierzy FILA ++ ++OUI:38F7CD1* ++ ID_OUI_FROM_DATABASE=NZIA Connect Inc ++ ++OUI:38F7CD2* ++ ID_OUI_FROM_DATABASE=RIPower Co.,Ltd ++ ++OUI:38F7CD3* ++ ID_OUI_FROM_DATABASE=VANGUARD ++ ++OUI:38F7CD4* ++ ID_OUI_FROM_DATABASE=NORDI TELEKOMMUNIKATSIOONI OÜ ++ ++OUI:38F7CD5* ++ ID_OUI_FROM_DATABASE=Shanghai qinzhuo Electronic Co., Ltd. ++ ++OUI:38F7CD6* ++ ID_OUI_FROM_DATABASE=Fast Cotton(Beijing) Limited ++ ++OUI:38F7CD7* ++ ID_OUI_FROM_DATABASE=ARUNAS PTY LTD ++ ++OUI:38F7CD8* ++ ID_OUI_FROM_DATABASE=BlastWave Inc. ++ ++OUI:38F7CD9* ++ ID_OUI_FROM_DATABASE=RFbeam Microwave GmbH ++ ++OUI:38F7CDA* ++ ID_OUI_FROM_DATABASE=Distech Controls ++ ++OUI:38F7CDB* ++ ID_OUI_FROM_DATABASE=Fibergate Inc. ++ ++OUI:38F7CDC* ++ ID_OUI_FROM_DATABASE=Shenzhen MADIGI Electronic Technology Co., Ltd ++ ++OUI:38F7CDD* ++ ID_OUI_FROM_DATABASE=Macherey-Nagel GmbH & Co. KG ++ ++OUI:38F7CDE* ++ ID_OUI_FROM_DATABASE=APT MOBILE SATCOM LIMITED ++ ++OUI:38F85E* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ + OUI:38F889* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -49166,9 +53945,21 @@ OUI:38F8B7* + OUI:38F8CA* + ID_OUI_FROM_DATABASE=OWIN Inc. + ++OUI:38F9D3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:38FACA* + ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd + ++OUI:38FB14* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:38FC98* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:38FDF8* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:38FDFE0* + ID_OUI_FROM_DATABASE=Edge I&D Co., Ltd. + +@@ -49217,9 +54008,15 @@ OUI:38FDFEE* + OUI:38FEC5* + ID_OUI_FROM_DATABASE=Ellips B.V. + ++OUI:38FF13* ++ ID_OUI_FROM_DATABASE=Joint Stock Company Research Instinite Masshtab ++ + OUI:38FF36* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:3C01EF* ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ + OUI:3C02B1* + ID_OUI_FROM_DATABASE=Creation Technologies LP + +@@ -49235,6 +54032,12 @@ OUI:3C0518* + OUI:3C05AB* + ID_OUI_FROM_DATABASE=Product Creation Studio + ++OUI:3C0630* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:3C06A7* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:3C0754* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -49253,6 +54056,9 @@ OUI:3C096D* + OUI:3C0C48* + ID_OUI_FROM_DATABASE=Servergy, Inc. + ++OUI:3C0C7D* ++ ID_OUI_FROM_DATABASE=Tiny Mesh AS ++ + OUI:3C0CDB* + ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD + +@@ -49274,6 +54080,12 @@ OUI:3C10E6* + OUI:3C11B2* + ID_OUI_FROM_DATABASE=Fraunhofer FIT + ++OUI:3C13CC* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:3C1512* ++ ID_OUI_FROM_DATABASE=Shenzhen Huanhu Technology Co.,Ltd ++ + OUI:3C15C2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -49295,6 +54107,9 @@ OUI:3C18A0* + OUI:3C1915* + ID_OUI_FROM_DATABASE=GFI Chrono Time + ++OUI:3C195E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:3C197D* + ID_OUI_FROM_DATABASE=Ericsson AB + +@@ -49307,6 +54122,9 @@ OUI:3C1A57* + OUI:3C1A79* + ID_OUI_FROM_DATABASE=Huayuan Technology CO.,LTD + ++OUI:3C1A9E* ++ ID_OUI_FROM_DATABASE=VitalThings AS ++ + OUI:3C1CBE* + ID_OUI_FROM_DATABASE=JADAK LLC + +@@ -49316,6 +54134,15 @@ OUI:3C1E04* + OUI:3C1E13* + ID_OUI_FROM_DATABASE=HANGZHOU SUNRISE TECHNOLOGY CO., LTD + ++OUI:3C2093* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:3C20F6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:3C22FB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3C24F00* + ID_OUI_FROM_DATABASE=SHENZHEN PINSIDA TECHNOLOGY CO.,LTD. + +@@ -49370,9 +54197,18 @@ OUI:3C26D5* + OUI:3C2763* + ID_OUI_FROM_DATABASE=SLE quality engineering GmbH & Co. KG + ++OUI:3C286D* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:3C28A6* ++ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise (China) ++ + OUI:3C2AF4* + ID_OUI_FROM_DATABASE=Brother Industries, LTD. + ++OUI:3C2C30* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:3C2C94* + ID_OUI_FROM_DATABASE=杭州德澜科技有限公司(HangZhou Delan Technology Co.,Ltd) + +@@ -49394,6 +54230,9 @@ OUI:3C2F3A* + OUI:3C300C* + ID_OUI_FROM_DATABASE=Dewar Electronics Pty Ltd + ++OUI:3C306F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:3C3178* + ID_OUI_FROM_DATABASE=Qolsys Inc. + +@@ -49409,6 +54248,12 @@ OUI:3C363D* + OUI:3C36E4* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:3C3712* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ ++OUI:3C3786* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:3C3888* + ID_OUI_FROM_DATABASE=ConnectQuest, llc + +@@ -49469,6 +54314,9 @@ OUI:3C3F51* + OUI:3C404F* + ID_OUI_FROM_DATABASE=GUANGDONG PISEN ELECTRONICS CO.,LTD + ++OUI:3C410E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:3C427E0* + ID_OUI_FROM_DATABASE=Grandway Technology (Shenzhen) Limited + +@@ -49538,12 +54386,27 @@ OUI:3C4C69* + OUI:3C4CD0* + ID_OUI_FROM_DATABASE=CERAGON NETWORKS + ++OUI:3C4DBE* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3C4E47* + ID_OUI_FROM_DATABASE=Etronic A/S + ++OUI:3C510E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:3C5282* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:3C53D7* ++ ID_OUI_FROM_DATABASE=CEDES AG ++ ++OUI:3C5447* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:3C5731* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:3C574F* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + +@@ -49556,6 +54419,9 @@ OUI:3C57BD* + OUI:3C57D5* + ID_OUI_FROM_DATABASE=FiveCo + ++OUI:3C58C2* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:3C591E* + ID_OUI_FROM_DATABASE=TCL King Electrical Appliances (Huizhou) Co., Ltd + +@@ -49568,6 +54434,12 @@ OUI:3C5AB4* + OUI:3C5CC3* + ID_OUI_FROM_DATABASE=Shenzhen First Blue Chip Technology Ltd + ++OUI:3C5CC4* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:3C5CF1* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:3C5EC3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -49577,12 +54449,18 @@ OUI:3C5F01* + OUI:3C6104* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:3C6105* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:3C6200* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:3C6278* + ID_OUI_FROM_DATABASE=SHENZHEN JETNET TECHNOLOGY CO.,LTD. + ++OUI:3C62F0* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:3C6716* + ID_OUI_FROM_DATABASE=Lily Robotics + +@@ -49595,6 +54473,51 @@ OUI:3C678C* + OUI:3C6816* + ID_OUI_FROM_DATABASE=VXi Corporation + ++OUI:3C6A2C0* ++ ID_OUI_FROM_DATABASE=Rio Lago Technologies LLC ++ ++OUI:3C6A2C1* ++ ID_OUI_FROM_DATABASE=Olibra LLC ++ ++OUI:3C6A2C2* ++ ID_OUI_FROM_DATABASE=Bosch Automotive Products (Suzhou) Co., Ltd. ++ ++OUI:3C6A2C3* ++ ID_OUI_FROM_DATABASE=figur8, Inc. ++ ++OUI:3C6A2C4* ++ ID_OUI_FROM_DATABASE=XI'AN YEP TELECOM TECHNOLOGY CO.,LTD ++ ++OUI:3C6A2C5* ++ ID_OUI_FROM_DATABASE=Qingdao iGuan Technology Co., Ltd. ++ ++OUI:3C6A2C6* ++ ID_OUI_FROM_DATABASE=La Barrière Automatique ++ ++OUI:3C6A2C7* ++ ID_OUI_FROM_DATABASE=Homegear GmbH ++ ++OUI:3C6A2C8* ++ ID_OUI_FROM_DATABASE=TP Radio ++ ++OUI:3C6A2C9* ++ ID_OUI_FROM_DATABASE=WICKS Co., Ltd. ++ ++OUI:3C6A2CA* ++ ID_OUI_FROM_DATABASE=Metro ++ ++OUI:3C6A2CB* ++ ID_OUI_FROM_DATABASE=Phytium Technology Co., Ltd. ++ ++OUI:3C6A2CC* ++ ID_OUI_FROM_DATABASE=Eltov System ++ ++OUI:3C6A2CD* ++ ID_OUI_FROM_DATABASE=Xiamen Smarttek CO., Ltd. ++ ++OUI:3C6A2CE* ++ ID_OUI_FROM_DATABASE=Beijing Donghua Hongtai Polytron Technologies Inc ++ + OUI:3C6A7D* + ID_OUI_FROM_DATABASE=Niigata Power Systems Co., Ltd. + +@@ -49640,12 +54563,30 @@ OUI:3C7873* + OUI:3C7A8A* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:3C7AAA* ++ ID_OUI_FROM_DATABASE=China Dragon Technology Limited ++ ++OUI:3C7AC4* ++ ID_OUI_FROM_DATABASE=Chemtronics ++ ++OUI:3C7AF0* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ ++OUI:3C7C3F* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ ++OUI:3C7D0A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3C7DB1* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:3C7F6F* + ID_OUI_FROM_DATABASE=Telechips, Inc. + ++OUI:3C806B* ++ ID_OUI_FROM_DATABASE=Hunan Voc Acoustics Technology Co., Ltd. ++ + OUI:3C80AA* + ID_OUI_FROM_DATABASE=Ransnet Singapore Pte Ltd + +@@ -49661,9 +54602,18 @@ OUI:3C8375* + OUI:3C83B5* + ID_OUI_FROM_DATABASE=Advance Vision Electronics Co. Ltd. + ++OUI:3C846A* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:3C86A8* + ID_OUI_FROM_DATABASE=Sangshin elecom .co,, LTD + ++OUI:3C86D1* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:3C894D* ++ ID_OUI_FROM_DATABASE=Dr. Ing. h.c. F. Porsche AG ++ + OUI:3C8970* + ID_OUI_FROM_DATABASE=Neosfar + +@@ -49688,9 +54638,18 @@ OUI:3C8BFE* + OUI:3C8C40* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:3C8C93* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:3C8CF8* + ID_OUI_FROM_DATABASE=TRENDnet, Inc. + ++OUI:3C8D20* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:3C8F06* ++ ID_OUI_FROM_DATABASE=Shenzhen Libtor Technology Co.,Ltd ++ + OUI:3C9066* + ID_OUI_FROM_DATABASE=SmartRG, Inc. + +@@ -49703,9 +54662,15 @@ OUI:3C9157* + OUI:3C9174* + ID_OUI_FROM_DATABASE=ALONG COMMUNICATION TECHNOLOGY + ++OUI:3C9180* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:3C92DC* + ID_OUI_FROM_DATABASE=Octopod Technology Co. Ltd. + ++OUI:3C93F4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:3C94D5* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -49730,9 +54695,24 @@ OUI:3C99F7* + OUI:3C9A77* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:3C9BC6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:3C9BD6* ++ ID_OUI_FROM_DATABASE=Vizio, Inc ++ ++OUI:3C9C0F* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:3C9D56* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:3C9F81* + ID_OUI_FROM_DATABASE=Shenzhen CATIC Bit Communications Technology Co.,Ltd + ++OUI:3C9FC3* ++ ID_OUI_FROM_DATABASE=Beijing Sinead Technology Co., Ltd. ++ + OUI:3CA067* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -49751,18 +54731,30 @@ OUI:3CA31A* + OUI:3CA348* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:3CA37E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:3CA581* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:3CA616* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:3CA62F* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ ++OUI:3CA6F6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3CA72B* + ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD + + OUI:3CA82A* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:3CA8ED* ++ ID_OUI_FROM_DATABASE=smart light technology ++ + OUI:3CA9F4* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -49781,12 +54773,21 @@ OUI:3CB15B* + OUI:3CB17F* + ID_OUI_FROM_DATABASE=Wattwatchers Pty Ld + ++OUI:3CB233* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:3CB53D* ++ ID_OUI_FROM_DATABASE=HUNAN GOKE MICROELECTRONICS CO.,LTD ++ + OUI:3CB6B7* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:3CB72B* + ID_OUI_FROM_DATABASE=PLUMgrid Inc + ++OUI:3CB74B* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:3CB792* + ID_OUI_FROM_DATABASE=Hitachi Maxell, Ltd., Optronics Division + +@@ -49805,12 +54806,18 @@ OUI:3CBBFD* + OUI:3CBD3E* + ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. + ++OUI:3CBDC5* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:3CBDD8* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + + OUI:3CBEE1* + ID_OUI_FROM_DATABASE=NIKON CORPORATION + ++OUI:3CBF60* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:3CC079* + ID_OUI_FROM_DATABASE=Shenzhen One-Nine Intelligent Electronic Science and Technology Co., Ltd + +@@ -49829,6 +54836,9 @@ OUI:3CC243* + OUI:3CC2E1* + ID_OUI_FROM_DATABASE=XINHUA CONTROL ENGINEERING CO.,LTD + ++OUI:3CC786* ++ ID_OUI_FROM_DATABASE=DONGGUAN HUARONG COMMUNICATION TECHNOLOGIES CO.,LTD. ++ + OUI:3CC99E* + ID_OUI_FROM_DATABASE=Huiyang Technology Co., Ltd + +@@ -49838,6 +54848,12 @@ OUI:3CCA87* + OUI:3CCB7C* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:3CCD36* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:3CCD57* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:3CCD5A* + ID_OUI_FROM_DATABASE=Technische Alternative GmbH + +@@ -49862,6 +54878,9 @@ OUI:3CD0F8* + OUI:3CD16E* + ID_OUI_FROM_DATABASE=Telepower Communication Co., Ltd + ++OUI:3CD2E5* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:3CD4D6* + ID_OUI_FROM_DATABASE=WirelessWERX, Inc + +@@ -49877,6 +54896,9 @@ OUI:3CD9CE* + OUI:3CDA2A* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:3CDA6D* ++ ID_OUI_FROM_DATABASE=Tiandy Technologies CO.,LTD ++ + OUI:3CDCBC* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -49892,12 +54914,21 @@ OUI:3CDFA9* + OUI:3CDFBD* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:3CE038* ++ ID_OUI_FROM_DATABASE=Plumeria Networks, Inc. ++ + OUI:3CE072* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:3CE1A1* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:3CE36B* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ ++OUI:3CE3E7* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:3CE5A6* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +@@ -49919,9 +54950,15 @@ OUI:3CEAF9* + OUI:3CEAFB* + ID_OUI_FROM_DATABASE=NSE AG + ++OUI:3CECEF* ++ ID_OUI_FROM_DATABASE=Super Micro Computer, Inc. ++ + OUI:3CEF8C* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + ++OUI:3CF011* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:3CF392* + ID_OUI_FROM_DATABASE=Virtualtek. Co. Ltd + +@@ -49937,6 +54974,9 @@ OUI:3CF591* + OUI:3CF5CC* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + ++OUI:3CF652* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:3CF72A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -49955,6 +54995,51 @@ OUI:3CF862* + OUI:3CFA43* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:3CFAD30* ++ ID_OUI_FROM_DATABASE=Home Control AS ++ ++OUI:3CFAD31* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:3CFAD32* ++ ID_OUI_FROM_DATABASE=Naruida Technology Ltd. ++ ++OUI:3CFAD33* ++ ID_OUI_FROM_DATABASE=Harman Connected Services, Inc. ++ ++OUI:3CFAD34* ++ ID_OUI_FROM_DATABASE=GRG Banking Technology Co.,Ltd ++ ++OUI:3CFAD35* ++ ID_OUI_FROM_DATABASE=Gulf Security Technology Co., Ltd ++ ++OUI:3CFAD36* ++ ID_OUI_FROM_DATABASE=Nox Medical ++ ++OUI:3CFAD37* ++ ID_OUI_FROM_DATABASE=LIPS Corporation ++ ++OUI:3CFAD38* ++ ID_OUI_FROM_DATABASE=Energous Corporation ++ ++OUI:3CFAD39* ++ ID_OUI_FROM_DATABASE=Shenzhen Vplus Communication Intelligent Co., Ltd. ++ ++OUI:3CFAD3A* ++ ID_OUI_FROM_DATABASE=UltiMachine ++ ++OUI:3CFAD3B* ++ ID_OUI_FROM_DATABASE=Corelink Technology Co.,Ltd ++ ++OUI:3CFAD3C* ++ ID_OUI_FROM_DATABASE=Shenzhen zhong ju Fiber optical Co.Ltd ++ ++OUI:3CFAD3D* ++ ID_OUI_FROM_DATABASE=AMobile Solutions (Xiamen) CO. , LTD. ++ ++OUI:3CFAD3E* ++ ID_OUI_FROM_DATABASE=Mirico ++ + OUI:3CFB5C* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -49964,6 +55049,9 @@ OUI:3CFB96* + OUI:3CFDFE* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:3CFFD8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:4000E0* + ID_OUI_FROM_DATABASE=Derek(Shaoguan)Limited + +@@ -49979,6 +55067,12 @@ OUI:4001C6* + OUI:40040C* + ID_OUI_FROM_DATABASE=A&T + ++OUI:400589* ++ ID_OUI_FROM_DATABASE=T-Mobile, USA ++ ++OUI:400634* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:4006A0* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -49994,6 +55088,51 @@ OUI:400E67* + OUI:400E85* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:4011750* ++ ID_OUI_FROM_DATABASE=Lexi Devices, Inc. ++ ++OUI:4011751* ++ ID_OUI_FROM_DATABASE=Fujian Kuke3D Technology Co.,LTD ++ ++OUI:4011752* ++ ID_OUI_FROM_DATABASE=Kanda Kogyo ++ ++OUI:4011753* ++ ID_OUI_FROM_DATABASE=Beijing Hexinruitong Electric Power Technology Co., Ltd. ++ ++OUI:4011754* ++ ID_OUI_FROM_DATABASE=Table Trac Inc ++ ++OUI:4011755* ++ ID_OUI_FROM_DATABASE=MIRC ELECTRONICS LTD ++ ++OUI:4011756* ++ ID_OUI_FROM_DATABASE=ShenZhen LanShuo Communication Equipment CO.,LTD. ++ ++OUI:4011757* ++ ID_OUI_FROM_DATABASE=Guangzhou RALID Information System Co.Ltd ++ ++OUI:4011758* ++ ID_OUI_FROM_DATABASE=Beijing Gemotech Intelligent Technology Co., Ltd. ++ ++OUI:4011759* ++ ID_OUI_FROM_DATABASE=ADH Guardian USA ++ ++OUI:401175A* ++ ID_OUI_FROM_DATABASE=BWT Tianjin Ltd. ++ ++OUI:401175B* ++ ID_OUI_FROM_DATABASE=Chongqing IQIYI Intelligence Technology Co., Ltd. ++ ++OUI:401175C* ++ ID_OUI_FROM_DATABASE=disguise Technologies Limited ++ ++OUI:401175D* ++ ID_OUI_FROM_DATABASE=NanJing HuaStart Network Technology Co.,Ltd. ++ ++OUI:401175E* ++ ID_OUI_FROM_DATABASE=NIBBLE ++ + OUI:4011DC* + ID_OUI_FROM_DATABASE=Sonance + +@@ -50003,6 +55142,9 @@ OUI:4012E4* + OUI:4013D9* + ID_OUI_FROM_DATABASE=Global ES + ++OUI:4014AD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:401597* + ID_OUI_FROM_DATABASE=Protect America, Inc. + +@@ -50022,31 +55164,94 @@ OUI:4017E2* + ID_OUI_FROM_DATABASE=INTAI TECHNOLOGY CORP. + + OUI:4018B1* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:4018D7* + ID_OUI_FROM_DATABASE=Smartronix, Inc. + ++OUI:401920* ++ ID_OUI_FROM_DATABASE=Movon Corporation ++ + OUI:401B5F* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + ++OUI:401C83* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:401D59* + ID_OUI_FROM_DATABASE=Biometric Associates, LP + + OUI:4022ED* + ID_OUI_FROM_DATABASE=Digital Projection Ltd + ++OUI:402343* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:4024B2* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:4025C2* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:402619* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:40270B* + ID_OUI_FROM_DATABASE=Mobileeco Co., Ltd + + OUI:402814* + ID_OUI_FROM_DATABASE=RFI Engineering + ++OUI:402B50* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:402B69* ++ ID_OUI_FROM_DATABASE=Kumho Electric Inc. ++ + OUI:402BA1* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:402C760* ++ ID_OUI_FROM_DATABASE=Lista AG ++ ++OUI:402C761* ++ ID_OUI_FROM_DATABASE=Shanghai Dahua Scale Factory ++ ++OUI:402C762* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:402C764* ++ ID_OUI_FROM_DATABASE=Beijing Smarot Technology Co., Ltd. ++ ++OUI:402C765* ++ ID_OUI_FROM_DATABASE=Baumer Bourdon-Haenni ++ ++OUI:402C766* ++ ID_OUI_FROM_DATABASE=Guangzhou LANGO Electronics Technology Co., Ltd. ++ ++OUI:402C767* ++ ID_OUI_FROM_DATABASE=Zhejiang Guoli Security Technology Co., Ltd. ++ ++OUI:402C768* ++ ID_OUI_FROM_DATABASE=Suteng Innovation Technology Co., Ltd. ++ ++OUI:402C769* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:402C76A* ++ ID_OUI_FROM_DATABASE=NowTechnologies Zrt ++ ++OUI:402C76B* ++ ID_OUI_FROM_DATABASE=Beijing Kuaiyu Electronic Co., Ltd. ++ ++OUI:402C76C* ++ ID_OUI_FROM_DATABASE=gridX GmbH ++ ++OUI:402C76D* ++ ID_OUI_FROM_DATABASE=Guangzhou Qi'an Technology Co., Ltd. ++ ++OUI:402C76E* ++ ID_OUI_FROM_DATABASE=LS Energy Solutions + + OUI:402CF4* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. +@@ -50054,6 +55259,12 @@ OUI:402CF4* + OUI:402E28* + ID_OUI_FROM_DATABASE=MiXTelematics + ++OUI:402E71* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:402F86* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:403004* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -50084,20 +55295,32 @@ OUI:403F8C* + OUI:404022* + ID_OUI_FROM_DATABASE=ZIV + ++OUI:404028* ++ ID_OUI_FROM_DATABASE=ZIV ++ + OUI:40406B* + ID_OUI_FROM_DATABASE=Icomera + ++OUI:40406C* ++ ID_OUI_FROM_DATABASE=Icomera ++ + OUI:4040A7* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:404101* ++ ID_OUI_FROM_DATABASE=Rockwell Automation + + OUI:404229* + ID_OUI_FROM_DATABASE=Layer3TV, Inc + ++OUI:4044FD* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:4045DA* + ID_OUI_FROM_DATABASE=Spreadtrum Communications (Shanghai) Co., Ltd. + + OUI:40476A* +- ID_OUI_FROM_DATABASE=AG Acquisition Corp. d.b.a. ASTRO Gaming ++ ID_OUI_FROM_DATABASE=Astro Gaming + + OUI:4048FD0* + ID_OUI_FROM_DATABASE=BEIJING C&W ELECTRONICS(GROUP)CO.,LTD +@@ -50159,6 +55382,9 @@ OUI:404A18* + OUI:404AD4* + ID_OUI_FROM_DATABASE=Widex A/S + ++OUI:404C77* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:404D7F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -50189,6 +55415,9 @@ OUI:4054E4* + OUI:405539* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:405582* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:40560C* + ID_OUI_FROM_DATABASE=In Home Displays Ltd + +@@ -50198,9 +55427,15 @@ OUI:40562D* + OUI:405662* + ID_OUI_FROM_DATABASE=GuoTengShengHua Electronics LTD. + ++OUI:405899* ++ ID_OUI_FROM_DATABASE=Logitech Far East ++ + OUI:405A9B* + ID_OUI_FROM_DATABASE=ANOVO + ++OUI:405BD8* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:405CFD* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -50228,6 +55463,9 @@ OUI:40618E* + OUI:406231* + ID_OUI_FROM_DATABASE=GIFA + ++OUI:406234* ++ ID_OUI_FROM_DATABASE=Telink Semiconductor (Shanghai) Co., Ltd. ++ + OUI:4062B6* + ID_OUI_FROM_DATABASE=Tele system communication + +@@ -50267,12 +55505,21 @@ OUI:40704A* + OUI:407074* + ID_OUI_FROM_DATABASE=Life Technology (China) Co., Ltd + ++OUI:4070F5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:407183* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:407496* + ID_OUI_FROM_DATABASE=aFUN TECHNOLOGY INC. + ++OUI:4074E0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:4077A9* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:40786A* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -50312,9 +55559,15 @@ OUI:40862E* + OUI:408805* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:40882F* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:4088E0* + ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Limited Shenzhen Branch + ++OUI:4089A8* ++ ID_OUI_FROM_DATABASE=WiredIQ, LLC ++ + OUI:408A9A* + ID_OUI_FROM_DATABASE=TITENG CO., Ltd. + +@@ -50324,9 +55577,24 @@ OUI:408B07* + OUI:408BF6* + ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co., Ltd + ++OUI:408C1F* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:408C4C* ++ ID_OUI_FROM_DATABASE=Shenzhen MiaoMing Intelligent Technology Co.,Ltd ++ + OUI:408D5C* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + ++OUI:408F9D* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:409151* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:409505* ++ ID_OUI_FROM_DATABASE=ACOINFO TECHNOLOGY CO.,LTD ++ + OUI:409558* + ID_OUI_FROM_DATABASE=Aisino Corporation + +@@ -50360,6 +55628,9 @@ OUI:409BCD* + OUI:409C28* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:409CA6* ++ ID_OUI_FROM_DATABASE=Curvalux ++ + OUI:409F38* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + +@@ -50372,6 +55643,9 @@ OUI:409FC7* + OUI:40A108* + ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. + ++OUI:40A2DB* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:40A36B0* + ID_OUI_FROM_DATABASE=Fin Robotics Inc + +@@ -50391,7 +55665,7 @@ OUI:40A36B5* + ID_OUI_FROM_DATABASE=National Research Council of Canada + + OUI:40A36B6* +- ID_OUI_FROM_DATABASE=Bixi Systems Ltd. ++ ID_OUI_FROM_DATABASE=Securiton AG + + OUI:40A36B7* + ID_OUI_FROM_DATABASE=Pella Corporation +@@ -50426,6 +55700,9 @@ OUI:40A677* + OUI:40A6A4* + ID_OUI_FROM_DATABASE=PassivSystems Ltd + ++OUI:40A6B7* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:40A6D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -50436,7 +55713,13 @@ OUI:40A8F0* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:40A93F* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Pivotal Commware, Inc. ++ ++OUI:40A9CF* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:40AA56* ++ ID_OUI_FROM_DATABASE=China Dragon Technology Limited + + OUI:40AC8D* + ID_OUI_FROM_DATABASE=Data Management, Inc. +@@ -50444,12 +55727,21 @@ OUI:40AC8D* + OUI:40B034* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:40B076* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:40B0FA* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + + OUI:40B2C8* + ID_OUI_FROM_DATABASE=Nortel Networks + ++OUI:40B30E* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ ++OUI:40B31E* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:40B395* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -50465,17 +55757,23 @@ OUI:40B4CD* + OUI:40B4F0* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:40B5C1* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:40B688* + ID_OUI_FROM_DATABASE=LEGIC Identsystems AG + + OUI:40B6B1* + ID_OUI_FROM_DATABASE=SUNGSAM CO,.Ltd + ++OUI:40B6E7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:40B7F3* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:40B837* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:40B89A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. +@@ -50486,6 +55784,12 @@ OUI:40B93C* + OUI:40BA61* + ID_OUI_FROM_DATABASE=ARIMA Communications Corp. + ++OUI:40BC60* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:40BC68* ++ ID_OUI_FROM_DATABASE=Wuhan Funshion Online Technologies Co.,Ltd ++ + OUI:40BC73* + ID_OUI_FROM_DATABASE=Cronoplast S.L. + +@@ -50498,6 +55802,9 @@ OUI:40BD32* + OUI:40BD9E* + ID_OUI_FROM_DATABASE=Physio-Control, Inc + ++OUI:40BEEE* ++ ID_OUI_FROM_DATABASE=Shenzhen Yunding Information Technology Co.,Ltd ++ + OUI:40BF17* + ID_OUI_FROM_DATABASE=Digistar Telecom. SA + +@@ -50507,12 +55814,18 @@ OUI:40C245* + OUI:40C3C6* + ID_OUI_FROM_DATABASE=SnapRoute + ++OUI:40C48C* ++ ID_OUI_FROM_DATABASE=N-iTUS CO.,LTD. ++ + OUI:40C4D6* + ID_OUI_FROM_DATABASE=ChongQing Camyu Technology Development Co.,Ltd. + + OUI:40C62A* + ID_OUI_FROM_DATABASE=Shanghai Jing Ren Electronic Technology Co., Ltd. + ++OUI:40C711* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:40C729* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -50540,6 +55853,9 @@ OUI:40CD7A* + OUI:40CE24* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:40D25F* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:40D28A* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +@@ -50555,6 +55871,9 @@ OUI:40D3AE* + OUI:40D40E* + ID_OUI_FROM_DATABASE=Biodata Ltd + ++OUI:40D4BD* ++ ID_OUI_FROM_DATABASE=SK Networks Service CO., LTD. ++ + OUI:40D559* + ID_OUI_FROM_DATABASE=MICRO S.E.R.I. + +@@ -50567,11 +55886,32 @@ OUI:40D855* + OUI:40DC9D* + ID_OUI_FROM_DATABASE=HAJEN + ++OUI:40DCA5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:40DDD1* ++ ID_OUI_FROM_DATABASE=Beautiful Card Corporation ++ ++OUI:40DE17* ++ ID_OUI_FROM_DATABASE=Shenzhen Lanfeng Times Industrial Co.,Ltd. ++ ++OUI:40DEAD* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:40DF02* ++ ID_OUI_FROM_DATABASE=LINE BIZ Plus ++ ++OUI:40E1E4* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:40E230* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + + OUI:40E3D6* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:40E64B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:40E730* + ID_OUI_FROM_DATABASE=DEY Storage Systems, Inc. +@@ -50582,6 +55922,9 @@ OUI:40E793* + OUI:40EACE* + ID_OUI_FROM_DATABASE=FOUNDER BROADBAND NETWORK SERVICE CO.,LTD + ++OUI:40EC99* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:40ECF8* + ID_OUI_FROM_DATABASE=Siemens AG + +@@ -50630,6 +55973,9 @@ OUI:40ED98D* + OUI:40ED98E* + ID_OUI_FROM_DATABASE=BORDA TECHNOLOGY + ++OUI:40EE15* ++ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. ++ + OUI:40EEDD* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -50642,12 +55988,18 @@ OUI:40F02F* + OUI:40F04E* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:40F078* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:40F14C* + ID_OUI_FROM_DATABASE=ISE Europe SPRL + + OUI:40F201* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:40F21C* ++ ID_OUI_FROM_DATABASE=DASAN Zhone Solutions ++ + OUI:40F2E9* + ID_OUI_FROM_DATABASE=IBM + +@@ -50706,14 +56058,23 @@ OUI:40F413* + ID_OUI_FROM_DATABASE=Rubezh + + OUI:40F420* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:40F4EC* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:40F520* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:40F52E* + ID_OUI_FROM_DATABASE=Leica Microsystems (Schweiz) AG + ++OUI:40F946* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:40F9D5* ++ ID_OUI_FROM_DATABASE=Tecore Networks ++ + OUI:40FA7F* + ID_OUI_FROM_DATABASE=Preh Car Connect GmbH + +@@ -50726,21 +56087,81 @@ OUI:40FE0D* + OUI:440010* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:440049* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:44004D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:4401BB* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ + OUI:44032C* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4403770* ++ ID_OUI_FROM_DATABASE=Musashi Seimitsu Industry Co.,Ltd ++ ++OUI:4403771* ++ ID_OUI_FROM_DATABASE=Atari, Inc. ++ ++OUI:4403772* ++ ID_OUI_FROM_DATABASE=Exsom Computers LLC ++ ++OUI:4403773* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:4403774* ++ ID_OUI_FROM_DATABASE=Lenovo Image(Tianjin) Technology Ltd. ++ ++OUI:4403775* ++ ID_OUI_FROM_DATABASE=Norden Communication UK Ltd. ++ ++OUI:4403776* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN HUAWANG TECHNOLOGY CO; LTD ++ ++OUI:4403777* ++ ID_OUI_FROM_DATABASE=Stara S/A Indústria de Implementos Agrícolas ++ ++OUI:4403778* ++ ID_OUI_FROM_DATABASE=Gemmy Electronics (Shenzhen) Co, Ltd ++ ++OUI:4403779* ++ ID_OUI_FROM_DATABASE=SHENZHEN UT-KING TECHNOLOGY CO.,LTD ++ ++OUI:440377A* ++ ID_OUI_FROM_DATABASE=symplr ++ ++OUI:440377B* ++ ID_OUI_FROM_DATABASE=Hangzhou Asia Infrastructure Tech. Co., Ltd. ++ ++OUI:440377C* ++ ID_OUI_FROM_DATABASE=BIG Climatic Manufacture, Co. LTD, Zhongshan Branch ++ ++OUI:440377D* ++ ID_OUI_FROM_DATABASE=OMNISENSE SYSTEMS PRIVATE LIMITED TAIWAN BRANCH ++ ++OUI:440377E* ++ ID_OUI_FROM_DATABASE=Bolin Technology Co., Ltd ++ + OUI:4403A7* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:440444* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:44070B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:4409B8* + ID_OUI_FROM_DATABASE=Salcomp (Shenzhen) CO., LTD. + + OUI:440CFD* + ID_OUI_FROM_DATABASE=NetMan Co., Ltd. + ++OUI:4410FE* ++ ID_OUI_FROM_DATABASE=Huizhou Foryou General Electronics Co., Ltd. ++ + OUI:441102* + ID_OUI_FROM_DATABASE=EDMI Europe Ltd + +@@ -50750,15 +56171,39 @@ OUI:4411C2* + OUI:441319* + ID_OUI_FROM_DATABASE=WKK TECHNOLOGY LTD. + ++OUI:4413D0* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:441441* + ID_OUI_FROM_DATABASE=AudioControl Inc. + ++OUI:441622* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ ++OUI:441793* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:441847* ++ ID_OUI_FROM_DATABASE=HUNAN SCROWN ELECTRONIC INFORMATION TECH.CO.,LTD ++ + OUI:44184F* + ID_OUI_FROM_DATABASE=Fitview + ++OUI:4418FD* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:4419B6* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + ++OUI:441AFA* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:441C12* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:441C7F* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:441CA8* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -50771,15 +56216,30 @@ OUI:441E98* + OUI:441EA1* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:44227C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:442295* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ + OUI:4422F1* + ID_OUI_FROM_DATABASE=S.FAC, INC + ++OUI:44237C* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:4423AA* + ID_OUI_FROM_DATABASE=Farmage Co., Ltd. + + OUI:4425BB* + ID_OUI_FROM_DATABASE=Bamboo Entertainment Corporation + ++OUI:4427F3* ++ ID_OUI_FROM_DATABASE=70mai Co.,Ltd. ++ ++OUI:4428A3* ++ ID_OUI_FROM_DATABASE=Jiangsu fulian Communication Technology Co., Ltd. ++ + OUI:442938* + ID_OUI_FROM_DATABASE=NietZsche enterprise Co.Ltd. + +@@ -50814,7 +56274,10 @@ OUI:4434A7* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:44356F* +- ID_OUI_FROM_DATABASE=Neterix ++ ID_OUI_FROM_DATABASE=Neterix Ltd ++ ++OUI:443583* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:443708* + ID_OUI_FROM_DATABASE=MRV Comunications +@@ -50834,21 +56297,42 @@ OUI:443839* + OUI:4439C4* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:443B32* ++ ID_OUI_FROM_DATABASE=Intelbras ++ ++OUI:443C88* ++ ID_OUI_FROM_DATABASE=FICOSA MAROC INTERNATIONAL ++ + OUI:443C9C* + ID_OUI_FROM_DATABASE=Pintsch Tiefenbach GmbH + + OUI:443D21* + ID_OUI_FROM_DATABASE=Nuvolt + ++OUI:443E07* ++ ID_OUI_FROM_DATABASE=Electrolux ++ + OUI:443EB2* + ID_OUI_FROM_DATABASE=DEOTRON Co., LTD. + ++OUI:44422F* ++ ID_OUI_FROM_DATABASE=TESTOP CO.,LTD. ++ + OUI:444450* + ID_OUI_FROM_DATABASE=OttoQ + ++OUI:444687* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ ++OUI:4447CC* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:444891* + ID_OUI_FROM_DATABASE=HDMI Licensing, LLC + ++OUI:4448B9* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:4448C1* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -50858,9 +56342,15 @@ OUI:444A65* + OUI:444AB0* + ID_OUI_FROM_DATABASE=Zhejiang Moorgen Intelligence Technology Co., Ltd + ++OUI:444ADB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:444B5D* + ID_OUI_FROM_DATABASE=GE Healthcare + ++OUI:444B7E* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:444C0C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -50876,6 +56366,9 @@ OUI:444E6D* + OUI:444F5E* + ID_OUI_FROM_DATABASE=Pan Studios Co.,Ltd. + ++OUI:444F8E* ++ ID_OUI_FROM_DATABASE=WiZ ++ + OUI:4451DB* + ID_OUI_FROM_DATABASE=Raytheon BBN Technologies + +@@ -50885,18 +56378,39 @@ OUI:4454C0* + OUI:4455B1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:4455C4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:44568D* + ID_OUI_FROM_DATABASE=PNC Technologies Co., Ltd. + + OUI:4456B7* + ID_OUI_FROM_DATABASE=Spawn Labs, Inc + ++OUI:4456E2* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:445829* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:445943* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:44599F* + ID_OUI_FROM_DATABASE=Criticare Systems, Inc + ++OUI:4459E3* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:445BED* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:445CE9* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:445D5E* ++ ID_OUI_FROM_DATABASE=SHENZHEN Coolkit Technology CO.,LTD ++ + OUI:445ECD* + ID_OUI_FROM_DATABASE=Razer Inc + +@@ -50933,9 +56447,18 @@ OUI:44666E* + OUI:4466FC* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:446747* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:446752* ++ ID_OUI_FROM_DATABASE=Wistron INFOCOMM (Zhongshan) CORPORATION ++ + OUI:446755* + ID_OUI_FROM_DATABASE=Orbit Irrigation + ++OUI:44680C* ++ ID_OUI_FROM_DATABASE=Wacom Co.,Ltd. ++ + OUI:4468AB* + ID_OUI_FROM_DATABASE=JUIN COMPANY, LIMITED + +@@ -50957,6 +56480,54 @@ OUI:446D6C* + OUI:446EE5* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:446FD80* ++ ID_OUI_FROM_DATABASE=Sichuan subao network technology ltd.co. ++ ++OUI:446FD81* ++ ID_OUI_FROM_DATABASE=Shenzhen Furuilian Electronic Co.,Ltd. ++ ++OUI:446FD82* ++ ID_OUI_FROM_DATABASE=BAYKON Endüstriyel Kontrol Sistemleri San. ve Tic. A.Ş. ++ ++OUI:446FD83* ++ ID_OUI_FROM_DATABASE=Shenzhen Mestechs Technology CO., LTD ++ ++OUI:446FD84* ++ ID_OUI_FROM_DATABASE=lb Lautsprecher gmbH ++ ++OUI:446FD85* ++ ID_OUI_FROM_DATABASE=ZHEJIANG SHIP ELECTRONICS & TECHNOLOGY CO., LTD. ++ ++OUI:446FD86* ++ ID_OUI_FROM_DATABASE=Anhui GuDao Tech ++ ++OUI:446FD87* ++ ID_OUI_FROM_DATABASE=ITC ++ ++OUI:446FD88* ++ ID_OUI_FROM_DATABASE=Global Telecom Engineering, Inc ++ ++OUI:446FD89* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:446FD8A* ++ ID_OUI_FROM_DATABASE=ZHEJIANG HIKAILINK TECHNOLOGY Co., Ltd ++ ++OUI:446FD8B* ++ ID_OUI_FROM_DATABASE=Beijing gpthink technology co.,LTD. ++ ++OUI:446FD8C* ++ ID_OUI_FROM_DATABASE=Changzhou Haitu Electronic Technology Co.,Ltd ++ ++OUI:446FD8D* ++ ID_OUI_FROM_DATABASE=SCAIME ++ ++OUI:446FD8E* ++ ID_OUI_FROM_DATABASE=CTE ++ ++OUI:446FF8* ++ ID_OUI_FROM_DATABASE=Dyson Limited ++ + OUI:44700B* + ID_OUI_FROM_DATABASE=IFFU + +@@ -50967,7 +56538,10 @@ OUI:4473D6* + ID_OUI_FROM_DATABASE=Logitech + + OUI:44746C* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:447654* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:44783E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -51011,6 +56585,9 @@ OUI:4486C1* + OUI:448723* + ID_OUI_FROM_DATABASE=HOYA SERVICE CORPORATION + ++OUI:4487DB* ++ ID_OUI_FROM_DATABASE=Tymphany Acoustic Technology (Huizhou) Co., Ltd. ++ + OUI:4487FC* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd. + +@@ -51023,6 +56600,9 @@ OUI:448A5B* + OUI:448C52* + ID_OUI_FROM_DATABASE=KTIS CO., Ltd + ++OUI:448DBF* ++ ID_OUI_FROM_DATABASE=Rhino Mobility LLC ++ + OUI:448E12* + ID_OUI_FROM_DATABASE=DT Research, Inc. + +@@ -51032,15 +56612,24 @@ OUI:448E81* + OUI:448F17* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK + ++OUI:4490BB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:449160* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:44917C* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:4491DB* + ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd + + OUI:4494FC* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:44953B* ++ ID_OUI_FROM_DATABASE=RLTech India Private Limited ++ + OUI:4495FA* + ID_OUI_FROM_DATABASE=Qingdao Santong Digital Technology Co.Ltd + +@@ -51053,21 +56642,42 @@ OUI:44975A* + OUI:449B78* + ID_OUI_FROM_DATABASE=The Now Factory + ++OUI:449BC1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:449CB5* + ID_OUI_FROM_DATABASE=Alcomp, Inc + + OUI:449EF9* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:449F46* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:449F7F* + ID_OUI_FROM_DATABASE=DataCore Software Corporation + ++OUI:44A191* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:44A42D* + ID_OUI_FROM_DATABASE=TCT mobile ltd + + OUI:44A466* + ID_OUI_FROM_DATABASE=GROUPE LDLC + ++OUI:44A54E* ++ ID_OUI_FROM_DATABASE=Qorvo International Pte. Ltd. ++ ++OUI:44A56E* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ ++OUI:44A61E* ++ ID_OUI_FROM_DATABASE=INGRAM MICRO SERVICES ++ ++OUI:44A642* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:44A689* + ID_OUI_FROM_DATABASE=PROMAX ELECTRONICA SA + +@@ -51083,6 +56693,54 @@ OUI:44A842* + OUI:44A8C2* + ID_OUI_FROM_DATABASE=SEWOO TECH CO., LTD + ++OUI:44A8FC* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:44A92C0* ++ ID_OUI_FROM_DATABASE=ZHEJIANG HISING TECHNOLOGY CO.,LTD ++ ++OUI:44A92C1* ++ ID_OUI_FROM_DATABASE=uimcom ++ ++OUI:44A92C2* ++ ID_OUI_FROM_DATABASE=Anhui Zhongxin Electronic Technology Co., Ltd. ++ ++OUI:44A92C3* ++ ID_OUI_FROM_DATABASE=Luxonis Holding Corporation ++ ++OUI:44A92C4* ++ ID_OUI_FROM_DATABASE=NetX Networks a.s. ++ ++OUI:44A92C5* ++ ID_OUI_FROM_DATABASE=Shenzhen Lianfaxun Electronic Technology Co.,Ltd ++ ++OUI:44A92C6* ++ ID_OUI_FROM_DATABASE=Ningbo joyson new energy automotive technology Co.,Ltd ++ ++OUI:44A92C7* ++ ID_OUI_FROM_DATABASE=Efficient Building Automation Corp. ++ ++OUI:44A92C8* ++ ID_OUI_FROM_DATABASE=RT-Systemtechnik GmbH ++ ++OUI:44A92C9* ++ ID_OUI_FROM_DATABASE=China Electronics Corporation Greatwall Shengfeifan information system Co.,ltd. Hu'nan computer R.&D. Center ++ ++OUI:44A92CA* ++ ID_OUI_FROM_DATABASE=Digiport OU ++ ++OUI:44A92CB* ++ ID_OUI_FROM_DATABASE=Amethystum Storage Technology Co., Ltd ++ ++OUI:44A92CC* ++ ID_OUI_FROM_DATABASE=Cubitech ++ ++OUI:44A92CD* ++ ID_OUI_FROM_DATABASE=NPP KOMETEH JSC ++ ++OUI:44A92CE* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ + OUI:44AA27* + ID_OUI_FROM_DATABASE=udworks Co., Ltd. + +@@ -51098,9 +56756,27 @@ OUI:44AAF5* + OUI:44AD19* + ID_OUI_FROM_DATABASE=XINGFEI (H.K)LIMITED + ++OUI:44ADB1* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:44ADD9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:44AE25* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:44AE44* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:44AEAB* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:44AF28* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:44B295* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:44B32D* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -51110,8 +56786,26 @@ OUI:44B382* + OUI:44B412* + ID_OUI_FROM_DATABASE=SIUS AG + ++OUI:44B433* ++ ID_OUI_FROM_DATABASE=tide.co.,ltd ++ ++OUI:44B462* ++ ID_OUI_FROM_DATABASE=Flextronics Tech.(Ind) Pvt Ltd ++ ++OUI:44B6BE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:44B994* ++ ID_OUI_FROM_DATABASE=Douglas Lighting Controls ++ + OUI:44BA46* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:44BB3B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:44BDDE* ++ ID_OUI_FROM_DATABASE=BHTC GmbH + + OUI:44BFE3* + ID_OUI_FROM_DATABASE=Shenzhen Longtech Electronics Co.,Ltd +@@ -51137,18 +56831,30 @@ OUI:44C4A9* + OUI:44C56F* + ID_OUI_FROM_DATABASE=NGN Easy Satfinder (Tianjin) Electronic Co., Ltd + ++OUI:44C65D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:44C69B* + ID_OUI_FROM_DATABASE=Wuhan Feng Tian Information Network CO.,LTD + ++OUI:44C7FC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:44C874* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + + OUI:44C9A2* + ID_OUI_FROM_DATABASE=Greenwald Industries + ++OUI:44CB8B* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:44CD0E* + ID_OUI_FROM_DATABASE=FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. + ++OUI:44CE3A* ++ ID_OUI_FROM_DATABASE=Jiangsu Huacun Electronic Technology Co., Ltd. ++ + OUI:44CE7D* + ID_OUI_FROM_DATABASE=SFR + +@@ -51164,33 +56870,102 @@ OUI:44D244* + OUI:44D2CA* + ID_OUI_FROM_DATABASE=Anvia TV Oy + ++OUI:44D3AD* ++ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. ++ + OUI:44D3CA* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:44D437* + ID_OUI_FROM_DATABASE=Inteno Broadband Technology AB + ++OUI:44D453* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:44D454* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:44D4E0* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:44D5A5* + ID_OUI_FROM_DATABASE=AddOn Computer + ++OUI:44D5CC* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:44D5F20* ++ ID_OUI_FROM_DATABASE=TIBA Research & Development (1986) LTD ++ ++OUI:44D5F21* ++ ID_OUI_FROM_DATABASE=SIMPLERED TECHNOLOGY LTD. ++ ++OUI:44D5F22* ++ ID_OUI_FROM_DATABASE=Shenzhen Hebang Electronic Co., Ltd ++ ++OUI:44D5F23* ++ ID_OUI_FROM_DATABASE=VURO LLC ++ ++OUI:44D5F24* ++ ID_OUI_FROM_DATABASE=APPOTRONICS CO., LTD ++ ++OUI:44D5F25* ++ ID_OUI_FROM_DATABASE=tiga.eleven GmbH ++ ++OUI:44D5F26* ++ ID_OUI_FROM_DATABASE=Beam Communications Pty Ltd ++ ++OUI:44D5F27* ++ ID_OUI_FROM_DATABASE=Shenzhen Qiutian Technology Co.,Ltd ++ ++OUI:44D5F28* ++ ID_OUI_FROM_DATABASE=CETC Avionics.L td ++ ++OUI:44D5F29* ++ ID_OUI_FROM_DATABASE=Auctus Technologies Co.,Ltd. ++ ++OUI:44D5F2A* ++ ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH ++ ++OUI:44D5F2B* ++ ID_OUI_FROM_DATABASE=Valeo Interior Controls (Shenzhen) Co.,Ltd ++ ++OUI:44D5F2C* ++ ID_OUI_FROM_DATABASE=neocontrol soluções em automação ++ ++OUI:44D5F2D* ++ ID_OUI_FROM_DATABASE=Shenzhen Nation RFID Technology Co.,Ltd. ++ ++OUI:44D5F2E* ++ ID_OUI_FROM_DATABASE=Joint-Stock Company Research and Development Center ELVEES ++ + OUI:44D63D* + ID_OUI_FROM_DATABASE=Talari Networks + + OUI:44D6E1* + ID_OUI_FROM_DATABASE=Snuza International Pty. Ltd. + ++OUI:44D791* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:44D832* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:44D878* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:44D884* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:44D9E7* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + ++OUI:44DB60* ++ ID_OUI_FROM_DATABASE=Nanjing Baihezhengliu Technology Co., Ltd ++ ++OUI:44DC4E* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:44DC91* + ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. + +@@ -51212,9 +56987,21 @@ OUI:44E4D9* + OUI:44E4EE* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + ++OUI:44E517* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:44E66E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:44E6B0* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:44E8A5* + ID_OUI_FROM_DATABASE=Myreka Technologies Sdn. Bhd. + ++OUI:44E968* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:44E9DD* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -51224,6 +57011,12 @@ OUI:44EA4B* + OUI:44EAD8* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:44EB2E* ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO .,LTD ++ ++OUI:44ECCE* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:44ED57* + ID_OUI_FROM_DATABASE=Longicorn, inc. + +@@ -51233,12 +57026,21 @@ OUI:44EE02* + OUI:44EE30* + ID_OUI_FROM_DATABASE=Budelmann Elektronik GmbH + ++OUI:44EFBF* ++ ID_OUI_FROM_DATABASE=China Dragon Technology Limited ++ + OUI:44EFCF* + ID_OUI_FROM_DATABASE=UGENE SOLUTION inc. + + OUI:44F034* + ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. + ++OUI:44F09E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:44F21B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:44F436* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -51248,15 +57050,27 @@ OUI:44F459* + OUI:44F477* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:44F4E7* ++ ID_OUI_FROM_DATABASE=Cohesity Inc ++ + OUI:44F849* + ID_OUI_FROM_DATABASE=Union Pacific Railroad + ++OUI:44F971* ++ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. ++ + OUI:44FB42* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:44FB5A* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:44FDA3* + ID_OUI_FROM_DATABASE=Everysight LTD. + ++OUI:44FE3B* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:44FFBA* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -51266,12 +57080,27 @@ OUI:480031* + OUI:480033* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:48007D* ++ ID_OUI_FROM_DATABASE=DTS ELEKTRONIK SAN. TIC. LTD. STI. ++ ++OUI:4801C5* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ + OUI:48022A* + ID_OUI_FROM_DATABASE=B-Link Electronic Limited + + OUI:480362* + ID_OUI_FROM_DATABASE=DESAY ELECTRONICS(HUIZHOU)CO.,LTD + ++OUI:48049F* ++ ID_OUI_FROM_DATABASE=ELECOM CO., LTD ++ ++OUI:4805E2* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:48062B* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:48066A* + ID_OUI_FROM_DATABASE=Tempered Networks, Inc. + +@@ -51294,7 +57123,7 @@ OUI:480BB25* + ID_OUI_FROM_DATABASE=Solaredge LTD. + + OUI:480BB26* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:480BB27* + ID_OUI_FROM_DATABASE=Beijing Dragon Resources Limited. +@@ -51335,18 +57164,27 @@ OUI:481063* + OUI:481249* + ID_OUI_FROM_DATABASE=Luxcom Technologies Inc. + ++OUI:481258* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:48137E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:4813F3* + ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD. + ++OUI:481693* ++ ID_OUI_FROM_DATABASE=Lear Corporation GmbH ++ + OUI:48174C* + ID_OUI_FROM_DATABASE=MicroPower technologies + + OUI:481842* + ID_OUI_FROM_DATABASE=Shanghai Winaas Co. Equipment Co. Ltd. + ++OUI:48188D* ++ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD ++ + OUI:4818FA* + ID_OUI_FROM_DATABASE=Nocsys + +@@ -51359,21 +57197,54 @@ OUI:481BD2* + OUI:481D70* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:481F2D* ++ ID_OUI_FROM_DATABASE=Shenzhen Jie Shi Lian Industrial Co.,LTD ++ ++OUI:48210B* ++ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION ++ ++OUI:48216C* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ ++OUI:482218* ++ ID_OUI_FROM_DATABASE=Shenzhen Yipingfang Network Technology Co., Ltd. ++ ++OUI:482335* ++ ID_OUI_FROM_DATABASE=Dialog Semiconductor Hellas SA ++ ++OUI:482567* ++ ID_OUI_FROM_DATABASE=Poly ++ ++OUI:48262C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:4826E8* + ID_OUI_FROM_DATABASE=Tek-Air Systems, Inc. + ++OUI:482759* ++ ID_OUI_FROM_DATABASE=Levven Electronics Ltd. ++ + OUI:4827EA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:48282F* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:482952* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:4829E4* ++ ID_OUI_FROM_DATABASE=ZAO NPK Rotek ++ + OUI:482AE3* + ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. + + OUI:482CA0* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:482CD0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:482CEA* + ID_OUI_FROM_DATABASE=Motorola Inc Business Light Radios + +@@ -51383,9 +57254,15 @@ OUI:4833DD* + OUI:48343D* + ID_OUI_FROM_DATABASE=IEP GmbH + ++OUI:48352E* ++ ID_OUI_FROM_DATABASE=Shenzhen Wolck Network Product Co.,LTD ++ + OUI:48365F* + ID_OUI_FROM_DATABASE=Wintecronics Ltd. + ++OUI:483871* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:483974* + ID_OUI_FROM_DATABASE=Proware Technologies Co., Ltd. + +@@ -51398,12 +57275,21 @@ OUI:483C0C* + OUI:483D32* + ID_OUI_FROM_DATABASE=Syscor Controls & Automation + ++OUI:483FDA* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:483FE9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:48435A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:48437C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:4843DD* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:484487* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +@@ -51413,30 +57299,60 @@ OUI:4844F7* + OUI:484520* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4846C1* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:4846F1* + ID_OUI_FROM_DATABASE=Uros Oy + + OUI:4846FB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:48474B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:4849C7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:484A30* ++ ID_OUI_FROM_DATABASE=George Robotics Limited ++ + OUI:484AE9* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:484BAA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:484BD4* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:484C29* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:484C86* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:484D7E* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:484EFC* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:485073* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:485169* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:4851B7* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4851C5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:4851CF* ++ ID_OUI_FROM_DATABASE=Intelbras ++ + OUI:485261* + ID_OUI_FROM_DATABASE=SOREEL + +@@ -51464,6 +57380,9 @@ OUI:4859A4* + OUI:485A3F* + ID_OUI_FROM_DATABASE=WISOL + ++OUI:485A67* ++ ID_OUI_FROM_DATABASE=Shaanxi Ruixun Electronic Information Technology Co., Ltd ++ + OUI:485AB6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -51476,6 +57395,9 @@ OUI:485D36* + OUI:485D60* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:485DEB* ++ ID_OUI_FROM_DATABASE=Just Add Power ++ + OUI:485F99* + ID_OUI_FROM_DATABASE=Cloud Network Technology (Samoa) Limited + +@@ -51539,6 +57461,9 @@ OUI:4865EEE* + OUI:486834* + ID_OUI_FROM_DATABASE=Silicon Motion, Inc. + ++OUI:48684A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:486B2C* + ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD. + +@@ -51548,6 +57473,9 @@ OUI:486B91* + OUI:486DBB* + ID_OUI_FROM_DATABASE=Vestel Elektronik San ve Tic. A.Ş. + ++OUI:486E70* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:486E73* + ID_OUI_FROM_DATABASE=Pica8, Inc. + +@@ -51557,9 +57485,15 @@ OUI:486EFB* + OUI:486FD2* + ID_OUI_FROM_DATABASE=StorSimple Inc + ++OUI:48701E* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:487119* + ID_OUI_FROM_DATABASE=SGB GROUP LTD. + ++OUI:487397* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:48746E* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -51569,42 +57503,87 @@ OUI:487583* + OUI:487604* + ID_OUI_FROM_DATABASE=Private + ++OUI:487746* ++ ID_OUI_FROM_DATABASE=Calix Inc. ++ ++OUI:4877BD* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:48785E* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:48794D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:487A55* + ID_OUI_FROM_DATABASE=ALE International + + OUI:487ADA* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:487AF6* ++ ID_OUI_FROM_DATABASE=NCS ELECTRICAL SDN BHD ++ ++OUI:487AFF* ++ ID_OUI_FROM_DATABASE=ESSYS ++ ++OUI:487B5E* ++ ID_OUI_FROM_DATABASE=SMT TELECOMM HK ++ + OUI:487B6B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:487D2E* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:487E48* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:488244* + ID_OUI_FROM_DATABASE=Life Fitness / Div. of Brunswick + + OUI:4882F2* + ID_OUI_FROM_DATABASE=Appel Elektronik GmbH + ++OUI:4883B4* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:4883C7* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + + OUI:4886E8* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:48872D* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN DA XIA LONG QUE TECHNOLOGY CO.,LTD ++ ++OUI:488764* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:488803* + ID_OUI_FROM_DATABASE=ManTechnology Inc. + + OUI:48881E* + ID_OUI_FROM_DATABASE=EthoSwitch LLC + ++OUI:488899* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:4888CA* + ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. + ++OUI:4889E7* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:488AD2* + ID_OUI_FROM_DATABASE=MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + ++OUI:488B0A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:488C63* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:488D36* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + +@@ -51614,18 +57593,30 @@ OUI:488E42* + OUI:488EEF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:488F5A* ++ ID_OUI_FROM_DATABASE=Routerboard.com ++ ++OUI:48902F* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:489153* + ID_OUI_FROM_DATABASE=Weinmann Geräte für Medizin GmbH + Co. KG + + OUI:4891F6* + ID_OUI_FROM_DATABASE=Shenzhen Reach software technology CO.,LTD + ++OUI:489507* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:4898CA* + ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. + + OUI:489A42* + ID_OUI_FROM_DATABASE=Technomate Ltd + ++OUI:489BD5* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:489BE2* + ID_OUI_FROM_DATABASE=SCI Innovations Ltd + +@@ -51635,6 +57626,12 @@ OUI:489D18* + OUI:489D24* + ID_OUI_FROM_DATABASE=BlackBerry RTS + ++OUI:489DD1* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:489EBD* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:48A0F8* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -51647,15 +57644,36 @@ OUI:48A22D* + OUI:48A2B7* + ID_OUI_FROM_DATABASE=Kodofon JSC + ++OUI:48A2B8* ++ ID_OUI_FROM_DATABASE=Chengdu Vision-Zenith Tech.Co,.Ltd ++ ++OUI:48A2E6* ++ ID_OUI_FROM_DATABASE=Resideo ++ + OUI:48A380* + ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co.,Ltd. + + OUI:48A472* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:48A493* ++ ID_OUI_FROM_DATABASE=TAIYO YUDEN CO.,LTD ++ ++OUI:48A516* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:48A5E7* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:48A6B8* ++ ID_OUI_FROM_DATABASE=Sonos, Inc. ++ + OUI:48A6D2* + ID_OUI_FROM_DATABASE=GJsun Optical Science and Tech Co.,Ltd. + ++OUI:48A73C* ++ ID_OUI_FROM_DATABASE=Sichuan tianyi kanghe communications co., LTD ++ + OUI:48A74E* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -51671,15 +57689,24 @@ OUI:48AA5D* + OUI:48AD08* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:48B02D* ++ ID_OUI_FROM_DATABASE=NVIDIA Corporation ++ + OUI:48B253* + ID_OUI_FROM_DATABASE=Marketaxess Corporation + ++OUI:48B25D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:48B5A7* + ID_OUI_FROM_DATABASE=Glory Horse Industries Ltd. + + OUI:48B620* + ID_OUI_FROM_DATABASE=ROLI Ltd. + ++OUI:48B8A3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:48B8DE* + ID_OUI_FROM_DATABASE=HOMEWINS TECHNOLOGY CO.,LTD. + +@@ -51695,6 +57722,9 @@ OUI:48BA4E* + OUI:48BCA6* + ID_OUI_FROM_DATABASE=​ASUNG TECHNO CO.,Ltd + ++OUI:48BD0E* ++ ID_OUI_FROM_DATABASE=Quanta Storage Inc. ++ + OUI:48BD3D* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + +@@ -51716,6 +57746,9 @@ OUI:48C093* + OUI:48C1AC* + ID_OUI_FROM_DATABASE=PLANTRONICS, INC. + ++OUI:48C3B0* ++ ID_OUI_FROM_DATABASE=Pharos Co.Ltd ++ + OUI:48C58D* + ID_OUI_FROM_DATABASE=Lear Corporation GmbH + +@@ -51743,6 +57776,9 @@ OUI:48D18E* + OUI:48D224* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:48D24F* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:48D343* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -51764,9 +57800,18 @@ OUI:48D705* + OUI:48D7FF* + ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH + ++OUI:48D845* ++ ID_OUI_FROM_DATABASE=Shenzhen Mainuoke Electronics Co., Ltd ++ + OUI:48D855* + ID_OUI_FROM_DATABASE=Telvent + ++OUI:48D875* ++ ID_OUI_FROM_DATABASE=China TransInfo Technology Co., Ltd ++ ++OUI:48D890* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:48D8FE* + ID_OUI_FROM_DATABASE=ClarIDy Solutions, Inc. + +@@ -51776,9 +57821,15 @@ OUI:48DA96* + OUI:48DB50* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:48DC2D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:48DCFB* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:48DD0C* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:48DD9D* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + +@@ -51791,9 +57842,24 @@ OUI:48DF37* + OUI:48E1AF* + ID_OUI_FROM_DATABASE=Vity + ++OUI:48E1E9* ++ ID_OUI_FROM_DATABASE=Chengdu Meross Technology Co., Ltd. ++ + OUI:48E244* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:48E3C3* ++ ID_OUI_FROM_DATABASE=JENOPTIK Advanced Systems GmbH ++ ++OUI:48E695* ++ ID_OUI_FROM_DATABASE=Insigma Inc ++ ++OUI:48E6C0* ++ ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd. ++ ++OUI:48E7DA* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:48E9F1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -51803,8 +57869,11 @@ OUI:48EA63* + OUI:48EB30* + ID_OUI_FROM_DATABASE=ETERNA TECHNOLOGY, INC. + ++OUI:48EB62* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:48EC5B* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:48ED80* + ID_OUI_FROM_DATABASE=daesung eltec +@@ -51818,11 +57887,17 @@ OUI:48EE0C* + OUI:48EE86* + ID_OUI_FROM_DATABASE=UTStarcom (China) Co.,Ltd + ++OUI:48EF61* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:48F027* + ID_OUI_FROM_DATABASE=Chengdu newifi Co.,Ltd + + OUI:48F07B* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ ++OUI:48F17F* ++ ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:48F230* + ID_OUI_FROM_DATABASE=Ubizcore Co.,LTD +@@ -51830,6 +57905,9 @@ OUI:48F230* + OUI:48F317* + ID_OUI_FROM_DATABASE=Private + ++OUI:48F3F3* ++ ID_OUI_FROM_DATABASE=Baidu Online Network Technology (Beijing) Co., Ltd ++ + OUI:48F47D* + ID_OUI_FROM_DATABASE=TechVision Holding Internation Limited + +@@ -51842,9 +57920,15 @@ OUI:48F7F1* + OUI:48F8B3* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + ++OUI:48F8DB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:48F8E1* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:48F8FF* ++ ID_OUI_FROM_DATABASE=CHENGDU KT ELECTRONIC HI-TECH CO.,LTD ++ + OUI:48F925* + ID_OUI_FROM_DATABASE=Maestronic + +@@ -51860,6 +57944,9 @@ OUI:48FCB8* + OUI:48FD8E* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:48FDA3* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:48FEEA* + ID_OUI_FROM_DATABASE=HOMA B.V. + +@@ -51869,6 +57956,9 @@ OUI:4C0082* + OUI:4C0143* + ID_OUI_FROM_DATABASE=eero inc. + ++OUI:4C0220* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:4C022E* + ID_OUI_FROM_DATABASE=CMR KOREA CO., LTD + +@@ -51887,6 +57977,9 @@ OUI:4C09B4* + OUI:4C09D4* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + ++OUI:4C0A3D* ++ ID_OUI_FROM_DATABASE=ADNACOM INC. ++ + OUI:4C0B3A* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -51902,9 +57995,15 @@ OUI:4C0F6E* + OUI:4C0FC7* + ID_OUI_FROM_DATABASE=Earda Technologies co Ltd + ++OUI:4C1154* ++ ID_OUI_FROM_DATABASE=Mobiwire Mobiles (NingBo) Co., LTD ++ + OUI:4C1159* + ID_OUI_FROM_DATABASE=Vision Information & Communications + ++OUI:4C11AE* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:4C11BF* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + +@@ -51929,6 +58028,9 @@ OUI:4C16F1* + OUI:4C16FC* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:4C1744* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:4C17EB* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -51947,15 +58049,33 @@ OUI:4C1A95* + OUI:4C1B86* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + ++OUI:4C1D96* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:4C1FCC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:4C20B8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:4C2113* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ ++OUI:4C218C* ++ ID_OUI_FROM_DATABASE=Panasonic India Private limited ++ + OUI:4C21D0* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:4C2219* ++ ID_OUI_FROM_DATABASE=YUANFUDAO HK LIMTED + + OUI:4C2258* + ID_OUI_FROM_DATABASE=cozybit, Inc. + ++OUI:4C2498* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:4C2578* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -51968,9 +58088,15 @@ OUI:4C2C80* + OUI:4C2C83* + ID_OUI_FROM_DATABASE=Zhejiang KaNong Network Technology Co.,Ltd. + ++OUI:4C2EFE* ++ ID_OUI_FROM_DATABASE=Shenzhen Comnect Technology Co.,LTD ++ + OUI:4C2F9D* + ID_OUI_FROM_DATABASE=ICM Controls + ++OUI:4C2FD7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:4C3089* + ID_OUI_FROM_DATABASE=Thales Transportation Systems GmbH + +@@ -51983,6 +58109,9 @@ OUI:4C3275* + OUI:4C32D9* + ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd. + ++OUI:4C3329* ++ ID_OUI_FROM_DATABASE=Sweroam ++ + OUI:4C334E* + ID_OUI_FROM_DATABASE=HIGHTECH + +@@ -52004,33 +58133,108 @@ OUI:4C3909* + OUI:4C3910* + ID_OUI_FROM_DATABASE=Newtek Electronics co., Ltd. + ++OUI:4C3B6C* ++ ID_OUI_FROM_DATABASE=GARO AB ++ + OUI:4C3B74* + ID_OUI_FROM_DATABASE=VOGTEC(H.K.) Co., Ltd + ++OUI:4C3BDF* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:4C3C16* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:4C3FD3* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:4C4088* ++ ID_OUI_FROM_DATABASE=SANSHIN ELECTRONICS CO.,LTD. ++ ++OUI:4C4576* ++ ID_OUI_FROM_DATABASE=China Mobile(Hangzhou) Information Technology Co.,Ltd. ++ + OUI:4C48DA* + ID_OUI_FROM_DATABASE=Beijing Autelan Technology Co.,Ltd + ++OUI:4C494F* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:4C49E3* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:4C4B68* + ID_OUI_FROM_DATABASE=Mobile Device, Inc. + ++OUI:4C4BF90* ++ ID_OUI_FROM_DATABASE=Multitek Elektronik Sanayi ve Ticaret A.S. ++ ++OUI:4C4BF91* ++ ID_OUI_FROM_DATABASE=Jiangsu acrel Co., Ltd. ++ ++OUI:4C4BF92* ++ ID_OUI_FROM_DATABASE=Shenzhen HommPro Technology Co.,Ltd ++ ++OUI:4C4BF93* ++ ID_OUI_FROM_DATABASE=Power Active Co., Ltd ++ ++OUI:4C4BF94* ++ ID_OUI_FROM_DATABASE=Shenzhen dingsheng technology co., LTD ++ ++OUI:4C4BF95* ++ ID_OUI_FROM_DATABASE=Remedee Labs ++ ++OUI:4C4BF96* ++ ID_OUI_FROM_DATABASE=Shandong Linkotech Electronic Co., Ltd. ++ ++OUI:4C4BF97* ++ ID_OUI_FROM_DATABASE=GLONEXS ++ ++OUI:4C4BF98* ++ ID_OUI_FROM_DATABASE=Zivid AS ++ ++OUI:4C4BF99* ++ ID_OUI_FROM_DATABASE=Tecnoplus Srl ++ ++OUI:4C4BF9A* ++ ID_OUI_FROM_DATABASE=Electrolux Professional AB ++ ++OUI:4C4BF9B* ++ ID_OUI_FROM_DATABASE=Stored Energy Systems ++ ++OUI:4C4BF9C* ++ ID_OUI_FROM_DATABASE=Connected IO ++ ++OUI:4C4BF9D* ++ ID_OUI_FROM_DATABASE=Shenzhen Haichuan Intelligent Information Technology Co., Ltd. ++ ++OUI:4C4BF9E* ++ ID_OUI_FROM_DATABASE=Beijing AutoAi Technology co. LTD ++ ++OUI:4C4D66* ++ ID_OUI_FROM_DATABASE=Nanjing Jiahao Technology Co., Ltd. ++ + OUI:4C4E03* + ID_OUI_FROM_DATABASE=TCT mobile ltd + + OUI:4C4E35* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:4C4FEE* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ ++OUI:4C5077* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:4C50F1* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:4C5262* + ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions GmbH + ++OUI:4C52EC* ++ ID_OUI_FROM_DATABASE=SOLARWATT GmbH ++ + OUI:4C5427* + ID_OUI_FROM_DATABASE=Linepro Sp. z o.o. + +@@ -52046,9 +58250,18 @@ OUI:4C55B8* + OUI:4C55CC* + ID_OUI_FROM_DATABASE=Zentri Pty Ltd + ++OUI:4C569D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:4C56DF* ++ ID_OUI_FROM_DATABASE=Targus US LLC ++ + OUI:4C57CA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:4C5D3C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:4C5DCD* + ID_OUI_FROM_DATABASE=Oy Finnish Electric Vehicle Technologies Ltd + +@@ -52064,9 +58277,15 @@ OUI:4C60D5* + OUI:4C60DE* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:4C617E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:4C6255* + ID_OUI_FROM_DATABASE=SANMINA-SCI SYSTEM DE MEXICO S.A. DE C.V. + ++OUI:4C6371* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:4C63EB* + ID_OUI_FROM_DATABASE=Application Solutions (Electronics and Vision) Ltd + +@@ -52121,9 +58340,33 @@ OUI:4C65A8E* + OUI:4C6641* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:4C6AF6* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:4C6BE8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:4C6C13* ++ ID_OUI_FROM_DATABASE=IoT Company Solucoes Tecnologicas Ltda ++ ++OUI:4C6D58* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:4C6E6E* + ID_OUI_FROM_DATABASE=Comnect Technology CO.,LTD + ++OUI:4C6F9C* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:4C710C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:4C710D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:4C7167* ++ ID_OUI_FROM_DATABASE=PoLabs d.o.o. ++ + OUI:4C72B9* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +@@ -52142,27 +58385,45 @@ OUI:4C7487* + OUI:4C74BF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:4C7525* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:4C7625* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:4C774F* + ID_OUI_FROM_DATABASE=Embedded Wireless Labs + ++OUI:4C7766* ++ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. ++ + OUI:4C776D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:4C77CB* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:4C7872* + ID_OUI_FROM_DATABASE=Cav. Uff. Giacomo Cimberio S.p.A. + + OUI:4C7897* + ID_OUI_FROM_DATABASE=Arrowhead Alarm Products Ltd + ++OUI:4C796E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:4C79BA* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4C7A48* ++ ID_OUI_FROM_DATABASE=Nippon Seiki (Europe) B.V. ++ + OUI:4C7C5F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:4C7CD9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:4C7F62* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -52172,6 +58433,9 @@ OUI:4C804F* + OUI:4C8093* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4C80BA* ++ ID_OUI_FROM_DATABASE=Wuhan Tianyu Information Industry Co., Ltd. ++ + OUI:4C8120* + ID_OUI_FROM_DATABASE=Taicang T&W Electronics + +@@ -52181,6 +58445,9 @@ OUI:4C82CF* + OUI:4C83DE* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:4C875D* ++ ID_OUI_FROM_DATABASE=Bose Corporation ++ + OUI:4C8B30* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +@@ -52199,12 +58466,111 @@ OUI:4C8ECC* + OUI:4C8FA5* + ID_OUI_FROM_DATABASE=Jastec + ++OUI:4C90DB* ++ ID_OUI_FROM_DATABASE=JL Audio ++ + OUI:4C910C* + ID_OUI_FROM_DATABASE=Lanix Internacional, S.A. de C.V. + ++OUI:4C9157* ++ ID_OUI_FROM_DATABASE=Fujian LANDI Commercial Equipment Co.,Ltd ++ ++OUI:4C917A0* ++ ID_OUI_FROM_DATABASE=Shenzhen Dangs Science & Technology CO.,LTD ++ ++OUI:4C917A1* ++ ID_OUI_FROM_DATABASE=Inster Tecnología y Comunicaciones SAU ++ ++OUI:4C917A2* ++ ID_OUI_FROM_DATABASE=Chongqing Unisinsight Technology Co.,Ltd. ++ ++OUI:4C917A3* ++ ID_OUI_FROM_DATABASE=Smart Access ++ ++OUI:4C917A4* ++ ID_OUI_FROM_DATABASE=LumiGrow Inc. ++ ++OUI:4C917A5* ++ ID_OUI_FROM_DATABASE=mtekvision ++ ++OUI:4C917A6* ++ ID_OUI_FROM_DATABASE=Openeye ++ ++OUI:4C917A7* ++ ID_OUI_FROM_DATABASE=S.I.C.E.S. srl ++ ++OUI:4C917A8* ++ ID_OUI_FROM_DATABASE=Camsat Przemysław Gralak ++ ++OUI:4C917A9* ++ ID_OUI_FROM_DATABASE=Hangzhou Hangtu Technology Co.,Ltd. ++ ++OUI:4C917AA* ++ ID_OUI_FROM_DATABASE=Erlab DFS SAS ++ ++OUI:4C917AB* ++ ID_OUI_FROM_DATABASE=AvertX ++ ++OUI:4C917AC* ++ ID_OUI_FROM_DATABASE=Alibaba (Beijing) Software Service Inc. ++ ++OUI:4C917AD* ++ ID_OUI_FROM_DATABASE=Shenzhen bankledger Technology Co, Ltd ++ ++OUI:4C917AE* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:4C93A60* ++ ID_OUI_FROM_DATABASE=Vestaboard, Inc. ++ ++OUI:4C93A61* ++ ID_OUI_FROM_DATABASE=Atrie Technology Fzc ++ ++OUI:4C93A62* ++ ID_OUI_FROM_DATABASE=Diehl Controls Nanjing Co., Ltd. ++ ++OUI:4C93A63* ++ ID_OUI_FROM_DATABASE=Commsignia, Ltd. ++ ++OUI:4C93A64* ++ ID_OUI_FROM_DATABASE=4TheWall - 4D Sistem A.S ++ ++OUI:4C93A65* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:4C93A66* ++ ID_OUI_FROM_DATABASE=Shandong Senter Electronic Co., Ltd ++ ++OUI:4C93A67* ++ ID_OUI_FROM_DATABASE=5Voxel Co., Ltd. ++ ++OUI:4C93A68* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:4C93A69* ++ ID_OUI_FROM_DATABASE=Advantics ++ ++OUI:4C93A6A* ++ ID_OUI_FROM_DATABASE=Hanwang Technology Co.,Ltd ++ ++OUI:4C93A6B* ++ ID_OUI_FROM_DATABASE=Felten Electronics ++ ++OUI:4C93A6C* ++ ID_OUI_FROM_DATABASE=Wuhan Maiwe communication Co.,Ltd ++ ++OUI:4C93A6D* ++ ID_OUI_FROM_DATABASE=Cantronic Systems (Canada) Inc ++ ++OUI:4C93A6E* ++ ID_OUI_FROM_DATABASE=CELLTRON ++ + OUI:4C9614* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:4C962D* ++ ID_OUI_FROM_DATABASE=Fresh AB ++ + OUI:4C98EF* + ID_OUI_FROM_DATABASE=Zeo + +@@ -52218,7 +58584,7 @@ OUI:4C9EFF* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + + OUI:4CA003* +- ID_OUI_FROM_DATABASE=T-21 Technologies LLC ++ ID_OUI_FROM_DATABASE=VITEC + + OUI:4CA161* + ID_OUI_FROM_DATABASE=Rain Bird Corporation +@@ -52229,6 +58595,9 @@ OUI:4CA515* + OUI:4CA56D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:4CA64D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:4CA74B* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +@@ -52241,18 +58610,33 @@ OUI:4CAA16* + OUI:4CAB33* + ID_OUI_FROM_DATABASE=KST technology + ++OUI:4CAB4F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:4CABFC* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:4CAC0A* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:4CADA8* ++ ID_OUI_FROM_DATABASE=PANOPTICS CORP. ++ ++OUI:4CAE13* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:4CAE1C* + ID_OUI_FROM_DATABASE=SaiNXT Technologies LLP + + OUI:4CAE31* + ID_OUI_FROM_DATABASE=ShengHai Electronics (Shenzhen) Ltd + ++OUI:4CAEA3* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ ++OUI:4CAEEC* ++ ID_OUI_FROM_DATABASE=Guangzhou limee technology co.,LTD ++ + OUI:4CB008* + ID_OUI_FROM_DATABASE=Shenzhen Gwelltimes Technology Co.,Ltd + +@@ -52265,6 +58649,9 @@ OUI:4CB16C* + OUI:4CB199* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:4CB1CD* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:4CB21C* + ID_OUI_FROM_DATABASE=Maxphotonics Co.,Ltd + +@@ -52286,6 +58673,15 @@ OUI:4CB82C* + OUI:4CB8B5* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + ++OUI:4CB910* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:4CB911* ++ ID_OUI_FROM_DATABASE=Raisecom Technology CO.,LTD ++ ++OUI:4CB99B* ++ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD ++ + OUI:4CB9C8* + ID_OUI_FROM_DATABASE=CONET CO., LTD. + +@@ -52298,9 +58694,66 @@ OUI:4CBB58* + OUI:4CBC42* + ID_OUI_FROM_DATABASE=Shenzhen Hangsheng Electronics Co.,Ltd. + ++OUI:4CBC48* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:4CBC72* ++ ID_OUI_FROM_DATABASE=Primex Wireless ++ ++OUI:4CBC980* ++ ID_OUI_FROM_DATABASE=Charge-Amps AB ++ ++OUI:4CBC981* ++ ID_OUI_FROM_DATABASE=JSC NIC ++ ++OUI:4CBC982* ++ ID_OUI_FROM_DATABASE=Quake Global Inc ++ ++OUI:4CBC983* ++ ID_OUI_FROM_DATABASE=Machine Max ++ ++OUI:4CBC984* ++ ID_OUI_FROM_DATABASE=Nemon Co., Ltd. ++ ++OUI:4CBC985* ++ ID_OUI_FROM_DATABASE=Gronic Systems GmbH ++ ++OUI:4CBC986* ++ ID_OUI_FROM_DATABASE=Humanplus Intelligent Robotics Technology Co.,Ltd. ++ ++OUI:4CBC987* ++ ID_OUI_FROM_DATABASE=Voegtlin Instruments GmbH ++ ++OUI:4CBC988* ++ ID_OUI_FROM_DATABASE=Shenzhen Shanling Digital Technology Development Co.,Ltd. ++ ++OUI:4CBC989* ++ ID_OUI_FROM_DATABASE=Airtex Manufacturing Partnership ++ ++OUI:4CBC98A* ++ ID_OUI_FROM_DATABASE=Shenzhen Cogitation Technology Co.,Ltd. ++ ++OUI:4CBC98B* ++ ID_OUI_FROM_DATABASE=Dongguan SmartAction Technology Co.,Ltd ++ ++OUI:4CBC98C* ++ ID_OUI_FROM_DATABASE=Heliotis AG ++ ++OUI:4CBC98D* ++ ID_OUI_FROM_DATABASE=Elink Technology (Shenzhen) Co., Limited ++ ++OUI:4CBC98E* ++ ID_OUI_FROM_DATABASE=Wonder Workshop ++ + OUI:4CBCA5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:4CBCB4* ++ ID_OUI_FROM_DATABASE=ABB SpA - DIN Rail ++ ++OUI:4CBCE9* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:4CBD8F* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + +@@ -52313,15 +58766,27 @@ OUI:4CC206* + OUI:4CC452* + ID_OUI_FROM_DATABASE=Shang Hai Tyd. Electon Technology Ltd. + ++OUI:4CC53E* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:4CC602* + ID_OUI_FROM_DATABASE=Radios, Inc. + + OUI:4CC681* + ID_OUI_FROM_DATABASE=Shenzhen Aisat Electronic Co., Ltd. + ++OUI:4CC7D6* ++ ID_OUI_FROM_DATABASE=FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. ++ ++OUI:4CC8A1* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:4CC94F* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:4CC95E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:4CCA53* + ID_OUI_FROM_DATABASE=Skyera, Inc. + +@@ -52334,6 +58799,9 @@ OUI:4CCC34* + OUI:4CCC6A* + ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. + ++OUI:4CCE2D* ++ ID_OUI_FROM_DATABASE=Danlaw Inc ++ + OUI:4CD08A* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + +@@ -52343,18 +58811,36 @@ OUI:4CD0CB* + OUI:4CD1A1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:4CD3AF* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:4CD577* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:4CD629* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:4CD637* + ID_OUI_FROM_DATABASE=Qsono Electronics Co., Ltd + + OUI:4CD7B6* + ID_OUI_FROM_DATABASE=Helmer Scientific + ++OUI:4CD98F* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:4CD9C4* + ID_OUI_FROM_DATABASE=Magneti Marelli Automotive Electronics (Guangzhou) Co. Ltd + ++OUI:4CDC0D* ++ ID_OUI_FROM_DATABASE=Coral Telecom Limited ++ + OUI:4CDD31* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:4CDD7D* ++ ID_OUI_FROM_DATABASE=LHP Telematics LLC ++ + OUI:4CDF3D* + ID_OUI_FROM_DATABASE=TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD + +@@ -52403,11 +58889,23 @@ OUI:4CE173D* + OUI:4CE173E* + ID_OUI_FROM_DATABASE=Plus One Japan Limited + ++OUI:4CE175* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:4CE176* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:4CE19E* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:4CE1BB* + ID_OUI_FROM_DATABASE=Zhuhai HiFocus Technology Co., Ltd. + + OUI:4CE2F1* +- ID_OUI_FROM_DATABASE=sclak srl ++ ID_OUI_FROM_DATABASE=Udino srl ++ ++OUI:4CE5AE* ++ ID_OUI_FROM_DATABASE=Tianjin Beebox Intelligent Technology Co.,Ltd. + + OUI:4CE676* + ID_OUI_FROM_DATABASE=BUFFALO.INC +@@ -52415,9 +58913,18 @@ OUI:4CE676* + OUI:4CE933* + ID_OUI_FROM_DATABASE=RailComm, LLC + ++OUI:4CE9E4* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:4CEB42* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:4CEBBD* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:4CEBD6* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:4CECEF* + ID_OUI_FROM_DATABASE=Soraa, Inc. + +@@ -52430,21 +58937,36 @@ OUI:4CEDFB* + OUI:4CEEB0* + ID_OUI_FROM_DATABASE=SHC Netzwerktechnik GmbH + ++OUI:4CEF56* ++ ID_OUI_FROM_DATABASE=Shenzhen Sundray Technologies Company Limited ++ + OUI:4CEFC0* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + + OUI:4CF02E* + ID_OUI_FROM_DATABASE=Vifa Denmark A/S + ++OUI:4CF19E* ++ ID_OUI_FROM_DATABASE=Groupe Atlantic ++ ++OUI:4CF202* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:4CF2BF* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + + OUI:4CF45B* + ID_OUI_FROM_DATABASE=Blue Clover Devices + ++OUI:4CF55B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:4CF5A0* + ID_OUI_FROM_DATABASE=Scalable Network Technologies Inc + ++OUI:4CF5DC* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:4CF737* + ID_OUI_FROM_DATABASE=SamJi Electronics Co., Ltd + +@@ -52457,9 +58979,21 @@ OUI:4CFACA* + OUI:4CFB45* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:4CFBF4* ++ ID_OUI_FROM_DATABASE=Optimal Audio Ltd ++ ++OUI:4CFBFE* ++ ID_OUI_FROM_DATABASE=Sercomm Japan Corporation ++ ++OUI:4CFCAA* ++ ID_OUI_FROM_DATABASE=Tesla,Inc. ++ + OUI:4CFF12* + ID_OUI_FROM_DATABASE=Fuze Entertainment Co., ltd + ++OUI:500084* ++ ID_OUI_FROM_DATABASE=Siemens Canada ++ + OUI:50008C* + ID_OUI_FROM_DATABASE=Hong Kong Telecommunications (HKT) Limited + +@@ -52472,6 +59006,9 @@ OUI:5001BB* + OUI:5001D9* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:500291* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:5004B8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -52487,6 +59024,12 @@ OUI:5006AB* + OUI:500959* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:5009E5* ++ ID_OUI_FROM_DATABASE=Drimsys,Inc ++ ++OUI:500A52* ++ ID_OUI_FROM_DATABASE=Huiwan Technologies Co. Ltd ++ + OUI:500B32* + ID_OUI_FROM_DATABASE=Foxda Technology Industrial(ShenZhen)Co.,LTD + +@@ -52497,7 +59040,7 @@ OUI:500B911* + ID_OUI_FROM_DATABASE=SPD Development Company Ltd + + OUI:500B912* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:500B913* + ID_OUI_FROM_DATABASE=EWIN TECHNOLOGY LIMITED +@@ -52538,6 +59081,9 @@ OUI:500B91E* + OUI:500E6D* + ID_OUI_FROM_DATABASE=TrafficCast International + ++OUI:500F59* ++ ID_OUI_FROM_DATABASE=STMicrolectronics International NV ++ + OUI:500F80* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -52547,6 +59093,12 @@ OUI:500FF5* + OUI:5011EB* + ID_OUI_FROM_DATABASE=SilverNet Ltd + ++OUI:501395* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ ++OUI:501408* ++ ID_OUI_FROM_DATABASE=AiNET ++ + OUI:501479* + ID_OUI_FROM_DATABASE=iRobot Corporation + +@@ -52565,6 +59117,9 @@ OUI:501AA5* + OUI:501AC5* + ID_OUI_FROM_DATABASE=Microsoft + ++OUI:501B32* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:501CB0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -52577,9 +59132,15 @@ OUI:501D93* + OUI:501E2D* + ID_OUI_FROM_DATABASE=StreamUnlimited Engineering GmbH + ++OUI:501FC6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:50206B* + ID_OUI_FROM_DATABASE=Emerson Climate Technologies Transportation Solutions + ++OUI:5021EC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:502267* + ID_OUI_FROM_DATABASE=PixeLINK + +@@ -52592,9 +59153,18 @@ OUI:502690* + OUI:5027C7* + ID_OUI_FROM_DATABASE=TECHNART Co.,Ltd + ++OUI:502873* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:50294D* + ID_OUI_FROM_DATABASE=NANJING IOT SENSOR TECHNOLOGY CO,LTD + ++OUI:50297B* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:5029F5* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:502A7E* + ID_OUI_FROM_DATABASE=Smart electronic GmbH + +@@ -52604,21 +59174,36 @@ OUI:502A8B* + OUI:502B73* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + ++OUI:502B98* ++ ID_OUI_FROM_DATABASE=Es-tech International ++ ++OUI:502CC6* ++ ID_OUI_FROM_DATABASE=GREE ELECTRIC APPLIANCES, INC. OF ZHUHAI ++ + OUI:502D1D* + ID_OUI_FROM_DATABASE=Nokia Corporation + + OUI:502DA2* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:502DBB* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ + OUI:502DF4* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + ++OUI:502DFB* ++ ID_OUI_FROM_DATABASE=IGShare Co., Ltd. ++ + OUI:502E5C* + ID_OUI_FROM_DATABASE=HTC Corporation + + OUI:502ECE* + ID_OUI_FROM_DATABASE=Asahi Electronics Co.,Ltd + ++OUI:502F9B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:502FA8* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -52628,6 +59213,9 @@ OUI:5031AD* + OUI:503237* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:50325F* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:503275* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -52637,6 +59225,9 @@ OUI:50338B* + OUI:5033F0* + ID_OUI_FROM_DATABASE=YICHEN (SHENZHEN) TECHNOLOGY CO.LTD + ++OUI:50382F* ++ ID_OUI_FROM_DATABASE=ASE Group Chung-Li ++ + OUI:503955* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +@@ -52655,9 +59246,18 @@ OUI:503CEA* + OUI:503DA1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:503DC6* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:503DE5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:503DEB* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ ++OUI:503E7C* ++ ID_OUI_FROM_DATABASE=LeiShen Intelligent System Co.Ltd ++ + OUI:503EAA* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -52670,15 +59270,33 @@ OUI:503F98* + OUI:504061* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:50411C* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ ++OUI:5041B9* ++ ID_OUI_FROM_DATABASE=I-O DATA DEVICE,INC. ++ ++OUI:504348* ++ ID_OUI_FROM_DATABASE=ThingsMatrix Inc. ++ ++OUI:5043B9* ++ ID_OUI_FROM_DATABASE=OktoInform RUS ++ + OUI:5045F7* + ID_OUI_FROM_DATABASE=Liuhe Intelligence Technology Ltd. + ++OUI:50464A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:50465D* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:5048EB* + ID_OUI_FROM_DATABASE=BEIJING HAIHEJINSHENG NETWORK TECHNOLOGY CO. LTD. + ++OUI:5049B0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:504A5E* + ID_OUI_FROM_DATABASE=Masimo Corporation + +@@ -52688,6 +59306,9 @@ OUI:504A6E* + OUI:504B5B* + ID_OUI_FROM_DATABASE=CONTROLtronic GmbH + ++OUI:504B9E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:504C7E* + ID_OUI_FROM_DATABASE=THE 41ST INSTITUTE OF CETC + +@@ -52703,15 +59324,27 @@ OUI:50502A* + OUI:505065* + ID_OUI_FROM_DATABASE=TAKT Corporation + ++OUI:5050A4* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:5050CE* + ID_OUI_FROM_DATABASE=Hangzhou Dianyixia Communication Technology Co. Ltd. + ++OUI:5051A9* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:50523B* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:5052D2* + ID_OUI_FROM_DATABASE=Hangzhou Telin Technologies Co., Limited + + OUI:505527* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:50558D* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:505663* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -52733,6 +59366,9 @@ OUI:505800* + OUI:50584F* + ID_OUI_FROM_DATABASE=waytotec,Inc. + ++OUI:50586F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:505967* + ID_OUI_FROM_DATABASE=Intent Solutions Inc + +@@ -52742,9 +59378,15 @@ OUI:505AC6* + OUI:505BC2* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:505D7A* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:505DAC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:505FB5* ++ ID_OUI_FROM_DATABASE=Askey Computer Corp. ++ + OUI:506028* + ID_OUI_FROM_DATABASE=Xirrus Inc. + +@@ -52757,6 +59399,54 @@ OUI:5061BF* + OUI:5061D6* + ID_OUI_FROM_DATABASE=Indu-Sol GmbH + ++OUI:5061F6* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ ++OUI:5062550* ++ ID_OUI_FROM_DATABASE=Ufanet SC ++ ++OUI:5062551* ++ ID_OUI_FROM_DATABASE=Hagiwara Solutions Co., Ltd ++ ++OUI:5062552* ++ ID_OUI_FROM_DATABASE=ShenZhen ChuangMo Electronics Technology Co., Ltd ++ ++OUI:5062553* ++ ID_OUI_FROM_DATABASE=Hypertech Advance Co., LTD ++ ++OUI:5062554* ++ ID_OUI_FROM_DATABASE=XSLAB Inc. ++ ++OUI:5062555* ++ ID_OUI_FROM_DATABASE=Suzhou Ruixinjie Information Technology Co.,Ltd ++ ++OUI:5062556* ++ ID_OUI_FROM_DATABASE=Shenzhen Sinway South Technology Co., Ltd ++ ++OUI:5062557* ++ ID_OUI_FROM_DATABASE=AVTECH Software, Inc. ++ ++OUI:5062558* ++ ID_OUI_FROM_DATABASE=Roda industrial development Co.,Ltd. ++ ++OUI:5062559* ++ ID_OUI_FROM_DATABASE=Southern Ground Audio LLC ++ ++OUI:506255A* ++ ID_OUI_FROM_DATABASE=CCTV Manufacturer ++ ++OUI:506255B* ++ ID_OUI_FROM_DATABASE=CHENGDU COVE TECHNOLOGY CO.,LTD ++ ++OUI:506255C* ++ ID_OUI_FROM_DATABASE=AED Distribution ++ ++OUI:506255D* ++ ID_OUI_FROM_DATABASE=COTT Electronics ++ ++OUI:506255E* ++ ID_OUI_FROM_DATABASE=SHINSOFT CO., LTD. ++ + OUI:506313* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -52799,6 +59489,9 @@ OUI:506CBE* + OUI:506E92* + ID_OUI_FROM_DATABASE=Innocent Technology Co., Ltd. + ++OUI:506F0C* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:506F77* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -52808,6 +59501,12 @@ OUI:506F98* + OUI:506F9A* + ID_OUI_FROM_DATABASE=Wi-Fi Alliance + ++OUI:507043* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:507097* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:5070E5* + ID_OUI_FROM_DATABASE=He Shan World Fair Electronics Technology Limited + +@@ -52817,21 +59516,36 @@ OUI:507224* + OUI:50724D* + ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH + ++OUI:5075F1* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:507691* + ID_OUI_FROM_DATABASE=Tekpea, Inc. + + OUI:5076A6* + ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda + ++OUI:5076AF* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:507705* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:5078B0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:5078B3* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:50795B* + ID_OUI_FROM_DATABASE=Interexport Telecomunicaciones S.A. + + OUI:507A55* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:507AC5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:507B9D* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd + +@@ -52841,6 +59555,12 @@ OUI:507D02* + OUI:507E5D* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + ++OUI:50804A* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ ++OUI:508140* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:5082D5* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -52856,6 +59576,9 @@ OUI:5087B8* + OUI:508965* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + ++OUI:508A06* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:508A0F* + ID_OUI_FROM_DATABASE=SHENZHEN FISE TECHNOLOGY HOLDING CO.,LTD. + +@@ -52871,9 +59594,15 @@ OUI:508C77* + OUI:508CB1* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:508CF5* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:508D6F* + ID_OUI_FROM_DATABASE=CHAHOO Limited + ++OUI:508E49* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:508F4C* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -52886,18 +59615,36 @@ OUI:50934F* + OUI:509551* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:509707* ++ ID_OUI_FROM_DATABASE=Xiamen Paperang Technology Co.,Ltd. ++ ++OUI:509744* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:509772* + ID_OUI_FROM_DATABASE=Westinghouse Digital + ++OUI:509839* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:509871* + ID_OUI_FROM_DATABASE=Inventum Technologies Private Limited + ++OUI:5098B8* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:5098F3* + ID_OUI_FROM_DATABASE=Rheem Australia Pty Ltd + ++OUI:509A46* ++ ID_OUI_FROM_DATABASE=Safetrust Inc ++ + OUI:509A4C* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:509A88* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:509EA7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -52913,9 +59660,15 @@ OUI:50A009* + OUI:50A054* + ID_OUI_FROM_DATABASE=Actineon + ++OUI:50A0A4* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:50A0BF* + ID_OUI_FROM_DATABASE=Alba Fiber Systems Inc. + ++OUI:50A132* ++ ID_OUI_FROM_DATABASE=Shenzhen MiaoMing Intelligent Technology Co.,Ltd ++ + OUI:50A4C8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -52964,6 +59717,9 @@ OUI:50A4D0D* + OUI:50A4D0E* + ID_OUI_FROM_DATABASE=Sagetech Corporation + ++OUI:50A5DC* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:50A67F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -52991,9 +59747,21 @@ OUI:50AB3E* + OUI:50ABBF* + ID_OUI_FROM_DATABASE=Hoseo Telecom + ++OUI:50AD71* ++ ID_OUI_FROM_DATABASE=Tessolve Semiconductor Private Limited ++ ++OUI:50AD92* ++ ID_OUI_FROM_DATABASE=NX Technologies ++ + OUI:50ADD5* + ID_OUI_FROM_DATABASE=Dynalec Corporation + ++OUI:50AE86* ++ ID_OUI_FROM_DATABASE=Linkintec Co., Ltd ++ ++OUI:50AF4D* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:50AF73* + ID_OUI_FROM_DATABASE=Shenzhen Bitland Information Technology Co., Ltd. + +@@ -53024,9 +59792,30 @@ OUI:50C006* + OUI:50C271* + ID_OUI_FROM_DATABASE=SECURETECH INC + ++OUI:50C2E8* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ ++OUI:50C2ED* ++ ID_OUI_FROM_DATABASE=GN Audio A/S ++ ++OUI:50C3A2* ++ ID_OUI_FROM_DATABASE=nFore Technology Co.,Ltd. ++ ++OUI:50C4DD* ++ ID_OUI_FROM_DATABASE=BUFFALO.INC ++ + OUI:50C58D* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:50C68E* ++ ID_OUI_FROM_DATABASE=Biwin Semiconductor (HK) Company Limted ++ ++OUI:50C6AD* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:50C709* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:50C7BF* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -53051,15 +59840,27 @@ OUI:50CD32* + OUI:50CE75* + ID_OUI_FROM_DATABASE=Measy Electronics Co., Ltd. + ++OUI:50CEE3* ++ ID_OUI_FROM_DATABASE=Gigafirm.co.LTD ++ ++OUI:50D065* ++ ID_OUI_FROM_DATABASE=ESYLUX GmbH ++ + OUI:50D213* + ID_OUI_FROM_DATABASE=CviLux Corporation + + OUI:50D274* + ID_OUI_FROM_DATABASE=Steffes Corporation + ++OUI:50D2F5* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:50D37F* + ID_OUI_FROM_DATABASE=Yu Fly Mikly Way Science and Technology Co., Ltd. + ++OUI:50D4F7* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:50D59C* + ID_OUI_FROM_DATABASE=Thai Habel Industrial Co., Ltd. + +@@ -53072,6 +59873,9 @@ OUI:50D753* + OUI:50DA00* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:50DB3F* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:50DCE7* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -53081,9 +59885,63 @@ OUI:50DCFC* + OUI:50DD4F* + ID_OUI_FROM_DATABASE=Automation Components, Inc + ++OUI:50DE06* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:50DE190* ++ ID_OUI_FROM_DATABASE=Telic AG ++ ++OUI:50DE191* ++ ID_OUI_FROM_DATABASE=Clear Flow by Antiference ++ ++OUI:50DE192* ++ ID_OUI_FROM_DATABASE=SPII SPA ++ ++OUI:50DE193* ++ ID_OUI_FROM_DATABASE=TRAXENS ++ ++OUI:50DE194* ++ ID_OUI_FROM_DATABASE=Langogo Technology Co., Ltd. ++ ++OUI:50DE195* ++ ID_OUI_FROM_DATABASE=Bliq B.V. ++ ++OUI:50DE196* ++ ID_OUI_FROM_DATABASE=OCEANCCTV LTD ++ ++OUI:50DE197* ++ ID_OUI_FROM_DATABASE=Tianjin Natianal Health Technology Co.,Ltd ++ ++OUI:50DE198* ++ ID_OUI_FROM_DATABASE=IVATIV, INC ++ ++OUI:50DE199* ++ ID_OUI_FROM_DATABASE=AEG Identifikationssysteme GmbH ++ ++OUI:50DE19A* ++ ID_OUI_FROM_DATABASE=Tannak International AB ++ ++OUI:50DE19B* ++ ID_OUI_FROM_DATABASE=BRAINWARE TERAHERTA INFORMATION TECHNOLOGY CO.,LTD. ++ ++OUI:50DE19C* ++ ID_OUI_FROM_DATABASE=Shenzhen Vipstech Co., Ltd ++ ++OUI:50DE19D* ++ ID_OUI_FROM_DATABASE=Penny & Giles Aerospace Ltd ++ ++OUI:50DE19E* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:50DF95* + ID_OUI_FROM_DATABASE=Lytx + ++OUI:50E039* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ ++OUI:50E085* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:50E0C7* + ID_OUI_FROM_DATABASE=TurControlSystme AG + +@@ -53093,12 +59951,18 @@ OUI:50E0EF* + OUI:50E14A* + ID_OUI_FROM_DATABASE=Private + ++OUI:50E24E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:50E549* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + + OUI:50E666* + ID_OUI_FROM_DATABASE=Shenzhen Techtion Electronics Co., Ltd. + ++OUI:50E7A0* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:50E971* + ID_OUI_FROM_DATABASE=Jibo, Inc. + +@@ -53106,7 +59970,16 @@ OUI:50EAD6* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:50EB1A* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC ++ ++OUI:50EB71* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:50EC50* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:50ED3C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:50ED78* + ID_OUI_FROM_DATABASE=Changzhou Yongse Infotech Co.,Ltd +@@ -53126,6 +59999,9 @@ OUI:50F14A* + OUI:50F43C* + ID_OUI_FROM_DATABASE=Leeo Inc + ++OUI:50F4EB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:50F520* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -53138,12 +60014,27 @@ OUI:50F61A* + OUI:50F722* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:50F7ED* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:50F8A5* ++ ID_OUI_FROM_DATABASE=eWBM Co., Ltd. ++ ++OUI:50F908* ++ ID_OUI_FROM_DATABASE=Wizardlab Co., Ltd. ++ ++OUI:50F958* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:50FA84* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:50FAAB* + ID_OUI_FROM_DATABASE=L-tek d.o.o. + ++OUI:50FB19* ++ ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. ++ + OUI:50FC30* + ID_OUI_FROM_DATABASE=Treehouse Labs + +@@ -53205,7 +60096,7 @@ OUI:540237* + ID_OUI_FROM_DATABASE=Teltronic AG + + OUI:540384* +- ID_OUI_FROM_DATABASE=Hangkong Nano IC Technologies Co., Ltd ++ ID_OUI_FROM_DATABASE=Hongkong Nano IC Technologies Co., Ltd + + OUI:5403F5* + ID_OUI_FROM_DATABASE=EBN Technology Corp. +@@ -53225,12 +60116,33 @@ OUI:54055F* + OUI:540593* + ID_OUI_FROM_DATABASE=WOORI ELEC Co.,Ltd + ++OUI:5405DB* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:54068B* ++ ID_OUI_FROM_DATABASE=Ningbo Deli Kebei Technology Co.LTD ++ ++OUI:540764* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:540910* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:540955* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:54098D* + ID_OUI_FROM_DATABASE=deister electronic GmbH + ++OUI:540DF9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:540E2D* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:540E58* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:541031* + ID_OUI_FROM_DATABASE=SMARTO + +@@ -53243,15 +60155,24 @@ OUI:54112F* + OUI:54115F* + ID_OUI_FROM_DATABASE=Atamo Pty Ltd + ++OUI:541310* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:541379* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:541473* + ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited + ++OUI:5414F3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:5414FD* + ID_OUI_FROM_DATABASE=Orbbec 3D Technology International + ++OUI:541589* ++ ID_OUI_FROM_DATABASE=MCS Logic Inc. ++ + OUI:5419C8* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +@@ -53270,8 +60191,14 @@ OUI:541FD5* + OUI:542018* + ID_OUI_FROM_DATABASE=Tely Labs + ++OUI:54211D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:542160* +- ID_OUI_FROM_DATABASE=Resolution Products ++ ID_OUI_FROM_DATABASE=Alula ++ ++OUI:54219D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:5422F8* + ID_OUI_FROM_DATABASE=zte corporation +@@ -53294,6 +60221,9 @@ OUI:54276C* + OUI:54278D* + ID_OUI_FROM_DATABASE=NXP (China) Management Ltd. + ++OUI:542A1B* ++ ID_OUI_FROM_DATABASE=Sonos, Inc. ++ + OUI:542A9C* + ID_OUI_FROM_DATABASE=LSY Defense, LLC. + +@@ -53303,6 +60233,12 @@ OUI:542AA2* + OUI:542B57* + ID_OUI_FROM_DATABASE=Night Owl SP + ++OUI:542B8D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:542BDE* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:542CEA* + ID_OUI_FROM_DATABASE=PROTECTRON + +@@ -53318,6 +60254,9 @@ OUI:543131* + OUI:5433CB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:5434EF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:543530* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -53327,12 +60266,18 @@ OUI:5435DF* + OUI:54369B* + ID_OUI_FROM_DATABASE=1Verge Internet Technology (Beijing) Co., Ltd. + ++OUI:5437BB* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:543968* + ID_OUI_FROM_DATABASE=Edgewater Networks Inc + + OUI:5439DF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:543AD6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:543B30* + ID_OUI_FROM_DATABASE=duagon AG + +@@ -53351,15 +60296,33 @@ OUI:544249* + OUI:544408* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:5444A3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:544617* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:54466B* + ID_OUI_FROM_DATABASE=Shenzhen CZTIC Electronic Technology Co., Ltd + ++OUI:544741* ++ ID_OUI_FROM_DATABASE=XCHENG HOLDING ++ ++OUI:5447D3* ++ ID_OUI_FROM_DATABASE=TSAT AS ++ + OUI:544810* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:54489C* + ID_OUI_FROM_DATABASE=CDOUBLES ELECTRONICS CO. LTD. + ++OUI:5448E6* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:5449DF* ++ ID_OUI_FROM_DATABASE=Peloton Interactive, Inc ++ + OUI:544A00* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -53393,6 +60356,9 @@ OUI:545414* + OUI:5454CF* + ID_OUI_FROM_DATABASE=PROBEDIGITAL CO.,LTD + ++OUI:5455D5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:545AA6* + ID_OUI_FROM_DATABASE=Espressif Inc. + +@@ -53411,20 +60377,32 @@ OUI:546172* + OUI:5461EA* + ID_OUI_FROM_DATABASE=Zaplox AB + ++OUI:5462E2* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:5464D9* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:546503* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ + OUI:5465DE* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:54666C* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + ++OUI:5466F9* ++ ID_OUI_FROM_DATABASE=ConMet ++ + OUI:546751* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + ++OUI:5467E6* ++ ID_OUI_FROM_DATABASE=SHENZHEN MTC CO LTD ++ + OUI:546AD8* +- ID_OUI_FROM_DATABASE=Elster Water Metering Limited ++ ID_OUI_FROM_DATABASE=Elster Water Metering + + OUI:546C0E* + ID_OUI_FROM_DATABASE=Texas Instruments +@@ -53432,9 +60410,18 @@ OUI:546C0E* + OUI:546D52* + ID_OUI_FROM_DATABASE=TOPVIEW OPTRONICS CORP. + ++OUI:546F71* ++ ID_OUI_FROM_DATABASE=uAvionix Corporation ++ ++OUI:5471DD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:54724F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:54725E* ++ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD ++ + OUI:547398* + ID_OUI_FROM_DATABASE=Toyo Electronics Corporation + +@@ -53447,6 +60434,12 @@ OUI:547595* + OUI:5475D0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:547787* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ ++OUI:54778A* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:54781A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -53468,30 +60461,57 @@ OUI:547F54* + OUI:547FA8* + ID_OUI_FROM_DATABASE=TELCO systems, s.r.o. + ++OUI:547FBC* ++ ID_OUI_FROM_DATABASE=iodyne ++ + OUI:547FEE* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:548028* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:54812D* + ID_OUI_FROM_DATABASE=PAX Computer Technology(Shenzhen) Ltd. + + OUI:5481AD* + ID_OUI_FROM_DATABASE=Eagle Research Corporation + ++OUI:54833A* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:54847B* + ID_OUI_FROM_DATABASE=Digital Devices GmbH + ++OUI:5484DC* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:5486BC* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:54880E* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:5488DE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:548922* + ID_OUI_FROM_DATABASE=Zelfy Inc + + OUI:548998* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:548ABA* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:548CA0* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:548D5A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:549209* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:5492BE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -53561,6 +60581,12 @@ OUI:549A4C* + OUI:549B12* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:549B72* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ ++OUI:549C27* ++ ID_OUI_FROM_DATABASE=Plasma Cloud Limited ++ + OUI:549D85* + ID_OUI_FROM_DATABASE=EnerAccess inc + +@@ -53570,6 +60596,12 @@ OUI:549F13* + OUI:549F35* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:549FAE* ++ ID_OUI_FROM_DATABASE=iBASE Gaming Inc ++ ++OUI:549FC6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:54A04F* + ID_OUI_FROM_DATABASE=t-mac Technologies Ltd + +@@ -53585,6 +60617,51 @@ OUI:54A31B* + OUI:54A3FA* + ID_OUI_FROM_DATABASE=BQT Solutions (Australia)Pty Ltd + ++OUI:54A4930* ++ ID_OUI_FROM_DATABASE=Intelligent Surveillance Corp ++ ++OUI:54A4931* ++ ID_OUI_FROM_DATABASE=ShenZhen Smart&Aspiration Co.,LTD ++ ++OUI:54A4932* ++ ID_OUI_FROM_DATABASE=genua GmbH ++ ++OUI:54A4933* ++ ID_OUI_FROM_DATABASE=I-MOON TECHNOLOGY CO., LIMITED ++ ++OUI:54A4934* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ ++OUI:54A4935* ++ ID_OUI_FROM_DATABASE=AUSOUNDS INTELLIGENCE, LLC ++ ++OUI:54A4936* ++ ID_OUI_FROM_DATABASE=Hannto Technology Co., Ltd ++ ++OUI:54A4937* ++ ID_OUI_FROM_DATABASE=RED Hydrogen LLC ++ ++OUI:54A4938* ++ ID_OUI_FROM_DATABASE=Chengdu EVECCA Technology Co.,Ltd. ++ ++OUI:54A4939* ++ ID_OUI_FROM_DATABASE=Do Easy International Limited ++ ++OUI:54A493A* ++ ID_OUI_FROM_DATABASE=Wonders Technology Co., Ltd. ++ ++OUI:54A493B* ++ ID_OUI_FROM_DATABASE=Advice ++ ++OUI:54A493C* ++ ID_OUI_FROM_DATABASE=BJ COTYTECH TECHNOLOGY CO.,LTD ++ ++OUI:54A493D* ++ ID_OUI_FROM_DATABASE=ASSEM TECHNOLOGY CO.,LTD. ++ ++OUI:54A493E* ++ ID_OUI_FROM_DATABASE=Nederman Holding AB ++ + OUI:54A51B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -53597,15 +60674,27 @@ OUI:54A619* + OUI:54A65C* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:54A6DB* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:54A703* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:54A9D4* + ID_OUI_FROM_DATABASE=Minibar Systems + + OUI:54AB3A* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:54AE27* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:54AED0* ++ ID_OUI_FROM_DATABASE=DASAN Networks, Inc. ++ ++OUI:54AED2* ++ ID_OUI_FROM_DATABASE=CSL Dualcom Ltd ++ + OUI:54B121* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -53630,6 +60719,9 @@ OUI:54B802* + OUI:54B80A* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:54BAD6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:54BD79* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -53642,6 +60734,9 @@ OUI:54BEF7* + OUI:54BF64* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:54C250* ++ ID_OUI_FROM_DATABASE=Iskratel d.o.o. ++ + OUI:54C33E* + ID_OUI_FROM_DATABASE=Ciena Corporation + +@@ -53666,6 +60761,12 @@ OUI:54CDA7* + OUI:54CDEE* + ID_OUI_FROM_DATABASE=ShenZhen Apexis Electronic Co.,Ltd + ++OUI:54CE69* ++ ID_OUI_FROM_DATABASE=Hikari Trading Co.,Ltd. ++ ++OUI:54CE82* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:54D0B4* + ID_OUI_FROM_DATABASE=Xiamen Four-Faith Communication Technology Co.,Ltd + +@@ -53675,6 +60776,9 @@ OUI:54D0ED* + OUI:54D163* + ID_OUI_FROM_DATABASE=MAX-TECH,INC + ++OUI:54D17D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:54D1B0* + ID_OUI_FROM_DATABASE=Universal Laser Systems, Inc + +@@ -53687,12 +60791,21 @@ OUI:54D46F* + OUI:54D751* + ID_OUI_FROM_DATABASE=Proximus + ++OUI:54D9C6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:54D9E4* + ID_OUI_FROM_DATABASE=BRILLIANTTS CO., LTD + ++OUI:54DBA2* ++ ID_OUI_FROM_DATABASE=Fibrain ++ + OUI:54DC1D* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd + ++OUI:54DED0* ++ ID_OUI_FROM_DATABASE=Sevio Srl ++ + OUI:54DF00* + ID_OUI_FROM_DATABASE=Ulterius Technologies, LLC + +@@ -53702,11 +60815,14 @@ OUI:54DF24* + OUI:54DF63* + ID_OUI_FROM_DATABASE=Intrakey technologies GmbH + ++OUI:54E019* ++ ID_OUI_FROM_DATABASE=Ring LLC ++ + OUI:54E032* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:54E061* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:54E140* + ID_OUI_FROM_DATABASE=INGENICO +@@ -53729,42 +60845,72 @@ OUI:54E3F6* + OUI:54E43A* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:54E4A9* ++ ID_OUI_FROM_DATABASE=BHR Tech GmbH ++ + OUI:54E4BD* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + ++OUI:54E61B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:54E63F* + ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd. + + OUI:54E6FC* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:54E7D5* ++ ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD ++ + OUI:54EAA8* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:54EC2F* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:54EDA3* + ID_OUI_FROM_DATABASE=Navdy, Inc. + + OUI:54EE75* + ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. + ++OUI:54EF33* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ ++OUI:54EF44* ++ ID_OUI_FROM_DATABASE=Lumi United Technology Co., Ltd ++ + OUI:54EF92* + ID_OUI_FROM_DATABASE=Shenzhen Elink Technology Co., LTD + + OUI:54EFFE* + ID_OUI_FROM_DATABASE=Fullpower Technologies, Inc. + ++OUI:54F15F* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:54F201* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:54F294* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:54F5B6* + ID_OUI_FROM_DATABASE=ORIENTAL PACIFIC INTERNATIONAL LIMITED + ++OUI:54F607* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:54F666* + ID_OUI_FROM_DATABASE=Berthold Technologies GmbH and Co.KG + + OUI:54F6C5* + ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD + ++OUI:54F6E2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:54F876* + ID_OUI_FROM_DATABASE=ABB AG + +@@ -53772,7 +60918,7 @@ OUI:54FA3E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:54FA96* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:54FB58* + ID_OUI_FROM_DATABASE=WISEWARE, Lda +@@ -53822,17 +60968,29 @@ OUI:5809E5* + OUI:580A20* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:580AD4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:58108C* + ID_OUI_FROM_DATABASE=Intelbras + ++OUI:5810B7* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ + OUI:581243* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + ++OUI:5813D3* ++ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. ++ + OUI:581626* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:5816D7* ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ + OUI:58170C* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:5819F8* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. +@@ -53855,6 +61013,48 @@ OUI:581FAA* + OUI:581FEF* + ID_OUI_FROM_DATABASE=Tuttnaer LTD + ++OUI:582059* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:58208A0* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:58208A2* ++ ID_OUI_FROM_DATABASE=MARS DIGI TECH CO .,LTD ++ ++OUI:58208A3* ++ ID_OUI_FROM_DATABASE=Aggregate Co.,Ltd. ++ ++OUI:58208A4* ++ ID_OUI_FROM_DATABASE=TRING ++ ++OUI:58208A5* ++ ID_OUI_FROM_DATABASE=JIA HUANG JHAN YE CO.,LTD ++ ++OUI:58208A6* ++ ID_OUI_FROM_DATABASE=Shangyin Intelligence Technology Shandong Co.,Ltd ++ ++OUI:58208A7* ++ ID_OUI_FROM_DATABASE=pureLiFi Ltd ++ ++OUI:58208A8* ++ ID_OUI_FROM_DATABASE=SAMIL CTS Co., Ltd. ++ ++OUI:58208A9* ++ ID_OUI_FROM_DATABASE=Suzhou Ruilisi Technology Ltd. ++ ++OUI:58208AA* ++ ID_OUI_FROM_DATABASE=Conductix-Wampfler ++ ++OUI:58208AB* ++ ID_OUI_FROM_DATABASE=Infodev Electronic Designers Intl. ++ ++OUI:58208AD* ++ ID_OUI_FROM_DATABASE=SAMBO HITECH ++ ++OUI:58208AE* ++ ID_OUI_FROM_DATABASE=UPM Technology, Inc ++ + OUI:5820B1* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -53867,6 +61067,15 @@ OUI:5821E9* + OUI:58238C* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:582429* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:582575* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:58278C* ++ ID_OUI_FROM_DATABASE=BUFFALO.INC ++ + OUI:582AF7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -53885,6 +61094,9 @@ OUI:582F40* + OUI:582F42* + ID_OUI_FROM_DATABASE=Universal Electric Corporation + ++OUI:582FF7* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:583112* + ID_OUI_FROM_DATABASE=DRUST + +@@ -53894,6 +61106,15 @@ OUI:583277* + OUI:58343B* + ID_OUI_FROM_DATABASE=Glovast Technology Ltd. + ++OUI:583526* ++ ID_OUI_FROM_DATABASE=DEEPLET TECHNOLOGY CORP ++ ++OUI:58355D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:58356B* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:5835D9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -53912,12 +61133,18 @@ OUI:583F54* + OUI:58404E* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:584120* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:5842E4* + ID_OUI_FROM_DATABASE=Baxter International Inc + + OUI:584498* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:58454C* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ + OUI:58468F* + ID_OUI_FROM_DATABASE=Koncar Electronics and Informatics + +@@ -53928,7 +61155,52 @@ OUI:584704* + ID_OUI_FROM_DATABASE=Shenzhen Webridge Technology Co.,Ltd + + OUI:584822* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:5848490* ++ ID_OUI_FROM_DATABASE=Beijing Zhongyuanyishang Technology Co Ltd ++ ++OUI:5848491* ++ ID_OUI_FROM_DATABASE=SKAARHOJ ApS ++ ++OUI:5848492* ++ ID_OUI_FROM_DATABASE=X-speed lnformation Technology Co.,Ltd ++ ++OUI:5848493* ++ ID_OUI_FROM_DATABASE=Viper Design LLC ++ ++OUI:5848494* ++ ID_OUI_FROM_DATABASE=SERNET (SUZHOU) TECHNOLOGIES CORPORATION ++ ++OUI:5848495* ++ ID_OUI_FROM_DATABASE=Hubei Shudi Communication Technology Co., Ltd ++ ++OUI:5848496* ++ ID_OUI_FROM_DATABASE=Shenzhen hongqifu Technology Co., Ltd ++ ++OUI:5848497* ++ ID_OUI_FROM_DATABASE=Shandong Aotai Electric Co., LTD. ++ ++OUI:5848498* ++ ID_OUI_FROM_DATABASE=STACKFORCE GmbH ++ ++OUI:5848499* ++ ID_OUI_FROM_DATABASE=Shenzhen Tongye Technology Co.,Ltd ++ ++OUI:584849A* ++ ID_OUI_FROM_DATABASE=Waoo ++ ++OUI:584849B* ++ ID_OUI_FROM_DATABASE=Daatrics LTD ++ ++OUI:584849C* ++ ID_OUI_FROM_DATABASE=Haag-Streit AG ++ ++OUI:584849D* ++ ID_OUI_FROM_DATABASE=Telegaertner Elektronik GmbH ++ ++OUI:584849E* ++ ID_OUI_FROM_DATABASE=Avadesign Technology Co. Ltd. + + OUI:5848C0* + ID_OUI_FROM_DATABASE=COFLEC +@@ -53948,6 +61220,9 @@ OUI:584C19* + OUI:584CEE* + ID_OUI_FROM_DATABASE=Digital One Technologies, Limited + ++OUI:584D42* ++ ID_OUI_FROM_DATABASE=Dragos, Inc. ++ + OUI:585076* + ID_OUI_FROM_DATABASE=Linear Equipamentos Eletronicos SA + +@@ -53957,6 +61232,9 @@ OUI:5850AB* + OUI:5850E6* + ID_OUI_FROM_DATABASE=Best Buy Corporation + ++OUI:5850ED* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:58528A* + ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation + +@@ -53966,18 +61244,27 @@ OUI:5853C0* + OUI:5855CA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:5856C2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:5856E8* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:58570D* + ID_OUI_FROM_DATABASE=Danfoss Solar Inverters + ++OUI:5859C2* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:585FF6* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:58605F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:5860D8* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:586163* + ID_OUI_FROM_DATABASE=Quantum Networks (SG) Pte. Ltd. + +@@ -53988,7 +61275,7 @@ OUI:58639A* + ID_OUI_FROM_DATABASE=TPL SYSTEMES + + OUI:5865E6* +- ID_OUI_FROM_DATABASE=INFOMARK CO., LTD. ++ ID_OUI_FROM_DATABASE=infomark + + OUI:5866BA* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited +@@ -54011,6 +61298,12 @@ OUI:5869F9* + OUI:586AB1* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:586B14* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:586C25* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:586D8F* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +@@ -54068,6 +61361,15 @@ OUI:5884E4* + OUI:58856E* + ID_OUI_FROM_DATABASE=QSC AG + ++OUI:5885A2* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ ++OUI:5885E9* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ ++OUI:588694* ++ ID_OUI_FROM_DATABASE=EFM Networks ++ + OUI:58874C* + ID_OUI_FROM_DATABASE=LITE-ON CLEAN ENERGY TECHNOLOGY CORP. + +@@ -54086,9 +61388,15 @@ OUI:588D09* + OUI:588D64* + ID_OUI_FROM_DATABASE=Xi'an Clevbee Technology Co.,Ltd + ++OUI:588E81* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:589043* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:589153* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:5891CF* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -54098,12 +61406,75 @@ OUI:58920D* + OUI:589396* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:5893D8* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:58946B* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:5894A2* ++ ID_OUI_FROM_DATABASE=KETEK GmbH ++ ++OUI:5894AE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:5894B2* ++ ID_OUI_FROM_DATABASE=BrainCo ++ + OUI:5894CF* + ID_OUI_FROM_DATABASE=Vertex Standard LMR, Inc. + ++OUI:5895D80* ++ ID_OUI_FROM_DATABASE=Shenzhen DOOGEE Hengtong Technology CO.,LTD ++ ++OUI:5895D81* ++ ID_OUI_FROM_DATABASE=shenzhen UDD Technologies,co.,Ltd ++ ++OUI:5895D82* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:5895D83* ++ ID_OUI_FROM_DATABASE=Tonnet Telecommunication International Co., Ltd. ++ ++OUI:5895D84* ++ ID_OUI_FROM_DATABASE=Unity Surveillance, Inc. ++ ++OUI:5895D85* ++ ID_OUI_FROM_DATABASE=elgris UG ++ ++OUI:5895D86* ++ ID_OUI_FROM_DATABASE=Norgren Manufacturing Co., Ltd. ++ ++OUI:5895D87* ++ ID_OUI_FROM_DATABASE=Epiphan Systems Inc ++ ++OUI:5895D88* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ ++OUI:5895D89* ++ ID_OUI_FROM_DATABASE=Loftie ++ ++OUI:5895D8A* ++ ID_OUI_FROM_DATABASE=Peak Communications Limited ++ ++OUI:5895D8B* ++ ID_OUI_FROM_DATABASE=SuZhou Ruishengwei Intelligent Technology Co.,Ltd ++ ++OUI:5895D8C* ++ ID_OUI_FROM_DATABASE=LOCTEK ERGONOMIC TECHNOLOGY CORP. ++ ++OUI:5895D8D* ++ ID_OUI_FROM_DATABASE=Alunos AG ++ ++OUI:5895D8E* ++ ID_OUI_FROM_DATABASE=Gmv sistemas SAU ++ ++OUI:58961D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:589630* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:58971E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -54111,7 +61482,7 @@ OUI:5897BD* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:589835* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:58986F* + ID_OUI_FROM_DATABASE=Revolution Display +@@ -54122,6 +61493,12 @@ OUI:589B0B* + OUI:589CFC* + ID_OUI_FROM_DATABASE=FreeBSD Foundation + ++OUI:589EC6* ++ ID_OUI_FROM_DATABASE=Gigaset Communications GmbH ++ ++OUI:58A023* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:58A0CB* + ID_OUI_FROM_DATABASE=TrackNet, Inc + +@@ -54131,21 +61508,39 @@ OUI:58A2B5* + OUI:58A48E* + ID_OUI_FROM_DATABASE=PixArt Imaging Inc. + ++OUI:58A639* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:58A76F* + ID_OUI_FROM_DATABASE=iD corporation + + OUI:58A839* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:58A87B* ++ ID_OUI_FROM_DATABASE=Fitbit, Inc. ++ + OUI:58AC78* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:58AE2B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:58AEA8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:58AEF1* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:58B035* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:58B0D4* + ID_OUI_FROM_DATABASE=ZuniData Systems Inc. + ++OUI:58B0FE* ++ ID_OUI_FROM_DATABASE=Team EPS GmbH ++ + OUI:58B10F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -54158,6 +61553,9 @@ OUI:58B42D* + OUI:58B568* + ID_OUI_FROM_DATABASE=SECURITAS DIRECT ESPAÑA, SAU + ++OUI:58B623* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:58B633* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -54182,6 +61580,12 @@ OUI:58BDA3* + OUI:58BDF9* + ID_OUI_FROM_DATABASE=Sigrand + ++OUI:58BE72* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:58BF25* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:58BFEA* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -54200,33 +61604,57 @@ OUI:58C583* + OUI:58C5CB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:58C6F0* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:58C876* + ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. + + OUI:58C935* + ID_OUI_FROM_DATABASE=Chiun Mai Communication Systems, Inc + ++OUI:58CB52* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:58CF4B* + ID_OUI_FROM_DATABASE=Lufkin Industries + ++OUI:58D061* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:58D071* + ID_OUI_FROM_DATABASE=BW Broadcast + + OUI:58D08F* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + ++OUI:58D349* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:58D391* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ ++OUI:58D50A* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:58D56E* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:58D67A* + ID_OUI_FROM_DATABASE=TCPlink + ++OUI:58D697* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:58D6D3* + ID_OUI_FROM_DATABASE=Dairy Cheq Inc + + OUI:58D759* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:58D9C3* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:58D9D5* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + +@@ -54257,14 +61685,20 @@ OUI:58E476* + OUI:58E636* + ID_OUI_FROM_DATABASE=EVRsafe Technologies + ++OUI:58E6BA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:58E747* + ID_OUI_FROM_DATABASE=Deltanet AG + + OUI:58E808* + ID_OUI_FROM_DATABASE=AUTONICS CORPORATION + ++OUI:58E873* ++ ID_OUI_FROM_DATABASE=HANGZHOU DANGBEI NETWORK TECH.Co.,Ltd ++ + OUI:58E8760* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Zhuhai Raysharp Technology Co.,Ltd + + OUI:58E8761* + ID_OUI_FROM_DATABASE=Beijing Perabytes IS Technology Co., Ltd +@@ -54297,7 +61731,7 @@ OUI:58E876A* + ID_OUI_FROM_DATABASE=SHENZHEN DIGISSIN TECHNOLOGY + + OUI:58E876B* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:58E876C* + ID_OUI_FROM_DATABASE=KUSTOM SIGNALS INC +@@ -54308,12 +61742,18 @@ OUI:58E876D* + OUI:58E876E* + ID_OUI_FROM_DATABASE=Baoruh Electronic Co., Ltd. + ++OUI:58EAFC* ++ ID_OUI_FROM_DATABASE=ELL-IoT Inc ++ + OUI:58EB14* + ID_OUI_FROM_DATABASE=Proteus Digital Health + + OUI:58ECE1* + ID_OUI_FROM_DATABASE=Newport Corporation + ++OUI:58ECED* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:58EECE* + ID_OUI_FROM_DATABASE=Icon Time Systems + +@@ -54323,6 +61763,9 @@ OUI:58EF68* + OUI:58F102* + ID_OUI_FROM_DATABASE=BLU Products Inc. + ++OUI:58F2FC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:58F387* + ID_OUI_FROM_DATABASE=HCCP + +@@ -54347,6 +61790,12 @@ OUI:58F98E* + OUI:58FB84* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:58FB96* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ ++OUI:58FC20* ++ ID_OUI_FROM_DATABASE=Altice Labs S.A. ++ + OUI:58FC73* + ID_OUI_FROM_DATABASE=Arria Live Media, Inc. + +@@ -54399,7 +61848,13 @@ OUI:58FCDBF* + ID_OUI_FROM_DATABASE=Private + + OUI:58FD20* +- ID_OUI_FROM_DATABASE=Bravida Sakerhet AB ++ ID_OUI_FROM_DATABASE=Systemhouse Solutions AB ++ ++OUI:58FD5D* ++ ID_OUI_FROM_DATABASE=Hangzhou Xinyun technology Co., Ltd. ++ ++OUI:58FDB1* ++ ID_OUI_FROM_DATABASE=LG Electronics + + OUI:58FDBE* + ID_OUI_FROM_DATABASE=Shenzhen Taikaida Technology Co., Ltd +@@ -54407,9 +61862,15 @@ OUI:58FDBE* + OUI:5C0038* + ID_OUI_FROM_DATABASE=Viasat Group S.p.A. + ++OUI:5C0214* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:5C026A* + ID_OUI_FROM_DATABASE=Applied Vision Corporation + ++OUI:5C0272* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:5C0339* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -54425,15 +61886,27 @@ OUI:5C0979* + OUI:5C0A5B* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + ++OUI:5C0BCA* ++ ID_OUI_FROM_DATABASE=Tunstall Nordic AB ++ + OUI:5C0C0E* + ID_OUI_FROM_DATABASE=Guizhou Huaxintong Semiconductor Technology Co Ltd + + OUI:5C0CBB* + ID_OUI_FROM_DATABASE=CELIZION Inc. + ++OUI:5C0CE6* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:5C0E8B* + ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + ++OUI:5C0FFB* ++ ID_OUI_FROM_DATABASE=Amino Communications Ltd ++ ++OUI:5C10C5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:5C1193* + ID_OUI_FROM_DATABASE=Seal One AG + +@@ -54449,9 +61922,15 @@ OUI:5C15E1* + OUI:5C16C7* + ID_OUI_FROM_DATABASE=Big Switch Networks + ++OUI:5C1720* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:5C1737* + ID_OUI_FROM_DATABASE=I-View Now, LLC. + ++OUI:5C17CF* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ + OUI:5C17D3* + ID_OUI_FROM_DATABASE=LGE + +@@ -54461,6 +61940,9 @@ OUI:5C18B5* + OUI:5C1A6F* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:5C1CB9* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:5C1DD9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -54470,6 +61952,9 @@ OUI:5C20D0* + OUI:5C22C4* + ID_OUI_FROM_DATABASE=DAE EUN ELETRONICS CO., LTD + ++OUI:5C2316* ++ ID_OUI_FROM_DATABASE=Squirrels Research Labs LLC ++ + OUI:5C2443* + ID_OUI_FROM_DATABASE=O-Sung Telecom Co., Ltd. + +@@ -54485,8 +61970,11 @@ OUI:5C260A* + OUI:5C2623* + ID_OUI_FROM_DATABASE=WaveLynx Technologies Corporation + ++OUI:5C27D4* ++ ID_OUI_FROM_DATABASE=Shenzhen Qihu Intelligent Technology Company Limited ++ + OUI:5C2AEF* +- ID_OUI_FROM_DATABASE=Open Access Pty Ltd ++ ID_OUI_FROM_DATABASE=r2p Asia-Pacific Pty Ltd + + OUI:5C2BF5* + ID_OUI_FROM_DATABASE=Vivint Wireless Inc. +@@ -54500,6 +61988,9 @@ OUI:5C2ED2* + OUI:5C313E* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:5C32C5* ++ ID_OUI_FROM_DATABASE=Teracom Ltd. ++ + OUI:5C3327* + ID_OUI_FROM_DATABASE=Spazio Italia srl + +@@ -54509,6 +62000,9 @@ OUI:5C335C* + OUI:5C338E* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + ++OUI:5C3400* ++ ID_OUI_FROM_DATABASE=Hisense Electric Co.,Ltd ++ + OUI:5C353B* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + +@@ -54521,6 +62015,12 @@ OUI:5C36B8* + OUI:5C38E0* + ID_OUI_FROM_DATABASE=Shanghai Super Electronics Technology Co.,LTD + ++OUI:5C3A3D* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:5C3A45* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:5C3B35* + ID_OUI_FROM_DATABASE=Gehirn Inc. + +@@ -54530,12 +62030,18 @@ OUI:5C3C27* + OUI:5C4058* + ID_OUI_FROM_DATABASE=Jefferson Audio Video Systems, Inc. + ++OUI:5C415A* ++ ID_OUI_FROM_DATABASE=Amazon.com, LLC ++ + OUI:5C41E7* + ID_OUI_FROM_DATABASE=Wiatec International Ltd. + + OUI:5C43D2* + ID_OUI_FROM_DATABASE=HAZEMEYER + ++OUI:5C443E* ++ ID_OUI_FROM_DATABASE=Skullcandy ++ + OUI:5C4527* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -54546,7 +62052,7 @@ OUI:5C497D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:5C4A1F* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:5C4A26* + ID_OUI_FROM_DATABASE=Enguity Technology Corp +@@ -54569,9 +62075,18 @@ OUI:5C5188* + OUI:5C521E* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:5C5230* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:5C546D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:5C5578* ++ ID_OUI_FROM_DATABASE=iryx corp ++ ++OUI:5C56A4* ++ ID_OUI_FROM_DATABASE=Wanan Hongsheng Electronic Co.Ltd ++ + OUI:5C56ED* + ID_OUI_FROM_DATABASE=3pleplay Electronics Private Limited + +@@ -54584,9 +62099,15 @@ OUI:5C57C8* + OUI:5C5819* + ID_OUI_FROM_DATABASE=Jingsheng Technology Co., Ltd. + ++OUI:5C58E6* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ + OUI:5C5948* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:5C5AC7* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:5C5AEA* + ID_OUI_FROM_DATABASE=FORD + +@@ -54602,15 +62123,33 @@ OUI:5C5EAB* + OUI:5C5F67* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:5C6199* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ ++OUI:5C625A* ++ ID_OUI_FROM_DATABASE=CANON INC. ++ + OUI:5C63BF* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:5C63C9* + ID_OUI_FROM_DATABASE=Intellithings Ltd. + ++OUI:5C647A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:5C648E* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ ++OUI:5C666C* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:5C6776* + ID_OUI_FROM_DATABASE=IDS Imaging Development Systems GmbH + ++OUI:5C68D0* ++ ID_OUI_FROM_DATABASE=Aurora Innovation Inc. ++ + OUI:5C6984* + ID_OUI_FROM_DATABASE=NUVICO + +@@ -54626,33 +62165,114 @@ OUI:5C6B32* + OUI:5C6B4F* + ID_OUI_FROM_DATABASE=Hello Inc. + ++OUI:5C6BD7* ++ ID_OUI_FROM_DATABASE=Foshan VIOMI Electric Appliance Technology Co. Ltd. ++ + OUI:5C6D20* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:5C6F4F* + ID_OUI_FROM_DATABASE=S.A. SISTEL + ++OUI:5C6F69* ++ ID_OUI_FROM_DATABASE=Broadcom Limited ++ ++OUI:5C7017* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:5C70A3* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:5C710D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:5C75AF* ++ ID_OUI_FROM_DATABASE=Fitbit, Inc. ++ ++OUI:5C75C6* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:5C7695* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:5C7757* + ID_OUI_FROM_DATABASE=Haivision Network Video + + OUI:5C7776* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:5C78F8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:5C7D5E* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:5C7D7D* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:5C80B6* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:5C81A7* + ID_OUI_FROM_DATABASE=Network Devices Pty Ltd + ++OUI:5C8382* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:5C838F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:5C8486* + ID_OUI_FROM_DATABASE=Brightsource Industries Israel LTD + ++OUI:5C857E0* ++ ID_OUI_FROM_DATABASE=28 Gorilla ++ ++OUI:5C857E1* ++ ID_OUI_FROM_DATABASE=Sichuan C.H Control Technology Co., Ltd. ++ ++OUI:5C857E2* ++ ID_OUI_FROM_DATABASE=mobilogix HongKong ++ ++OUI:5C857E3* ++ ID_OUI_FROM_DATABASE=Cable Matters Inc. ++ ++OUI:5C857E4* ++ ID_OUI_FROM_DATABASE=Shenzhen IP3 Century Intelligent Technology CO.,Ltd ++ ++OUI:5C857E5* ++ ID_OUI_FROM_DATABASE=Shanghai Yanhe automation technology co.,LTD ++ ++OUI:5C857E6* ++ ID_OUI_FROM_DATABASE=ProdataKey ++ ++OUI:5C857E7* ++ ID_OUI_FROM_DATABASE=Beijing HZFD Technology Co., Ltd ++ ++OUI:5C857E8* ++ ID_OUI_FROM_DATABASE=BeiJing Xinsheng Technology Co.,Ltd ++ ++OUI:5C857E9* ++ ID_OUI_FROM_DATABASE=Express LUCK Industrial Ltd. ++ ++OUI:5C857EA* ++ ID_OUI_FROM_DATABASE=Zhejiang Jetron Ark Digital Technology Co., Ltd ++ ++OUI:5C857EB* ++ ID_OUI_FROM_DATABASE=HHCC Plant Technology Co., Ltd. ++ ++OUI:5C857EC* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:5C857ED* ++ ID_OUI_FROM_DATABASE=Nautech Electronics Ltd ++ ++OUI:5C857EE* ++ ID_OUI_FROM_DATABASE=Guoyi Liangzi (Hefei) Technology Co., Ltd(CIQTEK) ++ ++OUI:5C85F8* ++ ID_OUI_FROM_DATABASE=SHENZHEN KAIFA TECHNOLOGY CO.,LTD. ++ + OUI:5C8613* + ID_OUI_FROM_DATABASE=Beijing Zhoenet Technology Co., Ltd + +@@ -54665,9 +62285,18 @@ OUI:5C865C* + OUI:5C86C1* + ID_OUI_FROM_DATABASE=DONGGUAN SOLUM ELECTRONICS CO.,LTD + ++OUI:5C8730* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:5C8778* + ID_OUI_FROM_DATABASE=Cybertelbridge co.,ltd + ++OUI:5C879C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:5C8816* ++ ID_OUI_FROM_DATABASE=Rockwell Automation ++ + OUI:5C899A* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -54683,9 +62312,24 @@ OUI:5C8D2D* + OUI:5C8D4E* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:5C8F40* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:5C8FE0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:5C9012* ++ ID_OUI_FROM_DATABASE=Owl Cyber Defense Solutions, LLC ++ ++OUI:5C9157* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:5C91FD* ++ ID_OUI_FROM_DATABASE=Jaewoncnc ++ ++OUI:5C925E* ++ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. ++ + OUI:5C93A2* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -54707,15 +62351,21 @@ OUI:5C97F3* + OUI:5C9960* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:5C9AA1* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:5C9AD8* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + + OUI:5CA176* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:5CA178* + ID_OUI_FROM_DATABASE=TableTop Media (dba Ziosk) + ++OUI:5CA1E0* ++ ID_OUI_FROM_DATABASE=EmbedWay Technologies ++ + OUI:5CA39D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + +@@ -54725,6 +62375,18 @@ OUI:5CA3EB* + OUI:5CA48A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:5CA4A4* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:5CA5BC* ++ ID_OUI_FROM_DATABASE=eero inc. ++ ++OUI:5CA62D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:5CA721* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:5CA86A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -54746,9 +62408,21 @@ OUI:5CADCF* + OUI:5CAF06* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:5CB00A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:5CB066* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:5CB13E* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:5CB15F* ++ ID_OUI_FROM_DATABASE=Oceanblue Cloud Technology Limited ++ ++OUI:5CB29E* ++ ID_OUI_FROM_DATABASE=ASCO Power Technologies ++ + OUI:5CB395* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -54758,8 +62432,11 @@ OUI:5CB3F6* + OUI:5CB43E* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:5CB4E2* ++ ID_OUI_FROM_DATABASE=Inspur Software Group Ltd. ++ + OUI:5CB524* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:5CB559* + ID_OUI_FROM_DATABASE=CNEX Labs +@@ -54773,18 +62450,36 @@ OUI:5CB8CB* + OUI:5CB901* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:5CBA2C* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:5CBA37* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:5CBAEF* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:5CBD9A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:5CBD9E* + ID_OUI_FROM_DATABASE=HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED + ++OUI:5CC0A0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:5CC1D7* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:5CC213* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + + OUI:5CC307* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:5CC336* ++ ID_OUI_FROM_DATABASE=ittim ++ + OUI:5CC5D4* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -54797,6 +62492,9 @@ OUI:5CC6E9* + OUI:5CC7D7* + ID_OUI_FROM_DATABASE=AZROAD TECHNOLOGY COMPANY LIMITED + ++OUI:5CC8E3* ++ ID_OUI_FROM_DATABASE=Shintec Hozumi co.ltd. ++ + OUI:5CC999* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + +@@ -54809,12 +62507,24 @@ OUI:5CCA1A* + OUI:5CCA32* + ID_OUI_FROM_DATABASE=Theben AG + ++OUI:5CCAD3* ++ ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. ++ ++OUI:5CCB99* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:5CCBCA* ++ ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD ++ + OUI:5CCCA0* + ID_OUI_FROM_DATABASE=Gridwiz Inc. + + OUI:5CCCFF* + ID_OUI_FROM_DATABASE=Techroutes Network Pvt Ltd + ++OUI:5CCD5B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:5CCD7C* + ID_OUI_FROM_DATABASE=MEIZU Technology Co.,Ltd. + +@@ -54824,6 +62534,9 @@ OUI:5CCEAD* + OUI:5CCF7F* + ID_OUI_FROM_DATABASE=Espressif Inc. + ++OUI:5CD06E* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:5CD135* + ID_OUI_FROM_DATABASE=Xtreme Power Systems + +@@ -54839,9 +62552,15 @@ OUI:5CD41B* + OUI:5CD4AB* + ID_OUI_FROM_DATABASE=Zektor + ++OUI:5CD5B5* ++ ID_OUI_FROM_DATABASE=Shenzhen WiSiYiLink Technology Co.,Ltd ++ + OUI:5CD61F* + ID_OUI_FROM_DATABASE=Qardio, Inc + ++OUI:5CD89E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:5CD998* + ID_OUI_FROM_DATABASE=D-Link Corporation + +@@ -54854,6 +62573,12 @@ OUI:5CDC96* + OUI:5CDD70* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:5CDE34* ++ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. ++ ++OUI:5CDFB8* ++ ID_OUI_FROM_DATABASE=Shenzhen Unionmemory Information System Limited ++ + OUI:5CE0C5* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -54863,6 +62588,9 @@ OUI:5CE0CA* + OUI:5CE0F6* + ID_OUI_FROM_DATABASE=NIC.br- Nucleo de Informacao e Coordenacao do Ponto BR + ++OUI:5CE176* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:5CE223* + ID_OUI_FROM_DATABASE=Delphin Technology AG + +@@ -54881,9 +62609,24 @@ OUI:5CE30E* + OUI:5CE3B6* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:5CE42A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:5CE50C* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:5CE747* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:5CE7A0* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:5CE7BF* + ID_OUI_FROM_DATABASE=New Singularity International Technical Development Co.,Ltd + ++OUI:5CE883* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:5CE8B7* + ID_OUI_FROM_DATABASE=Oraimo Technology Limited + +@@ -54899,6 +62642,9 @@ OUI:5CEB4E* + OUI:5CEB68* + ID_OUI_FROM_DATABASE=Cheerstar Technology Co., Ltd + ++OUI:5CED8C* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:5CEE79* + ID_OUI_FROM_DATABASE=Global Digitech Co LTD + +@@ -54992,12 +62738,24 @@ OUI:5CF9DD* + OUI:5CF9F0* + ID_OUI_FROM_DATABASE=Atomos Engineering P/L + ++OUI:5CF9FD* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ ++OUI:5CFAFB* ++ ID_OUI_FROM_DATABASE=Acubit ++ ++OUI:5CFB3A* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:5CFB7C* + ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd + + OUI:5CFC66* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:5CFE9E* ++ ID_OUI_FROM_DATABASE=Wiwynn Corporation Tainan Branch ++ + OUI:5CFF35* + ID_OUI_FROM_DATABASE=Wistron Corporation + +@@ -55019,27 +62777,45 @@ OUI:600308* + OUI:600347* + ID_OUI_FROM_DATABASE=Billion Electric Co. Ltd. + ++OUI:6003A6* ++ ID_OUI_FROM_DATABASE=Inteno Broadband Technology AB ++ + OUI:600417* + ID_OUI_FROM_DATABASE=POSBANK CO.,LTD + + OUI:60058A* + ID_OUI_FROM_DATABASE=Hitachi Metals, Ltd. + ++OUI:6006E3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:60077C* ++ ID_OUI_FROM_DATABASE=Jala Group ++ + OUI:600810* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:600837* + ID_OUI_FROM_DATABASE=ivvi Scientific(Nanchang)Co.Ltd + ++OUI:6009C3* ++ ID_OUI_FROM_DATABASE=u-blox AG ++ + OUI:600B03* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + + OUI:600F77* + ID_OUI_FROM_DATABASE=SilverPlus, Inc + ++OUI:6010A2* ++ ID_OUI_FROM_DATABASE=Crompton Instruments ++ + OUI:601199* + ID_OUI_FROM_DATABASE=Siama Systems Inc + ++OUI:60123C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:601283* + ID_OUI_FROM_DATABASE=TSB REAL TIME LOCATION SYSTEMS S.L. + +@@ -55052,6 +62828,48 @@ OUI:601466* + OUI:6014B3* + ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. + ++OUI:6015920* ++ ID_OUI_FROM_DATABASE=S Labs sp. z o.o. ++ ++OUI:6015921* ++ ID_OUI_FROM_DATABASE=RTDS Technologies Inc. ++ ++OUI:6015922* ++ ID_OUI_FROM_DATABASE=EDA Technology Co.,LTD ++ ++OUI:6015923* ++ ID_OUI_FROM_DATABASE=OSI TECHNOLOGY CO.,LTD. ++ ++OUI:6015924* ++ ID_OUI_FROM_DATABASE=Zaptec ++ ++OUI:6015926* ++ ID_OUI_FROM_DATABASE=BEIJING KUANGSHI TECHNOLOGY CO., LTD ++ ++OUI:6015927* ++ ID_OUI_FROM_DATABASE=Faster CZ spol. s r.o. ++ ++OUI:6015928* ++ ID_OUI_FROM_DATABASE=Yangzhou Wanfang Electronic Technology,CO .,Ltd. ++ ++OUI:6015929* ++ ID_OUI_FROM_DATABASE=JIANGSU SUNFY TECHNOLOGIES HOLDING CO.,LTD. ++ ++OUI:601592A* ++ ID_OUI_FROM_DATABASE=insensiv GmbH ++ ++OUI:601592B* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:601592C* ++ ID_OUI_FROM_DATABASE=PSS Co., Ltd ++ ++OUI:601592D* ++ ID_OUI_FROM_DATABASE=REMOWIRELESS COMMUNICATION INTERNATIONAL CO.,LIMITED ++ ++OUI:601592E* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ + OUI:6015C7* + ID_OUI_FROM_DATABASE=IdaTech + +@@ -55064,6 +62882,9 @@ OUI:60182E* + OUI:601888* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:601895* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:60190C* + ID_OUI_FROM_DATABASE=RRAMAC + +@@ -55079,6 +62900,12 @@ OUI:601971* + OUI:601D0F* + ID_OUI_FROM_DATABASE=Midnite Solar + ++OUI:601D91* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:601D9D* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:601E02* + ID_OUI_FROM_DATABASE=EltexAlatau + +@@ -55091,12 +62918,21 @@ OUI:602103* + OUI:6021C0* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:6023A4* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:6024C1* + ID_OUI_FROM_DATABASE=Jiangsu Zhongxun Electronic Technology Co., Ltd + ++OUI:6026EF* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:60271C* + ID_OUI_FROM_DATABASE=VIDEOR E. Hartig GmbH + ++OUI:6029D5* ++ ID_OUI_FROM_DATABASE=DAVOLINK Inc. ++ + OUI:602A54* + ID_OUI_FROM_DATABASE=CardioTek B.V. + +@@ -55115,6 +62951,9 @@ OUI:60313B* + OUI:603197* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + ++OUI:6032B1* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:6032F0* + ID_OUI_FROM_DATABASE=Mplus technology + +@@ -55124,6 +62963,9 @@ OUI:60334B* + OUI:603553* + ID_OUI_FROM_DATABASE=Buwon Technology + ++OUI:603573* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:6035C0* + ID_OUI_FROM_DATABASE=SFR + +@@ -55134,7 +62976,7 @@ OUI:6036DD* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:60380E* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:6038E0* + ID_OUI_FROM_DATABASE=Belkin International Inc. +@@ -55142,6 +62984,15 @@ OUI:6038E0* + OUI:60391F* + ID_OUI_FROM_DATABASE=ABB Ltd + ++OUI:603A7C* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:603AAF* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:603CEE* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:603D26* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + +@@ -55157,6 +63008,9 @@ OUI:603FC5* + OUI:60427F* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD + ++OUI:60447A* ++ ID_OUI_FROM_DATABASE=Water-i.d. GmbH ++ + OUI:6044F5* + ID_OUI_FROM_DATABASE=Easy Digital Ltd. + +@@ -55202,21 +63056,45 @@ OUI:6052D0* + OUI:605317* + ID_OUI_FROM_DATABASE=Sandstone Technologies + ++OUI:605375* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:605464* + ID_OUI_FROM_DATABASE=Eyedro Green Solutions Inc. + ++OUI:6055F9* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:605661* ++ ID_OUI_FROM_DATABASE=IXECLOUD Tech ++ + OUI:605718* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:60577D* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:605BB4* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:605E4F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:605F8D* + ID_OUI_FROM_DATABASE=eero inc. + + OUI:60601F* + ID_OUI_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD + ++OUI:606134* ++ ID_OUI_FROM_DATABASE=Genesis Technical Systems Corp ++ ++OUI:6061DF* ++ ID_OUI_FROM_DATABASE=Z-meta Research LLC ++ ++OUI:60634C* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:6063F9* + ID_OUI_FROM_DATABASE=Ciholas, Inc. + +@@ -55235,6 +63113,9 @@ OUI:6064A1* + OUI:606720* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:60684E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:606944* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -55247,6 +63128,9 @@ OUI:606BBD* + OUI:606BFF* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:606C63* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:606C66* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -55256,6 +63140,18 @@ OUI:606D3C* + OUI:606DC7* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:606ED0* ++ ID_OUI_FROM_DATABASE=SEAL AG ++ ++OUI:606EE8* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:607072* ++ ID_OUI_FROM_DATABASE=SHENZHEN HONGDE SMART LINK TECHNOLOGY CO., LTD ++ ++OUI:6070C0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:60720B* + ID_OUI_FROM_DATABASE=BLU Products Inc + +@@ -55271,14 +63167,26 @@ OUI:60748D* + OUI:607688* + ID_OUI_FROM_DATABASE=Velodyne + ++OUI:607771* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:6077E2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:607EA4* ++ ID_OUI_FROM_DATABASE=Shanghai Imilab Technology Co.Ltd ++ ++OUI:607EC9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:607ECD* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:607EDD* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + + OUI:60812B* +- ID_OUI_FROM_DATABASE=Custom Control Concepts ++ ID_OUI_FROM_DATABASE=Astronics Custom Control Concepts + + OUI:6081F9* + ID_OUI_FROM_DATABASE=Helium Systems, Inc +@@ -55286,6 +63194,9 @@ OUI:6081F9* + OUI:608334* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:608373* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:6083B2* + ID_OUI_FROM_DATABASE=GkWare e.K. + +@@ -55307,21 +63218,39 @@ OUI:6089B1* + OUI:6089B7* + ID_OUI_FROM_DATABASE=KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ + ++OUI:608A10* ++ ID_OUI_FROM_DATABASE=Microchip Technology Inc. ++ ++OUI:608B0E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:608C2B* + ID_OUI_FROM_DATABASE=Hanson Technology + ++OUI:608C4A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:608CDF* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:608CE6* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:608D17* + ID_OUI_FROM_DATABASE=Sentrus Government Systems Division, Inc + ++OUI:608D26* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:608E08* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:608F5C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:608FA4* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:609084* + ID_OUI_FROM_DATABASE=DSSD Inc + +@@ -55331,6 +63260,54 @@ OUI:6091F3* + OUI:609217* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:6092F5* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:6095CE0* ++ ID_OUI_FROM_DATABASE=Siema Applications ++ ++OUI:6095CE1* ++ ID_OUI_FROM_DATABASE=Ponoor Experiments Inc. ++ ++OUI:6095CE2* ++ ID_OUI_FROM_DATABASE=Q-SENTECH Co.,Ltd. ++ ++OUI:6095CE3* ++ ID_OUI_FROM_DATABASE=Robot S.A. ++ ++OUI:6095CE4* ++ ID_OUI_FROM_DATABASE=Untangle, Inc. ++ ++OUI:6095CE5* ++ ID_OUI_FROM_DATABASE=AdvanWISE Corporation ++ ++OUI:6095CE6* ++ ID_OUI_FROM_DATABASE=Xiamen Sigmastar Technology Ltd. ++ ++OUI:6095CE7* ++ ID_OUI_FROM_DATABASE=Cadmo Soluciones SAC ++ ++OUI:6095CE8* ++ ID_OUI_FROM_DATABASE=Trophy SAS ++ ++OUI:6095CE9* ++ ID_OUI_FROM_DATABASE=Jlztlink Industry(ShenZhen)Co.,Ltd. ++ ++OUI:6095CEA* ++ ID_OUI_FROM_DATABASE=(UN)MANNED ++ ++OUI:6095CEB* ++ ID_OUI_FROM_DATABASE=Beijing Sinomedisite Bio-tech Co.,Ltd ++ ++OUI:6095CEC* ++ ID_OUI_FROM_DATABASE=Synamedia ++ ++OUI:6095CED* ++ ID_OUI_FROM_DATABASE=GovComm ++ ++OUI:6095CEE* ++ ID_OUI_FROM_DATABASE=VNS Inc. ++ + OUI:609620* + ID_OUI_FROM_DATABASE=Private + +@@ -55340,6 +63317,9 @@ OUI:6097DD* + OUI:609813* + ID_OUI_FROM_DATABASE=Shanghai Visking Digital Technology Co. LTD + ++OUI:609866* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:6099D1* + ID_OUI_FROM_DATABASE=Vuzix / Lenovo + +@@ -55349,11 +63329,17 @@ OUI:609AA4* + OUI:609AC1* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:609B2D* ++ ID_OUI_FROM_DATABASE=JMACS Japan Co., Ltd. ++ ++OUI:609BB4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:609BC8* + ID_OUI_FROM_DATABASE=Hipad Intelligent Technology Co., Ltd. + + OUI:609C9F* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:609E64* + ID_OUI_FROM_DATABASE=Vivonic GmbH +@@ -55364,21 +63350,51 @@ OUI:609F9D* + OUI:60A10A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:60A11E* ++ ID_OUI_FROM_DATABASE=Wuhan Maxsine Electric Co.,Ltd. ++ + OUI:60A37D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:60A423* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:60A44C* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:60A4B7* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:60A4D0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:60A5E2* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:60A730* ++ ID_OUI_FROM_DATABASE=Shenzhen Yipinfang Internet Technology Co.,Ltd ++ ++OUI:60A751* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:60A8FE* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:60A9B0* + ID_OUI_FROM_DATABASE=Merchandising Technologies, Inc + ++OUI:60AAEF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:60AB14* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ ++OUI:60AB67* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:60ABD2* ++ ID_OUI_FROM_DATABASE=Bose Corporation ++ + OUI:60ACC8* + ID_OUI_FROM_DATABASE=KunTeng Inc. + +@@ -55403,6 +63419,12 @@ OUI:60B606* + OUI:60B617* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:60B6E1* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:60B76E* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:60B933* + ID_OUI_FROM_DATABASE=Deutron Electronics Corp. + +@@ -55424,6 +63446,9 @@ OUI:60BD91* + OUI:60BEB5* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:60BEC4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:60C0BF* + ID_OUI_FROM_DATABASE=ON Semiconductor + +@@ -55442,6 +63467,9 @@ OUI:60C5A8* + OUI:60C5AD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:60C5E6* ++ ID_OUI_FROM_DATABASE=Skullcandy ++ + OUI:60C658* + ID_OUI_FROM_DATABASE=PHYTRONIX Co.,Ltd. + +@@ -55460,6 +63488,15 @@ OUI:60CDA9* + OUI:60CDC5* + ID_OUI_FROM_DATABASE=Taiwan Carol Electronics., Ltd + ++OUI:60CE41* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:60CE86* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:60CE92* ++ ID_OUI_FROM_DATABASE=The Refined Industry Company Limited ++ + OUI:60D02C* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -55472,15 +63509,27 @@ OUI:60D1AA* + OUI:60D21C* + ID_OUI_FROM_DATABASE=Sunnovo International Limited + ++OUI:60D248* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:60D262* + ID_OUI_FROM_DATABASE=Tzukuri Pty Ltd + + OUI:60D2B9* + ID_OUI_FROM_DATABASE=REALAND BIO CO., LTD. + ++OUI:60D2DD* ++ ID_OUI_FROM_DATABASE=Shenzhen Baitong Putian Technology Co.,Ltd. ++ + OUI:60D30A* + ID_OUI_FROM_DATABASE=Quatius Limited + ++OUI:60D4E9* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:60D755* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:60D7E30* + ID_OUI_FROM_DATABASE=Avalun + +@@ -55529,6 +63578,9 @@ OUI:60D7E3E* + OUI:60D819* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:60D89C* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:60D9A0* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +@@ -55541,9 +63593,21 @@ OUI:60DA23* + OUI:60DA83* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:60DB15* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:60DB2A* + ID_OUI_FROM_DATABASE=HNS + ++OUI:60DB98* ++ ID_OUI_FROM_DATABASE=Calix Inc. ++ ++OUI:60DD8E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:60DE35* ++ ID_OUI_FROM_DATABASE=GITSN, Inc. ++ + OUI:60DE44* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -55556,12 +63620,18 @@ OUI:60E00E* + OUI:60E327* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:60E32B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:60E3AC* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + + OUI:60E6BC* + ID_OUI_FROM_DATABASE=Sino-Telecom Technology Co.,Ltd. + ++OUI:60E6F0* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:60E701* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -55571,8 +63641,11 @@ OUI:60E78A* + OUI:60E956* + ID_OUI_FROM_DATABASE=Ayla Networks, Inc + ++OUI:60EB5A* ++ ID_OUI_FROM_DATABASE=Asterfusion Data Technologies Co.,Ltd ++ + OUI:60EB69* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:60EE5C* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD +@@ -55589,6 +63662,9 @@ OUI:60F189* + OUI:60F18A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:60F262* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:60F281* + ID_OUI_FROM_DATABASE=TRANWO TECHNOLOGY CO., LTD. + +@@ -55598,6 +63674,9 @@ OUI:60F2EF* + OUI:60F3DA* + ID_OUI_FROM_DATABASE=Logic Way GmbH + ++OUI:60F43A* ++ ID_OUI_FROM_DATABASE=Edifier International ++ + OUI:60F445* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -55616,6 +63695,9 @@ OUI:60F677* + OUI:60F81D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:60F8F2* ++ ID_OUI_FROM_DATABASE=Synaptec ++ + OUI:60FA9D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -55625,6 +63707,9 @@ OUI:60FACD* + OUI:60FB42* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:60FCF1* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:60FD56* + ID_OUI_FROM_DATABASE=WOORISYSTEMS CO., Ltd + +@@ -55655,21 +63740,39 @@ OUI:6400F1* + OUI:6402CB* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:64037F* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:6405BE* + ID_OUI_FROM_DATABASE=NEW LIGHT LED + ++OUI:6405E4* ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO .,LTD ++ + OUI:6405E9* + ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd. + ++OUI:6407F6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:64094C* + ID_OUI_FROM_DATABASE=Beijing Superbee Wireless Technology Co.,Ltd + + OUI:640980* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:6409AC* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:640B4A* + ID_OUI_FROM_DATABASE=Digital Telecom Technology Limited + ++OUI:640BD7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:640D22* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:640DCE* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + +@@ -55682,6 +63785,9 @@ OUI:640E36* + OUI:640E94* + ID_OUI_FROM_DATABASE=Pluribus Networks, Inc. + ++OUI:640E9B* ++ ID_OUI_FROM_DATABASE=ISHIDA MEDICAL CO., LTD. ++ + OUI:640F28* + ID_OUI_FROM_DATABASE=2Wire Inc + +@@ -55691,6 +63797,9 @@ OUI:641084* + OUI:641225* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:641236* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:641269* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -55700,6 +63809,9 @@ OUI:641331* + OUI:64136C* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:6413AB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:641666* + ID_OUI_FROM_DATABASE=Nest Labs Inc. + +@@ -55712,6 +63824,9 @@ OUI:64168D* + OUI:6416F0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:641759* ++ ID_OUI_FROM_DATABASE=Intellivision Holdings, LLC ++ + OUI:641A22* + ID_OUI_FROM_DATABASE=Heliospectra AB + +@@ -55733,24 +63848,90 @@ OUI:64200C* + OUI:64209F* + ID_OUI_FROM_DATABASE=Tilgin AB + ++OUI:6420E0* ++ ID_OUI_FROM_DATABASE=T3 Technology Co., Ltd. ++ + OUI:642184* + ID_OUI_FROM_DATABASE=Nippon Denki Kagaku Co.,LTD + + OUI:642216* + ID_OUI_FROM_DATABASE=Shandong Taixin Electronic co.,Ltd + ++OUI:642315* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:642400* + ID_OUI_FROM_DATABASE=Xorcom Ltd. + ++OUI:64255E* ++ ID_OUI_FROM_DATABASE=Observint Technologies, Inc. ++ ++OUI:642656* ++ ID_OUI_FROM_DATABASE=Shenzhen Fanweitai Technology Service Co.,Ltd ++ ++OUI:642677* ++ ID_OUI_FROM_DATABASE=BKM-Micronic Richtfunkanlagen GmbH ++ + OUI:642737* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:642753* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:6429ED* ++ ID_OUI_FROM_DATABASE=AO PKK Milandr ++ + OUI:642B8A* + ID_OUI_FROM_DATABASE=ALL BEST Industrial Co., Ltd. + ++OUI:642C0F* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:642CAC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:642DB7* + ID_OUI_FROM_DATABASE=SEUNGIL ELECTRONICS + ++OUI:6431390* ++ ID_OUI_FROM_DATABASE=SHENZHEN EMEET INTELLIGENT TECHNOLOGY CO., LTD. ++ ++OUI:6431391* ++ ID_OUI_FROM_DATABASE=Livongo Health ++ ++OUI:6431392* ++ ID_OUI_FROM_DATABASE=Smartplus Inc. ++ ++OUI:6431393* ++ ID_OUI_FROM_DATABASE=KOANGYOW INTEGRATION MACHINE CO., LTD. ++ ++OUI:6431394* ++ ID_OUI_FROM_DATABASE=Active Brains ++ ++OUI:6431395* ++ ID_OUI_FROM_DATABASE=Shenzhen He&e Technology Co.,Ltd. ++ ++OUI:6431396* ++ ID_OUI_FROM_DATABASE=Hunan Voc Acoustics Technology Co., Ltd. ++ ++OUI:6431397* ++ ID_OUI_FROM_DATABASE=Dongguan Huili electroacoustic Industrial Co.,ltd ++ ++OUI:6431398* ++ ID_OUI_FROM_DATABASE=Shenzhen Huanyin Electronics Ltd. ++ ++OUI:643139A* ++ ID_OUI_FROM_DATABASE=Product Development Associates, Inc. ++ ++OUI:643139C* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN FUCHANG TECHNOLOGY Co.,Ltd. ++ ++OUI:643139D* ++ ID_OUI_FROM_DATABASE=ZHEJIANG MOORGEN INTELLIGENT TECHNOLOGY CO.,LTD ++ ++OUI:643139E* ++ ID_OUI_FROM_DATABASE=ATG UV Technology ++ + OUI:643150* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -55760,6 +63941,54 @@ OUI:64317E* + OUI:6432A8* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:6433B50* ++ ID_OUI_FROM_DATABASE=Duomondi International Development Co., Ltd. ++ ++OUI:6433B51* ++ ID_OUI_FROM_DATABASE=Huaqin Telecom Technology Co.,Ltd. ++ ++OUI:6433B52* ++ ID_OUI_FROM_DATABASE=Adesso, Inc ++ ++OUI:6433B53* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd ++ ++OUI:6433B54* ++ ID_OUI_FROM_DATABASE=Eagle Eye Networks, Inc ++ ++OUI:6433B55* ++ ID_OUI_FROM_DATABASE=Revo Smart Technologies co.,limited ++ ++OUI:6433B56* ++ ID_OUI_FROM_DATABASE=MICROIT SRL ++ ++OUI:6433B57* ++ ID_OUI_FROM_DATABASE=ABB Electrification Smart Power (ELSP) ++ ++OUI:6433B58* ++ ID_OUI_FROM_DATABASE=LACO Technologies ++ ++OUI:6433B59* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:6433B5A* ++ ID_OUI_FROM_DATABASE=Hometek Eletronics Co., Ltd ++ ++OUI:6433B5B* ++ ID_OUI_FROM_DATABASE=electroCore Inc. ++ ++OUI:6433B5C* ++ ID_OUI_FROM_DATABASE=Geksacon ++ ++OUI:6433B5D* ++ ID_OUI_FROM_DATABASE=IIYAMA CORPORATION ++ ++OUI:6433B5E* ++ ID_OUI_FROM_DATABASE=University of Texas at Austin ++ ++OUI:6433DB* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:643409* + ID_OUI_FROM_DATABASE=BITwave Pte Ltd + +@@ -55767,7 +63996,10 @@ OUI:64351C* + ID_OUI_FROM_DATABASE=e-CON SYSTEMS INDIA PVT LTD + + OUI:643AB1* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:643AEA* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:643E8C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -55790,6 +64022,9 @@ OUI:644BC3* + OUI:644BF0* + ID_OUI_FROM_DATABASE=CalDigit, Inc + ++OUI:644C36* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:644D70* + ID_OUI_FROM_DATABASE=dSPACE GmbH + +@@ -55802,6 +64037,9 @@ OUI:644F74* + OUI:644FB0* + ID_OUI_FROM_DATABASE=Hyunjin.com + ++OUI:6450D6* ++ ID_OUI_FROM_DATABASE=Liquidtool Systems ++ + OUI:645106* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -55829,45 +64067,114 @@ OUI:6455B1* + OUI:645601* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:6458AD* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:6459F8* + ID_OUI_FROM_DATABASE=Vodafone Omnitel B.V. + + OUI:645A04* + ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. + ++OUI:645A36* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:645AED* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:645CF3* ++ ID_OUI_FROM_DATABASE=ParanTek Inc. ++ + OUI:645D86* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:645D92* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:645DD7* + ID_OUI_FROM_DATABASE=Shenzhen Lifesense Medical Electronics Co., Ltd. + ++OUI:645E10* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:645E2C* ++ ID_OUI_FROM_DATABASE=IRay Technology Co., Ltd. ++ + OUI:645EBE* + ID_OUI_FROM_DATABASE=Yahoo! JAPAN + + OUI:645FFF* + ID_OUI_FROM_DATABASE=Nicolet Neuro + ++OUI:646038* ++ ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH ++ + OUI:646184* + ID_OUI_FROM_DATABASE=VELUX + + OUI:646223* + ID_OUI_FROM_DATABASE=Cellient Co., Ltd. + ++OUI:6462660* ++ ID_OUI_FROM_DATABASE=MiiVii Dynamics Technology CO.,LTD ++ ++OUI:6462661* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:6462662* ++ ID_OUI_FROM_DATABASE=Protectli ++ ++OUI:6462663* ++ ID_OUI_FROM_DATABASE=FaceHeart Inc. ++ ++OUI:6462664* ++ ID_OUI_FROM_DATABASE=Redstone Systems, Inc. ++ ++OUI:6462665* ++ ID_OUI_FROM_DATABASE=Bühler AG ++ ++OUI:6462666* ++ ID_OUI_FROM_DATABASE=Pass & Seymour, Inc d/b/a Legrand ++ ++OUI:6462667* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ ++OUI:6462668* ++ ID_OUI_FROM_DATABASE=Leontech Limited ++ ++OUI:6462669* ++ ID_OUI_FROM_DATABASE=Chunghwa System Integration Co., Ltd. ++ ++OUI:646266A* ++ ID_OUI_FROM_DATABASE=Sensoro Co., Ltd. ++ ++OUI:646266B* ++ ID_OUI_FROM_DATABASE=Signal Hound ++ ++OUI:646266C* ++ ID_OUI_FROM_DATABASE=Jiangsu Aisida Electronic Co.,Ltd ++ ++OUI:646266D* ++ ID_OUI_FROM_DATABASE=Kobol Innovations Pte. Ltd. ++ ++OUI:646266E* ++ ID_OUI_FROM_DATABASE=Shenzhen Jie Shi Lian Industrial Co., LTD ++ + OUI:64628A* + ID_OUI_FROM_DATABASE=evon GmbH + ++OUI:64644A* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:64649B* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:6465C0* + ID_OUI_FROM_DATABASE=Nuvon, Inc + ++OUI:646624* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:6466B3* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -55877,6 +64184,9 @@ OUI:646707* + OUI:64680C* + ID_OUI_FROM_DATABASE=Comtrend Corporation + ++OUI:64694E* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:6469BC* + ID_OUI_FROM_DATABASE=Hytera Communications Co .,ltd + +@@ -55886,9 +64196,15 @@ OUI:646A52* + OUI:646A74* + ID_OUI_FROM_DATABASE=AUTH-SERVERS, LLC + ++OUI:646C80* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:646CB2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:646D4E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:646D6C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -55898,6 +64214,12 @@ OUI:646E69* + OUI:646E6C* + ID_OUI_FROM_DATABASE=Radio Datacom LLC + ++OUI:646E97* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:646EE0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:646EEA* + ID_OUI_FROM_DATABASE=Iskratel d.o.o. + +@@ -55910,6 +64232,9 @@ OUI:647033* + OUI:6472D8* + ID_OUI_FROM_DATABASE=GooWi Technology Co.,Limited + ++OUI:647366* ++ ID_OUI_FROM_DATABASE=Shenzhen Siera Technology Ltd ++ + OUI:6473E2* + ID_OUI_FROM_DATABASE=Arbiter Systems, Inc. + +@@ -55928,9 +64253,18 @@ OUI:64777D* + OUI:647791* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:647924* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:6479A7* + ID_OUI_FROM_DATABASE=Phison Electronics Corp. + ++OUI:6479F0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:647BCE* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:647BD4* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -55964,9 +64298,21 @@ OUI:6488FF* + OUI:64899A* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:6489F1* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:648D9E* + ID_OUI_FROM_DATABASE=IVT Electronic Co.,Ltd + ++OUI:6490C1* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:64956C* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ ++OUI:649714* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:649829* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + +@@ -55997,6 +64343,9 @@ OUI:649C81* + OUI:649C8E* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:649D99* ++ ID_OUI_FROM_DATABASE=FS COM INC ++ + OUI:649EF3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -56006,9 +64355,18 @@ OUI:649FF7* + OUI:64A0E7* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:64A198* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:64A200* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:64A232* + ID_OUI_FROM_DATABASE=OOO Samlight + ++OUI:64A28A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:64A2F9* + ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd + +@@ -56036,15 +64394,24 @@ OUI:64A7DD* + OUI:64A837* + ID_OUI_FROM_DATABASE=Juni Korea Co., Ltd + ++OUI:64A965* ++ ID_OUI_FROM_DATABASE=Linkflow Co., Ltd. ++ + OUI:64AE0C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:64AE88* + ID_OUI_FROM_DATABASE=Polytec GmbH + ++OUI:64AEF1* ++ ID_OUI_FROM_DATABASE=Qingdao Hisense Electronics Co.,Ltd. ++ + OUI:64B0A6* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:64B0E8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:64B21D* + ID_OUI_FROM_DATABASE=Chengdu Phycom Tech Co., Ltd. + +@@ -56054,12 +64421,18 @@ OUI:64B310* + OUI:64B370* + ID_OUI_FROM_DATABASE=PowerComm Solutions LLC + ++OUI:64B379* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:64B473* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:64B5C6* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:64B623* ++ ID_OUI_FROM_DATABASE=Schrack Seconet Care Communication GmbH ++ + OUI:64B64A* + ID_OUI_FROM_DATABASE=ViVOtech, Inc. + +@@ -56078,12 +64451,24 @@ OUI:64BC0C* + OUI:64BC11* + ID_OUI_FROM_DATABASE=CombiQ AB + ++OUI:64BC58* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:64C2DE* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:64C354* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:64C394* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:64C3D6* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:64C403* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co.,Ltd. ++ + OUI:64C5AA* + ID_OUI_FROM_DATABASE=South African Broadcasting Corporation + +@@ -56093,23 +64478,38 @@ OUI:64C667* + OUI:64C6AF* + ID_OUI_FROM_DATABASE=AXERRA Networks Ltd + ++OUI:64C753* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:64C901* ++ ID_OUI_FROM_DATABASE=INVENTEC Corporation ++ + OUI:64C944* + ID_OUI_FROM_DATABASE=LARK Technologies, Inc + + OUI:64CB5D* + ID_OUI_FROM_DATABASE=SIA TeleSet + ++OUI:64CB9F* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:64CBA3* + ID_OUI_FROM_DATABASE=Pointmobile + ++OUI:64CC22* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:64CC2E* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:64CE6E* ++ ID_OUI_FROM_DATABASE=Sierra Wireless ++ + OUI:64CFD9* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:64D02D* +- ID_OUI_FROM_DATABASE=Next Generation Integration (NGI) ++ ID_OUI_FROM_DATABASE=NEXT GENERATION INTEGRATION LIMITED (NGI) + + OUI:64D154* + ID_OUI_FROM_DATABASE=Routerboard.com +@@ -56120,12 +64520,18 @@ OUI:64D1A3* + OUI:64D241* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + ++OUI:64D2C4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:64D4BD* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:64D4DA* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:64D7C0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:64D814* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -56159,15 +64565,33 @@ OUI:64DBA0* + OUI:64DC01* + ID_OUI_FROM_DATABASE=Static Systems Group PLC + ++OUI:64DCDE* ++ ID_OUI_FROM_DATABASE=ZheJiang FuChunJiang Information Technology Co.,Ltd ++ ++OUI:64DDE9* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:64DE1C* + ID_OUI_FROM_DATABASE=Kingnetic Pte Ltd + ++OUI:64DF10* ++ ID_OUI_FROM_DATABASE=JingLue Semiconductor(SH) Ltd. ++ + OUI:64DFE9* + ID_OUI_FROM_DATABASE=ATEME + ++OUI:64E003* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ ++OUI:64E0AB* ++ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD ++ + OUI:64E161* + ID_OUI_FROM_DATABASE=DEP Corp. + ++OUI:64E172* ++ ID_OUI_FROM_DATABASE=Shenzhen Qihoo Intelligent Technology Co.,Ltd ++ + OUI:64E599* + ID_OUI_FROM_DATABASE=EFM Networks + +@@ -56177,9 +64601,15 @@ OUI:64E625* + OUI:64E682* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:64E7D8* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:64E84F* + ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd + ++OUI:64E881* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:64E892* + ID_OUI_FROM_DATABASE=Morio Denki Co., Ltd. + +@@ -56201,24 +64631,51 @@ OUI:64ED57* + OUI:64ED62* + ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd + ++OUI:64EEB7* ++ ID_OUI_FROM_DATABASE=Netcore Technology Inc ++ + OUI:64F242* + ID_OUI_FROM_DATABASE=Gerdes Aktiengesellschaft + ++OUI:64F2FB* ++ ID_OUI_FROM_DATABASE=Hangzhou Ezviz Software Co.,Ltd. ++ + OUI:64F50E* + ID_OUI_FROM_DATABASE=Kinion Technology Company Limited + ++OUI:64F54E* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:64F69D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:64F6BB* ++ ID_OUI_FROM_DATABASE=Fibocom Wireless Inc. ++ ++OUI:64F6F7* ++ ID_OUI_FROM_DATABASE=Anhui Dynamic Power Co., Ltd. ++ ++OUI:64F705* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:64F81C* ++ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd. ++ + OUI:64F88A* + ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited + ++OUI:64F947* ++ ID_OUI_FROM_DATABASE=Senscomm Semiconductor Co., Ltd. ++ + OUI:64F970* + ID_OUI_FROM_DATABASE=Kenade Electronics Technology Co.,LTD. + + OUI:64F987* + ID_OUI_FROM_DATABASE=Avvasi Inc. + ++OUI:64F9C0* ++ ID_OUI_FROM_DATABASE=ANALOG DEVICES ++ + OUI:64FB50* + ID_OUI_FROM_DATABASE=RoomReady/Zdi, Inc. + +@@ -56270,18 +64727,30 @@ OUI:64FB81E* + OUI:64FB81F* + ID_OUI_FROM_DATABASE=Private + ++OUI:64FB92* ++ ID_OUI_FROM_DATABASE=PPC Broadband Inc. ++ + OUI:64FC8C* + ID_OUI_FROM_DATABASE=Zonar Systems + ++OUI:64FF0A* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:680235* + ID_OUI_FROM_DATABASE=Konten Networks Inc. + ++OUI:6802B8* ++ ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. ++ + OUI:680571* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:6805CA* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:68070A* ++ ID_OUI_FROM_DATABASE=TPVision Europe B.V ++ + OUI:680715* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -56291,12 +64760,18 @@ OUI:680927* + OUI:680AD7* + ID_OUI_FROM_DATABASE=Yancheng Kecheng Optoelectronic Technology Co., Ltd + ++OUI:680AE2* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:68122D* + ID_OUI_FROM_DATABASE=Special Instrument Development Co., Ltd. + + OUI:681295* + ID_OUI_FROM_DATABASE=Lupine Lighting Systems GmbH + ++OUI:681324* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:681401* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -56315,9 +64790,15 @@ OUI:681729* + OUI:68193F* + ID_OUI_FROM_DATABASE=Digital Airways + ++OUI:6819AC* ++ ID_OUI_FROM_DATABASE=Guangzhou Xianyou Intelligent Technogoly CO., LTD ++ + OUI:681AB2* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:681BEF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:681CA2* + ID_OUI_FROM_DATABASE=Rosewill Inc. + +@@ -56336,11 +64817,17 @@ OUI:681F40* + OUI:681FD8* + ID_OUI_FROM_DATABASE=Siemens Industry, Inc. + ++OUI:68215F* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:68234B* + ID_OUI_FROM_DATABASE=Nihon Dengyo Kousaku + + OUI:68262A* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:682719* ++ ID_OUI_FROM_DATABASE=Microchip Technology Inc. + + OUI:682737* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -56351,15 +64838,30 @@ OUI:6828BA* + OUI:6828F6* + ID_OUI_FROM_DATABASE=Vubiq Networks, Inc. + ++OUI:6829DC* ++ ID_OUI_FROM_DATABASE=Ficosa Electronics S.L.U. ++ + OUI:682C7B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:682D83* ++ ID_OUI_FROM_DATABASE=SHENZHEN DINGHE COMMUNICATION COMPANY ++ + OUI:682DDC* + ID_OUI_FROM_DATABASE=Wuhan Changjiang Electro-Communication Equipment CO.,LTD + ++OUI:682F67* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:6831FE* + ID_OUI_FROM_DATABASE=Teladin Co.,Ltd. + ++OUI:68332C* ++ ID_OUI_FROM_DATABASE=KENSTEL NETWORKS LIMITED ++ ++OUI:683489* ++ ID_OUI_FROM_DATABASE=LEA Professional ++ + OUI:683563* + ID_OUI_FROM_DATABASE=SHENZHEN LIOWN ELECTRONICS CO.,LTD. + +@@ -56369,51 +64871,93 @@ OUI:6836B5* + OUI:6837E9* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:683943* ++ ID_OUI_FROM_DATABASE=ittim ++ + OUI:683A1E* + ID_OUI_FROM_DATABASE=Cisco Meraki + ++OUI:683A48* ++ ID_OUI_FROM_DATABASE=SAMJIN Co., Ltd. ++ + OUI:683B1E* + ID_OUI_FROM_DATABASE=Countwise LTD + ++OUI:683B78* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:683C7D* + ID_OUI_FROM_DATABASE=Magic Intelligence Technology Limited + + OUI:683E02* + ID_OUI_FROM_DATABASE=SIEMENS AG, Digital Factory, Motion Control System + ++OUI:683E26* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:683E34* + ID_OUI_FROM_DATABASE=MEIZU Technology Co., Ltd. + + OUI:683EEC* + ID_OUI_FROM_DATABASE=ERECA + ++OUI:683F1E* ++ ID_OUI_FROM_DATABASE=EFFECT Photonics B.V. ++ ++OUI:683F7D* ++ ID_OUI_FROM_DATABASE=INGRAM MICRO SERVICES ++ + OUI:684352* + ID_OUI_FROM_DATABASE=Bhuu Limited + + OUI:6843D7* + ID_OUI_FROM_DATABASE=Agilecom Photonics Solutions Guangdong Limited + ++OUI:684571* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:6845F1* ++ ID_OUI_FROM_DATABASE=TOSHIBA CLIENT SOLUTIONS CO., LTD. ++ + OUI:684749* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:684898* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:6849B2* ++ ID_OUI_FROM_DATABASE=CARLO GAVAZZI LTD ++ ++OUI:684A76* ++ ID_OUI_FROM_DATABASE=eero inc. ++ ++OUI:684AAE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:684B88* + ID_OUI_FROM_DATABASE=Galtronics Telemetry Inc. + + OUI:684CA8* + ID_OUI_FROM_DATABASE=Shenzhen Herotel Tech. Co., Ltd. + ++OUI:684F64* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:6851B7* + ID_OUI_FROM_DATABASE=PowerCloud Systems, Inc. + ++OUI:6852D6* ++ ID_OUI_FROM_DATABASE=UGame Technology Co.,Ltd ++ + OUI:68536C* + ID_OUI_FROM_DATABASE=SPnS Co.,Ltd + + OUI:685388* + ID_OUI_FROM_DATABASE=P&S Technology + ++OUI:68545A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:6854C1* + ID_OUI_FROM_DATABASE=ColorTokens, Inc. + +@@ -56427,7 +64971,7 @@ OUI:6854FD* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + + OUI:68572D* +- ID_OUI_FROM_DATABASE=HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. + + OUI:6858C5* + ID_OUI_FROM_DATABASE=ZF TRW Automotive +@@ -56450,6 +64994,9 @@ OUI:685D43* + OUI:685E6B* + ID_OUI_FROM_DATABASE=PowerRay Co., Ltd. + ++OUI:686350* ++ ID_OUI_FROM_DATABASE=Hella India Automotive Pvt Ltd ++ + OUI:686359* + ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA + +@@ -56462,9 +65009,15 @@ OUI:68692E* + OUI:686975* + ID_OUI_FROM_DATABASE=Angler Labs Inc + ++OUI:6869CA* ++ ID_OUI_FROM_DATABASE=Hitachi, Ltd. ++ + OUI:6869F2* + ID_OUI_FROM_DATABASE=ComAp s.r.o. + ++OUI:686DBC* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:686E23* + ID_OUI_FROM_DATABASE=Wi3 Inc. + +@@ -56474,18 +65027,69 @@ OUI:686E48* + OUI:687251* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + ++OUI:6872C3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:6872DC* + ID_OUI_FROM_DATABASE=CETORY.TV Company Limited + ++OUI:687627* ++ ID_OUI_FROM_DATABASE=Zhuhai Dingzhi Electronic Technology Co., Ltd ++ + OUI:68764F* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:687848* +- ID_OUI_FROM_DATABASE=Westunitis Co., Ltd. ++ ID_OUI_FROM_DATABASE=WESTUNITIS CO., LTD. + + OUI:68784C* + ID_OUI_FROM_DATABASE=Nortel Networks + ++OUI:6879120* ++ ID_OUI_FROM_DATABASE=PCTEL, Inc. ++ ++OUI:6879121* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:6879122* ++ ID_OUI_FROM_DATABASE=CNDI CO.,LTD ++ ++OUI:6879123* ++ ID_OUI_FROM_DATABASE=Stephan Electronics SARL ++ ++OUI:6879124* ++ ID_OUI_FROM_DATABASE=McDonald's Corporation ++ ++OUI:6879125* ++ ID_OUI_FROM_DATABASE=Copper Labs, Inc. ++ ++OUI:6879126* ++ ID_OUI_FROM_DATABASE=APPOTRONICS CO., LTD ++ ++OUI:6879127* ++ ID_OUI_FROM_DATABASE=Babbit and Friends, SIA ++ ++OUI:6879128* ++ ID_OUI_FROM_DATABASE=ShangHai Aigentoo Information Technology Co., Ltd ++ ++OUI:6879129* ++ ID_OUI_FROM_DATABASE=LEAPS s.r.o. ++ ++OUI:687912A* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co., Ltd. ++ ++OUI:687912B* ++ ID_OUI_FROM_DATABASE=Swisscom Broadcast Ltd ++ ++OUI:687912C* ++ ID_OUI_FROM_DATABASE=Globus Infocom Limited ++ ++OUI:687912D* ++ ID_OUI_FROM_DATABASE=Neurolab ++ ++OUI:687912E* ++ ID_OUI_FROM_DATABASE=Ametek Solidstate Controls ++ + OUI:687924* + ID_OUI_FROM_DATABASE=ELS-GmbH & Co. KG + +@@ -56498,15 +65102,30 @@ OUI:687CC8* + OUI:687CD5* + ID_OUI_FROM_DATABASE=Y Soft Corporation, a.s. + ++OUI:687D6B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:687DB4* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:687F74* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + ++OUI:6881E0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:6882F2* ++ ID_OUI_FROM_DATABASE=grandcentrix GmbH ++ + OUI:68831A* + ID_OUI_FROM_DATABASE=Pandora Mobility Corporation + + OUI:688470* + ID_OUI_FROM_DATABASE=eSSys Co.,Ltd + ++OUI:68847E* ++ ID_OUI_FROM_DATABASE=FUJITSU LIMITED ++ + OUI:688540* + ID_OUI_FROM_DATABASE=IGI Mobile, Inc. + +@@ -56522,6 +65141,12 @@ OUI:6886E7* + OUI:68876B* + ID_OUI_FROM_DATABASE=INQ Mobile Limited + ++OUI:6887C6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:6888A1* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:688975* + ID_OUI_FROM_DATABASE=nuoxc + +@@ -56534,12 +65159,21 @@ OUI:688AB5* + OUI:688AF0* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:688B0F* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:688DB6* + ID_OUI_FROM_DATABASE=AETEK INC. + ++OUI:688F2E* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:688F84* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:688FC9* ++ ID_OUI_FROM_DATABASE=Zhuolian (Shenzhen) Communication Co., Ltd ++ + OUI:6891D00* + ID_OUI_FROM_DATABASE=Central Railway Manufacturing + +@@ -56588,12 +65222,18 @@ OUI:6891D0E* + OUI:689234* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:689320* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:689361* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + + OUI:689423* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:68966A* ++ ID_OUI_FROM_DATABASE=OHSUNG ++ + OUI:68967B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -56609,6 +65249,9 @@ OUI:689861* + OUI:6899CD* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:689A87* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:689AB7* + ID_OUI_FROM_DATABASE=Atelier Vision Corporation + +@@ -56621,12 +65264,21 @@ OUI:689C70* + OUI:689CE2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:689E0B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:689E19* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:689E6A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:689FF0* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:68A03E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:68A0F6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -56642,6 +65294,9 @@ OUI:68A3C4* + OUI:68A40E* + ID_OUI_FROM_DATABASE=BSH Hausgeräte GmbH + ++OUI:68A47D* ++ ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD ++ + OUI:68A682* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + +@@ -56657,18 +65312,27 @@ OUI:68A8E1* + OUI:68AAD2* + ID_OUI_FROM_DATABASE=DATECS LTD., + ++OUI:68AB09* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:68AB1E* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:68AB8A* + ID_OUI_FROM_DATABASE=RF IDeas + ++OUI:68ABBC* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:68AE20* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:68AF13* + ID_OUI_FROM_DATABASE=Futura Mobility + ++OUI:68AFFF* ++ ID_OUI_FROM_DATABASE=Shanghai Cambricon Information Technology Co., Ltd. ++ + OUI:68B094* + ID_OUI_FROM_DATABASE=INESA ELECTRON CO.,LTD + +@@ -56690,12 +65354,18 @@ OUI:68B8D9* + OUI:68B983* + ID_OUI_FROM_DATABASE=b-plus GmbH + ++OUI:68B9D3* ++ ID_OUI_FROM_DATABASE=Shenzhen Trolink Technology CO, LTD ++ + OUI:68BC0C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:68BDAB* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:68BFC4* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:68C44D* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -56735,6 +65405,15 @@ OUI:68D247* + OUI:68D482* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:68D48B* ++ ID_OUI_FROM_DATABASE=Hailo Technologies Ltd. ++ ++OUI:68D6ED* ++ ID_OUI_FROM_DATABASE=GooWi Wireless Technology Co., Limited ++ ++OUI:68D79A* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ + OUI:68D925* + ID_OUI_FROM_DATABASE=ProSys Development Services + +@@ -56745,7 +65424,7 @@ OUI:68DB54* + ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd. + + OUI:68DB67* +- ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd ++ ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd. + + OUI:68DB96* + ID_OUI_FROM_DATABASE=OPWILL Technologies CO .,LTD +@@ -56753,18 +65432,27 @@ OUI:68DB96* + OUI:68DBCA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:68DBF5* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:68DCE8* + ID_OUI_FROM_DATABASE=PacketStorm Communications + + OUI:68DD26* + ID_OUI_FROM_DATABASE=Shanghai Focus Vision Security Technology Co.,Ltd + ++OUI:68DDD9* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:68DFDD* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:68E166* + ID_OUI_FROM_DATABASE=Private + ++OUI:68E209* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:68E41F* + ID_OUI_FROM_DATABASE=Unglaube Identech GmbH + +@@ -56783,6 +65471,9 @@ OUI:68EBC5* + OUI:68EC62* + ID_OUI_FROM_DATABASE=YODO Technology Corp. Ltd. + ++OUI:68EC8A* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:68ECC5* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -56807,9 +65498,15 @@ OUI:68F06D* + OUI:68F0BC* + ID_OUI_FROM_DATABASE=Shenzhen LiWiFi Technology Co., Ltd + ++OUI:68F0D0* ++ ID_OUI_FROM_DATABASE=SkyBell Technologies Inc. ++ + OUI:68F125* + ID_OUI_FROM_DATABASE=Data Controls Inc. + ++OUI:68F38E* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:68F728* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd + +@@ -56834,26 +65531,53 @@ OUI:68FEDA* + OUI:68FEF7* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:68FF7B* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:6C006B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:6C0273* + ID_OUI_FROM_DATABASE=Shenzhen Jin Yun Video Equipment Co., Ltd. + ++OUI:6C02E0* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ ++OUI:6C0309* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6C0460* + ID_OUI_FROM_DATABASE=RBH Access Technologies Inc. + + OUI:6C05D5* + ID_OUI_FROM_DATABASE=Ethertronics Inc + ++OUI:6C06D6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:6C090A* + ID_OUI_FROM_DATABASE=GEMATICA SRL + ++OUI:6C09BF* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:6C09D6* + ID_OUI_FROM_DATABASE=Digiquest Electronics LTD + + OUI:6C0B84* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:6C0D34* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:6C0DC4* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ ++OUI:6C0DE1* ++ ID_OUI_FROM_DATABASE=Dongguan Cannice Precision Manufacturing Co., Ltd. ++ + OUI:6C0E0D* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:6C0EE6* + ID_OUI_FROM_DATABASE=Chengdu Xiyida Electronic Technology Co,.Ltd +@@ -56861,6 +65585,21 @@ OUI:6C0EE6* + OUI:6C0F6A* + ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd. + ++OUI:6C108B* ++ ID_OUI_FROM_DATABASE=WeLink Communications ++ ++OUI:6C11B3* ++ ID_OUI_FROM_DATABASE=Wu Qi Technologies,Inc. ++ ++OUI:6C13D5* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:6C1414* ++ ID_OUI_FROM_DATABASE=BUJEON ELECTRONICS Co,.Ltd ++ ++OUI:6C146E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C14F7* + ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH + +@@ -56870,6 +65609,9 @@ OUI:6C15F9* + OUI:6C160E* + ID_OUI_FROM_DATABASE=ShotTracker + ++OUI:6C1632* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C1811* + ID_OUI_FROM_DATABASE=Decatur Electronics + +@@ -56879,12 +65621,27 @@ OUI:6C198F* + OUI:6C19C0* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:6C1A75* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:6C1B3F* ++ ID_OUI_FROM_DATABASE=MiraeSignal Co., Ltd ++ ++OUI:6C1C71* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ ++OUI:6C1DEB* ++ ID_OUI_FROM_DATABASE=u-blox AG ++ + OUI:6C1E70* + ID_OUI_FROM_DATABASE=Guangzhou YBDS IT Co.,Ltd + + OUI:6C1E90* + ID_OUI_FROM_DATABASE=Hansol Technics Co., Ltd. + ++OUI:6C1ED7* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:6C2056* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -56895,26 +65652,47 @@ OUI:6C22AB* + ID_OUI_FROM_DATABASE=Ainsworth Game Technology + + OUI:6C23B9* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:6C23CB* ++ ID_OUI_FROM_DATABASE=Wattty Corporation + + OUI:6C2483* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + ++OUI:6C24A6* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:6C25B9* + ID_OUI_FROM_DATABASE=BBK EDUCATIONAL ELECTRONICS CORP.,LTD. + ++OUI:6C2636* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C2779* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + ++OUI:6C2990* ++ ID_OUI_FROM_DATABASE=WiZ Connected Lighting Company Limited ++ + OUI:6C2995* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:6C2ACB* + ID_OUI_FROM_DATABASE=Paxton Access Ltd + ++OUI:6C2B59* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:6C2C06* + ID_OUI_FROM_DATABASE=OOO NPP Systemotechnika-NN + ++OUI:6C2CDC* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ ++OUI:6C2D24* ++ ID_OUI_FROM_DATABASE=Zhen Shi Information Technology (Shanghai) Co., Ltd. ++ + OUI:6C2E33* + ID_OUI_FROM_DATABASE=Accelink Technologies Co.,Ltd. + +@@ -56927,15 +65705,27 @@ OUI:6C2E85* + OUI:6C2F2C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:6C2F8A* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:6C310E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6C32DE* + ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd. + + OUI:6C33A9* + ID_OUI_FROM_DATABASE=Magicjack LP + ++OUI:6C3491* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C3838* + ID_OUI_FROM_DATABASE=Marking System Technology Co., Ltd. + ++OUI:6C3845* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:6C38A1* + ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited + +@@ -56964,29 +65754,53 @@ OUI:6C4008* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:6C40C6* +- ID_OUI_FROM_DATABASE=Nimbus Data Systems, Inc. ++ ID_OUI_FROM_DATABASE=Nimbus Data, Inc. ++ ++OUI:6C410E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:6C416A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:6C42AB* ++ ID_OUI_FROM_DATABASE=Subscriber Networks, Inc. ++ ++OUI:6C433C* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:6C4418* + ID_OUI_FROM_DATABASE=Zappware + ++OUI:6C442A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C4598* + ID_OUI_FROM_DATABASE=Antex Electronic Corp. + ++OUI:6C4760* ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd ++ + OUI:6C49C1* + ID_OUI_FROM_DATABASE=o2ones Co., Ltd. + + OUI:6C4A39* + ID_OUI_FROM_DATABASE=BITA + ++OUI:6C4A74* ++ ID_OUI_FROM_DATABASE=AERODISK LLC ++ ++OUI:6C4A85* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:6C4B7F* + ID_OUI_FROM_DATABASE=Vossloh-Schwabe Deutschland GmbH + + OUI:6C4B90* + ID_OUI_FROM_DATABASE=LiteON + ++OUI:6C4D51* ++ ID_OUI_FROM_DATABASE=Shenzhen Ceres Technology Co., Ltd. ++ + OUI:6C4D73* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -56999,6 +65813,12 @@ OUI:6C504D* + OUI:6C54CD* + ID_OUI_FROM_DATABASE=LAMPEX ELECTRONICS LIMITED + ++OUI:6C55E8* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:6C5640* ++ ID_OUI_FROM_DATABASE=BLU Products Inc ++ + OUI:6C5697* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -57014,18 +65834,72 @@ OUI:6C5976* + OUI:6C5A34* + ID_OUI_FROM_DATABASE=Shenzhen Haitianxiong Electronic Co., Ltd. + ++OUI:6C5AB0* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:6C5AB5* + ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd. + + OUI:6C5C14* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:6C5C3D0* ++ ID_OUI_FROM_DATABASE=ShenZhen Hugsun Technology Co.,Ltd. ++ ++OUI:6C5C3D1* ++ ID_OUI_FROM_DATABASE=Shenzhen Justek Technology Co., Ltd ++ ++OUI:6C5C3D2* ++ ID_OUI_FROM_DATABASE=Vertiv Industrial Systems ++ ++OUI:6C5C3D3* ++ ID_OUI_FROM_DATABASE=KWONG MING ELECTRICAL MANUFACTORY LIMITED ++ ++OUI:6C5C3D4* ++ ID_OUI_FROM_DATABASE=HTI Co., LTD. ++ ++OUI:6C5C3D5* ++ ID_OUI_FROM_DATABASE=Unitel Engineering ++ ++OUI:6C5C3D6* ++ ID_OUI_FROM_DATABASE=Hangzhou Netease Yanxuan Trading Co.,Ltd ++ ++OUI:6C5C3D7* ++ ID_OUI_FROM_DATABASE=SOUNDKING ELECTRONICS&SOUND CO., LTD. ++ ++OUI:6C5C3D8* ++ ID_OUI_FROM_DATABASE=GUANGZHOU GUANGRI ELEVATOR INDUSTRY CO.,LTD ++ ++OUI:6C5C3D9* ++ ID_OUI_FROM_DATABASE=IskraUralTEL ++ ++OUI:6C5C3DA* ++ ID_OUI_FROM_DATABASE=krtkl inc. ++ ++OUI:6C5C3DB* ++ ID_OUI_FROM_DATABASE=Reconova Technologies ++ ++OUI:6C5C3DC* ++ ID_OUI_FROM_DATABASE=choyang powertech ++ ++OUI:6C5C3DD* ++ ID_OUI_FROM_DATABASE=Syowatsusinkougyo Co.,Ltd. ++ ++OUI:6C5C3DE* ++ ID_OUI_FROM_DATABASE=Clinton Electronics Corporation ++ + OUI:6C5CDE* + ID_OUI_FROM_DATABASE=SunReports, Inc. + ++OUI:6C5D3A* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:6C5D63* + ID_OUI_FROM_DATABASE=ShenZhen Rapoo Technology Co., Ltd. + ++OUI:6C5E3B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6C5E7A* + ID_OUI_FROM_DATABASE=Ubiquitous Internet Telecom Co., Ltd + +@@ -57038,15 +65912,27 @@ OUI:6C60EB* + OUI:6C6126* + ID_OUI_FROM_DATABASE=Rinicom Holdings + ++OUI:6C61F4* ++ ID_OUI_FROM_DATABASE=SFR ++ + OUI:6C626D* + ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD + ++OUI:6C639C* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:6C641A* + ID_OUI_FROM_DATABASE=Penguin Computing + ++OUI:6C6A77* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:6C6CD3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:6C6D09* ++ ID_OUI_FROM_DATABASE=Kyowa Electronics Co.,Ltd. ++ + OUI:6C6EFE* + ID_OUI_FROM_DATABASE=Core Logic Inc. + +@@ -57059,9 +65945,15 @@ OUI:6C7039* + OUI:6C709F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:6C710D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6C71BD* + ID_OUI_FROM_DATABASE=EZELINK TELECOM + ++OUI:6C71D2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6C71D9* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + +@@ -57074,9 +65966,15 @@ OUI:6C72E7* + OUI:6C750D* + ID_OUI_FROM_DATABASE=WiFiSONG + ++OUI:6C7637* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:6C7660* + ID_OUI_FROM_DATABASE=KYOCERA CORPORATION + ++OUI:6C79B8* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:6C81FE* + ID_OUI_FROM_DATABASE=Mitsuba Corporation + +@@ -57092,9 +65990,15 @@ OUI:6C8686* + OUI:6C8814* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:6C8AEC* ++ ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd. ++ + OUI:6C8B2F* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:6C8BD3* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6C8CDB* + ID_OUI_FROM_DATABASE=Otus Technologies Ltd + +@@ -57110,12 +66014,21 @@ OUI:6C8FB5* + OUI:6C90B1* + ID_OUI_FROM_DATABASE=SanLogic Inc + ++OUI:6C9106* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:6C92BF* + ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd. + + OUI:6C9354* + ID_OUI_FROM_DATABASE=Yaojin Technology (Shenzhen) Co., LTD. + ++OUI:6C9392* ++ ID_OUI_FROM_DATABASE=BEKO Technologies GmbH ++ ++OUI:6C9466* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:6C94F8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -57128,6 +66041,9 @@ OUI:6C96CF* + OUI:6C98EB* + ID_OUI_FROM_DATABASE=Riverbed Technology, Inc. + ++OUI:6C9961* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:6C9989* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -57137,15 +66053,30 @@ OUI:6C9AC9* + OUI:6C9B02* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:6C9BC0* ++ ID_OUI_FROM_DATABASE=Chemoptics Inc. ++ + OUI:6C9CE9* + ID_OUI_FROM_DATABASE=Nimble Storage + + OUI:6C9CED* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:6C9E7C* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:6CA0B4* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:6CA100* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:6CA4D1* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:6CA604* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:6CA682* + ID_OUI_FROM_DATABASE=EDAM information & communications + +@@ -57167,12 +66098,21 @@ OUI:6CA858* + OUI:6CA906* + ID_OUI_FROM_DATABASE=Telefield Ltd + ++OUI:6CA928* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:6CA936* ++ ID_OUI_FROM_DATABASE=DisplayLink (UK) Ltd ++ + OUI:6CA96F* + ID_OUI_FROM_DATABASE=TransPacket AS + + OUI:6CAAB3* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:6CAB05* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:6CAB31* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -57185,6 +66125,9 @@ OUI:6CAC60* + OUI:6CAD3F* + ID_OUI_FROM_DATABASE=Hubbell Building Automation, Inc. + ++OUI:6CADAD* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:6CADEF* + ID_OUI_FROM_DATABASE=KZ Broadband Technologies, Ltd. + +@@ -57194,6 +66137,9 @@ OUI:6CADF8* + OUI:6CAE8B* + ID_OUI_FROM_DATABASE=IBM Corporation + ++OUI:6CAEF6* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:6CAF15* + ID_OUI_FROM_DATABASE=Webasto SE + +@@ -57215,6 +66161,9 @@ OUI:6CB350* + OUI:6CB4A7* + ID_OUI_FROM_DATABASE=Landauer, Inc. + ++OUI:6CB4FD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:6CB56B* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + +@@ -57227,9 +66176,15 @@ OUI:6CB749* + OUI:6CB7F4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:6CB881* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:6CB9C5* + ID_OUI_FROM_DATABASE=Delta Networks, Inc. + ++OUI:6CBAB8* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:6CBEE9* + ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD + +@@ -57254,27 +66209,117 @@ OUI:6CC374* + OUI:6CC4D5* + ID_OUI_FROM_DATABASE=HMD Global Oy + ++OUI:6CC63B* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ ++OUI:6CC7EC* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ + OUI:6CCA08* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:6CCDD6* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ ++OUI:6CCE44* ++ ID_OUI_FROM_DATABASE=1MORE ++ ++OUI:6CCF39* ++ ID_OUI_FROM_DATABASE=Guangdong Starfive Technology Co., Ltd. ++ + OUI:6CD032* + ID_OUI_FROM_DATABASE=LG Electronics + + OUI:6CD146* +- ID_OUI_FROM_DATABASE=Smartek d.o.o. ++ ID_OUI_FROM_DATABASE=FRAMOS GmbH + + OUI:6CD1B0* + ID_OUI_FROM_DATABASE=WING SING ELECTRONICS HONG KONG LIMITED + ++OUI:6CD1E5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:6CD2BA* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:6CD3EE* ++ ID_OUI_FROM_DATABASE=ZIMI CORPORATION ++ ++OUI:6CD630* ++ ID_OUI_FROM_DATABASE=Rootous System Co.,Ltd ++ + OUI:6CD68A* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:6CD704* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:6CD71F* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:6CD94C* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:6CDC6A* + ID_OUI_FROM_DATABASE=Promethean Limited + + OUI:6CDD30* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:6CDDBC* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:6CDDEF* ++ ID_OUI_FROM_DATABASE=EPCOMM Inc. ++ ++OUI:6CDEA9* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ ++OUI:6CDFFB0* ++ ID_OUI_FROM_DATABASE=Shenzhen HDCVT Technology ++ ++OUI:6CDFFB1* ++ ID_OUI_FROM_DATABASE=Chongqing Baoli Yota Technologies Limited ++ ++OUI:6CDFFB2* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:6CDFFB3* ++ ID_OUI_FROM_DATABASE=Beijing Ainemo Co Ltd ++ ++OUI:6CDFFB4* ++ ID_OUI_FROM_DATABASE=Lineable Inc ++ ++OUI:6CDFFB5* ++ ID_OUI_FROM_DATABASE=Greenbird Vertriebs GmbH ++ ++OUI:6CDFFB6* ++ ID_OUI_FROM_DATABASE=AAON ++ ++OUI:6CDFFB7* ++ ID_OUI_FROM_DATABASE=Hashtrend AG ++ ++OUI:6CDFFB8* ++ ID_OUI_FROM_DATABASE=Hardmeier ++ ++OUI:6CDFFB9* ++ ID_OUI_FROM_DATABASE=YongTechs Electric Co. Ltd ++ ++OUI:6CDFFBA* ++ ID_OUI_FROM_DATABASE=Guilin Zhishen Information TechonlogyCO.,Ltd ++ ++OUI:6CDFFBB* ++ ID_OUI_FROM_DATABASE=CELL System Co.,Ltd. ++ ++OUI:6CDFFBC* ++ ID_OUI_FROM_DATABASE=Toucan Systems Ltd ++ ++OUI:6CDFFBD* ++ ID_OUI_FROM_DATABASE=Nanjing Buruike Electronics Technology Co., Ltd. ++ ++OUI:6CDFFBE* ++ ID_OUI_FROM_DATABASE=Beijing Fimi Technology Co., Ltd. ++ + OUI:6CE01E* + ID_OUI_FROM_DATABASE=Modcam AB + +@@ -57290,9 +66335,21 @@ OUI:6CE4CE* + OUI:6CE4DA* + ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. + ++OUI:6CE5F7* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:6CE85C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:6CE873* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:6CE874* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:6CE8C6* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:6CE907* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -57302,6 +66359,9 @@ OUI:6CE983* + OUI:6CEBB2* + ID_OUI_FROM_DATABASE=Dongguan Sen DongLv Electronics Co.,Ltd + ++OUI:6CEBB6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:6CEC5A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. CO.,Ltd. + +@@ -57320,15 +66380,21 @@ OUI:6CEFC6* + OUI:6CF049* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + ++OUI:6CF17E* ++ ID_OUI_FROM_DATABASE=Zhejiang Uniview Technologies Co.,Ltd. ++ + OUI:6CF373* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:6CF37F* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:6CF5E8* + ID_OUI_FROM_DATABASE=Mooredoll Inc. + ++OUI:6CF712* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:6CF97C* + ID_OUI_FROM_DATABASE=Nanoptix Inc. + +@@ -57347,6 +66413,9 @@ OUI:6CFAA7* + OUI:6CFDB9* + ID_OUI_FROM_DATABASE=Proware Technologies Co Ltd. + ++OUI:6CFE54* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:6CFFBE* + ID_OUI_FROM_DATABASE=MPB Communications Inc. + +@@ -57362,15 +66431,27 @@ OUI:700258* + OUI:70037E* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:70039F* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:700433* ++ ID_OUI_FROM_DATABASE=California Things Inc. ++ + OUI:700514* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + + OUI:7006AC* + ID_OUI_FROM_DATABASE=Eastcompeace Technology Co., Ltd + ++OUI:700777* ++ ID_OUI_FROM_DATABASE=OnTarget Technologies, Inc ++ + OUI:700B01* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:700B4F* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:700BC0* + ID_OUI_FROM_DATABASE=Dewav Technology Company + +@@ -57407,12 +66488,24 @@ OUI:70169F* + OUI:70188B* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:7018A7* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:70192F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:701A04* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:701AD5* ++ ID_OUI_FROM_DATABASE=Openpath Security, Inc. ++ + OUI:701AED* + ID_OUI_FROM_DATABASE=ADVAS CO., LTD. + ++OUI:701BFB* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:701CE7* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -57425,6 +66518,15 @@ OUI:701D7F* + OUI:701DC4* + ID_OUI_FROM_DATABASE=NorthStar Battery Company, LLC + ++OUI:701E68* ++ ID_OUI_FROM_DATABASE=Hanna Instruments, Inc. ++ ++OUI:701F0B* ++ ID_OUI_FROM_DATABASE=WILOGY SRL ++ ++OUI:701F3C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:701F53* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -57458,6 +66560,9 @@ OUI:702AD5* + OUI:702B1D* + ID_OUI_FROM_DATABASE=E-Domus International Limited + ++OUI:702C09* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:702C1F* + ID_OUI_FROM_DATABASE=Wisol + +@@ -57470,8 +66575,17 @@ OUI:702DD1* + OUI:702E22* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:702E80* ++ ID_OUI_FROM_DATABASE=DIEHL Connectivity Solutions ++ ++OUI:702ED9* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronics Co., Ltd. ++ ++OUI:702F35* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:702F4B* +- ID_OUI_FROM_DATABASE=PolyVision Inc. ++ ID_OUI_FROM_DATABASE=Steelcase Inc. + + OUI:702F97* + ID_OUI_FROM_DATABASE=Aava Mobile Oy +@@ -57491,8 +66605,11 @@ OUI:703187* + OUI:7032D5* + ID_OUI_FROM_DATABASE=Athena Wireless Communications Inc + ++OUI:703509* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:703811* +- ID_OUI_FROM_DATABASE=Invensys Rail ++ ID_OUI_FROM_DATABASE=Siemens Mobility Limited + + OUI:7038B4* + ID_OUI_FROM_DATABASE=Low Tech Solutions +@@ -57501,11 +66618,20 @@ OUI:7038EE* + ID_OUI_FROM_DATABASE=Avaya Inc + + OUI:703A0E* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:703A2D* ++ ID_OUI_FROM_DATABASE=Shenzhen V-Link Technology CO., LTD. ++ ++OUI:703A51* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:703A73* + ID_OUI_FROM_DATABASE=Shenzhen Sundray Technologies Company Limited + ++OUI:703AA6* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:703ACB* + ID_OUI_FROM_DATABASE=Google, Inc. + +@@ -57518,15 +66644,27 @@ OUI:703C03* + OUI:703C39* + ID_OUI_FROM_DATABASE=SEAWING Kft + ++OUI:703C69* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:703D15* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:703E97* ++ ID_OUI_FROM_DATABASE=Iton Technology Corp. ++ + OUI:703EAC* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:7040FF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:7041B7* + ID_OUI_FROM_DATABASE=Edwards Lifesciences LLC + ++OUI:70441C* ++ ID_OUI_FROM_DATABASE=SHENZHEN KAIFA TECHNOLOGY CO.,LTD. ++ + OUI:704642* + ID_OUI_FROM_DATABASE=CHYNG HONG ELECTRONIC CO., LTD. + +@@ -57536,6 +66674,12 @@ OUI:7047E9* + OUI:70480F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:7048F7* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:704A0E* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:704AAE* + ID_OUI_FROM_DATABASE=Xstream Flow (Pty) Ltd + +@@ -57575,6 +66719,9 @@ OUI:7052C5* + OUI:70533F* + ID_OUI_FROM_DATABASE=Alfa Instrumentos Eletronicos Ltda. + ++OUI:705425* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:7054B4* + ID_OUI_FROM_DATABASE=Vestel Elektronik San ve Tic. A.Ş. + +@@ -57590,6 +66737,9 @@ OUI:7055F8* + OUI:705681* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:7057BF* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:705812* + ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company + +@@ -57620,15 +66770,33 @@ OUI:705B2E* + OUI:705CAD* + ID_OUI_FROM_DATABASE=Konami Gaming Inc + ++OUI:705DCC* ++ ID_OUI_FROM_DATABASE=EFM Networks ++ ++OUI:705E55* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ + OUI:705EAA* + ID_OUI_FROM_DATABASE=Action Target, Inc. + ++OUI:705FA3* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:7060DE* + ID_OUI_FROM_DATABASE=LaVision GmbH + + OUI:706173* + ID_OUI_FROM_DATABASE=Calantec GmbH + ++OUI:70617B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:7061BE* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ ++OUI:7061EE* ++ ID_OUI_FROM_DATABASE=Sunwoda Electronic Co.,Ltd ++ + OUI:7062B8* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -57644,15 +66812,69 @@ OUI:7065A3* + OUI:70661B* + ID_OUI_FROM_DATABASE=Sonova AG + ++OUI:706655* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ ++OUI:7066E1* ++ ID_OUI_FROM_DATABASE=dnt Innovation GmbH ++ + OUI:706879* + ID_OUI_FROM_DATABASE=Saijo Denki International Co., Ltd. + + OUI:70695A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:7069790* ++ ID_OUI_FROM_DATABASE=Full Solution Telecom ++ ++OUI:7069791* ++ ID_OUI_FROM_DATABASE=Linksys Telecom Shenzhen CO., LTD ++ ++OUI:7069792* ++ ID_OUI_FROM_DATABASE=Graphcore Ltd ++ ++OUI:7069793* ++ ID_OUI_FROM_DATABASE=Hebei Baina Xinda Technology Co., Ltd. ++ ++OUI:7069794* ++ ID_OUI_FROM_DATABASE=SelectTech GeoSpatial, LLC ++ ++OUI:7069795* ++ ID_OUI_FROM_DATABASE=Ibyte ++ ++OUI:7069796* ++ ID_OUI_FROM_DATABASE=Beijing Security Union Information Technology Co.,Ltd ++ ++OUI:7069797* ++ ID_OUI_FROM_DATABASE=Intelitech SIA ++ ++OUI:7069798* ++ ID_OUI_FROM_DATABASE=An Phat Information Technology Co., Ltd ++ ++OUI:7069799* ++ ID_OUI_FROM_DATABASE=Faurecia Clarion Electronics (Dongguan) Co., Ltd ++ ++OUI:706979A* ++ ID_OUI_FROM_DATABASE=Foxconn Brasil Industria e Comercio Ltda ++ ++OUI:706979B* ++ ID_OUI_FROM_DATABASE=Liquid Instruments Pty Ltd ++ ++OUI:706979C* ++ ID_OUI_FROM_DATABASE=Rivian Automotive LLC ++ ++OUI:706979D* ++ ID_OUI_FROM_DATABASE=FREUND ELEKTRONIKA D.O.O., IP-INTEGRA TECHNOLOGIES ++ ++OUI:706979E* ++ ID_OUI_FROM_DATABASE=BAS-IP LP ++ + OUI:706BB9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:706D15* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:706DEC* + ID_OUI_FROM_DATABASE=Wifi-soft LLC + +@@ -57689,11 +66911,14 @@ OUI:7072CF* + OUI:7073CB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:707414* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:707630* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:7076DD* +- ID_OUI_FROM_DATABASE=Oxyguard International A/S ++ ID_OUI_FROM_DATABASE=OxyGuard Internation A/S + + OUI:7076F0* + ID_OUI_FROM_DATABASE=LevelOne Communications (India) Private Limited +@@ -57749,6 +66974,9 @@ OUI:70820E* + OUI:70828E* + ID_OUI_FROM_DATABASE=OleumTech Corporation + ++OUI:708540* ++ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd ++ + OUI:7085C2* + ID_OUI_FROM_DATABASE=ASRock Incorporation + +@@ -57758,6 +66986,12 @@ OUI:7085C6* + OUI:7086C1* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:7086CE* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:70879E* ++ ID_OUI_FROM_DATABASE=Beken Corporation ++ + OUI:70884D* + ID_OUI_FROM_DATABASE=JAPAN RADIO CO., LTD. + +@@ -57794,6 +67028,9 @@ OUI:70886BB* + OUI:70886BC* + ID_OUI_FROM_DATABASE=MAX4G, Inc. + ++OUI:708976* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:7089CC* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + +@@ -57806,9 +67043,21 @@ OUI:708B78* + OUI:708BCD* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:708CB6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:708CBB* ++ ID_OUI_FROM_DATABASE=MIMODISPLAYKOREA ++ + OUI:708D09* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:708F47* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:7090B7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:70918F* + ID_OUI_FROM_DATABASE=Weber-Stephen Products LLC + +@@ -57821,6 +67070,9 @@ OUI:709383* + OUI:7093F8* + ID_OUI_FROM_DATABASE=Space Monkey, Inc. + ++OUI:709741* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:709756* + ID_OUI_FROM_DATABASE=Happyelectronics Co.,Ltd + +@@ -57839,6 +67091,9 @@ OUI:709BFC* + OUI:709C8F* + ID_OUI_FROM_DATABASE=Nero AG + ++OUI:709CD1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:709E29* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + +@@ -57860,9 +67115,15 @@ OUI:70A2B3* + OUI:70A41C* + ID_OUI_FROM_DATABASE=Advanced Wireless Dynamics S.L. + ++OUI:70A56A* ++ ID_OUI_FROM_DATABASE=Shenzhen C-Data Technology Co., Ltd. ++ + OUI:70A66A* + ID_OUI_FROM_DATABASE=Prox Dynamics AS + ++OUI:70A6CC* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:70A84C* + ID_OUI_FROM_DATABASE=MONAD., Inc. + +@@ -57872,6 +67133,9 @@ OUI:70A8E3* + OUI:70AAB2* + ID_OUI_FROM_DATABASE=BlackBerry RTS + ++OUI:70ACD7* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:70AD54* + ID_OUI_FROM_DATABASE=Malvern Instruments Ltd + +@@ -57890,33 +67154,63 @@ OUI:70B035* + OUI:70B08C* + ID_OUI_FROM_DATABASE=Shenou Communication Equipment Co.,Ltd + ++OUI:70B13D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:70B14E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:70B265* + ID_OUI_FROM_DATABASE=Hiltron s.r.l. + ++OUI:70B317* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:70B3D5001* + ID_OUI_FROM_DATABASE=SOREDI touch systems GmbH + + OUI:70B3D5002* + ID_OUI_FROM_DATABASE=Gogo BA + ++OUI:70B3D5003* ++ ID_OUI_FROM_DATABASE=ANYROAM ++ ++OUI:70B3D5004* ++ ID_OUI_FROM_DATABASE=LEIDOS ++ ++OUI:70B3D5005* ++ ID_OUI_FROM_DATABASE=CT Company ++ ++OUI:70B3D5006* ++ ID_OUI_FROM_DATABASE=Piranha EMS Inc. ++ + OUI:70B3D5007* + ID_OUI_FROM_DATABASE=SENSONEO + ++OUI:70B3D5008* ++ ID_OUI_FROM_DATABASE=ESYSE GmbH Embedded Systems Engineering ++ + OUI:70B3D5009* + ID_OUI_FROM_DATABASE=HolidayCoro + + OUI:70B3D500A* + ID_OUI_FROM_DATABASE=FUJICOM Co.,Ltd. + ++OUI:70B3D500B* ++ ID_OUI_FROM_DATABASE=AXING AG ++ ++OUI:70B3D500C* ++ ID_OUI_FROM_DATABASE=EXARA Group ++ + OUI:70B3D500D* + ID_OUI_FROM_DATABASE=Scrona AG + + OUI:70B3D500E* + ID_OUI_FROM_DATABASE=Magosys Systems LTD + ++OUI:70B3D500F* ++ ID_OUI_FROM_DATABASE=Neusoft Reach Automotive Technology (Shenyang) Co.,Ltd ++ + OUI:70B3D5010* + ID_OUI_FROM_DATABASE=Hanwa Electronic Ind.Co.,Ltd. + +@@ -57926,6 +67220,9 @@ OUI:70B3D5011* + OUI:70B3D5012* + ID_OUI_FROM_DATABASE=KST technology + ++OUI:70B3D5013* ++ ID_OUI_FROM_DATABASE=Sportsbeams Lighting, Inc. ++ + OUI:70B3D5014* + ID_OUI_FROM_DATABASE=FRAKO Kondensatoren und Anlagenbau GmbH + +@@ -57935,9 +67232,21 @@ OUI:70B3D5015* + OUI:70B3D5016* + ID_OUI_FROM_DATABASE=Guardian Controls International Ltd + ++OUI:70B3D5017* ++ ID_OUI_FROM_DATABASE=FTG Corporation ++ ++OUI:70B3D5018* ++ ID_OUI_FROM_DATABASE=DELITECH GROUP ++ ++OUI:70B3D5019* ++ ID_OUI_FROM_DATABASE=Transit Solutions, LLC. ++ + OUI:70B3D501A* + ID_OUI_FROM_DATABASE=Cubro Acronet GesmbH + ++OUI:70B3D501B* ++ ID_OUI_FROM_DATABASE=AUDI AG ++ + OUI:70B3D501C* + ID_OUI_FROM_DATABASE=Kumu Networks + +@@ -57950,6 +67259,12 @@ OUI:70B3D501E* + OUI:70B3D501F* + ID_OUI_FROM_DATABASE=SPX Flow Technology BV + ++OUI:70B3D5020* ++ ID_OUI_FROM_DATABASE=MICRO DEBUG, Y.K. ++ ++OUI:70B3D5021* ++ ID_OUI_FROM_DATABASE=HGL Dynamics Ltd ++ + OUI:70B3D5022* + ID_OUI_FROM_DATABASE=Ravelin Ltd + +@@ -57977,6 +67292,12 @@ OUI:70B3D5029* + OUI:70B3D502A* + ID_OUI_FROM_DATABASE=BAE Systems Surface Ships Limited + ++OUI:70B3D502B* ++ ID_OUI_FROM_DATABASE=Scorpion Precision Industry (HK)CO. Ltd. ++ ++OUI:70B3D502C* ++ ID_OUI_FROM_DATABASE=Iylus Inc. ++ + OUI:70B3D502D* + ID_OUI_FROM_DATABASE=NEXTtec srl + +@@ -57998,15 +67319,27 @@ OUI:70B3D5032* + OUI:70B3D5033* + ID_OUI_FROM_DATABASE=Sailmon BV + ++OUI:70B3D5034* ++ ID_OUI_FROM_DATABASE=Digital Systems Engineering ++ + OUI:70B3D5035* + ID_OUI_FROM_DATABASE=HKW-Elektronik GmbH + ++OUI:70B3D5036* ++ ID_OUI_FROM_DATABASE=Vema Venturi AB ++ + OUI:70B3D5037* + ID_OUI_FROM_DATABASE=EIFFAGE ENERGIE ELECTRONIQUE + ++OUI:70B3D5038* ++ ID_OUI_FROM_DATABASE=DONG IL VISION Co., Ltd. ++ + OUI:70B3D5039* + ID_OUI_FROM_DATABASE=DoWoo Digitech + ++OUI:70B3D503A* ++ ID_OUI_FROM_DATABASE=Ochno AB ++ + OUI:70B3D503B* + ID_OUI_FROM_DATABASE=SSL - Electrical Aerospace Ground Equipment Section + +@@ -58016,6 +67349,9 @@ OUI:70B3D503C* + OUI:70B3D503D* + ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. + ++OUI:70B3D503E* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ + OUI:70B3D503F* + ID_OUI_FROM_DATABASE=Elesar Limited + +@@ -58028,12 +67364,24 @@ OUI:70B3D5041* + OUI:70B3D5042* + ID_OUI_FROM_DATABASE=Coveloz Technologies Inc. + ++OUI:70B3D5043* ++ ID_OUI_FROM_DATABASE=cal4care Pte Ltd ++ + OUI:70B3D5044* + ID_OUI_FROM_DATABASE=Don Electronics Ltd + ++OUI:70B3D5045* ++ ID_OUI_FROM_DATABASE=Navaero Avionics AB ++ + OUI:70B3D5046* + ID_OUI_FROM_DATABASE=Shenzhen Rihuida Electronics Co,. Ltd + ++OUI:70B3D5047* ++ ID_OUI_FROM_DATABASE=OOO ORION-R ++ ++OUI:70B3D5048* ++ ID_OUI_FROM_DATABASE=AvMap srlu ++ + OUI:70B3D5049* + ID_OUI_FROM_DATABASE=APP Engineering, Inc. + +@@ -58052,15 +67400,33 @@ OUI:70B3D504D* + OUI:70B3D504E* + ID_OUI_FROM_DATABASE=HUGEL GmbH + ++OUI:70B3D504F* ++ ID_OUI_FROM_DATABASE=EVPU Defence a.s. ++ + OUI:70B3D5050* + ID_OUI_FROM_DATABASE=Compusign Systems Pty Ltd + ++OUI:70B3D5051* ++ ID_OUI_FROM_DATABASE=JT ++ + OUI:70B3D5052* + ID_OUI_FROM_DATABASE=Sudo Premium Engineering + ++OUI:70B3D5053* ++ ID_OUI_FROM_DATABASE=YAMAKATSU ELECTRONICS INDUSTRY CO., LTD. ++ + OUI:70B3D5054* + ID_OUI_FROM_DATABASE=Groupeer Technologies + ++OUI:70B3D5055* ++ ID_OUI_FROM_DATABASE=BAE SYSTEMS ++ ++OUI:70B3D5056* ++ ID_OUI_FROM_DATABASE=MIRAE INFORMATION TECHNOLOGY CO., LTD. ++ ++OUI:70B3D5057* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ + OUI:70B3D5058* + ID_OUI_FROM_DATABASE=Telink Semiconductor CO, Limtied, Taiwan + +@@ -58070,6 +67436,12 @@ OUI:70B3D5059* + OUI:70B3D505A* + ID_OUI_FROM_DATABASE=Uni Control System Sp. z o. o. + ++OUI:70B3D505B* ++ ID_OUI_FROM_DATABASE=PAL Inc. ++ ++OUI:70B3D505C* ++ ID_OUI_FROM_DATABASE=Amber Kinetics Inc ++ + OUI:70B3D505D* + ID_OUI_FROM_DATABASE=KOMS Co.,Ltd. + +@@ -58079,6 +67451,9 @@ OUI:70B3D505E* + OUI:70B3D505F* + ID_OUI_FROM_DATABASE=UNISOR MULTISYSTEMS LTD + ++OUI:70B3D5060* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ + OUI:70B3D5061* + ID_OUI_FROM_DATABASE=IntelliDesign Pty Ltd + +@@ -58088,30 +67463,63 @@ OUI:70B3D5062* + OUI:70B3D5063* + ID_OUI_FROM_DATABASE=PoolDigital GmbH & Co. KG + ++OUI:70B3D5064* ++ ID_OUI_FROM_DATABASE=AB PRECISION (POOLE) LTD ++ ++OUI:70B3D5065* ++ ID_OUI_FROM_DATABASE=EXATEL ++ + OUI:70B3D5066* + ID_OUI_FROM_DATABASE=North Pole Engineering, Inc. + ++OUI:70B3D5067* ++ ID_OUI_FROM_DATABASE=NEOPATH INTEGRATED SYSTEMS LTDA ++ ++OUI:70B3D5068* ++ ID_OUI_FROM_DATABASE=Onethinx BV ++ + OUI:70B3D5069* + ID_OUI_FROM_DATABASE=ONDEMAND LABORATORY Co., Ltd. + ++OUI:70B3D506A* ++ ID_OUI_FROM_DATABASE=Guangdong Centnet Technology Co.,Ltd ++ + OUI:70B3D506B* + ID_OUI_FROM_DATABASE=U-Tech + + OUI:70B3D506C* + ID_OUI_FROM_DATABASE=AppTek + ++OUI:70B3D506D* ++ ID_OUI_FROM_DATABASE=Panoramic Power ++ ++OUI:70B3D506E* ++ ID_OUI_FROM_DATABASE=GLOBAL-KING INTERNATIONAL CO., LTD. ++ + OUI:70B3D506F* + ID_OUI_FROM_DATABASE=Beijing Daswell Science and Technology Co.LTD + + OUI:70B3D5070* + ID_OUI_FROM_DATABASE=Lumiplan Duhamel + ++OUI:70B3D5071* ++ ID_OUI_FROM_DATABASE=FSR, INC. ++ ++OUI:70B3D5072* ++ ID_OUI_FROM_DATABASE=Lightdrop ++ + OUI:70B3D5073* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:70B3D5074* ++ ID_OUI_FROM_DATABASE=Orlaco Products B.V. ++ + OUI:70B3D5075* + ID_OUI_FROM_DATABASE=Mo-Sys Engineering Ltd + ++OUI:70B3D5076* ++ ID_OUI_FROM_DATABASE=Private Enterprise Scientific and Production Private EnterpriseSparing-Vist Center ++ + OUI:70B3D5077* + ID_OUI_FROM_DATABASE=InAccess Networks SA + +@@ -58127,6 +67535,9 @@ OUI:70B3D507A* + OUI:70B3D507B* + ID_OUI_FROM_DATABASE=wallbe GmbH + ++OUI:70B3D507C* ++ ID_OUI_FROM_DATABASE=ISAC SRL ++ + OUI:70B3D507D* + ID_OUI_FROM_DATABASE=PANORAMIC POWER + +@@ -58136,9 +67547,15 @@ OUI:70B3D507E* + OUI:70B3D507F* + ID_OUI_FROM_DATABASE=Abalance Corporation + ++OUI:70B3D5080* ++ ID_OUI_FROM_DATABASE=ABB ++ + OUI:70B3D5081* + ID_OUI_FROM_DATABASE=IST Technologies (SHENZHEN) Limited + ++OUI:70B3D5082* ++ ID_OUI_FROM_DATABASE=Sakura Seiki Co.,Ltd. ++ + OUI:70B3D5083* + ID_OUI_FROM_DATABASE=ZAO ZEO + +@@ -58157,9 +67574,18 @@ OUI:70B3D5087* + OUI:70B3D5088* + ID_OUI_FROM_DATABASE=OptiScan Biomedical Corp. + ++OUI:70B3D5089* ++ ID_OUI_FROM_DATABASE=Kazdream Technologies LLP ++ + OUI:70B3D508A* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D508B* ++ ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau AG ++ ++OUI:70B3D508C* ++ ID_OUI_FROM_DATABASE=Airmar Technology Corp ++ + OUI:70B3D508D* + ID_OUI_FROM_DATABASE=Clover Electronics Technology Co., Ltd. + +@@ -58178,15 +67604,24 @@ OUI:70B3D5091* + OUI:70B3D5092* + ID_OUI_FROM_DATABASE=inomed Medizintechnik GmbH + ++OUI:70B3D5093* ++ ID_OUI_FROM_DATABASE=Legrand Electric Ltd ++ + OUI:70B3D5094* + ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd + ++OUI:70B3D5095* ++ ID_OUI_FROM_DATABASE=plc-tec AG ++ + OUI:70B3D5096* + ID_OUI_FROM_DATABASE=HAVELSAN A.Ş. + + OUI:70B3D5097* + ID_OUI_FROM_DATABASE=Avant Technologies + ++OUI:70B3D5098* ++ ID_OUI_FROM_DATABASE=Alcodex Technologies Private Limited ++ + OUI:70B3D5099* + ID_OUI_FROM_DATABASE=Schwer+Kopka GmbH + +@@ -58196,8 +67631,11 @@ OUI:70B3D509A* + OUI:70B3D509B* + ID_OUI_FROM_DATABASE=Jacarta Ltd + ++OUI:70B3D509C* ++ ID_OUI_FROM_DATABASE=Cardinal Kinetic ++ + OUI:70B3D509D* +- ID_OUI_FROM_DATABASE=P&S GmbH ++ ID_OUI_FROM_DATABASE=PuS GmbH und Co. KG + + OUI:70B3D509E* + ID_OUI_FROM_DATABASE=MobiPromo +@@ -58226,6 +67664,9 @@ OUI:70B3D50A5* + OUI:70B3D50A6* + ID_OUI_FROM_DATABASE=PA CONSULTING SERVICES + ++OUI:70B3D50A7* ++ ID_OUI_FROM_DATABASE=Traffic and Parking Control Co, Inc. ++ + OUI:70B3D50A8* + ID_OUI_FROM_DATABASE=Symetrics Industries d.b.a. Extant Aerospace + +@@ -58241,6 +67682,9 @@ OUI:70B3D50AB* + OUI:70B3D50AC* + ID_OUI_FROM_DATABASE=RoboCore Tecnologia + ++OUI:70B3D50AD* ++ ID_OUI_FROM_DATABASE=Vega-Absolute ++ + OUI:70B3D50AE* + ID_OUI_FROM_DATABASE=Norsat International Inc. + +@@ -58250,6 +67694,9 @@ OUI:70B3D50AF* + OUI:70B3D50B0* + ID_OUI_FROM_DATABASE=Raven Systems Design, Inc + ++OUI:70B3D50B1* ++ ID_OUI_FROM_DATABASE=AirBie AG ++ + OUI:70B3D50B2* + ID_OUI_FROM_DATABASE=ndb technologies + +@@ -58259,9 +67706,15 @@ OUI:70B3D50B3* + OUI:70B3D50B4* + ID_OUI_FROM_DATABASE=AVER + ++OUI:70B3D50B5* ++ ID_OUI_FROM_DATABASE=Capgemini Netherlands ++ + OUI:70B3D50B6* + ID_OUI_FROM_DATABASE=Landis Gyr + ++OUI:70B3D50B7* ++ ID_OUI_FROM_DATABASE=HAI ROBOTICS Co., Ltd. ++ + OUI:70B3D50B8* + ID_OUI_FROM_DATABASE=Lucas-Nülle GmbH + +@@ -58271,6 +67724,9 @@ OUI:70B3D50B9* + OUI:70B3D50BA* + ID_OUI_FROM_DATABASE=Ayre Acoustics, Inc. + ++OUI:70B3D50BB* ++ ID_OUI_FROM_DATABASE=AnaPico AG ++ + OUI:70B3D50BC* + ID_OUI_FROM_DATABASE=Practical Software Studio LLC + +@@ -58292,6 +67748,9 @@ OUI:70B3D50C1* + OUI:70B3D50C2* + ID_OUI_FROM_DATABASE=LOOK EASY INTERNATIONAL LIMITED + ++OUI:70B3D50C3* ++ ID_OUI_FROM_DATABASE=Aug. Winkhaus GmbH & Co. KG ++ + OUI:70B3D50C4* + ID_OUI_FROM_DATABASE=TIAMA + +@@ -58301,18 +67760,36 @@ OUI:70B3D50C5* + OUI:70B3D50C6* + ID_OUI_FROM_DATABASE=Embedded Arts Co., Ltd. + ++OUI:70B3D50C7* ++ ID_OUI_FROM_DATABASE=PEEK TRAFFIC ++ + OUI:70B3D50C8* + ID_OUI_FROM_DATABASE=Fin Robotics Inc + + OUI:70B3D50C9* + ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., + ++OUI:70B3D50CA* ++ ID_OUI_FROM_DATABASE=VITEC ++ ++OUI:70B3D50CB* ++ ID_OUI_FROM_DATABASE=NIRECO CORPORATION ++ ++OUI:70B3D50CC* ++ ID_OUI_FROM_DATABASE=ADMiTAS CCTV Taiwan Co. Ltd ++ + OUI:70B3D50CD* + ID_OUI_FROM_DATABASE=AML Oceanographic + + OUI:70B3D50CE* + ID_OUI_FROM_DATABASE=Innominds Software Inc + ++OUI:70B3D50CF* ++ ID_OUI_FROM_DATABASE=sohonet ltd ++ ++OUI:70B3D50D0* ++ ID_OUI_FROM_DATABASE=ProHound Controles Eirelli ++ + OUI:70B3D50D1* + ID_OUI_FROM_DATABASE=Common Sense Monitoring Solutions Ltd. + +@@ -58325,6 +67802,9 @@ OUI:70B3D50D3* + OUI:70B3D50D4* + ID_OUI_FROM_DATABASE=Guangzhou Male Industrial Animation Technology Co.,Ltd. + ++OUI:70B3D50D5* ++ ID_OUI_FROM_DATABASE=Kahler Automation ++ + OUI:70B3D50D6* + ID_OUI_FROM_DATABASE=TATTILE SRL + +@@ -58340,9 +67820,15 @@ OUI:70B3D50D9* + OUI:70B3D50DA* + ID_OUI_FROM_DATABASE=Aquavision Distribution Ltd + ++OUI:70B3D50DB* ++ ID_OUI_FROM_DATABASE=Cryptotronix LLC ++ + OUI:70B3D50DC* + ID_OUI_FROM_DATABASE=Talleres de Escoriaza + ++OUI:70B3D50DD* ++ ID_OUI_FROM_DATABASE=Shenzhen Virtual Clusters Information Technology Co.,Ltd. ++ + OUI:70B3D50DE* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +@@ -58355,21 +67841,42 @@ OUI:70B3D50E0* + OUI:70B3D50E1* + ID_OUI_FROM_DATABASE=MiWave Consulting, LLC + ++OUI:70B3D50E2* ++ ID_OUI_FROM_DATABASE=JESE Ltd ++ + OUI:70B3D50E3* + ID_OUI_FROM_DATABASE=SinTau SrL + ++OUI:70B3D50E4* ++ ID_OUI_FROM_DATABASE=Walter Müller AG ++ + OUI:70B3D50E5* + ID_OUI_FROM_DATABASE=Delta Solutions LLC + + OUI:70B3D50E6* + ID_OUI_FROM_DATABASE=Nasdaq + ++OUI:70B3D50E7* ++ ID_OUI_FROM_DATABASE=Pure Air Filtration ++ + OUI:70B3D50E8* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + ++OUI:70B3D50E9* ++ ID_OUI_FROM_DATABASE=VNT electronics s.r.o. ++ ++OUI:70B3D50EA* ++ ID_OUI_FROM_DATABASE=AEV Broadcast Srl ++ ++OUI:70B3D50EB* ++ ID_OUI_FROM_DATABASE=Tomahawk Robotics ++ + OUI:70B3D50EC* + ID_OUI_FROM_DATABASE=ACS MOTION CONTROL + ++OUI:70B3D50ED* ++ ID_OUI_FROM_DATABASE=Lupa Tecnologia e Sistemas Ltda ++ + OUI:70B3D50EE* + ID_OUI_FROM_DATABASE=Picture Elements, Inc. + +@@ -58382,15 +67889,30 @@ OUI:70B3D50F0* + OUI:70B3D50F1* + ID_OUI_FROM_DATABASE=Beijing One City Science & Technology Co., LTD + ++OUI:70B3D50F2* ++ ID_OUI_FROM_DATABASE=TrexEdge, Inc. ++ + OUI:70B3D50F3* + ID_OUI_FROM_DATABASE=MonsoonRF, Inc. + ++OUI:70B3D50F4* ++ ID_OUI_FROM_DATABASE=Visual Robotics ++ ++OUI:70B3D50F5* ++ ID_OUI_FROM_DATABASE=Season Electronics Ltd ++ ++OUI:70B3D50F6* ++ ID_OUI_FROM_DATABASE=KSE GmbH ++ + OUI:70B3D50F7* + ID_OUI_FROM_DATABASE=Bespoon + + OUI:70B3D50F8* + ID_OUI_FROM_DATABASE=Special Services Group, LLC + ++OUI:70B3D50F9* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ + OUI:70B3D50FA* + ID_OUI_FROM_DATABASE=InsideRF Co., Ltd. + +@@ -58400,6 +67922,9 @@ OUI:70B3D50FB* + OUI:70B3D50FC* + ID_OUI_FROM_DATABASE=vitalcare + ++OUI:70B3D50FD* ++ ID_OUI_FROM_DATABASE=JSC Ural Factories ++ + OUI:70B3D50FE* + ID_OUI_FROM_DATABASE=Vocality International Ltd + +@@ -58409,6 +67934,12 @@ OUI:70B3D50FF* + OUI:70B3D5100* + ID_OUI_FROM_DATABASE=Gupsy GmbH + ++OUI:70B3D5101* ++ ID_OUI_FROM_DATABASE=Adolf Nissen Elektrobau GmbH + Co. KG ++ ++OUI:70B3D5102* ++ ID_OUI_FROM_DATABASE=Oxford Monitoring Solutions Ltd ++ + OUI:70B3D5103* + ID_OUI_FROM_DATABASE=HANYOUNG NUX CO.,LTD + +@@ -58421,6 +67952,9 @@ OUI:70B3D5105* + OUI:70B3D5106* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D5107* ++ ID_OUI_FROM_DATABASE=OOO Alyans ++ + OUI:70B3D5108* + ID_OUI_FROM_DATABASE=TEX COMPUTER SRL + +@@ -58430,27 +67964,54 @@ OUI:70B3D5109* + OUI:70B3D510A* + ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY + ++OUI:70B3D510B* ++ ID_OUI_FROM_DATABASE=SECUREAN CO.,Ltd ++ + OUI:70B3D510C* + ID_OUI_FROM_DATABASE=Vocality International Ltd + ++OUI:70B3D510D* ++ ID_OUI_FROM_DATABASE=CoreEL Technologies Pvt Ltd ++ + OUI:70B3D510E* + ID_OUI_FROM_DATABASE=Colorimetry Research, Inc + + OUI:70B3D510F* + ID_OUI_FROM_DATABASE=neQis + ++OUI:70B3D5110* ++ ID_OUI_FROM_DATABASE=Orion Power Systems, Inc. ++ ++OUI:70B3D5111* ++ ID_OUI_FROM_DATABASE=Leonardo Sistemi Integrati S.r.l. ++ + OUI:70B3D5112* + ID_OUI_FROM_DATABASE=DiTEST Fahrzeugdiagnose GmbH + ++OUI:70B3D5113* ++ ID_OUI_FROM_DATABASE=iREA System Industry ++ + OUI:70B3D5114* + ID_OUI_FROM_DATABASE=Project H Pty Ltd + + OUI:70B3D5115* + ID_OUI_FROM_DATABASE=Welltec Corp. + ++OUI:70B3D5116* ++ ID_OUI_FROM_DATABASE=Momentum Data Systems ++ ++OUI:70B3D5117* ++ ID_OUI_FROM_DATABASE=SysCom Automationstechnik GmbH ++ ++OUI:70B3D5118* ++ ID_OUI_FROM_DATABASE=Macromatic Industrial Controls, Inc. ++ + OUI:70B3D5119* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D511A* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:70B3D511B* + ID_OUI_FROM_DATABASE=HoseoTelnet Inc... + +@@ -58460,12 +68021,18 @@ OUI:70B3D511C* + OUI:70B3D511D* + ID_OUI_FROM_DATABASE=Dakton Microlabs LLC + ++OUI:70B3D511E* ++ ID_OUI_FROM_DATABASE=KBPR LLC ++ + OUI:70B3D511F* + ID_OUI_FROM_DATABASE=Geppetto Electronics + + OUI:70B3D5120* + ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH + ++OUI:70B3D5121* ++ ID_OUI_FROM_DATABASE=Shenzhen Luxurite Smart Home Ltd ++ + OUI:70B3D5122* + ID_OUI_FROM_DATABASE=Henri Systems Holland bv + +@@ -58478,24 +68045,39 @@ OUI:70B3D5124* + OUI:70B3D5125* + ID_OUI_FROM_DATABASE=Securolytics, Inc. + ++OUI:70B3D5126* ++ ID_OUI_FROM_DATABASE=AddSecure Smart Grids ++ + OUI:70B3D5127* + ID_OUI_FROM_DATABASE=VITEC + ++OUI:70B3D5128* ++ ID_OUI_FROM_DATABASE=Akse srl ++ + OUI:70B3D5129* + ID_OUI_FROM_DATABASE=OOO Microlink-Svyaz + ++OUI:70B3D512A* ++ ID_OUI_FROM_DATABASE=Elvys s.r.o ++ + OUI:70B3D512B* + ID_OUI_FROM_DATABASE=RIC Electronics + + OUI:70B3D512C* + ID_OUI_FROM_DATABASE=CIELLE S.R.L. + ++OUI:70B3D512D* ++ ID_OUI_FROM_DATABASE=S.E.I. CO.,LTD. ++ + OUI:70B3D512E* + ID_OUI_FROM_DATABASE=GreenFlux + + OUI:70B3D512F* + ID_OUI_FROM_DATABASE=DSP4YOU LTd + ++OUI:70B3D5130* ++ ID_OUI_FROM_DATABASE=MG s.r.l. ++ + OUI:70B3D5131* + ID_OUI_FROM_DATABASE=Inova Design Solutions Ltd + +@@ -58514,6 +68096,9 @@ OUI:70B3D5135* + OUI:70B3D5136* + ID_OUI_FROM_DATABASE=Miguel Corporate Services Pte Ltd + ++OUI:70B3D5137* ++ ID_OUI_FROM_DATABASE=Subject Link Inc ++ + OUI:70B3D5138* + ID_OUI_FROM_DATABASE=SMITEC S.p.A. + +@@ -58536,7 +68121,7 @@ OUI:70B3D513E* + ID_OUI_FROM_DATABASE=Stara S/A Indústria de Implementos Agrícolas + + OUI:70B3D513F* +- ID_OUI_FROM_DATABASE=Farmobile ++ ID_OUI_FROM_DATABASE=Farmobile, LLC + + OUI:70B3D5140* + ID_OUI_FROM_DATABASE=Virta Laboratories, Inc. +@@ -58547,6 +68132,9 @@ OUI:70B3D5141* + OUI:70B3D5142* + ID_OUI_FROM_DATABASE=DAVE SRL + ++OUI:70B3D5143* ++ ID_OUI_FROM_DATABASE=A & T Technologies ++ + OUI:70B3D5144* + ID_OUI_FROM_DATABASE=GS Elektromedizinsiche Geräte G. Stemple GmbH + +@@ -58568,6 +68156,9 @@ OUI:70B3D5149* + OUI:70B3D514A* + ID_OUI_FROM_DATABASE=ExSens Technology (Pty) Ltd. + ++OUI:70B3D514B* ++ ID_OUI_FROM_DATABASE=C21 Systems Ltd ++ + OUI:70B3D514C* + ID_OUI_FROM_DATABASE=CRDE + +@@ -58580,6 +68171,12 @@ OUI:70B3D514E* + OUI:70B3D514F* + ID_OUI_FROM_DATABASE=Mobile Devices Unlimited + ++OUI:70B3D5150* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ ++OUI:70B3D5151* ++ ID_OUI_FROM_DATABASE=Virsae Group Ltd ++ + OUI:70B3D5152* + ID_OUI_FROM_DATABASE=Xped Corporation Pty Ltd + +@@ -58589,6 +68186,27 @@ OUI:70B3D5153* + OUI:70B3D5154* + ID_OUI_FROM_DATABASE=Walk Horizon Technology (Beijing) Co., Ltd. + ++OUI:70B3D5155* ++ ID_OUI_FROM_DATABASE=Sanwa New Tec Co.,Ltd ++ ++OUI:70B3D5156* ++ ID_OUI_FROM_DATABASE=Rivercity Innovations Ltd. ++ ++OUI:70B3D5157* ++ ID_OUI_FROM_DATABASE=Shanghai Jupper Technology Co.Ltd ++ ++OUI:70B3D5158* ++ ID_OUI_FROM_DATABASE=EAX Labs s.r.o. ++ ++OUI:70B3D5159* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ ++OUI:70B3D515A* ++ ID_OUI_FROM_DATABASE=ENABLER LTD. ++ ++OUI:70B3D515B* ++ ID_OUI_FROM_DATABASE=Armstrong International, Inc. ++ + OUI:70B3D515C* + ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution + +@@ -58601,6 +68219,9 @@ OUI:70B3D515E* + OUI:70B3D515F* + ID_OUI_FROM_DATABASE=SAVRONİK ELEKTRONİK + ++OUI:70B3D5160* ++ ID_OUI_FROM_DATABASE=European Synchrotron Radiation Facility ++ + OUI:70B3D5161* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + +@@ -58613,6 +68234,9 @@ OUI:70B3D5163* + OUI:70B3D5164* + ID_OUI_FROM_DATABASE=Tokyo Drawing Ltd. + ++OUI:70B3D5165* ++ ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd ++ + OUI:70B3D5166* + ID_OUI_FROM_DATABASE=SERIAL IMAGE INC. + +@@ -58625,18 +68249,30 @@ OUI:70B3D5168* + OUI:70B3D5169* + ID_OUI_FROM_DATABASE=Service Plus LLC + ++OUI:70B3D516A* ++ ID_OUI_FROM_DATABASE=4Jtech s.r.o. ++ + OUI:70B3D516B* + ID_OUI_FROM_DATABASE=IOT Engineering + + OUI:70B3D516C* + ID_OUI_FROM_DATABASE=OCEAN + ++OUI:70B3D516D* ++ ID_OUI_FROM_DATABASE=BluB0X Security, Inc. ++ + OUI:70B3D516E* + ID_OUI_FROM_DATABASE=Jemac Sweden AB + + OUI:70B3D516F* + ID_OUI_FROM_DATABASE=NimbeLink Corp + ++OUI:70B3D5170* ++ ID_OUI_FROM_DATABASE=Mutelcor GmbH ++ ++OUI:70B3D5171* ++ ID_OUI_FROM_DATABASE=Aetina Corporation ++ + OUI:70B3D5172* + ID_OUI_FROM_DATABASE=LumiGrow, Inc + +@@ -58649,6 +68285,12 @@ OUI:70B3D5174* + OUI:70B3D5175* + ID_OUI_FROM_DATABASE=Akribis Systems + ++OUI:70B3D5176* ++ ID_OUI_FROM_DATABASE=Larraioz Elektronika ++ ++OUI:70B3D5177* ++ ID_OUI_FROM_DATABASE=Wired Broadcast Ltd ++ + OUI:70B3D5178* + ID_OUI_FROM_DATABASE=Gamber Johnson-LLC + +@@ -58661,6 +68303,9 @@ OUI:70B3D517A* + OUI:70B3D517B* + ID_OUI_FROM_DATABASE=Vistec Electron Beam GmbH + ++OUI:70B3D517C* ++ ID_OUI_FROM_DATABASE=Farmpro Ltd ++ + OUI:70B3D517D* + ID_OUI_FROM_DATABASE=Entech Electronics + +@@ -58697,6 +68342,12 @@ OUI:70B3D5187* + OUI:70B3D5188* + ID_OUI_FROM_DATABASE=Birket Engineering + ++OUI:70B3D5189* ++ ID_OUI_FROM_DATABASE=DAVE SRL ++ ++OUI:70B3D518A* ++ ID_OUI_FROM_DATABASE=NSP Europe Ltd ++ + OUI:70B3D518B* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +@@ -58709,24 +68360,51 @@ OUI:70B3D518D* + OUI:70B3D518E* + ID_OUI_FROM_DATABASE=NIPPON SEIKI CO., LTD. + ++OUI:70B3D518F* ++ ID_OUI_FROM_DATABASE=Newtec A/S ++ + OUI:70B3D5190* + ID_OUI_FROM_DATABASE=Fantom Wireless, Inc. + ++OUI:70B3D5191* ++ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl ++ + OUI:70B3D5192* + ID_OUI_FROM_DATABASE=ASPT, INC. + ++OUI:70B3D5193* ++ ID_OUI_FROM_DATABASE=ERA TOYS LIMITED ++ + OUI:70B3D5194* + ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J. + ++OUI:70B3D5195* ++ ID_OUI_FROM_DATABASE=Ci4Rail ++ ++OUI:70B3D5196* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5197* + ID_OUI_FROM_DATABASE=Lattech Systems Pty Ltd + ++OUI:70B3D5198* ++ ID_OUI_FROM_DATABASE=Beijing Muniulinghang Technology Co., Ltd ++ ++OUI:70B3D5199* ++ ID_OUI_FROM_DATABASE=Smart Controls LLC ++ ++OUI:70B3D519A* ++ ID_OUI_FROM_DATABASE=WiSuite USA ++ + OUI:70B3D519B* + ID_OUI_FROM_DATABASE=Global Technical Systems + + OUI:70B3D519C* + ID_OUI_FROM_DATABASE=Kubu, Inc. + ++OUI:70B3D519D* ++ ID_OUI_FROM_DATABASE=Automata GmbH & Co. KG ++ + OUI:70B3D519E* + ID_OUI_FROM_DATABASE=J-Factor Embedded Technologies + +@@ -58739,21 +68417,33 @@ OUI:70B3D51A0* + OUI:70B3D51A1* + ID_OUI_FROM_DATABASE=HMicro Inc + ++OUI:70B3D51A2* ++ ID_OUI_FROM_DATABASE=Xirgo Technologies LLC ++ + OUI:70B3D51A3* + ID_OUI_FROM_DATABASE=Telairity Semiconductor + ++OUI:70B3D51A4* ++ ID_OUI_FROM_DATABASE=DAVEY BICKFORD ++ + OUI:70B3D51A5* + ID_OUI_FROM_DATABASE=METRONIC APARATURA KONTROLNO - POMIAROWA + + OUI:70B3D51A6* + ID_OUI_FROM_DATABASE=Robotelf Technologies (Chengdu) Co., Ltd. + ++OUI:70B3D51A7* ++ ID_OUI_FROM_DATABASE=Elk Solutions, LLC ++ + OUI:70B3D51A8* + ID_OUI_FROM_DATABASE=STC Rainbow Ltd. + + OUI:70B3D51A9* + ID_OUI_FROM_DATABASE=OCEANIX INC. + ++OUI:70B3D51AA* ++ ID_OUI_FROM_DATABASE=Echo Ridge, LLC ++ + OUI:70B3D51AB* + ID_OUI_FROM_DATABASE=Access Control Systems JSC + +@@ -58763,9 +68453,24 @@ OUI:70B3D51AC* + OUI:70B3D51AD* + ID_OUI_FROM_DATABASE=Techworld Industries Ltd + ++OUI:70B3D51AE* ++ ID_OUI_FROM_DATABASE=EcoG ++ + OUI:70B3D51AF* + ID_OUI_FROM_DATABASE=Teenage Engineering AB + ++OUI:70B3D51B0* ++ ID_OUI_FROM_DATABASE=NAL Research Corporation ++ ++OUI:70B3D51B1* ++ ID_OUI_FROM_DATABASE=Shanghai Danyan Information Technology Co., Ltd. ++ ++OUI:70B3D51B2* ++ ID_OUI_FROM_DATABASE=Cavagna Group Spa ++ ++OUI:70B3D51B3* ++ ID_OUI_FROM_DATABASE=Graphcore Ltd ++ + OUI:70B3D51B4* + ID_OUI_FROM_DATABASE=5nines + +@@ -58775,30 +68480,66 @@ OUI:70B3D51B5* + OUI:70B3D51B6* + ID_OUI_FROM_DATABASE=DACOM West GmbH + ++OUI:70B3D51B7* ++ ID_OUI_FROM_DATABASE=ULSee Inc ++ + OUI:70B3D51B8* + ID_OUI_FROM_DATABASE=OES Inc. + + OUI:70B3D51B9* + ID_OUI_FROM_DATABASE=RELISTE Ges.m.b.H. + ++OUI:70B3D51BA* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ + OUI:70B3D51BB* + ID_OUI_FROM_DATABASE=EFENTO T P SZYDŁOWSKI K ZARĘBA SPÓŁKA JAWNA + ++OUI:70B3D51BC* ++ ID_OUI_FROM_DATABASE=Flextronics International Kft ++ ++OUI:70B3D51BD* ++ ID_OUI_FROM_DATABASE=Shenzhen Siera Technology Ltd ++ + OUI:70B3D51BE* + ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC + ++OUI:70B3D51BF* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ ++OUI:70B3D51C0* ++ ID_OUI_FROM_DATABASE=W. H. Leary Co., Inc. ++ ++OUI:70B3D51C1* ++ ID_OUI_FROM_DATABASE=Sphere of economical technologies Ltd ++ ++OUI:70B3D51C2* ++ ID_OUI_FROM_DATABASE=CENSIS, Uiversity of Glasgow ++ ++OUI:70B3D51C3* ++ ID_OUI_FROM_DATABASE=Shanghai Tiancheng Communication Technology Corporation ++ + OUI:70B3D51C4* + ID_OUI_FROM_DATABASE=Smeg S.p.A. + + OUI:70B3D51C5* + ID_OUI_FROM_DATABASE=ELSAG + ++OUI:70B3D51C6* ++ ID_OUI_FROM_DATABASE=Bita-International Co., Ltd. ++ + OUI:70B3D51C7* + ID_OUI_FROM_DATABASE=Hoshin Electronics Co., Ltd. + + OUI:70B3D51C8* + ID_OUI_FROM_DATABASE=LDA audio video profesional S.L. + ++OUI:70B3D51C9* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D51CA* ++ ID_OUI_FROM_DATABASE=inomatic GmbH ++ + OUI:70B3D51CB* + ID_OUI_FROM_DATABASE=MatchX GmbH + +@@ -58808,36 +68549,69 @@ OUI:70B3D51CC* + OUI:70B3D51CD* + ID_OUI_FROM_DATABASE=ELEUSI GmbH + ++OUI:70B3D51CE* ++ ID_OUI_FROM_DATABASE=Clear Flow by Antiference ++ ++OUI:70B3D51CF* ++ ID_OUI_FROM_DATABASE=Dalcnet srl ++ + OUI:70B3D51D0* + ID_OUI_FROM_DATABASE=Shenzhen INVT Electric Co.,Ltd + + OUI:70B3D51D1* + ID_OUI_FROM_DATABASE=Eurotek Srl + ++OUI:70B3D51D2* ++ ID_OUI_FROM_DATABASE=Xacti Corporation ++ + OUI:70B3D51D3* + ID_OUI_FROM_DATABASE=AIROBOT OÜ + + OUI:70B3D51D4* + ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH + ++OUI:70B3D51D5* ++ ID_OUI_FROM_DATABASE=MIVO Technology AB ++ ++OUI:70B3D51D6* ++ ID_OUI_FROM_DATABASE=MacGray Services ++ + OUI:70B3D51D7* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D51D8* ++ ID_OUI_FROM_DATABASE=Blue Skies Global LLC ++ ++OUI:70B3D51D9* ++ ID_OUI_FROM_DATABASE=MondeF ++ + OUI:70B3D51DA* + ID_OUI_FROM_DATABASE=Promess Inc. + + OUI:70B3D51DB* + ID_OUI_FROM_DATABASE=Hudson Robotics + ++OUI:70B3D51DC* ++ ID_OUI_FROM_DATABASE=TEKVEL Ltd. ++ + OUI:70B3D51DD* + ID_OUI_FROM_DATABASE=RF CREATIONS LTD + + OUI:70B3D51DE* + ID_OUI_FROM_DATABASE=DYCEC, S.A. + ++OUI:70B3D51DF* ++ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. ++ + OUI:70B3D51E0* + ID_OUI_FROM_DATABASE=TOPROOTTechnology Corp. Ltd. + ++OUI:70B3D51E1* ++ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL ++ ++OUI:70B3D51E2* ++ ID_OUI_FROM_DATABASE=Shenzhen CAMERAY ELECTRONIC CO., LTD ++ + OUI:70B3D51E3* + ID_OUI_FROM_DATABASE=Hatel Elektronik LTD. STI. + +@@ -58850,12 +68624,39 @@ OUI:70B3D51E5* + OUI:70B3D51E6* + ID_OUI_FROM_DATABASE=Sanmina Israel + ++OUI:70B3D51E7* ++ ID_OUI_FROM_DATABASE=DogWatch Inc ++ ++OUI:70B3D51E8* ++ ID_OUI_FROM_DATABASE=Gogo BA ++ + OUI:70B3D51E9* + ID_OUI_FROM_DATABASE=comtime GmbH + ++OUI:70B3D51EA* ++ ID_OUI_FROM_DATABASE=Sense For Innovation ++ ++OUI:70B3D51EB* ++ ID_OUI_FROM_DATABASE=Xavant ++ ++OUI:70B3D51ED* ++ ID_OUI_FROM_DATABASE=SUS Corporation ++ ++OUI:70B3D51EE* ++ ID_OUI_FROM_DATABASE=MEGGITT ++ + OUI:70B3D51EF* + ID_OUI_FROM_DATABASE=ADTEK + ++OUI:70B3D51F0* ++ ID_OUI_FROM_DATABASE=Harmonic Design GmbH ++ ++OUI:70B3D51F1* ++ ID_OUI_FROM_DATABASE=DIEHL Connectivity Solutions ++ ++OUI:70B3D51F2* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D51F3* + ID_OUI_FROM_DATABASE=Smart Energy Code Company Limited + +@@ -58865,18 +68666,42 @@ OUI:70B3D51F4* + OUI:70B3D51F5* + ID_OUI_FROM_DATABASE=Martec S.p.A. + ++OUI:70B3D51F6* ++ ID_OUI_FROM_DATABASE=LinkAV Technology Co., Ltd ++ ++OUI:70B3D51F7* ++ ID_OUI_FROM_DATABASE=Morgan Schaffer Inc. ++ + OUI:70B3D51F8* + ID_OUI_FROM_DATABASE=Convergent Design + ++OUI:70B3D51F9* ++ ID_OUI_FROM_DATABASE=Automata GmbH & Co. KG ++ ++OUI:70B3D51FA* ++ ID_OUI_FROM_DATABASE=EBZ SysTec GmbH ++ ++OUI:70B3D51FB* ++ ID_OUI_FROM_DATABASE=Crane-elec. Co., LTD. ++ ++OUI:70B3D51FC* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ + OUI:70B3D51FD* + ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos + + OUI:70B3D51FE* + ID_OUI_FROM_DATABASE=MobiPromo + ++OUI:70B3D51FF* ++ ID_OUI_FROM_DATABASE=Audiodo AB ++ + OUI:70B3D5200* + ID_OUI_FROM_DATABASE=NextEV Co., Ltd. + ++OUI:70B3D5201* ++ ID_OUI_FROM_DATABASE=Leontech Limited ++ + OUI:70B3D5202* + ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH + +@@ -58889,6 +68714,9 @@ OUI:70B3D5204* + OUI:70B3D5205* + ID_OUI_FROM_DATABASE=Esource Srl + ++OUI:70B3D5206* ++ ID_OUI_FROM_DATABASE=ard sa ++ + OUI:70B3D5207* + ID_OUI_FROM_DATABASE=Savari Inc + +@@ -58901,6 +68729,9 @@ OUI:70B3D5209* + OUI:70B3D520A* + ID_OUI_FROM_DATABASE=Golden Grid Systems + ++OUI:70B3D520B* ++ ID_OUI_FROM_DATABASE=KST technology ++ + OUI:70B3D520C* + ID_OUI_FROM_DATABASE=Siemens Healthcare Diagnostics + +@@ -58913,9 +68744,15 @@ OUI:70B3D520E* + OUI:70B3D520F* + ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd + ++OUI:70B3D5210* ++ ID_OUI_FROM_DATABASE=Eastone Century Technology Co.,Ltd. ++ + OUI:70B3D5211* + ID_OUI_FROM_DATABASE=Fracarro srl + ++OUI:70B3D5212* ++ ID_OUI_FROM_DATABASE=Semiconsoft, inc ++ + OUI:70B3D5213* + ID_OUI_FROM_DATABASE=ETON Deutschland Electro Acoustic GmbH + +@@ -58931,6 +68768,15 @@ OUI:70B3D5216* + OUI:70B3D5217* + ID_OUI_FROM_DATABASE=Tecnint HTE SRL + ++OUI:70B3D5218* ++ ID_OUI_FROM_DATABASE=Gremesh.com ++ ++OUI:70B3D5219* ++ ID_OUI_FROM_DATABASE=D-E-K GmbH & Co.KG ++ ++OUI:70B3D521A* ++ ID_OUI_FROM_DATABASE=Acutronic Link Robotics AG ++ + OUI:70B3D521B* + ID_OUI_FROM_DATABASE=Lab241 Co.,Ltd. + +@@ -58949,9 +68795,15 @@ OUI:70B3D521F* + OUI:70B3D5220* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D5221* ++ ID_OUI_FROM_DATABASE=LX Design House ++ + OUI:70B3D5222* + ID_OUI_FROM_DATABASE=Marioff Corporation Oy + ++OUI:70B3D5223* ++ ID_OUI_FROM_DATABASE=Research Laboratory of Design Automation, Ltd. ++ + OUI:70B3D5224* + ID_OUI_FROM_DATABASE=Urbana Smart Solutions Pte Ltd + +@@ -58970,12 +68822,18 @@ OUI:70B3D5228* + OUI:70B3D5229* + ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl + ++OUI:70B3D522A* ++ ID_OUI_FROM_DATABASE=Shishido Electrostatic, Ltd. ++ + OUI:70B3D522B* + ID_OUI_FROM_DATABASE=VITEC + + OUI:70B3D522C* + ID_OUI_FROM_DATABASE=Hiquel Elektronik- und Anlagenbau GmbH + ++OUI:70B3D522D* ++ ID_OUI_FROM_DATABASE=Leder Elektronik Design ++ + OUI:70B3D522E* + ID_OUI_FROM_DATABASE=Private + +@@ -58991,15 +68849,24 @@ OUI:70B3D5231* + OUI:70B3D5232* + ID_OUI_FROM_DATABASE=UCONSYS + ++OUI:70B3D5234* ++ ID_OUI_FROM_DATABASE=EDFelectronics JRMM Sp z o.o. sp.k. ++ + OUI:70B3D5235* + ID_OUI_FROM_DATABASE=CAMEON S.A. + + OUI:70B3D5236* + ID_OUI_FROM_DATABASE=Monnit Corporation + ++OUI:70B3D5237* ++ ID_OUI_FROM_DATABASE=Sikom AS ++ + OUI:70B3D5238* + ID_OUI_FROM_DATABASE=Arete Associates + ++OUI:70B3D5239* ++ ID_OUI_FROM_DATABASE=Applied Silver ++ + OUI:70B3D523A* + ID_OUI_FROM_DATABASE=Mesa Labs, Inc. + +@@ -59009,6 +68876,9 @@ OUI:70B3D523B* + OUI:70B3D523C* + ID_OUI_FROM_DATABASE=Quasonix, LLC + ++OUI:70B3D523D* ++ ID_OUI_FROM_DATABASE=Circle Consult ApS ++ + OUI:70B3D523E* + ID_OUI_FROM_DATABASE=Tornado Modular Systems + +@@ -59021,21 +68891,39 @@ OUI:70B3D5240* + OUI:70B3D5241* + ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc. + ++OUI:70B3D5242* ++ ID_OUI_FROM_DATABASE=Comeo Technology Co.,Ltd ++ + OUI:70B3D5243* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + ++OUI:70B3D5244* ++ ID_OUI_FROM_DATABASE=DAT Informatics Pvt Ltd ++ + OUI:70B3D5245* + ID_OUI_FROM_DATABASE=Newtec A/S + + OUI:70B3D5246* + ID_OUI_FROM_DATABASE=Saline Lectronics, Inc. + ++OUI:70B3D5247* ++ ID_OUI_FROM_DATABASE=Satsky Communication Equipment Co.,Ltd. ++ + OUI:70B3D5248* + ID_OUI_FROM_DATABASE=GL TECH CO.,LTD + ++OUI:70B3D5249* ++ ID_OUI_FROM_DATABASE=Kospel S.A. ++ ++OUI:70B3D524A* ++ ID_OUI_FROM_DATABASE=Unmukti Technology Pvt Ltd ++ + OUI:70B3D524B* + ID_OUI_FROM_DATABASE=TOSEI ENGINEERING CORP. + ++OUI:70B3D524C* ++ ID_OUI_FROM_DATABASE=Astronomical Research Cameras, Inc. ++ + OUI:70B3D524D* + ID_OUI_FROM_DATABASE=INFO CREATIVE (HK) LTD + +@@ -59048,6 +68936,9 @@ OUI:70B3D524F* + OUI:70B3D5250* + ID_OUI_FROM_DATABASE=Datum Electronics Limited + ++OUI:70B3D5251* ++ ID_OUI_FROM_DATABASE=PixelApps s.r.o. ++ + OUI:70B3D5252* + ID_OUI_FROM_DATABASE=Sierra Nevada Corporation + +@@ -59060,9 +68951,15 @@ OUI:70B3D5254* + OUI:70B3D5255* + ID_OUI_FROM_DATABASE=Asystems Corporation + ++OUI:70B3D5256* ++ ID_OUI_FROM_DATABASE=Telco Antennas Pty Ltd ++ + OUI:70B3D5257* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:70B3D5258* ++ ID_OUI_FROM_DATABASE=BAYKON Endüstriyel Kontrol Sistemleri San. ve Tic. A.Ş. ++ + OUI:70B3D5259* + ID_OUI_FROM_DATABASE=Zebra Elektronik A.S. + +@@ -59072,15 +68969,36 @@ OUI:70B3D525A* + OUI:70B3D525B* + ID_OUI_FROM_DATABASE=GID Industrial + ++OUI:70B3D525C* ++ ID_OUI_FROM_DATABASE=ARCLAN'SYSTEM ++ + OUI:70B3D525D* + ID_OUI_FROM_DATABASE=Mimo Networks + ++OUI:70B3D525E* ++ ID_OUI_FROM_DATABASE=RFHIC ++ ++OUI:70B3D525F* ++ ID_OUI_FROM_DATABASE=COPPERNIC SAS ++ + OUI:70B3D5260* + ID_OUI_FROM_DATABASE=ModuSystems, Inc + + OUI:70B3D5261* + ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC + ++OUI:70B3D5262* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ ++OUI:70B3D5263* ++ ID_OUI_FROM_DATABASE=AXING AG ++ ++OUI:70B3D5264* ++ ID_OUI_FROM_DATABASE=ifak technology + service GmbH ++ ++OUI:70B3D5265* ++ ID_OUI_FROM_DATABASE=Rapiot ++ + OUI:70B3D5266* + ID_OUI_FROM_DATABASE=Spectra Displays Ltd + +@@ -59093,15 +69011,30 @@ OUI:70B3D5268* + OUI:70B3D5269* + ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root ‎ + ++OUI:70B3D526A* ++ ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA ++ + OUI:70B3D526B* + ID_OUI_FROM_DATABASE=Sorama BV + + OUI:70B3D526C* + ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG + ++OUI:70B3D526D* ++ ID_OUI_FROM_DATABASE=Sorion Electronics ltd ++ + OUI:70B3D526E* + ID_OUI_FROM_DATABASE=HI-TECH SYSTEM Co. Ltd. + ++OUI:70B3D526F* ++ ID_OUI_FROM_DATABASE=COMPAL ELECTRONICS, INC. ++ ++OUI:70B3D5270* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:70B3D5271* ++ ID_OUI_FROM_DATABASE=Code Blue Corporation ++ + OUI:70B3D5272* + ID_OUI_FROM_DATABASE=TELECOM SANTE + +@@ -59111,6 +69044,9 @@ OUI:70B3D5273* + OUI:70B3D5274* + ID_OUI_FROM_DATABASE=Stercom Power Solutions GmbH + ++OUI:70B3D5275* ++ ID_OUI_FROM_DATABASE=INTERNET PROTOCOLO LOGICA SL ++ + OUI:70B3D5276* + ID_OUI_FROM_DATABASE=TELL Software Hungaria Kft. + +@@ -59121,16 +69057,22 @@ OUI:70B3D5278* + ID_OUI_FROM_DATABASE=Private + + OUI:70B3D5279* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Medicomp, Inc + + OUI:70B3D527A* + ID_OUI_FROM_DATABASE=TD ECOPHISIKA + ++OUI:70B3D527B* ++ ID_OUI_FROM_DATABASE=DAVE SRL ++ ++OUI:70B3D527C* ++ ID_OUI_FROM_DATABASE=MOTION LIB,Inc. ++ + OUI:70B3D527D* + ID_OUI_FROM_DATABASE=Telenor Connexion AB + + OUI:70B3D527E* +- ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed ++ ID_OUI_FROM_DATABASE=Mettler Toledo + + OUI:70B3D527F* + ID_OUI_FROM_DATABASE=ST Aerospace Systems +@@ -59138,6 +69080,12 @@ OUI:70B3D527F* + OUI:70B3D5280* + ID_OUI_FROM_DATABASE=Computech International + ++OUI:70B3D5281* ++ ID_OUI_FROM_DATABASE=ITG.CO.LTD ++ ++OUI:70B3D5282* ++ ID_OUI_FROM_DATABASE=SAMBO HITECH ++ + OUI:70B3D5283* + ID_OUI_FROM_DATABASE=TextNinja Co. + +@@ -59150,6 +69098,9 @@ OUI:70B3D5285* + OUI:70B3D5286* + ID_OUI_FROM_DATABASE=Pedax Danmark + ++OUI:70B3D5287* ++ ID_OUI_FROM_DATABASE=Hypex Electronics BV ++ + OUI:70B3D5288* + ID_OUI_FROM_DATABASE=Bresslergroup + +@@ -59174,8 +69125,20 @@ OUI:70B3D528E* + OUI:70B3D528F* + ID_OUI_FROM_DATABASE=Overline Systems + ++OUI:70B3D5290* ++ ID_OUI_FROM_DATABASE=GETT Geraetetechnik GmbH ++ ++OUI:70B3D5291* ++ ID_OUI_FROM_DATABASE=Sequent AG ++ + OUI:70B3D5292* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Boston Dynamics ++ ++OUI:70B3D5293* ++ ID_OUI_FROM_DATABASE=Solar RIg Technologies ++ ++OUI:70B3D5294* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company + + OUI:70B3D5295* + ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd +@@ -59186,6 +69149,15 @@ OUI:70B3D5296* + OUI:70B3D5297* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + ++OUI:70B3D5298* ++ ID_OUI_FROM_DATABASE=Reflexion Medical ++ ++OUI:70B3D5299* ++ ID_OUI_FROM_DATABASE=KMtronic ltd ++ ++OUI:70B3D529A* ++ ID_OUI_FROM_DATABASE=Profusion Limited ++ + OUI:70B3D529B* + ID_OUI_FROM_DATABASE=DermaLumics S.L. + +@@ -59195,9 +69167,15 @@ OUI:70B3D529C* + OUI:70B3D529D* + ID_OUI_FROM_DATABASE=XTech2 SIA + ++OUI:70B3D529E* ++ ID_OUI_FROM_DATABASE=B2cloud lda ++ + OUI:70B3D529F* + ID_OUI_FROM_DATABASE=Code Hardware SA + ++OUI:70B3D52A0* ++ ID_OUI_FROM_DATABASE=Airthings ++ + OUI:70B3D52A1* + ID_OUI_FROM_DATABASE=Blink Services AB + +@@ -59213,9 +69191,15 @@ OUI:70B3D52A4* + OUI:70B3D52A5* + ID_OUI_FROM_DATABASE=Taitotekniikka + ++OUI:70B3D52A6* ++ ID_OUI_FROM_DATABASE=GSI Technology ++ + OUI:70B3D52A7* + ID_OUI_FROM_DATABASE=Plasmability, LLC + ++OUI:70B3D52A8* ++ ID_OUI_FROM_DATABASE=Dynamic Perspective GmbH ++ + OUI:70B3D52A9* + ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. + +@@ -59234,6 +69218,9 @@ OUI:70B3D52AD* + OUI:70B3D52AE* + ID_OUI_FROM_DATABASE=Alere Technologies AS + ++OUI:70B3D52AF* ++ ID_OUI_FROM_DATABASE=Enlaps ++ + OUI:70B3D52B0* + ID_OUI_FROM_DATABASE=Beijing Zhongyi Yue Tai Technology Co., Ltd + +@@ -59249,9 +69236,18 @@ OUI:70B3D52B3* + OUI:70B3D52B4* + ID_OUI_FROM_DATABASE=Foerster-Technik GmbH + ++OUI:70B3D52B5* ++ ID_OUI_FROM_DATABASE=Dosepack India LLP ++ ++OUI:70B3D52B6* ++ ID_OUI_FROM_DATABASE=HLT Micro ++ + OUI:70B3D52B7* + ID_OUI_FROM_DATABASE=Matrix Orbital Corporation + ++OUI:70B3D52B8* ++ ID_OUI_FROM_DATABASE=WideNorth AS ++ + OUI:70B3D52B9* + ID_OUI_FROM_DATABASE=BELECTRIC GmbH + +@@ -59273,18 +69269,42 @@ OUI:70B3D52BE* + OUI:70B3D52BF* + ID_OUI_FROM_DATABASE=FOSHAN VOHOM + ++OUI:70B3D52C0* ++ ID_OUI_FROM_DATABASE=Sensative AB ++ ++OUI:70B3D52C1* ++ ID_OUI_FROM_DATABASE=Avlinkpro ++ + OUI:70B3D52C2* + ID_OUI_FROM_DATABASE=Quantum Detectors + + OUI:70B3D52C3* + ID_OUI_FROM_DATABASE=Proterra + ++OUI:70B3D52C4* ++ ID_OUI_FROM_DATABASE=Hodwa Co., Ltd ++ ++OUI:70B3D52C5* ++ ID_OUI_FROM_DATABASE=MECT SRL ++ ++OUI:70B3D52C6* ++ ID_OUI_FROM_DATABASE=AM General Contractor ++ ++OUI:70B3D52C7* ++ ID_OUI_FROM_DATABASE=Worldsensing ++ ++OUI:70B3D52C8* ++ ID_OUI_FROM_DATABASE=SLAT ++ + OUI:70B3D52C9* + ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY + + OUI:70B3D52CA* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D52CB* ++ ID_OUI_FROM_DATABASE=Yongtong tech ++ + OUI:70B3D52CC* + ID_OUI_FROM_DATABASE=WeWork Companies, Inc. + +@@ -59300,9 +69320,15 @@ OUI:70B3D52CF* + OUI:70B3D52D0* + ID_OUI_FROM_DATABASE=ijin co.,ltd. + ++OUI:70B3D52D1* ++ ID_OUI_FROM_DATABASE=Integer.pl S.A. ++ + OUI:70B3D52D2* + ID_OUI_FROM_DATABASE=SHANGHAI IRISIAN OPTRONICS TECHNOLOGY CO.,LTD. + ++OUI:70B3D52D3* ++ ID_OUI_FROM_DATABASE=Hensoldt Sensors GmbH ++ + OUI:70B3D52D4* + ID_OUI_FROM_DATABASE=CT Company + +@@ -59312,6 +69338,15 @@ OUI:70B3D52D5* + OUI:70B3D52D6* + ID_OUI_FROM_DATABASE=Kvazar LLC + ++OUI:70B3D52D7* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:70B3D52D8* ++ ID_OUI_FROM_DATABASE=Unisight Digital Products ++ ++OUI:70B3D52D9* ++ ID_OUI_FROM_DATABASE=ZPAS S.A. ++ + OUI:70B3D52DA* + ID_OUI_FROM_DATABASE=Skywave Networks Private Limited + +@@ -59321,21 +69356,45 @@ OUI:70B3D52DB* + OUI:70B3D52DC* + ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc. + ++OUI:70B3D52DD* ++ ID_OUI_FROM_DATABASE=Melissa Climate Jsc ++ ++OUI:70B3D52DE* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ ++OUI:70B3D52DF* ++ ID_OUI_FROM_DATABASE=EASTERN SCIENCE & TECHNOLOGY CO., LTD ++ + OUI:70B3D52E0* + ID_OUI_FROM_DATABASE=Peter Huber + ++OUI:70B3D52E1* ++ ID_OUI_FROM_DATABASE=hiSky S.C.S LTD ++ + OUI:70B3D52E2* + ID_OUI_FROM_DATABASE=Spark Lasers + + OUI:70B3D52E3* + ID_OUI_FROM_DATABASE=Meiknologic GmbH + ++OUI:70B3D52E4* ++ ID_OUI_FROM_DATABASE=Schneider Electric Motion USA ++ + OUI:70B3D52E5* + ID_OUI_FROM_DATABASE=Fläkt Woods AB + ++OUI:70B3D52E6* ++ ID_OUI_FROM_DATABASE=IPG Photonics Corporation ++ + OUI:70B3D52E7* + ID_OUI_FROM_DATABASE=Atos spa + ++OUI:70B3D52E8* ++ ID_OUI_FROM_DATABASE=Telefire ++ ++OUI:70B3D52E9* ++ ID_OUI_FROM_DATABASE=NeurIT s.r.o. ++ + OUI:70B3D52EA* + ID_OUI_FROM_DATABASE=Schneider Electric Motion + +@@ -59345,6 +69404,9 @@ OUI:70B3D52EB* + OUI:70B3D52EC* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + ++OUI:70B3D52ED* ++ ID_OUI_FROM_DATABASE=Signals and systems india pvt ltd ++ + OUI:70B3D52EE* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +@@ -59366,9 +69428,15 @@ OUI:70B3D52F3* + OUI:70B3D52F4* + ID_OUI_FROM_DATABASE=Radixon s.r.o. + ++OUI:70B3D52F5* ++ ID_OUI_FROM_DATABASE=eze System, Inc. ++ + OUI:70B3D52F6* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D52F7* ++ ID_OUI_FROM_DATABASE=Military Research Institute ++ + OUI:70B3D52F8* + ID_OUI_FROM_DATABASE=Tunstall A/S + +@@ -59378,30 +69446,51 @@ OUI:70B3D52F9* + OUI:70B3D52FA* + ID_OUI_FROM_DATABASE=Toray Medical Co.,Ltd + ++OUI:70B3D52FB* ++ ID_OUI_FROM_DATABASE=IK MULTIMEDIA PRODUCTION SRL ++ ++OUI:70B3D52FC* ++ ID_OUI_FROM_DATABASE=Loanguard T/A SE Controls ++ + OUI:70B3D52FD* + ID_OUI_FROM_DATABASE=Special Projects Group, Inc + + OUI:70B3D52FE* + ID_OUI_FROM_DATABASE=Yaham Optoelectronics Co., Ltd + ++OUI:70B3D52FF* ++ ID_OUI_FROM_DATABASE=Sunstone Engineering ++ + OUI:70B3D5300* + ID_OUI_FROM_DATABASE=Novo DR Ltd. + ++OUI:70B3D5301* ++ ID_OUI_FROM_DATABASE=WAYNE ANALYTICS LLC ++ ++OUI:70B3D5302* ++ ID_OUI_FROM_DATABASE=DogWatch Inc ++ + OUI:70B3D5303* + ID_OUI_FROM_DATABASE=Fuchu Giken, Inc. + + OUI:70B3D5304* +- ID_OUI_FROM_DATABASE=Transas Marine Limited ++ ID_OUI_FROM_DATABASE=Wartsila Voyage Limited + + OUI:70B3D5305* + ID_OUI_FROM_DATABASE=CAITRON Industrial Solutions GmbH + ++OUI:70B3D5306* ++ ID_OUI_FROM_DATABASE=LEMZ-T, LLC ++ + OUI:70B3D5307* + ID_OUI_FROM_DATABASE=Energi innovation Aps + + OUI:70B3D5308* + ID_OUI_FROM_DATABASE=DSD MICROTECHNOLOGY,INC. + ++OUI:70B3D530A* ++ ID_OUI_FROM_DATABASE=HongSeok Ltd. ++ + OUI:70B3D530B* + ID_OUI_FROM_DATABASE=Ash Technologies + +@@ -59414,24 +69503,66 @@ OUI:70B3D530D* + OUI:70B3D530E* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D530F* ++ ID_OUI_FROM_DATABASE=Cardinal Scales Manufacturing Co ++ ++OUI:70B3D5310* ++ ID_OUI_FROM_DATABASE=Conserv Solutions ++ ++OUI:70B3D5311* ++ ID_OUI_FROM_DATABASE=Günther Spelsberg GmbH + Co. KG ++ ++OUI:70B3D5312* ++ ID_OUI_FROM_DATABASE=SMITEC S.p.A. ++ + OUI:70B3D5313* + ID_OUI_FROM_DATABASE=DIEHL Controls + ++OUI:70B3D5314* ++ ID_OUI_FROM_DATABASE=Grau Elektronik GmbH ++ ++OUI:70B3D5315* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:70B3D5316* ++ ID_OUI_FROM_DATABASE=Austco Marketing & Service (USA) ltd. ++ + OUI:70B3D5317* + ID_OUI_FROM_DATABASE=Iotopia Solutions + ++OUI:70B3D5318* ++ ID_OUI_FROM_DATABASE=Exemplar Medical, LLC ++ + OUI:70B3D5319* + ID_OUI_FROM_DATABASE=ISO/TC 22/SC 31 + ++OUI:70B3D531A* ++ ID_OUI_FROM_DATABASE=Terratel Technology s.r.o. ++ + OUI:70B3D531B* + ID_OUI_FROM_DATABASE=SilTerra Malaysia Sdn. Bhd. + + OUI:70B3D531C* + ID_OUI_FROM_DATABASE=FINANCIERE DE L'OMBREE (eolane) + ++OUI:70B3D531D* ++ ID_OUI_FROM_DATABASE=AVA Monitoring AB ++ + OUI:70B3D531E* + ID_OUI_FROM_DATABASE=GILLAM-FEI S.A. + ++OUI:70B3D531F* ++ ID_OUI_FROM_DATABASE=Elcoma ++ ++OUI:70B3D5320* ++ ID_OUI_FROM_DATABASE=CYNIX Systems Inc ++ ++OUI:70B3D5321* ++ ID_OUI_FROM_DATABASE=Yite technology ++ ++OUI:70B3D5322* ++ ID_OUI_FROM_DATABASE=PuS GmbH und Co. KG ++ + OUI:70B3D5323* + ID_OUI_FROM_DATABASE=TATTILE SRL + +@@ -59450,33 +69581,75 @@ OUI:70B3D5327* + OUI:70B3D5328* + ID_OUI_FROM_DATABASE=HIPODROMO DE AGUA CALIENTE SA CV + ++OUI:70B3D5329* ++ ID_OUI_FROM_DATABASE=Primalucelab isrl ++ + OUI:70B3D532A* + ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd + ++OUI:70B3D532B* ++ ID_OUI_FROM_DATABASE=RTA srl ++ ++OUI:70B3D532C* ++ ID_OUI_FROM_DATABASE=ATION Corporation ++ + OUI:70B3D532D* + ID_OUI_FROM_DATABASE=Hanwell Technology Co., Ltd. + ++OUI:70B3D532E* ++ ID_OUI_FROM_DATABASE=A&T Corporation ++ + OUI:70B3D532F* + ID_OUI_FROM_DATABASE=Movidius SRL + ++OUI:70B3D5330* ++ ID_OUI_FROM_DATABASE=iOne ++ ++OUI:70B3D5331* ++ ID_OUI_FROM_DATABASE=Firecom, Inc. ++ + OUI:70B3D5332* + ID_OUI_FROM_DATABASE=InnoSenT + ++OUI:70B3D5333* ++ ID_OUI_FROM_DATABASE=Orlaco Products B.V. ++ ++OUI:70B3D5334* ++ ID_OUI_FROM_DATABASE=Dokuen Co. Ltd. ++ ++OUI:70B3D5335* ++ ID_OUI_FROM_DATABASE=Jonsa Australia Pty Ltd ++ + OUI:70B3D5336* + ID_OUI_FROM_DATABASE=Synaccess Networks Inc. + ++OUI:70B3D5337* ++ ID_OUI_FROM_DATABASE=Laborie ++ ++OUI:70B3D5338* ++ ID_OUI_FROM_DATABASE=Opti-Sciences, Inc. ++ + OUI:70B3D5339* + ID_OUI_FROM_DATABASE=Sierra Nevada Corporation + ++OUI:70B3D533A* ++ ID_OUI_FROM_DATABASE=AudioTEC LLC ++ + OUI:70B3D533B* + ID_OUI_FROM_DATABASE=Seal Shield, LLC + + OUI:70B3D533C* + ID_OUI_FROM_DATABASE=Videri Inc. + ++OUI:70B3D533D* ++ ID_OUI_FROM_DATABASE=Schneider Electric Motion USA ++ + OUI:70B3D533E* + ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd. + ++OUI:70B3D533F* ++ ID_OUI_FROM_DATABASE=XANTIA SA ++ + OUI:70B3D5340* + ID_OUI_FROM_DATABASE=Renesas Electronics + +@@ -59492,6 +69665,9 @@ OUI:70B3D5343* + OUI:70B3D5344* + ID_OUI_FROM_DATABASE=IHI Inspection & Instrumentation Co., Ltd. + ++OUI:70B3D5345* ++ ID_OUI_FROM_DATABASE=AT-Automation Technology GmbH ++ + OUI:70B3D5346* + ID_OUI_FROM_DATABASE=Ultamation Limited + +@@ -59507,12 +69683,21 @@ OUI:70B3D5349* + OUI:70B3D534A* + ID_OUI_FROM_DATABASE=PAVO TASARIM ÜRETİM TİC A.Ş. + ++OUI:70B3D534B* ++ ID_OUI_FROM_DATABASE=LEAFF ENGINEERING SRL ++ + OUI:70B3D534C* + ID_OUI_FROM_DATABASE=GLT Exports Ltd + ++OUI:70B3D534D* ++ ID_OUI_FROM_DATABASE=Equos Research Co., Ltd ++ + OUI:70B3D534E* + ID_OUI_FROM_DATABASE=Risk Expert sarl + ++OUI:70B3D534F* ++ ID_OUI_FROM_DATABASE=Royal Engineering Consultancy Private Limited ++ + OUI:70B3D5350* + ID_OUI_FROM_DATABASE=Tickster AB + +@@ -59525,15 +69710,30 @@ OUI:70B3D5352* + OUI:70B3D5353* + ID_OUI_FROM_DATABASE=Digital Outfit + ++OUI:70B3D5354* ++ ID_OUI_FROM_DATABASE=IMP-Computer Systems ++ ++OUI:70B3D5355* ++ ID_OUI_FROM_DATABASE=Hongin., Ltd ++ ++OUI:70B3D5356* ++ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos ++ + OUI:70B3D5357* + ID_OUI_FROM_DATABASE=Movimento Group AB + ++OUI:70B3D5358* ++ ID_OUI_FROM_DATABASE=Nevotek ++ + OUI:70B3D5359* + ID_OUI_FROM_DATABASE=Boutronic + + OUI:70B3D535A* + ID_OUI_FROM_DATABASE=Applied Radar, Inc. + ++OUI:70B3D535B* ++ ID_OUI_FROM_DATABASE=Nuance Hearing Ltd. ++ + OUI:70B3D535C* + ID_OUI_FROM_DATABASE=ACS electronics srl + +@@ -59556,7 +69756,7 @@ OUI:70B3D5362* + ID_OUI_FROM_DATABASE=Asiga + + OUI:70B3D5363* +- ID_OUI_FROM_DATABASE=Contec DTx ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. + + OUI:70B3D5364* + ID_OUI_FROM_DATABASE=ADAMCZEWSKI elektronische Messtechnik GmbH +@@ -59564,12 +69764,18 @@ OUI:70B3D5364* + OUI:70B3D5365* + ID_OUI_FROM_DATABASE=CircuitMeter Inc. + ++OUI:70B3D5366* ++ ID_OUI_FROM_DATABASE=Solarlytics, Inc. ++ + OUI:70B3D5367* + ID_OUI_FROM_DATABASE=Living Water + + OUI:70B3D5368* + ID_OUI_FROM_DATABASE=White Matter LLC + ++OUI:70B3D5369* ++ ID_OUI_FROM_DATABASE=ALVAT s.r.o. ++ + OUI:70B3D536A* + ID_OUI_FROM_DATABASE=Becton Dickinson + +@@ -59579,6 +69785,9 @@ OUI:70B3D536C* + OUI:70B3D536D* + ID_OUI_FROM_DATABASE=Cyberteam Sp z o o + ++OUI:70B3D536E* ++ ID_OUI_FROM_DATABASE=Electrónica Falcón S.A.U ++ + OUI:70B3D536F* + ID_OUI_FROM_DATABASE=BuddyGuard GmbH + +@@ -59588,6 +69797,12 @@ OUI:70B3D5370* + OUI:70B3D5371* + ID_OUI_FROM_DATABASE=BEDEROV GmbH + ++OUI:70B3D5372* ++ ID_OUI_FROM_DATABASE=MATELEX ++ ++OUI:70B3D5373* ++ ID_OUI_FROM_DATABASE=Hangzhou Weimu Technology Co.,Ltd. ++ + OUI:70B3D5374* + ID_OUI_FROM_DATABASE=OOO NPP Mars-Energo + +@@ -59595,7 +69810,7 @@ OUI:70B3D5375* + ID_OUI_FROM_DATABASE=Adel System srl + + OUI:70B3D5376* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Magenta Labs, Inc. + + OUI:70B3D5377* + ID_OUI_FROM_DATABASE=Monnit Corporation +@@ -59618,9 +69833,15 @@ OUI:70B3D537C* + OUI:70B3D537D* + ID_OUI_FROM_DATABASE=The DX Shop Limited + ++OUI:70B3D537E* ++ ID_OUI_FROM_DATABASE=ELINKGATE JSC ++ + OUI:70B3D537F* + ID_OUI_FROM_DATABASE=IDS Innomic GmbH + ++OUI:70B3D5380* ++ ID_OUI_FROM_DATABASE=SeaTech Intelligent Technology (Shanghai) Co., LTD ++ + OUI:70B3D5381* + ID_OUI_FROM_DATABASE=CRDE + +@@ -59633,23 +69854,56 @@ OUI:70B3D5383* + OUI:70B3D5384* + ID_OUI_FROM_DATABASE=Sensohive Technologies + ++OUI:70B3D5385* ++ ID_OUI_FROM_DATABASE=Kamacho Scale Co., Ltd. ++ ++OUI:70B3D5386* ++ ID_OUI_FROM_DATABASE=GPSat Systems ++ + OUI:70B3D5387* + ID_OUI_FROM_DATABASE=GWF MessSysteme AG + ++OUI:70B3D5388* ++ ID_OUI_FROM_DATABASE=Xitron ++ + OUI:70B3D5389* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D538A* ++ ID_OUI_FROM_DATABASE=KSE GmbH ++ + OUI:70B3D538B* + ID_OUI_FROM_DATABASE=Lookman Electroplast Industries Ltd + + OUI:70B3D538C* + ID_OUI_FROM_DATABASE=MiraeSignal Co., Ltd + ++OUI:70B3D538D* ++ ID_OUI_FROM_DATABASE=IMP-TELEKOMUNIKACIJE DOO ++ ++OUI:70B3D538E* ++ ID_OUI_FROM_DATABASE=China Telecom Fufu Information Technology CO.,LTD ++ + OUI:70B3D538F* + ID_OUI_FROM_DATABASE=Sorynorydotcom Inc + ++OUI:70B3D5390* ++ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL ++ ++OUI:70B3D5391* ++ ID_OUI_FROM_DATABASE=Changshu Ruite Electric Co.,Ltd. ++ + OUI:70B3D5392* +- ID_OUI_FROM_DATABASE=Contec DTx ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. ++ ++OUI:70B3D5393* ++ ID_OUI_FROM_DATABASE=Monnit Corporation ++ ++OUI:70B3D5394* ++ ID_OUI_FROM_DATABASE=Romteck Australia ++ ++OUI:70B3D5395* ++ ID_OUI_FROM_DATABASE=ICsec S.A. + + OUI:70B3D5396* + ID_OUI_FROM_DATABASE=CTG sp. z o. o. +@@ -59657,6 +69911,12 @@ OUI:70B3D5396* + OUI:70B3D5397* + ID_OUI_FROM_DATABASE=Guangxi Hunter Information Industry Co.,Ltd + ++OUI:70B3D5398* ++ ID_OUI_FROM_DATABASE=SIPRO s.r.l. ++ ++OUI:70B3D5399* ++ ID_OUI_FROM_DATABASE=SPE Smartico, LLC ++ + OUI:70B3D539A* + ID_OUI_FROM_DATABASE=Videotrend srl + +@@ -59672,9 +69932,30 @@ OUI:70B3D539D* + OUI:70B3D539E* + ID_OUI_FROM_DATABASE=Lanmark Controls Inc. + ++OUI:70B3D539F* ++ ID_OUI_FROM_DATABASE=CT Company ++ ++OUI:70B3D53A0* ++ ID_OUI_FROM_DATABASE=chiconypower ++ ++OUI:70B3D53A1* ++ ID_OUI_FROM_DATABASE=Reckeen HDP Media sp. z o.o. sp. k. ++ ++OUI:70B3D53A2* ++ ID_OUI_FROM_DATABASE=Daifuku CO., Ltd. ++ ++OUI:70B3D53A3* ++ ID_OUI_FROM_DATABASE=CDS Institute of Management Strategy, Inc. ++ ++OUI:70B3D53A4* ++ ID_OUI_FROM_DATABASE=Ascenix Corporation ++ + OUI:70B3D53A5* + ID_OUI_FROM_DATABASE=KMtronic ltd + ++OUI:70B3D53A6* ++ ID_OUI_FROM_DATABASE=myenergi Ltd ++ + OUI:70B3D53A7* + ID_OUI_FROM_DATABASE=Varikorea + +@@ -59687,6 +69968,12 @@ OUI:70B3D53A9* + OUI:70B3D53AA* + ID_OUI_FROM_DATABASE=RCATSONE + ++OUI:70B3D53AB* ++ ID_OUI_FROM_DATABASE=Camozzi Automation SpA ++ ++OUI:70B3D53AC* ++ ID_OUI_FROM_DATABASE=RF-Tuote Oy ++ + OUI:70B3D53AD* + ID_OUI_FROM_DATABASE=CT Company + +@@ -59699,18 +69986,33 @@ OUI:70B3D53AF* + OUI:70B3D53B0* + ID_OUI_FROM_DATABASE=Millennial Net, Inc. + ++OUI:70B3D53B1* ++ ID_OUI_FROM_DATABASE=Global Power Products ++ + OUI:70B3D53B2* + ID_OUI_FROM_DATABASE=Sicon srl + ++OUI:70B3D53B3* ++ ID_OUI_FROM_DATABASE=Movicom Electric LLC ++ ++OUI:70B3D53B4* ++ ID_OUI_FROM_DATABASE=YOUSUNG ++ + OUI:70B3D53B5* + ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience + ++OUI:70B3D53B6* ++ ID_OUI_FROM_DATABASE=MedRx, Inc ++ + OUI:70B3D53B7* + ID_OUI_FROM_DATABASE=Paul Scherrer Institut (PSI) + + OUI:70B3D53B8* + ID_OUI_FROM_DATABASE=nVideon, Inc. + ++OUI:70B3D53B9* ++ ID_OUI_FROM_DATABASE=BirdDog Australia ++ + OUI:70B3D53BA* + ID_OUI_FROM_DATABASE=Silex Inside + +@@ -59720,6 +70022,9 @@ OUI:70B3D53BB* + OUI:70B3D53BC* + ID_OUI_FROM_DATABASE=SciTronix + ++OUI:70B3D53BD* ++ ID_OUI_FROM_DATABASE=DAO QIN TECHNOLOGY CO.LTD. ++ + OUI:70B3D53BE* + ID_OUI_FROM_DATABASE=MyDefence Communication ApS + +@@ -59729,6 +70034,9 @@ OUI:70B3D53BF* + OUI:70B3D53C0* + ID_OUI_FROM_DATABASE=DK-Technologies A/S + ++OUI:70B3D53C1* ++ ID_OUI_FROM_DATABASE=thingdust AG ++ + OUI:70B3D53C2* + ID_OUI_FROM_DATABASE=Cellular Specialties, Inc. + +@@ -59747,27 +70055,51 @@ OUI:70B3D53C6* + OUI:70B3D53C7* + ID_OUI_FROM_DATABASE=SOFTCREATE CORP. + ++OUI:70B3D53C8* ++ ID_OUI_FROM_DATABASE=ABC Electric Co. ++ + OUI:70B3D53C9* + ID_OUI_FROM_DATABASE=Duerkopp-Adler + + OUI:70B3D53CA* + ID_OUI_FROM_DATABASE=TTI Ltd + ++OUI:70B3D53CB* ++ ID_OUI_FROM_DATABASE=GeoSpectrum Technologies Inc ++ + OUI:70B3D53CC* + ID_OUI_FROM_DATABASE=TerOpta Ltd + ++OUI:70B3D53CD* ++ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos ++ + OUI:70B3D53CE* + ID_OUI_FROM_DATABASE=Aditec GmbH + + OUI:70B3D53CF* + ID_OUI_FROM_DATABASE=Systems Engineering Arts Pty Ltd + ++OUI:70B3D53D0* ++ ID_OUI_FROM_DATABASE=ORtek Technology, Inc. ++ ++OUI:70B3D53D1* ++ ID_OUI_FROM_DATABASE=Imenco Ltd ++ + OUI:70B3D53D2* + ID_OUI_FROM_DATABASE=Imagine Inc. + ++OUI:70B3D53D3* ++ ID_OUI_FROM_DATABASE=GS Elektromedizinsiche Geräte G. Stemple GmbH ++ ++OUI:70B3D53D4* ++ ID_OUI_FROM_DATABASE=Sanmina Israel ++ + OUI:70B3D53D5* + ID_OUI_FROM_DATABASE=oxynet Solutions + ++OUI:70B3D53D6* ++ ID_OUI_FROM_DATABASE=Ariston Thermo s.p.a. ++ + OUI:70B3D53D7* + ID_OUI_FROM_DATABASE=Remote Sensing Solutions, Inc. + +@@ -59783,12 +70115,21 @@ OUI:70B3D53DA* + OUI:70B3D53DB* + ID_OUI_FROM_DATABASE=KST technology + ++OUI:70B3D53DC* ++ ID_OUI_FROM_DATABASE=XIA LLC ++ ++OUI:70B3D53DD* ++ ID_OUI_FROM_DATABASE=Kniggendorf + Kögler Security GmbH ++ + OUI:70B3D53DE* + ID_OUI_FROM_DATABASE=ELOMAC Elektronik GmbH + + OUI:70B3D53DF* + ID_OUI_FROM_DATABASE=MultiDyne + ++OUI:70B3D53E0* ++ ID_OUI_FROM_DATABASE=Gogo Business Aviation ++ + OUI:70B3D53E1* + ID_OUI_FROM_DATABASE=Barnstormer Softworks + +@@ -59807,15 +70148,30 @@ OUI:70B3D53E5* + OUI:70B3D53E6* + ID_OUI_FROM_DATABASE=machineQ + ++OUI:70B3D53E7* ++ ID_OUI_FROM_DATABASE=JNR Sports Holdings, LLC ++ + OUI:70B3D53E8* + ID_OUI_FROM_DATABASE=COSMOS web Co., Ltd. + + OUI:70B3D53E9* + ID_OUI_FROM_DATABASE=APOLLO GIKEN Co.,Ltd. + ++OUI:70B3D53EA* ++ ID_OUI_FROM_DATABASE=DAVE SRL ++ ++OUI:70B3D53EB* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ ++OUI:70B3D53EC* ++ ID_OUI_FROM_DATABASE=Outsight SA ++ + OUI:70B3D53ED* + ID_OUI_FROM_DATABASE=Ultra Electronics Sonar System Division + ++OUI:70B3D53EE* ++ ID_OUI_FROM_DATABASE=Laser Imagineering Vertriebs GmbH ++ + OUI:70B3D53EF* + ID_OUI_FROM_DATABASE=Vtron Pty Ltd + +@@ -59843,11 +70199,26 @@ OUI:70B3D53F6* + OUI:70B3D53F7* + ID_OUI_FROM_DATABASE=Advansid + ++OUI:70B3D53F8* ++ ID_OUI_FROM_DATABASE=The Fire Horn, Inc. ++ + OUI:70B3D53F9* + ID_OUI_FROM_DATABASE=Herrick Tech Labs + ++OUI:70B3D53FA* ++ ID_OUI_FROM_DATABASE=Zaklad Energoelektroniki Twerd ++ ++OUI:70B3D53FB* ++ ID_OUI_FROM_DATABASE=Liberty Reach ++ ++OUI:70B3D53FC* ++ ID_OUI_FROM_DATABASE=TangRen C&S CO., Ltd ++ ++OUI:70B3D53FD* ++ ID_OUI_FROM_DATABASE=NaraControls Inc ++ + OUI:70B3D53FE* +- ID_OUI_FROM_DATABASE=Mentor Graphics ++ ID_OUI_FROM_DATABASE=Siemens Industry Software Inc. + + OUI:70B3D53FF* + ID_OUI_FROM_DATABASE=Hydra Controls +@@ -59858,6 +70229,12 @@ OUI:70B3D5400* + OUI:70B3D5401* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D5402* ++ ID_OUI_FROM_DATABASE=AKIS technologies ++ ++OUI:70B3D5403* ++ ID_OUI_FROM_DATABASE=Mighty Cube Co., Ltd. ++ + OUI:70B3D5404* + ID_OUI_FROM_DATABASE=RANIX,Inc. + +@@ -59873,21 +70250,48 @@ OUI:70B3D5407* + OUI:70B3D5408* + ID_OUI_FROM_DATABASE=Comrod AS + ++OUI:70B3D5409* ++ ID_OUI_FROM_DATABASE=Beijing Yutian Technology Co., Ltd. ++ + OUI:70B3D540A* + ID_OUI_FROM_DATABASE=Monroe Electronics, Inc. + ++OUI:70B3D540B* ++ ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. ++ ++OUI:70B3D540C* ++ ID_OUI_FROM_DATABASE=Tornado Modular Systems ++ ++OUI:70B3D540D* ++ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. ++ ++OUI:70B3D540E* ++ ID_OUI_FROM_DATABASE=Liaoyun Information Technology Co., Ltd. ++ ++OUI:70B3D540F* ++ ID_OUI_FROM_DATABASE=NEXELEC ++ + OUI:70B3D5410* + ID_OUI_FROM_DATABASE=Avant Technologies, Inc + ++OUI:70B3D5411* ++ ID_OUI_FROM_DATABASE=Mi-Fi Networks Pvt Ltd ++ + OUI:70B3D5412* + ID_OUI_FROM_DATABASE=TATTILE SRL + + OUI:70B3D5413* + ID_OUI_FROM_DATABASE=Axess AG + ++OUI:70B3D5414* ++ ID_OUI_FROM_DATABASE=Smith Meter, Inc. ++ + OUI:70B3D5415* + ID_OUI_FROM_DATABASE=IDEA SPA + ++OUI:70B3D5416* ++ ID_OUI_FROM_DATABASE=Antlia Systems ++ + OUI:70B3D5417* + ID_OUI_FROM_DATABASE=Figment Design Laboratories + +@@ -59897,12 +70301,39 @@ OUI:70B3D5418* + OUI:70B3D541A* + ID_OUI_FROM_DATABASE=HYOSUNG Power & Industrial Systems + ++OUI:70B3D541B* ++ ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH ++ ++OUI:70B3D541C* ++ ID_OUI_FROM_DATABASE=Twoway Communications, Inc. ++ ++OUI:70B3D541D* ++ ID_OUI_FROM_DATABASE=Azmoon Keifiat ++ + OUI:70B3D541E* + ID_OUI_FROM_DATABASE=Redler Computers + ++OUI:70B3D541F* ++ ID_OUI_FROM_DATABASE=Orion S.r.l. ++ ++OUI:70B3D5420* ++ ID_OUI_FROM_DATABASE=ECOINET ++ + OUI:70B3D5421* + ID_OUI_FROM_DATABASE=North Star Bestech Co., + ++OUI:70B3D5422* ++ ID_OUI_FROM_DATABASE=SUS Corporation ++ ++OUI:70B3D5423* ++ ID_OUI_FROM_DATABASE=Harman Connected Services Corporation India Pvt. Ltd. ++ ++OUI:70B3D5424* ++ ID_OUI_FROM_DATABASE=Underground Systems, Inc. ++ ++OUI:70B3D5425* ++ ID_OUI_FROM_DATABASE=SinterCast ++ + OUI:70B3D5426* + ID_OUI_FROM_DATABASE=Zehnder Group Nederland + +@@ -59918,11 +70349,17 @@ OUI:70B3D5429* + OUI:70B3D542A* + ID_OUI_FROM_DATABASE=Critical Link LLC + ++OUI:70B3D542B* ++ ID_OUI_FROM_DATABASE=Guangzhou Haoxiang Computer Technology Co.,Ltd. ++ + OUI:70B3D542C* + ID_OUI_FROM_DATABASE=D.Marchiori Srl + + OUI:70B3D542D* +- ID_OUI_FROM_DATABASE=RCH Italia SpA ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ ++OUI:70B3D542E* ++ ID_OUI_FROM_DATABASE=Dr. Zinngrebe GmbH + + OUI:70B3D542F* + ID_OUI_FROM_DATABASE=SINTOKOGIO, LTD +@@ -59948,48 +70385,114 @@ OUI:70B3D5435* + OUI:70B3D5436* + ID_OUI_FROM_DATABASE=Henrich Electronics Corporation + ++OUI:70B3D5437* ++ ID_OUI_FROM_DATABASE=Digital Way ++ + OUI:70B3D5439* + ID_OUI_FROM_DATABASE=TriLED + ++OUI:70B3D543A* ++ ID_OUI_FROM_DATABASE=ARKS Enterprises, Inc. ++ + OUI:70B3D543B* + ID_OUI_FROM_DATABASE=Kalycito Infotech Private Limited + ++OUI:70B3D543C* ++ ID_OUI_FROM_DATABASE=Scenario Automation ++ + OUI:70B3D543D* + ID_OUI_FROM_DATABASE=Veryx Technologies Private Limited + ++OUI:70B3D543E* ++ ID_OUI_FROM_DATABASE=Peloton Technology ++ ++OUI:70B3D543F* ++ ID_OUI_FROM_DATABASE=biosilver .co.,ltd ++ + OUI:70B3D5440* + ID_OUI_FROM_DATABASE=Discover Video + ++OUI:70B3D5441* ++ ID_OUI_FROM_DATABASE=Videoport S.A. ++ + OUI:70B3D5442* + ID_OUI_FROM_DATABASE=Blair Companies + + OUI:70B3D5443* + ID_OUI_FROM_DATABASE=Slot3 GmbH + ++OUI:70B3D5444* ++ ID_OUI_FROM_DATABASE=AMS Controls, Inc. ++ + OUI:70B3D5445* + ID_OUI_FROM_DATABASE=Advanced Devices SpA + + OUI:70B3D5446* + ID_OUI_FROM_DATABASE=Santa Barbara Imaging Systems + ++OUI:70B3D5447* ++ ID_OUI_FROM_DATABASE=Avid Controls Inc ++ + OUI:70B3D5448* + ID_OUI_FROM_DATABASE=B/E Aerospace, Inc. + ++OUI:70B3D5449* ++ ID_OUI_FROM_DATABASE=Edgeware AB ++ ++OUI:70B3D544A* ++ ID_OUI_FROM_DATABASE=CANON ELECTRON TUBES & DEVICES CO., LTD. ++ + OUI:70B3D544B* + ID_OUI_FROM_DATABASE=Open System Solutions Limited + ++OUI:70B3D544C* ++ ID_OUI_FROM_DATABASE=ejoin, s.r.o. ++ ++OUI:70B3D544D* ++ ID_OUI_FROM_DATABASE=Vessel Technology Ltd ++ + OUI:70B3D544E* + ID_OUI_FROM_DATABASE=Solace Systems Inc. + ++OUI:70B3D544F* ++ ID_OUI_FROM_DATABASE=Velvac Incorporated ++ ++OUI:70B3D5450* ++ ID_OUI_FROM_DATABASE=Apantac LLC ++ ++OUI:70B3D5451* ++ ID_OUI_FROM_DATABASE=Perform3-D LLC ++ ++OUI:70B3D5452* ++ ID_OUI_FROM_DATABASE=ITALIANA PONTI RADIO SRL ++ ++OUI:70B3D5453* ++ ID_OUI_FROM_DATABASE=Foerster-Technik GmbH ++ ++OUI:70B3D5454* ++ ID_OUI_FROM_DATABASE=Golding Audio Ltd ++ + OUI:70B3D5455* + ID_OUI_FROM_DATABASE=Heartlandmicropayments + ++OUI:70B3D5456* ++ ID_OUI_FROM_DATABASE=Technological Application and Production One Member Liability Company (Tecapro company) ++ + OUI:70B3D5457* + ID_OUI_FROM_DATABASE=Vivaldi Clima Srl + ++OUI:70B3D5458* ++ ID_OUI_FROM_DATABASE=Ongisul Co.,Ltd. ++ + OUI:70B3D5459* + ID_OUI_FROM_DATABASE=Protium Technologies, Inc. + ++OUI:70B3D545A* ++ ID_OUI_FROM_DATABASE=Palarum LLC ++ ++OUI:70B3D545B* ++ ID_OUI_FROM_DATABASE=KOMZ - IZMERENIYA ++ + OUI:70B3D545C* + ID_OUI_FROM_DATABASE=AlyTech + +@@ -60011,18 +70514,39 @@ OUI:70B3D5461* + OUI:70B3D5462* + ID_OUI_FROM_DATABASE=EarTex + ++OUI:70B3D5463* ++ ID_OUI_FROM_DATABASE=WARECUBE,INC ++ + OUI:70B3D5465* + ID_OUI_FROM_DATABASE=ENERGISME + ++OUI:70B3D5466* ++ ID_OUI_FROM_DATABASE=SYLink Technologie ++ ++OUI:70B3D5467* ++ ID_OUI_FROM_DATABASE=GreenWake Technologies ++ ++OUI:70B3D5468* ++ ID_OUI_FROM_DATABASE=Shanghai Junqian Sensing Technology Co., LTD ++ + OUI:70B3D5469* + ID_OUI_FROM_DATABASE=Gentec Systems Co. + ++OUI:70B3D546A* ++ ID_OUI_FROM_DATABASE=Shenzhen Vikings Technology Co., Ltd. ++ + OUI:70B3D546B* + ID_OUI_FROM_DATABASE=Airborne Engineering Limited + + OUI:70B3D546C* + ID_OUI_FROM_DATABASE=SHANGHAI CHENZHU INSTRUMENT CO., LTD. + ++OUI:70B3D546D* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ ++OUI:70B3D546E* ++ ID_OUI_FROM_DATABASE=Zamir Recognition Systems Ltd. ++ + OUI:70B3D546F* + ID_OUI_FROM_DATABASE=serva transport systems GmbH + +@@ -60035,33 +70559,69 @@ OUI:70B3D5471* + OUI:70B3D5472* + ID_OUI_FROM_DATABASE=Quadio Devices Private Limited + ++OUI:70B3D5473* ++ ID_OUI_FROM_DATABASE=KeyProd ++ ++OUI:70B3D5474* ++ ID_OUI_FROM_DATABASE=CTROGERS LLC ++ + OUI:70B3D5475* + ID_OUI_FROM_DATABASE=EWATTCH + + OUI:70B3D5476* + ID_OUI_FROM_DATABASE=FR-Team International SA + ++OUI:70B3D5477* ++ ID_OUI_FROM_DATABASE=digitrol limited ++ + OUI:70B3D5478* + ID_OUI_FROM_DATABASE=Touchnet/OneCard + + OUI:70B3D5479* + ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., + ++OUI:70B3D547A* ++ ID_OUI_FROM_DATABASE=GlooVir Inc. ++ ++OUI:70B3D547B* ++ ID_OUI_FROM_DATABASE=Monixo ++ + OUI:70B3D547C* + ID_OUI_FROM_DATABASE=Par-Tech, Inc. + ++OUI:70B3D547D* ++ ID_OUI_FROM_DATABASE=Shenyang TECHE Technology Co.,Ltd ++ ++OUI:70B3D547E* ++ ID_OUI_FROM_DATABASE=Fiber Optika Technologies Pvt. Ltd. ++ + OUI:70B3D547F* + ID_OUI_FROM_DATABASE=ASE GmbH + + OUI:70B3D5480* + ID_OUI_FROM_DATABASE=Emergency Lighting Products Limited + ++OUI:70B3D5481* ++ ID_OUI_FROM_DATABASE=STEP sarl ++ + OUI:70B3D5482* + ID_OUI_FROM_DATABASE=Aeryon Labs Inc + ++OUI:70B3D5483* ++ ID_OUI_FROM_DATABASE=LITUM BILGI TEKNOLOJILERI SAN. VE TIC. A.S. ++ ++OUI:70B3D5484* ++ ID_OUI_FROM_DATABASE=Hermann Sewerin GmbH ++ ++OUI:70B3D5485* ++ ID_OUI_FROM_DATABASE=CLARESYS LIMITED ++ + OUI:70B3D5486* + ID_OUI_FROM_DATABASE=ChongQing JianTao Technology Co., Ltd. + ++OUI:70B3D5487* ++ ID_OUI_FROM_DATABASE=ECS s.r.l. ++ + OUI:70B3D5488* + ID_OUI_FROM_DATABASE=Cardinal Scale Mfg Co + +@@ -60071,6 +70631,9 @@ OUI:70B3D5489* + OUI:70B3D548A* + ID_OUI_FROM_DATABASE=George Wilson Industries Ltd + ++OUI:70B3D548B* ++ ID_OUI_FROM_DATABASE=TATTILE SRL ++ + OUI:70B3D548C* + ID_OUI_FROM_DATABASE=Integrated Systems Engineering, Inc. + +@@ -60083,6 +70646,12 @@ OUI:70B3D548E* + OUI:70B3D548F* + ID_OUI_FROM_DATABASE=Seiwa Giken + ++OUI:70B3D5490* ++ ID_OUI_FROM_DATABASE=Xiamen Beogold Technology Co. Ltd. ++ ++OUI:70B3D5491* ++ ID_OUI_FROM_DATABASE=VONSCH ++ + OUI:70B3D5492* + ID_OUI_FROM_DATABASE=Jiangsu Jinheng Information Technology Co.,Ltd. + +@@ -60095,6 +70664,12 @@ OUI:70B3D5494* + OUI:70B3D5495* + ID_OUI_FROM_DATABASE=Fiem Industries Ltd. + ++OUI:70B3D5496* ++ ID_OUI_FROM_DATABASE=Profcon AB ++ ++OUI:70B3D5497* ++ ID_OUI_FROM_DATABASE=ALBIRAL DISPLAY SOLUTIONS SL ++ + OUI:70B3D5498* + ID_OUI_FROM_DATABASE=XGEM SAS + +@@ -60107,6 +70682,12 @@ OUI:70B3D549A* + OUI:70B3D549B* + ID_OUI_FROM_DATABASE=Algodue Elettronica Srl + ++OUI:70B3D549C* ++ ID_OUI_FROM_DATABASE=AC Power Corp. ++ ++OUI:70B3D549D* ++ ID_OUI_FROM_DATABASE=Shenzhen Chanslink Network Technology Co., Ltd ++ + OUI:70B3D549E* + ID_OUI_FROM_DATABASE=CAPTEMP, Lda + +@@ -60119,6 +70700,15 @@ OUI:70B3D54A0* + OUI:70B3D54A1* + ID_OUI_FROM_DATABASE=Herholdt Controls srl + ++OUI:70B3D54A2* ++ ID_OUI_FROM_DATABASE=DEVAU Lemppenau GmbH ++ ++OUI:70B3D54A3* ++ ID_OUI_FROM_DATABASE=TUALCOM ELEKTRONIK A.S. ++ ++OUI:70B3D54A4* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ + OUI:70B3D54A5* + ID_OUI_FROM_DATABASE=Intermind Inc. + +@@ -60128,12 +70718,21 @@ OUI:70B3D54A6* + OUI:70B3D54A7* + ID_OUI_FROM_DATABASE=aelettronica group srl + ++OUI:70B3D54A8* ++ ID_OUI_FROM_DATABASE=Acrodea, Inc. ++ + OUI:70B3D54A9* + ID_OUI_FROM_DATABASE=WARECUBE,INC + + OUI:70B3D54AA* + ID_OUI_FROM_DATABASE=Twoway Communications, Inc. + ++OUI:70B3D54AB* ++ ID_OUI_FROM_DATABASE=TruTeq Wireless (Pty) Ltd ++ ++OUI:70B3D54AC* ++ ID_OUI_FROM_DATABASE=Microsoft Research ++ + OUI:70B3D54AD* + ID_OUI_FROM_DATABASE=GACI + +@@ -60152,9 +70751,15 @@ OUI:70B3D54B1* + OUI:70B3D54B2* + ID_OUI_FROM_DATABASE=Certus Operations Ltd + ++OUI:70B3D54B3* ++ ID_OUI_FROM_DATABASE=Bacsoft ++ + OUI:70B3D54B4* + ID_OUI_FROM_DATABASE=Hi Tech Systems Ltd + ++OUI:70B3D54B5* ++ ID_OUI_FROM_DATABASE=Toolplanet Co., Ltd. ++ + OUI:70B3D54B6* + ID_OUI_FROM_DATABASE=VEILUX INC. + +@@ -60173,12 +70778,18 @@ OUI:70B3D54BA* + OUI:70B3D54BB* + ID_OUI_FROM_DATABASE=Plazma-T + ++OUI:70B3D54BC* ++ ID_OUI_FROM_DATABASE=TIAMA ++ + OUI:70B3D54BD* + ID_OUI_FROM_DATABASE=Boulder Amplifiers, Inc. + + OUI:70B3D54BE* + ID_OUI_FROM_DATABASE=GY-FX SAS + ++OUI:70B3D54BF* ++ ID_OUI_FROM_DATABASE=Exsom Computers LLC ++ + OUI:70B3D54C0* + ID_OUI_FROM_DATABASE=Technica Engineering GmbH + +@@ -60188,18 +70799,36 @@ OUI:70B3D54C1* + OUI:70B3D54C2* + ID_OUI_FROM_DATABASE=hera Laborsysteme GmbH + ++OUI:70B3D54C3* ++ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG ++ + OUI:70B3D54C4* + ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies + + OUI:70B3D54C5* + ID_OUI_FROM_DATABASE=Moving iMage Technologies LLC + ++OUI:70B3D54C6* ++ ID_OUI_FROM_DATABASE=BlueBox Video Limited ++ + OUI:70B3D54C7* + ID_OUI_FROM_DATABASE=SOLVERIS sp. z o.o. + + OUI:70B3D54C8* + ID_OUI_FROM_DATABASE=Hosokawa Micron Powder Systems + ++OUI:70B3D54C9* ++ ID_OUI_FROM_DATABASE=Elsist Srl ++ ++OUI:70B3D54CA* ++ ID_OUI_FROM_DATABASE=PCB Piezotronics ++ ++OUI:70B3D54CB* ++ ID_OUI_FROM_DATABASE=Cucos Retail Systems GmbH ++ ++OUI:70B3D54CC* ++ ID_OUI_FROM_DATABASE=FRESENIUS MEDICAL CARE ++ + OUI:70B3D54CD* + ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. + +@@ -60209,18 +70838,39 @@ OUI:70B3D54CE* + OUI:70B3D54CF* + ID_OUI_FROM_DATABASE=GREEN HOUSE CO., LTD. + ++OUI:70B3D54D0* ++ ID_OUI_FROM_DATABASE=Codewerk GmbH ++ + OUI:70B3D54D1* + ID_OUI_FROM_DATABASE=Contraves Advanced Devices Sdn. Bhd. + ++OUI:70B3D54D2* ++ ID_OUI_FROM_DATABASE=Biotage Sweden AB ++ ++OUI:70B3D54D3* ++ ID_OUI_FROM_DATABASE=Hefei STAROT Technology Co.,Ltd ++ + OUI:70B3D54D4* + ID_OUI_FROM_DATABASE=Nortek Global HVAC + + OUI:70B3D54D5* + ID_OUI_FROM_DATABASE=Moog Rekofa GmbH + ++OUI:70B3D54D6* ++ ID_OUI_FROM_DATABASE=Operational Technology Solutions ++ ++OUI:70B3D54D7* ++ ID_OUI_FROM_DATABASE=Technological Ray GmbH ++ + OUI:70B3D54D8* + ID_OUI_FROM_DATABASE=Versilis Inc. + ++OUI:70B3D54D9* ++ ID_OUI_FROM_DATABASE=Coda Octopus Products Limited ++ ++OUI:70B3D54DA* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:70B3D54DB* + ID_OUI_FROM_DATABASE=Temperature@lert + +@@ -60228,7 +70878,7 @@ OUI:70B3D54DC* + ID_OUI_FROM_DATABASE=JK DEVICE CORPORATION + + OUI:70B3D54DD* +- ID_OUI_FROM_DATABASE=Road-iQ, LLC ++ ID_OUI_FROM_DATABASE=Velvac Incorporated + + OUI:70B3D54DE* + ID_OUI_FROM_DATABASE=Oso Technologies, Inc. +@@ -60236,45 +70886,102 @@ OUI:70B3D54DE* + OUI:70B3D54DF* + ID_OUI_FROM_DATABASE=Nidec Avtron Automation Corp + ++OUI:70B3D54E0* ++ ID_OUI_FROM_DATABASE=Microvideo ++ + OUI:70B3D54E1* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + ++OUI:70B3D54E2* ++ ID_OUI_FROM_DATABASE=Transit Solutions, LLC. ++ ++OUI:70B3D54E3* ++ ID_OUI_FROM_DATABASE=adnexo GmbH ++ ++OUI:70B3D54E4* ++ ID_OUI_FROM_DATABASE=W.A. Benjamin Electric Co. ++ + OUI:70B3D54E5* + ID_OUI_FROM_DATABASE=viZaar industrial imaging AG + ++OUI:70B3D54E6* ++ ID_OUI_FROM_DATABASE=Santa Barbara Imaging Systems ++ + OUI:70B3D54E7* + ID_OUI_FROM_DATABASE=Digital Domain + ++OUI:70B3D54E8* ++ ID_OUI_FROM_DATABASE=Copious Imaging LLC ++ + OUI:70B3D54E9* + ID_OUI_FROM_DATABASE=ADETEC SAS + ++OUI:70B3D54EA* ++ ID_OUI_FROM_DATABASE=Vocality international T/A Cubic ++ + OUI:70B3D54EB* + ID_OUI_FROM_DATABASE=INFOSOFT DIGITAL DESIGN & SERVICES PRIVATE LIMITED + + OUI:70B3D54EC* + ID_OUI_FROM_DATABASE=Hangzhou Youshi Industry Co., Ltd. + ++OUI:70B3D54ED* ++ ID_OUI_FROM_DATABASE=Panoramic Power ++ ++OUI:70B3D54EE* ++ ID_OUI_FROM_DATABASE=NOA Co., Ltd. ++ + OUI:70B3D54EF* + ID_OUI_FROM_DATABASE=CMI, Inc. + + OUI:70B3D54F0* + ID_OUI_FROM_DATABASE=Li Seng Technology Ltd., + ++OUI:70B3D54F1* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ ++OUI:70B3D54F2* ++ ID_OUI_FROM_DATABASE=COMPAL ELECTRONICS, INC. ++ ++OUI:70B3D54F3* ++ ID_OUI_FROM_DATABASE=XPS ELETRONICA LTDA ++ + OUI:70B3D54F4* + ID_OUI_FROM_DATABASE=WiTagg, Inc + ++OUI:70B3D54F5* ++ ID_OUI_FROM_DATABASE=Orlaco Products B.V. ++ ++OUI:70B3D54F6* ++ ID_OUI_FROM_DATABASE=DORLET SAU ++ ++OUI:70B3D54F7* ++ ID_OUI_FROM_DATABASE=Foxtel srl ++ + OUI:70B3D54F8* + ID_OUI_FROM_DATABASE=Private + + OUI:70B3D54F9* + ID_OUI_FROM_DATABASE=OptoPrecision GmbH + ++OUI:70B3D54FA* ++ ID_OUI_FROM_DATABASE=Thruvision Limited ++ ++OUI:70B3D54FB* ++ ID_OUI_FROM_DATABASE=MAS Elettronica sas di Mascetti Sandro e C. ++ + OUI:70B3D54FC* + ID_OUI_FROM_DATABASE=Mettler Toledo + ++OUI:70B3D54FD* ++ ID_OUI_FROM_DATABASE=ENLESS WIRELESS ++ + OUI:70B3D54FE* + ID_OUI_FROM_DATABASE=WiTagg, Inc + ++OUI:70B3D54FF* ++ ID_OUI_FROM_DATABASE=Shanghai AiGentoo Information Technology Co.,Ltd. ++ + OUI:70B3D5500* + ID_OUI_FROM_DATABASE=Mistral Solutions Pvt. LTD + +@@ -60293,27 +71000,69 @@ OUI:70B3D5504* + OUI:70B3D5505* + ID_OUI_FROM_DATABASE=MC2-Technologies + ++OUI:70B3D5506* ++ ID_OUI_FROM_DATABASE=Tonbo Imaging Pte Ltd ++ + OUI:70B3D5507* + ID_OUI_FROM_DATABASE=Human Oriented Technology, Inc. + + OUI:70B3D5508* + ID_OUI_FROM_DATABASE=INSEVIS GmbH + ++OUI:70B3D5509* ++ ID_OUI_FROM_DATABASE=Tinkerforge GmbH ++ ++OUI:70B3D550A* ++ ID_OUI_FROM_DATABASE=AMEDTEC Medizintechnik Aue GmbH ++ ++OUI:70B3D550B* ++ ID_OUI_FROM_DATABASE=Nordson Corporation ++ ++OUI:70B3D550C* ++ ID_OUI_FROM_DATABASE=Hangzhou landesker digital technology co. LTD ++ ++OUI:70B3D550D* ++ ID_OUI_FROM_DATABASE=CT Company ++ + OUI:70B3D550E* + ID_OUI_FROM_DATABASE=Micro Trend Automation Co., LTD + ++OUI:70B3D550F* ++ ID_OUI_FROM_DATABASE=LLC Sarov Innovative Technologies (WIZOLUTION) ++ ++OUI:70B3D5510* ++ ID_OUI_FROM_DATABASE=PSL ELEKTRONİK SANAYİ VE TİCARET A.S. ++ + OUI:70B3D5511* + ID_OUI_FROM_DATABASE=Next Sight srl + ++OUI:70B3D5512* ++ ID_OUI_FROM_DATABASE=Techno Broad,Inc ++ + OUI:70B3D5513* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D5514* ++ ID_OUI_FROM_DATABASE=Intelligent Security Systems (ISS) ++ + OUI:70B3D5515* + ID_OUI_FROM_DATABASE=PCSC + ++OUI:70B3D5516* ++ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., ++ + OUI:70B3D5517* + ID_OUI_FROM_DATABASE=ISPHER + ++OUI:70B3D5518* ++ ID_OUI_FROM_DATABASE=CRUXELL Corp. ++ ++OUI:70B3D5519* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D551A* ++ ID_OUI_FROM_DATABASE=Shachihata Inc. ++ + OUI:70B3D551B* + ID_OUI_FROM_DATABASE=Vitrea Smart Home Technologies + +@@ -60326,6 +71075,15 @@ OUI:70B3D551D* + OUI:70B3D551E* + ID_OUI_FROM_DATABASE=Fundación Cardiovascular de Colombia + ++OUI:70B3D551F* ++ ID_OUI_FROM_DATABASE=VALEO CDA ++ ++OUI:70B3D5520* ++ ID_OUI_FROM_DATABASE=promedias AG ++ ++OUI:70B3D5521* ++ ID_OUI_FROM_DATABASE=Selex ES Inc. ++ + OUI:70B3D5522* + ID_OUI_FROM_DATABASE=Syncopated Engineering Inc + +@@ -60341,9 +71099,18 @@ OUI:70B3D5525* + OUI:70B3D5526* + ID_OUI_FROM_DATABASE=FlowNet LLC + ++OUI:70B3D5527* ++ ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd ++ + OUI:70B3D5528* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D5529* ++ ID_OUI_FROM_DATABASE=Inventeq B.V. ++ ++OUI:70B3D552A* ++ ID_OUI_FROM_DATABASE=Dataflex International BV ++ + OUI:70B3D552B* + ID_OUI_FROM_DATABASE=GE Aviation Cheltenham + +@@ -60356,6 +71123,9 @@ OUI:70B3D552D* + OUI:70B3D552E* + ID_OUI_FROM_DATABASE=Swissponic Sagl + ++OUI:70B3D552F* ++ ID_OUI_FROM_DATABASE=R.C. Systems Inc ++ + OUI:70B3D5530* + ID_OUI_FROM_DATABASE=iSiS-Ex Limited + +@@ -60365,11 +71135,29 @@ OUI:70B3D5531* + OUI:70B3D5532* + ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA + ++OUI:70B3D5533* ++ ID_OUI_FROM_DATABASE=Nippon Marine Enterprises, Ltd. ++ ++OUI:70B3D5534* ++ ID_OUI_FROM_DATABASE=Weihai Weigao Medical Imaging Technology Co., Ltd ++ ++OUI:70B3D5535* ++ ID_OUI_FROM_DATABASE=SITA Messtechnik GmbH ++ ++OUI:70B3D5536* ++ ID_OUI_FROM_DATABASE=LARIMART SPA ++ ++OUI:70B3D5537* ++ ID_OUI_FROM_DATABASE=Biennebi s.r.l. ++ + OUI:70B3D5538* + ID_OUI_FROM_DATABASE=sydetion UG (h.b.) + ++OUI:70B3D5539* ++ ID_OUI_FROM_DATABASE=Tempris GmbH ++ + OUI:70B3D553A* +- ID_OUI_FROM_DATABASE=Pano0ramic Power ++ ID_OUI_FROM_DATABASE=Panoramic Power + + OUI:70B3D553B* + ID_OUI_FROM_DATABASE=Mr.Loop +@@ -60380,12 +71168,30 @@ OUI:70B3D553C* + OUI:70B3D553D* + ID_OUI_FROM_DATABASE=ACCEL CORP + ++OUI:70B3D553E* ++ ID_OUI_FROM_DATABASE=Asiga Pty Ltd ++ ++OUI:70B3D553F* ++ ID_OUI_FROM_DATABASE=Abbott Diagnostics Technologies AS ++ ++OUI:70B3D5540* ++ ID_OUI_FROM_DATABASE=KMtronic ltd ++ ++OUI:70B3D5541* ++ ID_OUI_FROM_DATABASE=Nanjing Pingguang Electronic Technology Co., Ltd ++ + OUI:70B3D5542* + ID_OUI_FROM_DATABASE=RTDS Technologies Inc. + ++OUI:70B3D5543* ++ ID_OUI_FROM_DATABASE=wallbe GmbH ++ + OUI:70B3D5544* + ID_OUI_FROM_DATABASE=Silicon Safe Ltd + ++OUI:70B3D5545* ++ ID_OUI_FROM_DATABASE=Airity Technologies Inc. ++ + OUI:70B3D5546* + ID_OUI_FROM_DATABASE=Sensefarm AB + +@@ -60398,6 +71204,9 @@ OUI:70B3D5548* + OUI:70B3D5549* + ID_OUI_FROM_DATABASE=Procon automatic systems GmbH + ++OUI:70B3D554A* ++ ID_OUI_FROM_DATABASE=Digital Instrument Transformers ++ + OUI:70B3D554B* + ID_OUI_FROM_DATABASE=Brakels IT + +@@ -60419,15 +71228,27 @@ OUI:70B3D5550* + OUI:70B3D5551* + ID_OUI_FROM_DATABASE=infrachip + ++OUI:70B3D5552* ++ ID_OUI_FROM_DATABASE=ALTIT.CO.,Ltd. ++ ++OUI:70B3D5553* ++ ID_OUI_FROM_DATABASE=TAALEX Systemtechnik GmbH ++ + OUI:70B3D5554* + ID_OUI_FROM_DATABASE=Teletypes Manufacturing Plant + + OUI:70B3D5555* + ID_OUI_FROM_DATABASE=SoftLab-NSK + ++OUI:70B3D5556* ++ ID_OUI_FROM_DATABASE=OHASHI ENGINEERING CO.,LTD. ++ + OUI:70B3D5557* + ID_OUI_FROM_DATABASE=HEITEC AG + ++OUI:70B3D5558* ++ ID_OUI_FROM_DATABASE=Multiple Access Communications Ltd ++ + OUI:70B3D5559* + ID_OUI_FROM_DATABASE=Eagle Mountain Technology + +@@ -60446,36 +71267,90 @@ OUI:70B3D555D* + OUI:70B3D555E* + ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos + ++OUI:70B3D555F* ++ ID_OUI_FROM_DATABASE=Deep BV ++ ++OUI:70B3D5560* ++ ID_OUI_FROM_DATABASE=DaiShin Information & Communications Co., Ltd ++ ++OUI:70B3D5561* ++ ID_OUI_FROM_DATABASE=Liberator Pty Ltd ++ ++OUI:70B3D5562* ++ ID_OUI_FROM_DATABASE=JD Squared, Inc. ++ + OUI:70B3D5563* + ID_OUI_FROM_DATABASE=Zhejiang Hao Teng Electronic Technology Co., Ltd. + + OUI:70B3D5564* + ID_OUI_FROM_DATABASE=christmann informationstechnik + medien GmbH & Co. KG + ++OUI:70B3D5565* ++ ID_OUI_FROM_DATABASE=Clecell ++ + OUI:70B3D5566* + ID_OUI_FROM_DATABASE=Data Informs LLC + ++OUI:70B3D5567* ++ ID_OUI_FROM_DATABASE=DogWatch Inc ++ ++OUI:70B3D5568* ++ ID_OUI_FROM_DATABASE=Small Data Garden Oy ++ ++OUI:70B3D5569* ++ ID_OUI_FROM_DATABASE=Nuance Hearing Ltd. ++ + OUI:70B3D556A* + ID_OUI_FROM_DATABASE=Harvard Technology Ltd + + OUI:70B3D556B* + ID_OUI_FROM_DATABASE=S.E.I. CO.,LTD. + ++OUI:70B3D556C* ++ ID_OUI_FROM_DATABASE=Telensa Ltd ++ ++OUI:70B3D556D* ++ ID_OUI_FROM_DATABASE=Pro-Digital Projetos Eletronicos Ltda ++ ++OUI:70B3D556E* ++ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. ++ ++OUI:70B3D556F* ++ ID_OUI_FROM_DATABASE=Radikal d.o.o. ++ + OUI:70B3D5570* + ID_OUI_FROM_DATABASE=Bayern Engineering GmbH & Co. KG + ++OUI:70B3D5571* ++ ID_OUI_FROM_DATABASE=Echogear ++ + OUI:70B3D5572* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D5573* ++ ID_OUI_FROM_DATABASE=GEGA ELECTRONIQUE ++ ++OUI:70B3D5574* ++ ID_OUI_FROM_DATABASE=Cloud Intelligence Pty Ltd ++ ++OUI:70B3D5575* ++ ID_OUI_FROM_DATABASE=Konrad GmbH ++ + OUI:70B3D5576* + ID_OUI_FROM_DATABASE=Shandong Hospot IOT Technology Co.,Ltd. + ++OUI:70B3D5577* ++ ID_OUI_FROM_DATABASE=DSILOG ++ + OUI:70B3D5578* + ID_OUI_FROM_DATABASE=IMAGE TECH CO.,LTD + + OUI:70B3D5579* + ID_OUI_FROM_DATABASE=Chelsea Technologies Group Ltd + ++OUI:70B3D557A* ++ ID_OUI_FROM_DATABASE=Rhythm Engineering, LLC. ++ + OUI:70B3D557B* + ID_OUI_FROM_DATABASE=ELAMAKATO GmbH + +@@ -60485,9 +71360,18 @@ OUI:70B3D557C* + OUI:70B3D557D* + ID_OUI_FROM_DATABASE=WICOM1 GmbH + ++OUI:70B3D557E* ++ ID_OUI_FROM_DATABASE=Ascon Tecnologic S.r.l. ++ ++OUI:70B3D557F* ++ ID_OUI_FROM_DATABASE=MBio Diagnostics, Inc. ++ + OUI:70B3D5580* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D5581* ++ ID_OUI_FROM_DATABASE=Thermokon Sensortechnik GmbH ++ + OUI:70B3D5582* + ID_OUI_FROM_DATABASE=VAGLER International Sdn Bhd + +@@ -60500,12 +71384,24 @@ OUI:70B3D5584* + OUI:70B3D5585* + ID_OUI_FROM_DATABASE=Nefteavtomatika + ++OUI:70B3D5586* ++ ID_OUI_FROM_DATABASE=Aliter Technologies ++ + OUI:70B3D5587* + ID_OUI_FROM_DATABASE=INCAA Computers + ++OUI:70B3D5588* ++ ID_OUI_FROM_DATABASE=LLC NPO Svyazkomplektservis ++ + OUI:70B3D5589* + ID_OUI_FROM_DATABASE=Cityntel OU + ++OUI:70B3D558A* ++ ID_OUI_FROM_DATABASE=ITK Dr. Kassen GmbH ++ ++OUI:70B3D558B* ++ ID_OUI_FROM_DATABASE=Williams Sound LLC ++ + OUI:70B3D558C* + ID_OUI_FROM_DATABASE=OPTSYS + +@@ -60513,11 +71409,14 @@ OUI:70B3D558D* + ID_OUI_FROM_DATABASE=DORLET SAU + + OUI:70B3D558E* +- ID_OUI_FROM_DATABASE=Veilux Inc. ++ ID_OUI_FROM_DATABASE=VEILUX INC. + + OUI:70B3D558F* + ID_OUI_FROM_DATABASE=LSL systems + ++OUI:70B3D5590* ++ ID_OUI_FROM_DATABASE=812th AITS ++ + OUI:70B3D5591* + ID_OUI_FROM_DATABASE=Private + +@@ -60539,26 +71438,56 @@ OUI:70B3D5596* + OUI:70B3D5597* + ID_OUI_FROM_DATABASE=VAPE RAIL INTERNATIONAL + ++OUI:70B3D5598* ++ ID_OUI_FROM_DATABASE=Ruag Defence France SAS ++ + OUI:70B3D5599* + ID_OUI_FROM_DATABASE=LECO Corporation + ++OUI:70B3D559A* ++ ID_OUI_FROM_DATABASE=Wagner Group GmbH ++ ++OUI:70B3D559B* ++ ID_OUI_FROM_DATABASE=AUTOMATIZACION Y CONECTIVIDAD SA DE CV ++ + OUI:70B3D559C* + ID_OUI_FROM_DATABASE=DAVE SRL + + OUI:70B3D559D* + ID_OUI_FROM_DATABASE=servicios de consultoria independiente S.L. + ++OUI:70B3D559E* ++ ID_OUI_FROM_DATABASE=i2-electronics ++ ++OUI:70B3D559F* ++ ID_OUI_FROM_DATABASE=Megger Germany GmbH ++ + OUI:70B3D55A0* + ID_OUI_FROM_DATABASE=Ascon Tecnologic S.r.l. + ++OUI:70B3D55A1* ++ ID_OUI_FROM_DATABASE=BOE Technology Group Co., Ltd. ++ + OUI:70B3D55A2* + ID_OUI_FROM_DATABASE=Wallner Automation GmbH + + OUI:70B3D55A3* + ID_OUI_FROM_DATABASE=CT Company + ++OUI:70B3D55A4* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D55A5* ++ ID_OUI_FROM_DATABASE=Rehwork GmbH ++ ++OUI:70B3D55A6* ++ ID_OUI_FROM_DATABASE=TimeMachines Inc. ++ ++OUI:70B3D55A7* ++ ID_OUI_FROM_DATABASE=ABB S.p.A. ++ + OUI:70B3D55A8* +- ID_OUI_FROM_DATABASE=Farmobile ++ ID_OUI_FROM_DATABASE=Farmobile, LLC + + OUI:70B3D55A9* + ID_OUI_FROM_DATABASE=Bunka Shutter Co., Ltd. +@@ -60569,69 +71498,144 @@ OUI:70B3D55AA* + OUI:70B3D55AB* + ID_OUI_FROM_DATABASE=Sea Air and Land Communications Ltd + ++OUI:70B3D55AC* ++ ID_OUI_FROM_DATABASE=LM-Instruments Oy ++ ++OUI:70B3D55AD* ++ ID_OUI_FROM_DATABASE=Profotech ++ ++OUI:70B3D55AE* ++ ID_OUI_FROM_DATABASE=TinTec Co., Ltd. ++ ++OUI:70B3D55AF* ++ ID_OUI_FROM_DATABASE=JENG IoT BV ++ + OUI:70B3D55B0* + ID_OUI_FROM_DATABASE=Qxperts Italia S.r.l. + + OUI:70B3D55B1* + ID_OUI_FROM_DATABASE=EPD Electronics + ++OUI:70B3D55B2* ++ ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau AG ++ ++OUI:70B3D55B3* ++ ID_OUI_FROM_DATABASE=STENTORIUS by ADI ++ ++OUI:70B3D55B4* ++ ID_OUI_FROM_DATABASE=Systems Technologies ++ + OUI:70B3D55B5* + ID_OUI_FROM_DATABASE=Lehigh Electric Products Co + + OUI:70B3D55B6* + ID_OUI_FROM_DATABASE=Ethical Lighting and Sensor Solutions Limited + ++OUI:70B3D55B7* ++ ID_OUI_FROM_DATABASE=on-systems limited ++ + OUI:70B3D55B8* + ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH + ++OUI:70B3D55B9* ++ ID_OUI_FROM_DATABASE=EIZO RUGGED SOLUTIONS ++ ++OUI:70B3D55BA* ++ ID_OUI_FROM_DATABASE=INFRASAFE/ ADVANTOR SYSTEMS ++ ++OUI:70B3D55BB* ++ ID_OUI_FROM_DATABASE=Olympus NDT Canada ++ + OUI:70B3D55BC* + ID_OUI_FROM_DATABASE=LAMTEC Meß- und Regeltechnik für Feuerungen GmbH & Co. KG + ++OUI:70B3D55BD* ++ ID_OUI_FROM_DATABASE=nexgenwave ++ + OUI:70B3D55BE* + ID_OUI_FROM_DATABASE=CASWA + + OUI:70B3D55BF* + ID_OUI_FROM_DATABASE=Aton srl + ++OUI:70B3D55C0* ++ ID_OUI_FROM_DATABASE=Shenzhen Lianfaxun Electronic Technology Co., Ltd ++ + OUI:70B3D55C1* + ID_OUI_FROM_DATABASE=Shanghai JaWay Information Technology Co., Ltd. + ++OUI:70B3D55C2* ++ ID_OUI_FROM_DATABASE=Sono-Tek Corporation ++ ++OUI:70B3D55C3* ++ ID_OUI_FROM_DATABASE=DIC Corporation ++ + OUI:70B3D55C4* + ID_OUI_FROM_DATABASE=TATTILE SRL + + OUI:70B3D55C5* + ID_OUI_FROM_DATABASE=Haag-Streit AG + ++OUI:70B3D55C6* ++ ID_OUI_FROM_DATABASE=C4I Systems Ltd ++ ++OUI:70B3D55C7* ++ ID_OUI_FROM_DATABASE=QSnet Visual Technologies Ltd ++ + OUI:70B3D55C8* + ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd + ++OUI:70B3D55C9* ++ ID_OUI_FROM_DATABASE=ICTK Holdings ++ + OUI:70B3D55CA* + ID_OUI_FROM_DATABASE=ACD Elekronik GmbH + ++OUI:70B3D55CB* ++ ID_OUI_FROM_DATABASE=ECoCoMS Ltd. ++ + OUI:70B3D55CC* + ID_OUI_FROM_DATABASE=Akse srl + + OUI:70B3D55CD* + ID_OUI_FROM_DATABASE=MVT Video Technologies R + H Maedler GbR + ++OUI:70B3D55CE* ++ ID_OUI_FROM_DATABASE=IP Devices ++ + OUI:70B3D55CF* + ID_OUI_FROM_DATABASE=PROEL TSI s.r.l. + ++OUI:70B3D55D0* ++ ID_OUI_FROM_DATABASE=InterTalk Critical Information Systems ++ + OUI:70B3D55D1* + ID_OUI_FROM_DATABASE=Software Motor Corp + ++OUI:70B3D55D2* ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. ++ + OUI:70B3D55D3* + ID_OUI_FROM_DATABASE=Supracon AG + ++OUI:70B3D55D4* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ + OUI:70B3D55D5* + ID_OUI_FROM_DATABASE=CT Company + + OUI:70B3D55D6* + ID_OUI_FROM_DATABASE=BMT Messtechnik Gmbh + ++OUI:70B3D55D7* ++ ID_OUI_FROM_DATABASE=Clockwork Dog ++ + OUI:70B3D55D8* + ID_OUI_FROM_DATABASE=LYNX Technik AG + ++OUI:70B3D55D9* ++ ID_OUI_FROM_DATABASE=olympus-ossa ++ + OUI:70B3D55DA* + ID_OUI_FROM_DATABASE=Valk Welding B.V. + +@@ -60641,12 +71645,21 @@ OUI:70B3D55DB* + OUI:70B3D55DC* + ID_OUI_FROM_DATABASE=FactoryLab B.V. + ++OUI:70B3D55DD* ++ ID_OUI_FROM_DATABASE=Theatrixx Technologies, Inc. ++ + OUI:70B3D55DE* + ID_OUI_FROM_DATABASE=Hangzhou AwareTec Technology Co., Ltd + ++OUI:70B3D55DF* ++ ID_OUI_FROM_DATABASE=Semacon Business Machines ++ + OUI:70B3D55E0* + ID_OUI_FROM_DATABASE=Hexagon Metrology SAS + ++OUI:70B3D55E1* ++ ID_OUI_FROM_DATABASE=Arevita ++ + OUI:70B3D55E2* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +@@ -60662,6 +71675,9 @@ OUI:70B3D55E5* + OUI:70B3D55E6* + ID_OUI_FROM_DATABASE=Mechatronics Systems Private Limited + ++OUI:70B3D55E7* ++ ID_OUI_FROM_DATABASE=Heroic Technologies Inc. ++ + OUI:70B3D55E8* + ID_OUI_FROM_DATABASE=VITEC + +@@ -60671,6 +71687,12 @@ OUI:70B3D55E9* + OUI:70B3D55EA* + ID_OUI_FROM_DATABASE=KYS,INC + ++OUI:70B3D55EB* ++ ID_OUI_FROM_DATABASE=Loma Systems s.r.o. ++ ++OUI:70B3D55EC* ++ ID_OUI_FROM_DATABASE=Creative Electronics Ltd ++ + OUI:70B3D55ED* + ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG + +@@ -60695,9 +71717,18 @@ OUI:70B3D55F3* + OUI:70B3D55F4* + ID_OUI_FROM_DATABASE=FDSTiming + ++OUI:70B3D55F5* ++ ID_OUI_FROM_DATABASE=Microvision ++ + OUI:70B3D55F6* + ID_OUI_FROM_DATABASE=FreeFlight Systems + ++OUI:70B3D55F7* ++ ID_OUI_FROM_DATABASE=JFA Electronics Industry and Commerce EIRELI ++ ++OUI:70B3D55F8* ++ ID_OUI_FROM_DATABASE=Forcite Helmet Systems Pty Ltd ++ + OUI:70B3D55F9* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + +@@ -60713,18 +71744,33 @@ OUI:70B3D55FC* + OUI:70B3D55FD* + ID_OUI_FROM_DATABASE=Windar Photonics + ++OUI:70B3D55FE* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ + OUI:70B3D55FF* + ID_OUI_FROM_DATABASE=Vaisala Oyj + + OUI:70B3D5600* + ID_OUI_FROM_DATABASE=Stellwerk GmbH + ++OUI:70B3D5601* ++ ID_OUI_FROM_DATABASE=Tricom Research Inc. ++ + OUI:70B3D5602* + ID_OUI_FROM_DATABASE=Quantum Opus, LLC + ++OUI:70B3D5603* ++ ID_OUI_FROM_DATABASE=EGISTECH CO.,LTD. ++ ++OUI:70B3D5604* ++ ID_OUI_FROM_DATABASE=Foxtrot Research Corp ++ + OUI:70B3D5605* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D5606* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ + OUI:70B3D5607* + ID_OUI_FROM_DATABASE=ATEME + +@@ -60758,18 +71804,30 @@ OUI:70B3D5610* + OUI:70B3D5611* + ID_OUI_FROM_DATABASE=Avionica + ++OUI:70B3D5612* ++ ID_OUI_FROM_DATABASE=Edge Power Solutions ++ + OUI:70B3D5613* + ID_OUI_FROM_DATABASE=Suprock Technologies + ++OUI:70B3D5614* ++ ID_OUI_FROM_DATABASE=QUALITTEQ LLC ++ + OUI:70B3D5615* + ID_OUI_FROM_DATABASE=JSC OTZVUK + + OUI:70B3D5616* + ID_OUI_FROM_DATABASE=Axxess Identification Ltd + ++OUI:70B3D5617* ++ ID_OUI_FROM_DATABASE=Cominfo, Inc. ++ + OUI:70B3D5618* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + ++OUI:70B3D5619* ++ ID_OUI_FROM_DATABASE=ZAO ZEO ++ + OUI:70B3D561A* + ID_OUI_FROM_DATABASE=Rocket Lab Ltd. + +@@ -60788,21 +71846,66 @@ OUI:70B3D561E* + OUI:70B3D561F* + ID_OUI_FROM_DATABASE=Labotect Labor-Technik-Göttingen GmbH + ++OUI:70B3D5620* ++ ID_OUI_FROM_DATABASE=Orlaco Products B.V. ++ ++OUI:70B3D5621* ++ ID_OUI_FROM_DATABASE=SERTEC SRL ++ ++OUI:70B3D5622* ++ ID_OUI_FROM_DATABASE=PCS Inc. ++ ++OUI:70B3D5623* ++ ID_OUI_FROM_DATABASE=Beijing HuaLian Technology Co, Ltd. ++ ++OUI:70B3D5624* ++ ID_OUI_FROM_DATABASE=EBE Mobility & Green Energy GmbH ++ + OUI:70B3D5625* + ID_OUI_FROM_DATABASE=VX Instruments GmbH + ++OUI:70B3D5626* ++ ID_OUI_FROM_DATABASE=KRONOTECH SRL ++ ++OUI:70B3D5627* ++ ID_OUI_FROM_DATABASE=EarTex ++ + OUI:70B3D5628* +- ID_OUI_FROM_DATABASE=MECT S.R.L. ++ ID_OUI_FROM_DATABASE=MECT SRL ++ ++OUI:70B3D5629* ++ ID_OUI_FROM_DATABASE=OZRAY ++ ++OUI:70B3D562A* ++ ID_OUI_FROM_DATABASE=DOGA + + OUI:70B3D562B* + ID_OUI_FROM_DATABASE=Silicann Systems GmbH + ++OUI:70B3D562C* ++ ID_OUI_FROM_DATABASE=OOO NTC Rotek ++ ++OUI:70B3D562D* ++ ID_OUI_FROM_DATABASE=elements ++ ++OUI:70B3D562E* ++ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., ++ ++OUI:70B3D562F* ++ ID_OUI_FROM_DATABASE=BARCO, s.r.o. ++ + OUI:70B3D5630* + ID_OUI_FROM_DATABASE=LGE + + OUI:70B3D5631* + ID_OUI_FROM_DATABASE=SENSO2ME + ++OUI:70B3D5632* ++ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. ++ ++OUI:70B3D5633* ++ ID_OUI_FROM_DATABASE=OBSERVER FOUNDATION ++ + OUI:70B3D5634* + ID_OUI_FROM_DATABASE=idaqs Co.,Ltd. + +@@ -60815,6 +71918,12 @@ OUI:70B3D5636* + OUI:70B3D5637* + ID_OUI_FROM_DATABASE=INEO-SENSE + ++OUI:70B3D5638* ++ ID_OUI_FROM_DATABASE=Parkalot Denmark ApS ++ ++OUI:70B3D5639* ++ ID_OUI_FROM_DATABASE=DORLET SAU ++ + OUI:70B3D563A* + ID_OUI_FROM_DATABASE=DAVE SRL + +@@ -60825,17 +71934,23 @@ OUI:70B3D563C* + ID_OUI_FROM_DATABASE=Pivothead + + OUI:70B3D563D* +- ID_OUI_FROM_DATABASE=Storbyte, Inc. ++ ID_OUI_FROM_DATABASE=Topic Embedded Products B.V. + + OUI:70B3D563E* + ID_OUI_FROM_DATABASE=RIKEN OPTECH CORPORATION + + OUI:70B3D563F* +- ID_OUI_FROM_DATABASE=YG COMPANY CO., LTD ++ ID_OUI_FROM_DATABASE=DARBS Inc. + + OUI:70B3D5640* + ID_OUI_FROM_DATABASE=Electronic Equipment Company Pvt. Ltd. + ++OUI:70B3D5641* ++ ID_OUI_FROM_DATABASE=Burk Technology ++ ++OUI:70B3D5642* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ + OUI:70B3D5643* + ID_OUI_FROM_DATABASE=Marques,S.A. + +@@ -60845,9 +71960,15 @@ OUI:70B3D5644* + OUI:70B3D5645* + ID_OUI_FROM_DATABASE=Project Decibel, Inc. + ++OUI:70B3D5646* ++ ID_OUI_FROM_DATABASE=Xirgo Technologies LLC ++ + OUI:70B3D5647* + ID_OUI_FROM_DATABASE=KZTA + ++OUI:70B3D5648* ++ ID_OUI_FROM_DATABASE=Magnamed Tecnologia Medica S/A ++ + OUI:70B3D5649* + ID_OUI_FROM_DATABASE=swissled technologies AG + +@@ -60860,9 +71981,15 @@ OUI:70B3D564B* + OUI:70B3D564C* + ID_OUI_FROM_DATABASE=ACEMIS FRANCE + ++OUI:70B3D564D* ++ ID_OUI_FROM_DATABASE=SANMINA ISRAEL MEDICAL SYSTEMS LTD ++ + OUI:70B3D564E* + ID_OUI_FROM_DATABASE=BigStuff3, Inc. + ++OUI:70B3D564F* ++ ID_OUI_FROM_DATABASE=GUNMA ELECTRONICS CO LTD ++ + OUI:70B3D5650* + ID_OUI_FROM_DATABASE=GIFAS-ELECTRIC GmbH + +@@ -60884,6 +72011,9 @@ OUI:70B3D5655* + OUI:70B3D5656* + ID_OUI_FROM_DATABASE=SonoSound ApS + ++OUI:70B3D5657* ++ ID_OUI_FROM_DATABASE=ID Quantique SA ++ + OUI:70B3D5658* + ID_OUI_FROM_DATABASE=emperor brands + +@@ -60902,12 +72032,24 @@ OUI:70B3D565C* + OUI:70B3D565D* + ID_OUI_FROM_DATABASE=GEGA ELECTRONIQUE + ++OUI:70B3D565E* ++ ID_OUI_FROM_DATABASE=Season Electronics Ltd ++ ++OUI:70B3D565F* ++ ID_OUI_FROM_DATABASE=Axnes AS ++ + OUI:70B3D5660* + ID_OUI_FROM_DATABASE=Smart Service Technologies CO., LTD + + OUI:70B3D5661* + ID_OUI_FROM_DATABASE=DesignA Electronics Limited + ++OUI:70B3D5662* ++ ID_OUI_FROM_DATABASE=Icon Industrial Engineering ++ ++OUI:70B3D5663* ++ ID_OUI_FROM_DATABASE=Intrinsic Group Limited ++ + OUI:70B3D5664* + ID_OUI_FROM_DATABASE=Sankyo Intec co.,ltd + +@@ -60917,12 +72059,33 @@ OUI:70B3D5665* + OUI:70B3D5666* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D5667* ++ ID_OUI_FROM_DATABASE=CT Company ++ ++OUI:70B3D5668* ++ ID_OUI_FROM_DATABASE=Öresundskraft AB ++ ++OUI:70B3D5669* ++ ID_OUI_FROM_DATABASE=Panoramic Power ++ + OUI:70B3D566A* + ID_OUI_FROM_DATABASE=Private + + OUI:70B3D566B* + ID_OUI_FROM_DATABASE=Innitive B.V. + ++OUI:70B3D566C* ++ ID_OUI_FROM_DATABASE=KRISTECH Krzysztof Kajstura ++ ++OUI:70B3D566D* ++ ID_OUI_FROM_DATABASE=Sanmina Israel ++ ++OUI:70B3D566E* ++ ID_OUI_FROM_DATABASE=SIAME ++ ++OUI:70B3D566F* ++ ID_OUI_FROM_DATABASE=Simplified MFG ++ + OUI:70B3D5670* + ID_OUI_FROM_DATABASE=Particle sizing systems + +@@ -60932,6 +72095,9 @@ OUI:70B3D5671* + OUI:70B3D5672* + ID_OUI_FROM_DATABASE=KLEIBER Infrared GmbH + ++OUI:70B3D5673* ++ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH ++ + OUI:70B3D5674* + ID_OUI_FROM_DATABASE=Fortress Cyber Security + +@@ -60950,21 +72116,60 @@ OUI:70B3D5678* + OUI:70B3D5679* + ID_OUI_FROM_DATABASE=EMAC, Inc. + ++OUI:70B3D567A* ++ ID_OUI_FROM_DATABASE=Micatu ++ + OUI:70B3D567B* + ID_OUI_FROM_DATABASE=Stesalit Systems Ltd + ++OUI:70B3D567C* ++ ID_OUI_FROM_DATABASE=Benchmark Electronics - Secure Technology ++ + OUI:70B3D567D* + ID_OUI_FROM_DATABASE=Acrodea, Inc. + ++OUI:70B3D567E* ++ ID_OUI_FROM_DATABASE=Season Electronics Ltd ++ ++OUI:70B3D567F* ++ ID_OUI_FROM_DATABASE=IAAN Co., Ltd ++ + OUI:70B3D5680* + ID_OUI_FROM_DATABASE=BASF Corporation + ++OUI:70B3D5681* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ + OUI:70B3D5682* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + ++OUI:70B3D5683* ++ ID_OUI_FROM_DATABASE=DECYBEN ++ ++OUI:70B3D5684* ++ ID_OUI_FROM_DATABASE=LECO Corporation ++ ++OUI:70B3D5685* ++ ID_OUI_FROM_DATABASE=LDA Audiotech ++ ++OUI:70B3D5686* ++ ID_OUI_FROM_DATABASE=Access Protocol Pty Ltd ++ ++OUI:70B3D5687* ++ ID_OUI_FROM_DATABASE=Volution Group UK ++ ++OUI:70B3D5688* ++ ID_OUI_FROM_DATABASE=MG s.r.l. ++ + OUI:70B3D5689* + ID_OUI_FROM_DATABASE=Prisma Telecom Testing Srl + ++OUI:70B3D568A* ++ ID_OUI_FROM_DATABASE=Advanced Telecommunications Research Institute International ++ ++OUI:70B3D568B* ++ ID_OUI_FROM_DATABASE=Sadel S.p.A. ++ + OUI:70B3D568C* + ID_OUI_FROM_DATABASE=ND METER + +@@ -60977,6 +72182,12 @@ OUI:70B3D568E* + OUI:70B3D568F* + ID_OUI_FROM_DATABASE=PEEK TRAFFIC + ++OUI:70B3D5690* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ ++OUI:70B3D5691* ++ ID_OUI_FROM_DATABASE=PEEK TRAFFIC ++ + OUI:70B3D5692* + ID_OUI_FROM_DATABASE=HOSIN INDUSTRIAL LIMITED + +@@ -60986,15 +72197,33 @@ OUI:70B3D5693* + OUI:70B3D5694* + ID_OUI_FROM_DATABASE=MoviTHERM + ++OUI:70B3D5695* ++ ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH ++ + OUI:70B3D5696* + ID_OUI_FROM_DATABASE=Open Grow + + OUI:70B3D5697* + ID_OUI_FROM_DATABASE=Alazar Technologies Inc. + ++OUI:70B3D5698* ++ ID_OUI_FROM_DATABASE=ZIEHL-ABEGG SE ++ ++OUI:70B3D5699* ++ ID_OUI_FROM_DATABASE=Flextronics International Kft ++ ++OUI:70B3D569A* ++ ID_OUI_FROM_DATABASE=Altaneos ++ ++OUI:70B3D569B* ++ ID_OUI_FROM_DATABASE=HORIZON.INC ++ + OUI:70B3D569C* + ID_OUI_FROM_DATABASE=Keepen + ++OUI:70B3D569D* ++ ID_OUI_FROM_DATABASE=JPEmbedded Mazan Filipek Sp. J. ++ + OUI:70B3D569E* + ID_OUI_FROM_DATABASE=PTYPE Co., LTD. + +@@ -61007,21 +72236,45 @@ OUI:70B3D56A0* + OUI:70B3D56A1* + ID_OUI_FROM_DATABASE=GLIAL TECHNOLOGY + ++OUI:70B3D56A2* ++ ID_OUI_FROM_DATABASE=Root Automation ++ ++OUI:70B3D56A3* ++ ID_OUI_FROM_DATABASE=OutdoorLink ++ ++OUI:70B3D56A4* ++ ID_OUI_FROM_DATABASE=Acrodea, Inc. ++ + OUI:70B3D56A5* + ID_OUI_FROM_DATABASE=Akenori PTE LTD + + OUI:70B3D56A6* + ID_OUI_FROM_DATABASE=WOW System + ++OUI:70B3D56A7* ++ ID_OUI_FROM_DATABASE=Partilink Inc. ++ + OUI:70B3D56A8* + ID_OUI_FROM_DATABASE=Vitsch Electronics + + OUI:70B3D56A9* + ID_OUI_FROM_DATABASE=OHMORI ELECTRIC INDUSTRIES CO.LTD + ++OUI:70B3D56AA* ++ ID_OUI_FROM_DATABASE=Intermobility ++ ++OUI:70B3D56AB* ++ ID_OUI_FROM_DATABASE=ARROW (CHINA) ELECTRONICS TRADING CO., LTD. ++ ++OUI:70B3D56AC* ++ ID_OUI_FROM_DATABASE=Ketronixs Sdn Bhd ++ + OUI:70B3D56AD* + ID_OUI_FROM_DATABASE=CONNIT + ++OUI:70B3D56AE* ++ ID_OUI_FROM_DATABASE=Hangzhou Weimu Technology Co,.Ltd. ++ + OUI:70B3D56AF* + ID_OUI_FROM_DATABASE=Sensorberg GmbH + +@@ -61037,6 +72290,9 @@ OUI:70B3D56B2* + OUI:70B3D56B3* + ID_OUI_FROM_DATABASE=DuraComm Corporation + ++OUI:70B3D56B4* ++ ID_OUI_FROM_DATABASE=Nudron IoT Solutions LLP ++ + OUI:70B3D56B5* + ID_OUI_FROM_DATABASE=ART SPA + +@@ -61046,30 +72302,75 @@ OUI:70B3D56B6* + OUI:70B3D56B7* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + ++OUI:70B3D56B8* ++ ID_OUI_FROM_DATABASE=BT9 ++ ++OUI:70B3D56B9* ++ ID_OUI_FROM_DATABASE=Becton Dickinson ++ ++OUI:70B3D56BA* ++ ID_OUI_FROM_DATABASE=Integrotech sp. z o.o. ++ + OUI:70B3D56BB* + ID_OUI_FROM_DATABASE=LUCEO + ++OUI:70B3D56BC* ++ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG ++ ++OUI:70B3D56BD* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ + OUI:70B3D56BE* + ID_OUI_FROM_DATABASE=VANTAGE INTEGRATED SECURITY SOLUTIONS PVT LTD + + OUI:70B3D56BF* + ID_OUI_FROM_DATABASE=Otto Bihler Maschinenfabrik GmbH & Co. KG + ++OUI:70B3D56C0* ++ ID_OUI_FROM_DATABASE=LLC NTZ Mekhanotronika ++ + OUI:70B3D56C1* + ID_OUI_FROM_DATABASE=Labtronik s.r.l. + ++OUI:70B3D56C2* ++ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL ++ + OUI:70B3D56C3* + ID_OUI_FROM_DATABASE=BEIJING ZGH SECURITY RESEARCH INSTITUTE CO., LTD + ++OUI:70B3D56C4* ++ ID_OUI_FROM_DATABASE=Veo Robotics, Inc. ++ + OUI:70B3D56C5* + ID_OUI_FROM_DATABASE=CJSC «Russian telecom equipment company» (CJSC RTEC) + ++OUI:70B3D56C6* ++ ID_OUI_FROM_DATABASE=Abbott Diagnostics Technologies AS ++ + OUI:70B3D56C7* + ID_OUI_FROM_DATABASE=Becton Dickinson + ++OUI:70B3D56C8* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ ++OUI:70B3D56C9* ++ ID_OUI_FROM_DATABASE=Redstone Sunshine(Beijing)Technology Co.,Ltd. ++ ++OUI:70B3D56CA* ++ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., ++ ++OUI:70B3D56CB* ++ ID_OUI_FROM_DATABASE=NAJIN automation ++ ++OUI:70B3D56CC* ++ ID_OUI_FROM_DATABASE=ARINAX ++ + OUI:70B3D56CD* + ID_OUI_FROM_DATABASE=NORTHBOUND NETWORKS PTY. LTD. + ++OUI:70B3D56CE* ++ ID_OUI_FROM_DATABASE=Eredi Giuseppe Mercuri SPA ++ + OUI:70B3D56CF* + ID_OUI_FROM_DATABASE=Private + +@@ -61079,11 +72380,23 @@ OUI:70B3D56D0* + OUI:70B3D56D1* + ID_OUI_FROM_DATABASE=Visual Engineering Technologies Ltd + ++OUI:70B3D56D2* ++ ID_OUI_FROM_DATABASE=Ahrens & Birner Company GmbH ++ + OUI:70B3D56D3* + ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH + ++OUI:70B3D56D4* ++ ID_OUI_FROM_DATABASE=Telerob Gesellschaft für Fernhantierungs ++ ++OUI:70B3D56D5* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ + OUI:70B3D56D6* +- ID_OUI_FROM_DATABASE=KMtronic Ltd. ++ ID_OUI_FROM_DATABASE=KMtronic ltd ++ ++OUI:70B3D56D7* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + + OUI:70B3D56D8* + ID_OUI_FROM_DATABASE=Shanghai YuanAn Environmental Protection Technology Co.,Ltd +@@ -61094,6 +72407,18 @@ OUI:70B3D56D9* + OUI:70B3D56DA* + ID_OUI_FROM_DATABASE=Enovative Networks, Inc. + ++OUI:70B3D56DB* ++ ID_OUI_FROM_DATABASE=Techimp - Altanova group Srl ++ ++OUI:70B3D56DC* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ ++OUI:70B3D56DD* ++ ID_OUI_FROM_DATABASE=Abbott Diagnostics Technologies AS ++ ++OUI:70B3D56DE* ++ ID_OUI_FROM_DATABASE=Ametek Solidstate Controls ++ + OUI:70B3D56DF* + ID_OUI_FROM_DATABASE=Mango DSP, Inc. + +@@ -61103,6 +72428,12 @@ OUI:70B3D56E0* + OUI:70B3D56E1* + ID_OUI_FROM_DATABASE=Shanghai Holystar Information Technology Co.,Ltd + ++OUI:70B3D56E2* ++ ID_OUI_FROM_DATABASE=E-Controls ++ ++OUI:70B3D56E3* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN QLS ELECTRONIC TECHNOLOGY CO.,LTD. ++ + OUI:70B3D56E4* + ID_OUI_FROM_DATABASE=Institute of Power Engineering, Gdansk Division + +@@ -61133,15 +72464,30 @@ OUI:70B3D56EC* + OUI:70B3D56ED* + ID_OUI_FROM_DATABASE=Wiingtech International Co. LTD. + ++OUI:70B3D56EE* ++ ID_OUI_FROM_DATABASE=HANKOOK CTEC CO,. LTD. ++ ++OUI:70B3D56EF* ++ ID_OUI_FROM_DATABASE=Beringar ++ + OUI:70B3D56F0* + ID_OUI_FROM_DATABASE=iTelaSoft Pvt Ltd + ++OUI:70B3D56F1* ++ ID_OUI_FROM_DATABASE=Discover Battery ++ + OUI:70B3D56F2* + ID_OUI_FROM_DATABASE=P&C Micro's Pty Ltd + + OUI:70B3D56F3* + ID_OUI_FROM_DATABASE=iungo + ++OUI:70B3D56F4* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:70B3D56F5* ++ ID_OUI_FROM_DATABASE=Cominfo, Inc. ++ + OUI:70B3D56F6* + ID_OUI_FROM_DATABASE=Acco Brands Europe + +@@ -61160,15 +72506,24 @@ OUI:70B3D56FA* + OUI:70B3D56FB* + ID_OUI_FROM_DATABASE=Shachihata Inc. + ++OUI:70B3D56FC* ++ ID_OUI_FROM_DATABASE=MI Inc. ++ + OUI:70B3D56FD* + ID_OUI_FROM_DATABASE=Core Akıllı Ev Sistemleri + ++OUI:70B3D56FE* ++ ID_OUI_FROM_DATABASE=NTO IRE-POLUS ++ + OUI:70B3D56FF* + ID_OUI_FROM_DATABASE=AKEO PLUS + + OUI:70B3D5700* + ID_OUI_FROM_DATABASE=University Of Groningen + ++OUI:70B3D5701* ++ ID_OUI_FROM_DATABASE=COMPAR Computer GmbH ++ + OUI:70B3D5702* + ID_OUI_FROM_DATABASE=Sensor Highway Ltd + +@@ -61196,6 +72551,18 @@ OUI:70B3D5709* + OUI:70B3D570A* + ID_OUI_FROM_DATABASE=PULLNET TECHNOLOGY, SA DE CV SSC1012302S73 + ++OUI:70B3D570B* ++ ID_OUI_FROM_DATABASE=Alere Technologies AS ++ ++OUI:70B3D570C* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ ++OUI:70B3D570D* ++ ID_OUI_FROM_DATABASE=OMNISENSING PHOTONICS LLC ++ ++OUI:70B3D570E* ++ ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd ++ + OUI:70B3D570F* + ID_OUI_FROM_DATABASE=Alion Science & Technology + +@@ -61208,6 +72575,9 @@ OUI:70B3D5711* + OUI:70B3D5712* + ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC + ++OUI:70B3D5713* ++ ID_OUI_FROM_DATABASE=Coloet S.r.l. ++ + OUI:70B3D5714* + ID_OUI_FROM_DATABASE=Alturna Networks + +@@ -61220,14 +72590,32 @@ OUI:70B3D5716* + OUI:70B3D5717* + ID_OUI_FROM_DATABASE=Secure Systems & Services + ++OUI:70B3D5718* ++ ID_OUI_FROM_DATABASE=PEEK TRAFFIC ++ ++OUI:70B3D5719* ++ ID_OUI_FROM_DATABASE=2M Technology ++ ++OUI:70B3D571A* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ + OUI:70B3D571B* + ID_OUI_FROM_DATABASE=elsys + ++OUI:70B3D571C* ++ ID_OUI_FROM_DATABASE=Konzept Informationssysteme GmbH ++ ++OUI:70B3D571D* ++ ID_OUI_FROM_DATABASE=Connido Limited ++ + OUI:70B3D571E* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + ++OUI:70B3D571F* ++ ID_OUI_FROM_DATABASE=Grayshift ++ + OUI:70B3D5720* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Jeio Tech + + OUI:70B3D5721* + ID_OUI_FROM_DATABASE=Zoe Medical +@@ -61241,6 +72629,12 @@ OUI:70B3D5723* + OUI:70B3D5724* + ID_OUI_FROM_DATABASE=Quan International Co., Ltd. + ++OUI:70B3D5725* ++ ID_OUI_FROM_DATABASE=Swiss Timing LTD ++ ++OUI:70B3D5726* ++ ID_OUI_FROM_DATABASE=ATGS ++ + OUI:70B3D5727* + ID_OUI_FROM_DATABASE=LP Technologies Inc. + +@@ -61250,6 +72644,12 @@ OUI:70B3D5728* + OUI:70B3D5729* + ID_OUI_FROM_DATABASE=EMAC, Inc. + ++OUI:70B3D572A* ++ ID_OUI_FROM_DATABASE=MRC Systems GmbH ++ ++OUI:70B3D572B* ++ ID_OUI_FROM_DATABASE=Medipense Inc. ++ + OUI:70B3D572C* + ID_OUI_FROM_DATABASE=NuRi&G Engineering co,.Ltd. + +@@ -61259,6 +72659,9 @@ OUI:70B3D572D* + OUI:70B3D572E* + ID_OUI_FROM_DATABASE=Maharsystem + ++OUI:70B3D572F* ++ ID_OUI_FROM_DATABASE=AVA Technologies Inc. ++ + OUI:70B3D5730* + ID_OUI_FROM_DATABASE=Videogenix + +@@ -61277,24 +72680,36 @@ OUI:70B3D5734* + OUI:70B3D5735* + ID_OUI_FROM_DATABASE=Swiss Audio + ++OUI:70B3D5736* ++ ID_OUI_FROM_DATABASE=Jabil ++ + OUI:70B3D5737* + ID_OUI_FROM_DATABASE=SD Biosensor + ++OUI:70B3D5738* ++ ID_OUI_FROM_DATABASE=GRYPHON SECURE INC ++ + OUI:70B3D5739* + ID_OUI_FROM_DATABASE=Zigencorp, Inc + + OUI:70B3D573A* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=DOLBY LABORATORIES, INC. + + OUI:70B3D573B* + ID_OUI_FROM_DATABASE=S-I-C + ++OUI:70B3D573C* ++ ID_OUI_FROM_DATABASE=Centro de Ingenieria y Desarrollo industrial ++ + OUI:70B3D573D* + ID_OUI_FROM_DATABASE=NETWAYS GmbH + + OUI:70B3D573E* + ID_OUI_FROM_DATABASE=Trident RFID Pty Ltd + ++OUI:70B3D573F* ++ ID_OUI_FROM_DATABASE=LLC Open Converged Networks ++ + OUI:70B3D5740* + ID_OUI_FROM_DATABASE=Prisma Telecom Testing Srl + +@@ -61307,17 +72722,29 @@ OUI:70B3D5742* + OUI:70B3D5743* + ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG + ++OUI:70B3D5744* ++ ID_OUI_FROM_DATABASE=PHYZHON Health Inc ++ + OUI:70B3D5745* + ID_OUI_FROM_DATABASE=TMSI LLC + ++OUI:70B3D5746* ++ ID_OUI_FROM_DATABASE=Smart Systems LLC ++ + OUI:70B3D5747* + ID_OUI_FROM_DATABASE=Eva Automation + ++OUI:70B3D5748* ++ ID_OUI_FROM_DATABASE=KDT ++ + OUI:70B3D5749* + ID_OUI_FROM_DATABASE=Granite River Labs Inc + + OUI:70B3D574A* +- ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed ++ ID_OUI_FROM_DATABASE=Mettler Toledo ++ ++OUI:70B3D574B* ++ ID_OUI_FROM_DATABASE=Code Blue Corporation + + OUI:70B3D574C* + ID_OUI_FROM_DATABASE=Kwant Controls BV +@@ -61337,15 +72764,30 @@ OUI:70B3D5750* + OUI:70B3D5751* + ID_OUI_FROM_DATABASE=GNF + ++OUI:70B3D5752* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ + OUI:70B3D5753* + ID_OUI_FROM_DATABASE=HCH. Kündig & CIE. AG + ++OUI:70B3D5754* ++ ID_OUI_FROM_DATABASE=COSMOIT.CO.LTD ++ + OUI:70B3D5755* + ID_OUI_FROM_DATABASE=LandmarkTech Systems Technology Co.,Ltd. + ++OUI:70B3D5756* ++ ID_OUI_FROM_DATABASE=TimeMachines Inc. ++ ++OUI:70B3D5757* ++ ID_OUI_FROM_DATABASE=GABO ++ + OUI:70B3D5758* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + ++OUI:70B3D5759* ++ ID_OUI_FROM_DATABASE=AML ++ + OUI:70B3D575A* + ID_OUI_FROM_DATABASE=Standard Backhaul Communications + +@@ -61370,12 +72812,18 @@ OUI:70B3D5760* + OUI:70B3D5761* + ID_OUI_FROM_DATABASE=Critical Link LLC + ++OUI:70B3D5762* ++ ID_OUI_FROM_DATABASE=Transformational Security, LLC ++ + OUI:70B3D5763* + ID_OUI_FROM_DATABASE=A Trap, USA + + OUI:70B3D5764* + ID_OUI_FROM_DATABASE=SCHMID electronic + ++OUI:70B3D5765* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:70B3D5766* + ID_OUI_FROM_DATABASE=Tirasoft Nederland + +@@ -61391,6 +72839,9 @@ OUI:70B3D576A* + OUI:70B3D576B* + ID_OUI_FROM_DATABASE=EMPELOR GmbH + ++OUI:70B3D576C* ++ ID_OUI_FROM_DATABASE=Aural Ltd ++ + OUI:70B3D576D* + ID_OUI_FROM_DATABASE=Trimble + +@@ -61430,27 +72881,51 @@ OUI:70B3D5778* + OUI:70B3D5779* + ID_OUI_FROM_DATABASE=DR.BRIDGE AQUATECH + ++OUI:70B3D577A* ++ ID_OUI_FROM_DATABASE=Tecsag Innovation AG ++ + OUI:70B3D577B* + ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc. + + OUI:70B3D577C* + ID_OUI_FROM_DATABASE=HUSTY M.Styczen J.Hupert Sp.J. + ++OUI:70B3D577D* ++ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC ++ + OUI:70B3D577E* + ID_OUI_FROM_DATABASE=Blue Marble Communications, Inc. + ++OUI:70B3D577F* ++ ID_OUI_FROM_DATABASE=Microchip Technology Germany II GmbH&Co.KG ++ ++OUI:70B3D5780* ++ ID_OUI_FROM_DATABASE=NIDEC LEROY-SOMER ++ + OUI:70B3D5781* + ID_OUI_FROM_DATABASE=Project Service S.a.s. + + OUI:70B3D5782* + ID_OUI_FROM_DATABASE=thou&tech + ++OUI:70B3D5783* ++ ID_OUI_FROM_DATABASE=CHIeru., CO., Ltd. ++ + OUI:70B3D5784* + ID_OUI_FROM_DATABASE=Shenzhen bayue software co. LTD + + OUI:70B3D5785* + ID_OUI_FROM_DATABASE=Density Inc. + ++OUI:70B3D5786* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ ++OUI:70B3D5787* ++ ID_OUI_FROM_DATABASE=Den Automation ++ ++OUI:70B3D5788* ++ ID_OUI_FROM_DATABASE=Slan ++ + OUI:70B3D5789* + ID_OUI_FROM_DATABASE=SEMEX-EngCon GmbH + +@@ -61463,6 +72938,9 @@ OUI:70B3D578B* + OUI:70B3D578C* + ID_OUI_FROM_DATABASE=Survalent Technology Corporation + ++OUI:70B3D578D* ++ ID_OUI_FROM_DATABASE=AVL DiTEST GmbH ++ + OUI:70B3D578E* + ID_OUI_FROM_DATABASE=effectas GmbH + +@@ -61475,12 +72953,27 @@ OUI:70B3D5790* + OUI:70B3D5791* + ID_OUI_FROM_DATABASE=Romteck Australia + ++OUI:70B3D5792* ++ ID_OUI_FROM_DATABASE=IMMOLAS ++ ++OUI:70B3D5793* ++ ID_OUI_FROM_DATABASE=Gastech Australia Pty Ltd ++ + OUI:70B3D5794* + ID_OUI_FROM_DATABASE=Shadin Avionics + ++OUI:70B3D5795* ++ ID_OUI_FROM_DATABASE=TIECHE Engineered Systems ++ + OUI:70B3D5796* + ID_OUI_FROM_DATABASE=GAMPT mbH + ++OUI:70B3D5797* ++ ID_OUI_FROM_DATABASE=Mitsubishi Electric India Pvt. Ltd. ++ ++OUI:70B3D5798* ++ ID_OUI_FROM_DATABASE=TIAMA ++ + OUI:70B3D5799* + ID_OUI_FROM_DATABASE=Vitec System Engineering Inc. + +@@ -61490,9 +72983,18 @@ OUI:70B3D579A* + OUI:70B3D579B* + ID_OUI_FROM_DATABASE=Soniclean Pty Ltd + ++OUI:70B3D579C* ++ ID_OUI_FROM_DATABASE=ADDE ++ ++OUI:70B3D579D* ++ ID_OUI_FROM_DATABASE=Editech Co., Ltd ++ + OUI:70B3D579E* + ID_OUI_FROM_DATABASE=CW2. Gmbh & Co. KG + ++OUI:70B3D579F* ++ ID_OUI_FROM_DATABASE=Green Instruments A/S ++ + OUI:70B3D57A0* + ID_OUI_FROM_DATABASE=Reactec Ltd + +@@ -61544,6 +73046,9 @@ OUI:70B3D57AF* + OUI:70B3D57B0* + ID_OUI_FROM_DATABASE=Medisafe International + ++OUI:70B3D57B1* ++ ID_OUI_FROM_DATABASE=Panamera ++ + OUI:70B3D57B2* + ID_OUI_FROM_DATABASE=Rail Power Systems GmbH + +@@ -61553,6 +73058,9 @@ OUI:70B3D57B3* + OUI:70B3D57B4* + ID_OUI_FROM_DATABASE=Zumbach Electronic AG + ++OUI:70B3D57B5* ++ ID_OUI_FROM_DATABASE=VOCAL Technologies Ltd. ++ + OUI:70B3D57B6* + ID_OUI_FROM_DATABASE=Amada Miyachi America Inc. + +@@ -61565,6 +73073,21 @@ OUI:70B3D57B8* + OUI:70B3D57B9* + ID_OUI_FROM_DATABASE=QIAGEN Instruments AG + ++OUI:70B3D57BA* ++ ID_OUI_FROM_DATABASE=Decentlab GmbH ++ ++OUI:70B3D57BB* ++ ID_OUI_FROM_DATABASE=Aloxy ++ ++OUI:70B3D57BC* ++ ID_OUI_FROM_DATABASE=FIRST RF Corporation ++ ++OUI:70B3D57BD* ++ ID_OUI_FROM_DATABASE=TableConnect GmbH ++ ++OUI:70B3D57BE* ++ ID_OUI_FROM_DATABASE=Phytron GmbH ++ + OUI:70B3D57BF* + ID_OUI_FROM_DATABASE=Stone Three + +@@ -61580,6 +73103,15 @@ OUI:70B3D57C2* + OUI:70B3D57C3* + ID_OUI_FROM_DATABASE=Flexim Security Oy + ++OUI:70B3D57C4* ++ ID_OUI_FROM_DATABASE=MECT SRL ++ ++OUI:70B3D57C5* ++ ID_OUI_FROM_DATABASE=Projects Unlimited Inc. ++ ++OUI:70B3D57C6* ++ ID_OUI_FROM_DATABASE=Utrend Technology (Shanghai) Co., Ltd ++ + OUI:70B3D57C7* + ID_OUI_FROM_DATABASE=Sicon srl + +@@ -61589,6 +73121,15 @@ OUI:70B3D57C8* + OUI:70B3D57C9* + ID_OUI_FROM_DATABASE=Council Rock + ++OUI:70B3D57CA* ++ ID_OUI_FROM_DATABASE=Hunan Shengyun Photoelectric Technology Co., Ltd. ++ ++OUI:70B3D57CB* ++ ID_OUI_FROM_DATABASE=KeyW Corporation ++ ++OUI:70B3D57CC* ++ ID_OUI_FROM_DATABASE=MITSUBISHI HEAVY INDUSTRIES THERMAL SYSTEMS, LTD. ++ + OUI:70B3D57CD* + ID_OUI_FROM_DATABASE=Molekuler Goruntuleme A.S. + +@@ -61607,6 +73148,12 @@ OUI:70B3D57D1* + OUI:70B3D57D2* + ID_OUI_FROM_DATABASE=SDK Kristall + ++OUI:70B3D57D3* ++ ID_OUI_FROM_DATABASE=OLEDCOMM ++ ++OUI:70B3D57D4* ++ ID_OUI_FROM_DATABASE=Computechnic AG ++ + OUI:70B3D57D5* + ID_OUI_FROM_DATABASE=SICS Swedish ICT + +@@ -61616,9 +73163,21 @@ OUI:70B3D57D6* + OUI:70B3D57D7* + ID_OUI_FROM_DATABASE=Gedomo GmbH + ++OUI:70B3D57D8* ++ ID_OUI_FROM_DATABASE=Nuand LLC ++ + OUI:70B3D57D9* + ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd. + ++OUI:70B3D57DA* ++ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. ++ ++OUI:70B3D57DB* ++ ID_OUI_FROM_DATABASE=aquila biolabs GmbH ++ ++OUI:70B3D57DC* ++ ID_OUI_FROM_DATABASE=Software Systems Plus ++ + OUI:70B3D57DD* + ID_OUI_FROM_DATABASE=Excel Medical Electronics LLC + +@@ -61646,6 +73205,9 @@ OUI:70B3D57E4* + OUI:70B3D57E5* + ID_OUI_FROM_DATABASE=Megaflex Oy + ++OUI:70B3D57E6* ++ ID_OUI_FROM_DATABASE=11811347 CANADA Inc. ++ + OUI:70B3D57E7* + ID_OUI_FROM_DATABASE=Atessa, Inc. + +@@ -61662,7 +73224,7 @@ OUI:70B3D57EB* + ID_OUI_FROM_DATABASE=Xerox International Partners + + OUI:70B3D57EC* +- ID_OUI_FROM_DATABASE=GRIDSMART Technologies ++ ID_OUI_FROM_DATABASE=Cubic ITS, Inc. dba GRIDSMART Technologies + + OUI:70B3D57ED* + ID_OUI_FROM_DATABASE=The Things Network Foundation +@@ -61673,6 +73235,9 @@ OUI:70B3D57EE* + OUI:70B3D57EF* + ID_OUI_FROM_DATABASE=CRAVIS CO., LIMITED + ++OUI:70B3D57F0* ++ ID_OUI_FROM_DATABASE=YDK Technologies Co.,Ltd ++ + OUI:70B3D57F1* + ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc. + +@@ -61688,6 +73253,9 @@ OUI:70B3D57F4* + OUI:70B3D57F5* + ID_OUI_FROM_DATABASE=Incusense + ++OUI:70B3D57F6* ++ ID_OUI_FROM_DATABASE=IDZ Ltd ++ + OUI:70B3D57F7* + ID_OUI_FROM_DATABASE=JASCO Applied Sciences Canada Ltd + +@@ -61695,16 +73263,37 @@ OUI:70B3D57F8* + ID_OUI_FROM_DATABASE=Solvera Lynx d.d. + + OUI:70B3D57F9* +- ID_OUI_FROM_DATABASE=CSS Inc. ++ ID_OUI_FROM_DATABASE=Communication Systems Solutions ++ ++OUI:70B3D57FA* ++ ID_OUI_FROM_DATABASE=meoENERGY + + OUI:70B3D57FB* + ID_OUI_FROM_DATABASE=db Broadcast Products Ltd + ++OUI:70B3D57FC* ++ ID_OUI_FROM_DATABASE=Surion (Pty) Ltd ++ + OUI:70B3D57FD* + ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH + + OUI:70B3D57FE* +- ID_OUI_FROM_DATABASE=RCH Italia SpA ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ ++OUI:70B3D57FF* ++ ID_OUI_FROM_DATABASE=eumig industrie-TV GmbH. ++ ++OUI:70B3D5800* ++ ID_OUI_FROM_DATABASE=HeadsafeIP PTY LTD ++ ++OUI:70B3D5801* ++ ID_OUI_FROM_DATABASE=Glory Technology Service Inc. ++ ++OUI:70B3D5802* ++ ID_OUI_FROM_DATABASE=Qingdao CNR HITACH Railway Signal&communication co.,ltd ++ ++OUI:70B3D5803* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + + OUI:70B3D5804* + ID_OUI_FROM_DATABASE=PMT Corporation +@@ -61712,9 +73301,15 @@ OUI:70B3D5804* + OUI:70B3D5805* + ID_OUI_FROM_DATABASE=Eurotronik Kranj d.o.o. + ++OUI:70B3D5806* ++ ID_OUI_FROM_DATABASE=International Super Computer Co., Ltd. ++ + OUI:70B3D5807* + ID_OUI_FROM_DATABASE=Camsat Przemysław Gralak + ++OUI:70B3D5808* ++ ID_OUI_FROM_DATABASE=Becton Dickinson ++ + OUI:70B3D5809* + ID_OUI_FROM_DATABASE=Tecnint HTE SRL + +@@ -61724,9 +73319,15 @@ OUI:70B3D580A* + OUI:70B3D580B* + ID_OUI_FROM_DATABASE=Fischer Block, Inc. + ++OUI:70B3D580C* ++ ID_OUI_FROM_DATABASE=Algra tec AG ++ + OUI:70B3D580D* + ID_OUI_FROM_DATABASE=Data Physics Corporation + ++OUI:70B3D580E* ++ ID_OUI_FROM_DATABASE=Utopi Ltd ++ + OUI:70B3D580F* + ID_OUI_FROM_DATABASE=Quickware Eng & Des LLC + +@@ -61736,12 +73337,18 @@ OUI:70B3D5810* + OUI:70B3D5811* + ID_OUI_FROM_DATABASE=CJSC «INTERSET» + ++OUI:70B3D5812* ++ ID_OUI_FROM_DATABASE=TESCAN Brno, s.r.o. ++ + OUI:70B3D5813* + ID_OUI_FROM_DATABASE=Wavemed srl + + OUI:70B3D5814* + ID_OUI_FROM_DATABASE=Ingenieurbuero SOMTRONIK + ++OUI:70B3D5815* ++ ID_OUI_FROM_DATABASE=Waco Giken Co., Ltd. ++ + OUI:70B3D5816* + ID_OUI_FROM_DATABASE=Smith Meter, Inc. + +@@ -61760,18 +73367,33 @@ OUI:70B3D581A* + OUI:70B3D581B* + ID_OUI_FROM_DATABASE=bobz GmbH + ++OUI:70B3D581C* ++ ID_OUI_FROM_DATABASE=QIT Co., Ltd. ++ ++OUI:70B3D581D* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ + OUI:70B3D581E* + ID_OUI_FROM_DATABASE=Novathings + ++OUI:70B3D581F* ++ ID_OUI_FROM_DATABASE=CAR-connect GmbH ++ + OUI:70B3D5820* + ID_OUI_FROM_DATABASE=Becker Nachrichtentechnik GmbH + + OUI:70B3D5821* + ID_OUI_FROM_DATABASE=HL2 group + ++OUI:70B3D5822* ++ ID_OUI_FROM_DATABASE=Angora Networks ++ + OUI:70B3D5823* + ID_OUI_FROM_DATABASE=SP Controls + ++OUI:70B3D5824* ++ ID_OUI_FROM_DATABASE=Songwoo Information & Technology Co., Ltd ++ + OUI:70B3D5825* + ID_OUI_FROM_DATABASE=TATTILE SRL + +@@ -61784,6 +73406,15 @@ OUI:70B3D5827* + OUI:70B3D5828* + ID_OUI_FROM_DATABASE=Xacti Corporation + ++OUI:70B3D5829* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ ++OUI:70B3D582A* ++ ID_OUI_FROM_DATABASE=C W F Hamilton & Co Ltd ++ ++OUI:70B3D582B* ++ ID_OUI_FROM_DATABASE=Shangnuo company ++ + OUI:70B3D582C* + ID_OUI_FROM_DATABASE=NELS Ltd. + +@@ -61793,15 +73424,30 @@ OUI:70B3D582D* + OUI:70B3D582E* + ID_OUI_FROM_DATABASE=PlayAlive A/S + ++OUI:70B3D582F* ++ ID_OUI_FROM_DATABASE=SIANA Systems ++ ++OUI:70B3D5830* ++ ID_OUI_FROM_DATABASE=Nordson Corporation ++ + OUI:70B3D5831* + ID_OUI_FROM_DATABASE=Arnouse Digital Devices Corp + ++OUI:70B3D5832* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ + OUI:70B3D5833* + ID_OUI_FROM_DATABASE=Alpiq InTec Management AG + ++OUI:70B3D5834* ++ ID_OUI_FROM_DATABASE=NCE Network Consulting Engineering srl ++ + OUI:70B3D5835* + ID_OUI_FROM_DATABASE=CommBox P/L + ++OUI:70B3D5836* ++ ID_OUI_FROM_DATABASE=Authenticdata ++ + OUI:70B3D5837* + ID_OUI_FROM_DATABASE=HiDes, Inc. + +@@ -61811,12 +73457,21 @@ OUI:70B3D5838* + OUI:70B3D5839* + ID_OUI_FROM_DATABASE=Rockwell Collins Canada + ++OUI:70B3D583A* ++ ID_OUI_FROM_DATABASE=EMDEP CENTRO TECNOLOGICO MEXICO ++ + OUI:70B3D583B* + ID_OUI_FROM_DATABASE=Telefonix Incorporated + + OUI:70B3D583C* + ID_OUI_FROM_DATABASE=Sinoembed + ++OUI:70B3D583D* ++ ID_OUI_FROM_DATABASE=Gentec ++ ++OUI:70B3D583E* ++ ID_OUI_FROM_DATABASE=The Dini Group, La Jolla inc. ++ + OUI:70B3D583F* + ID_OUI_FROM_DATABASE=Lumine Lighting Solutions Oy + +@@ -61829,12 +73484,18 @@ OUI:70B3D5841* + OUI:70B3D5842* + ID_OUI_FROM_DATABASE=PLUTO Solution co.,ltd. + ++OUI:70B3D5843* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ + OUI:70B3D5844* + ID_OUI_FROM_DATABASE=SANSFIL Technologies + + OUI:70B3D5845* + ID_OUI_FROM_DATABASE=Harborside Technology + ++OUI:70B3D5846* ++ ID_OUI_FROM_DATABASE=National Time & Signal Corp. ++ + OUI:70B3D5847* + ID_OUI_FROM_DATABASE=Ai-Lynx + +@@ -61847,6 +73508,9 @@ OUI:70B3D5849* + OUI:70B3D584A* + ID_OUI_FROM_DATABASE=MOG Laboratories Pty Ltd + ++OUI:70B3D584B* ++ ID_OUI_FROM_DATABASE=QuestHouse, Inc. ++ + OUI:70B3D584C* + ID_OUI_FROM_DATABASE=CoreKinect + +@@ -61856,9 +73520,15 @@ OUI:70B3D584D* + OUI:70B3D584E* + ID_OUI_FROM_DATABASE=Chromalox, Inc. + ++OUI:70B3D584F* ++ ID_OUI_FROM_DATABASE=Mettler Toledo ++ + OUI:70B3D5850* + ID_OUI_FROM_DATABASE=REO AG + ++OUI:70B3D5851* ++ ID_OUI_FROM_DATABASE=EXASCEND (Wuhan) Co., Ltd ++ + OUI:70B3D5852* + ID_OUI_FROM_DATABASE=NetBoxSC, LLC + +@@ -61871,8 +73541,17 @@ OUI:70B3D5854* + OUI:70B3D5855* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D5856* ++ ID_OUI_FROM_DATABASE=Shanghai Westwell Information and Technology Company Ltd ++ + OUI:70B3D5857* +- ID_OUI_FROM_DATABASE=RCH Italia SpA ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ ++OUI:70B3D5858* ++ ID_OUI_FROM_DATABASE=Hubbell Power Systems ++ ++OUI:70B3D5859* ++ ID_OUI_FROM_DATABASE=HAN CHANG + + OUI:70B3D585A* + ID_OUI_FROM_DATABASE=BRUSHIES +@@ -61892,18 +73571,42 @@ OUI:70B3D585E* + OUI:70B3D585F* + ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd + ++OUI:70B3D5860* ++ ID_OUI_FROM_DATABASE=KBS Industrieelektronik GmbH ++ + OUI:70B3D5861* + ID_OUI_FROM_DATABASE=KST technology + + OUI:70B3D5862* + ID_OUI_FROM_DATABASE=TripleOre + ++OUI:70B3D5863* ++ ID_OUI_FROM_DATABASE=Shenzhen Wesion Technology Co., Ltd ++ ++OUI:70B3D5864* ++ ID_OUI_FROM_DATABASE=BORMANN EDV und Zubehoer ++ ++OUI:70B3D5865* ++ ID_OUI_FROM_DATABASE=Insitu, Inc. ++ + OUI:70B3D5866* + ID_OUI_FROM_DATABASE=MEPS Realtime + ++OUI:70B3D5867* ++ ID_OUI_FROM_DATABASE=Specialized Communications Corp. ++ + OUI:70B3D5868* + ID_OUI_FROM_DATABASE=U-JIN Mesco Co., Ltd. + ++OUI:70B3D5869* ++ ID_OUI_FROM_DATABASE=chargeBIG ++ ++OUI:70B3D586A* ++ ID_OUI_FROM_DATABASE=Stealth Communications ++ ++OUI:70B3D586B* ++ ID_OUI_FROM_DATABASE=AVL DiTEST ++ + OUI:70B3D586C* + ID_OUI_FROM_DATABASE=eeas gmbh + +@@ -61913,15 +73616,24 @@ OUI:70B3D586D* + OUI:70B3D586E* + ID_OUI_FROM_DATABASE=Profcon AB + ++OUI:70B3D586F* ++ ID_OUI_FROM_DATABASE=LLC NTC ACTOR ++ + OUI:70B3D5870* + ID_OUI_FROM_DATABASE=bentrup Industriesteuerungen + + OUI:70B3D5871* + ID_OUI_FROM_DATABASE=Oso Technologies + ++OUI:70B3D5872* ++ ID_OUI_FROM_DATABASE=Nippon Safety co,ltd ++ + OUI:70B3D5873* + ID_OUI_FROM_DATABASE=Vishay Nobel AB + ++OUI:70B3D5874* ++ ID_OUI_FROM_DATABASE=NORTHBOUND NETWORKS PTY. LTD. ++ + OUI:70B3D5875* + ID_OUI_FROM_DATABASE=Peek Traffic + +@@ -61937,6 +73649,9 @@ OUI:70B3D5878* + OUI:70B3D5879* + ID_OUI_FROM_DATABASE=ZIGPOS GmbH + ++OUI:70B3D587A* ++ ID_OUI_FROM_DATABASE=Accolade Technology Inc ++ + OUI:70B3D587B* + ID_OUI_FROM_DATABASE=Liquid Instruments Pty Ltd + +@@ -61949,6 +73664,9 @@ OUI:70B3D587D* + OUI:70B3D587E* + ID_OUI_FROM_DATABASE=Septentrio NV + ++OUI:70B3D587F* ++ ID_OUI_FROM_DATABASE=NAC Planning Co., Ltd. ++ + OUI:70B3D5880* + ID_OUI_FROM_DATABASE=Skopei B.V. + +@@ -61958,9 +73676,21 @@ OUI:70B3D5881* + OUI:70B3D5882* + ID_OUI_FROM_DATABASE=SIMON TECH, S.L. + ++OUI:70B3D5883* ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. ++ ++OUI:70B3D5884* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:70B3D5885* + ID_OUI_FROM_DATABASE=QuirkLogic + ++OUI:70B3D5886* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D5887* ++ ID_OUI_FROM_DATABASE=Entec Solar S.L. ++ + OUI:70B3D5888* + ID_OUI_FROM_DATABASE=Zetechtics Ltd + +@@ -61976,9 +73706,15 @@ OUI:70B3D588B* + OUI:70B3D588D* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:70B3D588E* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ + OUI:70B3D588F* + ID_OUI_FROM_DATABASE=Quaesta Instruments, LLC + ++OUI:70B3D5890* ++ ID_OUI_FROM_DATABASE=EIDOS s.r.l. ++ + OUI:70B3D5891* + ID_OUI_FROM_DATABASE=neocontrol soluções em automação + +@@ -62000,15 +73736,42 @@ OUI:70B3D5896* + OUI:70B3D5897* + ID_OUI_FROM_DATABASE=EFG CZ spol. s r.o. + ++OUI:70B3D5898* ++ ID_OUI_FROM_DATABASE=Salupo Sas ++ ++OUI:70B3D5899* ++ ID_OUI_FROM_DATABASE=Viotec USA ++ ++OUI:70B3D589A* ++ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl ++ + OUI:70B3D589B* + ID_OUI_FROM_DATABASE=ControlWorks, Inc. + ++OUI:70B3D589C* ++ ID_OUI_FROM_DATABASE=IHI Rotating Machinery Engineering Co.,Ltd. ++ ++OUI:70B3D589D* ++ ID_OUI_FROM_DATABASE=e-Matix Corporation ++ ++OUI:70B3D589E* ++ ID_OUI_FROM_DATABASE=Innovative Control Systems, LP ++ ++OUI:70B3D589F* ++ ID_OUI_FROM_DATABASE=Levelup Holding, Inc. ++ + OUI:70B3D58A0* + ID_OUI_FROM_DATABASE=DM RADIOCOM + ++OUI:70B3D58A1* ++ ID_OUI_FROM_DATABASE=TIAMA ++ + OUI:70B3D58A2* + ID_OUI_FROM_DATABASE=WINNERS DIGITAL CORPORATION + ++OUI:70B3D58A3* ++ ID_OUI_FROM_DATABASE=Loehnert Elektronik GmbH ++ + OUI:70B3D58A4* + ID_OUI_FROM_DATABASE=Phyton, Inc. Microsystems and Development Tools + +@@ -62018,9 +73781,18 @@ OUI:70B3D58A5* + OUI:70B3D58A6* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D58A7* ++ ID_OUI_FROM_DATABASE=Tucsen Photonics Co., Ltd. ++ + OUI:70B3D58A8* + ID_OUI_FROM_DATABASE=megatec electronic GmbH + ++OUI:70B3D58A9* ++ ID_OUI_FROM_DATABASE=WoKa-Elektronik GmbH ++ ++OUI:70B3D58AA* ++ ID_OUI_FROM_DATABASE=TATTILE SRL ++ + OUI:70B3D58AB* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +@@ -62030,6 +73802,12 @@ OUI:70B3D58AC* + OUI:70B3D58AD* + ID_OUI_FROM_DATABASE=Global Communications Technology LLC + ++OUI:70B3D58AE* ++ ID_OUI_FROM_DATABASE=FARECO ++ ++OUI:70B3D58AF* ++ ID_OUI_FROM_DATABASE=QBIC COMMUNICATIONS DMCC ++ + OUI:70B3D58B0* + ID_OUI_FROM_DATABASE=IES S.r.l. + +@@ -62045,15 +73823,42 @@ OUI:70B3D58B3* + OUI:70B3D58B4* + ID_OUI_FROM_DATABASE=Scenario Automation + ++OUI:70B3D58B5* ++ ID_OUI_FROM_DATABASE=xTom GmbH ++ ++OUI:70B3D58B6* ++ ID_OUI_FROM_DATABASE=Eldes Ltd ++ + OUI:70B3D58B7* +- ID_OUI_FROM_DATABASE=Contec DTx ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. ++ ++OUI:70B3D58B8* ++ ID_OUI_FROM_DATABASE=GDI Technology Inc + + OUI:70B3D58B9* + ID_OUI_FROM_DATABASE=Toptech Systems, Inc. + ++OUI:70B3D58BA* ++ ID_OUI_FROM_DATABASE=TIAMA ++ ++OUI:70B3D58BB* ++ ID_OUI_FROM_DATABASE=KST technology ++ ++OUI:70B3D58BC* ++ ID_OUI_FROM_DATABASE=GSI GeoSolutions International Ltd ++ ++OUI:70B3D58BD* ++ ID_OUI_FROM_DATABASE=MAHLE ELECTRONICS, SLU ++ + OUI:70B3D58BE* + ID_OUI_FROM_DATABASE=Connoiseur Electronics Private Limited + ++OUI:70B3D58BF* ++ ID_OUI_FROM_DATABASE=Hangzhou Leaper Technology Co. Ltd. ++ ++OUI:70B3D58C0* ++ ID_OUI_FROM_DATABASE=SenseNL ++ + OUI:70B3D58C1* + ID_OUI_FROM_DATABASE=Rievtech Electronic Co.,Ltd + +@@ -62063,21 +73868,36 @@ OUI:70B3D58C2* + OUI:70B3D58C3* + ID_OUI_FROM_DATABASE=Wyebot, Inc. + ++OUI:70B3D58C4* ++ ID_OUI_FROM_DATABASE=APE GmbH ++ + OUI:70B3D58C5* + ID_OUI_FROM_DATABASE=HMicro Inc + + OUI:70B3D58C6* + ID_OUI_FROM_DATABASE=Onosokki Co.,Ltd + ++OUI:70B3D58C7* ++ ID_OUI_FROM_DATABASE=Henschel-Robotics GmbH ++ + OUI:70B3D58C8* + ID_OUI_FROM_DATABASE=KRONOTECH SRL + ++OUI:70B3D58C9* ++ ID_OUI_FROM_DATABASE=Arwin Technology Limited ++ + OUI:70B3D58CA* + ID_OUI_FROM_DATABASE=Allied Data Systems + + OUI:70B3D58CB* + ID_OUI_FROM_DATABASE=WELT Corporation + ++OUI:70B3D58CC* ++ ID_OUI_FROM_DATABASE=Piranha EMS Inc. ++ ++OUI:70B3D58CD* ++ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG ++ + OUI:70B3D58CE* + ID_OUI_FROM_DATABASE=CORES Corporation + +@@ -62087,39 +73907,93 @@ OUI:70B3D58CF* + OUI:70B3D58D0* + ID_OUI_FROM_DATABASE=Raft Technologies + ++OUI:70B3D58D1* ++ ID_OUI_FROM_DATABASE=Field Design Inc. ++ ++OUI:70B3D58D2* ++ ID_OUI_FROM_DATABASE=WIZAPPLY CO.,LTD ++ + OUI:70B3D58D3* + ID_OUI_FROM_DATABASE=PERFORMANCE CONTROLS, INC. + ++OUI:70B3D58D4* ++ ID_OUI_FROM_DATABASE=Guangdong Transtek Medical Electronics Co., Ltd. ++ ++OUI:70B3D58D5* ++ ID_OUI_FROM_DATABASE=Guangzhou Wanglu ++ ++OUI:70B3D58D6* ++ ID_OUI_FROM_DATABASE=Beijing Xiansheng Technology Co., Ltd ++ ++OUI:70B3D58D7* ++ ID_OUI_FROM_DATABASE=Schneider Electric Motion USA ++ + OUI:70B3D58D8* + ID_OUI_FROM_DATABASE=VNG Corporation + + OUI:70B3D58D9* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D58DA* ++ ID_OUI_FROM_DATABASE=MicroElectronics System Co.Ltd ++ + OUI:70B3D58DB* + ID_OUI_FROM_DATABASE=Kratos Analytical Ltd + + OUI:70B3D58DC* + ID_OUI_FROM_DATABASE=Niveo International BV + ++OUI:70B3D58DD* ++ ID_OUI_FROM_DATABASE=Vertex Co.,Ltd. ++ ++OUI:70B3D58DE* ++ ID_OUI_FROM_DATABASE=Indutherm Giesstechnologie GmbH ++ ++OUI:70B3D58DF* ++ ID_OUI_FROM_DATABASE=DORLET SAU ++ + OUI:70B3D58E0* + ID_OUI_FROM_DATABASE=SOUDAX EQUIPEMENTS + + OUI:70B3D58E1* + ID_OUI_FROM_DATABASE=WoKa-Elektronik GmbH + ++OUI:70B3D58E2* ++ ID_OUI_FROM_DATABASE=Zhiye Electronics Co., Ltd. ++ + OUI:70B3D58E3* + ID_OUI_FROM_DATABASE=DORLET SAU + + OUI:70B3D58E4* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D58E5* ++ ID_OUI_FROM_DATABASE=Shanghai Armour Technology Co., Ltd. ++ ++OUI:70B3D58E6* ++ ID_OUI_FROM_DATABASE=Mothonic AB ++ ++OUI:70B3D58E7* ++ ID_OUI_FROM_DATABASE=REO AG ++ ++OUI:70B3D58E8* ++ ID_OUI_FROM_DATABASE=PREO INDUSTRIES FAR EAST LTD ++ ++OUI:70B3D58E9* ++ ID_OUI_FROM_DATABASE=COONTROL Tecnologia em Combustão LTDA EPP ++ ++OUI:70B3D58EA* ++ ID_OUI_FROM_DATABASE=JLCooper Electronics ++ + OUI:70B3D58EB* + ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd + + OUI:70B3D58EC* + ID_OUI_FROM_DATABASE=Rudy Tellert + ++OUI:70B3D58ED* ++ ID_OUI_FROM_DATABASE=NanoSense ++ + OUI:70B3D58EE* + ID_OUI_FROM_DATABASE=Network Additions + +@@ -62129,12 +74003,18 @@ OUI:70B3D58EF* + OUI:70B3D58F0* + ID_OUI_FROM_DATABASE=ERAESEEDS co.,ltd. + ++OUI:70B3D58F1* ++ ID_OUI_FROM_DATABASE=Paramount Bed Holdings Co., Ltd. ++ + OUI:70B3D58F2* + ID_OUI_FROM_DATABASE=Rimota Limited + + OUI:70B3D58F3* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D58F4* ++ ID_OUI_FROM_DATABASE=ACQUA-SYSTEMS srls ++ + OUI:70B3D58F5* + ID_OUI_FROM_DATABASE=Stmovic + +@@ -62147,14 +74027,29 @@ OUI:70B3D58F7* + OUI:70B3D58F8* + ID_OUI_FROM_DATABASE=Wi6labs + ++OUI:70B3D58F9* ++ ID_OUI_FROM_DATABASE=IWS Global Pty Ltd ++ + OUI:70B3D58FA* + ID_OUI_FROM_DATABASE=DEA SYSTEM SPA + ++OUI:70B3D58FB* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D58FC* ++ ID_OUI_FROM_DATABASE=Mianjie Technology ++ ++OUI:70B3D58FD* ++ ID_OUI_FROM_DATABASE=sonatest ++ ++OUI:70B3D58FE* ++ ID_OUI_FROM_DATABASE=Selmatec AS ++ + OUI:70B3D58FF* + ID_OUI_FROM_DATABASE=IMST GmbH + + OUI:70B3D5901* +- ID_OUI_FROM_DATABASE=ATS-CONVERS ++ ID_OUI_FROM_DATABASE=ATS-CONVERS,LLC + + OUI:70B3D5902* + ID_OUI_FROM_DATABASE=Unlimiterhear co.,ltd. taiwan branch +@@ -62165,6 +74060,9 @@ OUI:70B3D5903* + OUI:70B3D5904* + ID_OUI_FROM_DATABASE=PHB Eletronica Ltda. + ++OUI:70B3D5905* ++ ID_OUI_FROM_DATABASE=Wexiodisk AB ++ + OUI:70B3D5906* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +@@ -62174,6 +74072,9 @@ OUI:70B3D5907* + OUI:70B3D5908* + ID_OUI_FROM_DATABASE=Accusonic + ++OUI:70B3D5909* ++ ID_OUI_FROM_DATABASE=tetronik GmbH AEN ++ + OUI:70B3D590A* + ID_OUI_FROM_DATABASE=Hangzhou SunTown Intelligent Science & Technology Co.,Ltd. + +@@ -62187,7 +74088,7 @@ OUI:70B3D590D* + ID_OUI_FROM_DATABASE=Modtronix Engineering + + OUI:70B3D590E* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Maytronics Ltd. + + OUI:70B3D590F* + ID_OUI_FROM_DATABASE=DTRON Communications (Pty) Ltd +@@ -62198,9 +74099,18 @@ OUI:70B3D5910* + OUI:70B3D5911* + ID_OUI_FROM_DATABASE=Equatel + ++OUI:70B3D5912* ++ ID_OUI_FROM_DATABASE=VERTEL DIGITAL PRIVATE LIMITED ++ + OUI:70B3D5913* + ID_OUI_FROM_DATABASE=Shenzhen Riitek Technology Co.,Ltd + ++OUI:70B3D5914* ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. ++ ++OUI:70B3D5915* ++ ID_OUI_FROM_DATABASE=DHK Storage, LLC ++ + OUI:70B3D5916* + ID_OUI_FROM_DATABASE=Techno Mathematical Co.,Ltd + +@@ -62210,12 +74120,21 @@ OUI:70B3D5917* + OUI:70B3D5918* + ID_OUI_FROM_DATABASE=Glova Rail A/S + ++OUI:70B3D5919* ++ ID_OUI_FROM_DATABASE=Thesycon Software Solutions GmbH & Co. KG ++ + OUI:70B3D591A* + ID_OUI_FROM_DATABASE=Fujian Landfone Information Technology Co.,Ltd + + OUI:70B3D591B* + ID_OUI_FROM_DATABASE=Dolotron d.o.o. + ++OUI:70B3D591C* ++ ID_OUI_FROM_DATABASE=Alere Technologies AS ++ ++OUI:70B3D591D* ++ ID_OUI_FROM_DATABASE=Cubitech ++ + OUI:70B3D591E* + ID_OUI_FROM_DATABASE=Creotech Instruments S.A. + +@@ -62225,6 +74144,12 @@ OUI:70B3D591F* + OUI:70B3D5920* + ID_OUI_FROM_DATABASE=SLAT + ++OUI:70B3D5921* ++ ID_OUI_FROM_DATABASE=QDevil ++ ++OUI:70B3D5922* ++ ID_OUI_FROM_DATABASE=Adcole Space ++ + OUI:70B3D5923* + ID_OUI_FROM_DATABASE=eumig industrie-tv GmbH + +@@ -62234,9 +74159,15 @@ OUI:70B3D5924* + OUI:70B3D5925* + ID_OUI_FROM_DATABASE=Diamante Lighting Srl + ++OUI:70B3D5926* ++ ID_OUI_FROM_DATABASE=Advice ++ + OUI:70B3D5927* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:70B3D5928* ++ ID_OUI_FROM_DATABASE=Done Design Inc ++ + OUI:70B3D5929* + ID_OUI_FROM_DATABASE=OutSys + +@@ -62246,6 +74177,12 @@ OUI:70B3D592A* + OUI:70B3D592B* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. + ++OUI:70B3D592C* ++ ID_OUI_FROM_DATABASE=DISMUNTEL SAL ++ ++OUI:70B3D592D* ++ ID_OUI_FROM_DATABASE=Suzhou Wansong Electric Co.,Ltd ++ + OUI:70B3D592E* + ID_OUI_FROM_DATABASE=Medical Monitoring Center OOD + +@@ -62255,6 +74192,9 @@ OUI:70B3D592F* + OUI:70B3D5930* + ID_OUI_FROM_DATABASE=The Institute of Mine Seismology + ++OUI:70B3D5931* ++ ID_OUI_FROM_DATABASE=MARINE INSTRUMENTS, S.A. ++ + OUI:70B3D5932* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +@@ -62270,15 +74210,33 @@ OUI:70B3D5935* + OUI:70B3D5936* + ID_OUI_FROM_DATABASE=FARO TECHNOLOGIES, INC. + ++OUI:70B3D5937* ++ ID_OUI_FROM_DATABASE=TATTILE SRL ++ + OUI:70B3D5938* + ID_OUI_FROM_DATABASE=JETI Technische Instrumente GmbH + + OUI:70B3D5939* + ID_OUI_FROM_DATABASE=Invertek Drives Ltd + ++OUI:70B3D593A* ++ ID_OUI_FROM_DATABASE=Braemar Manufacturing, LLC ++ ++OUI:70B3D593B* ++ ID_OUI_FROM_DATABASE=Changchun FAW Yanfeng Visteon Automotive Electronics.,Ltd. ++ ++OUI:70B3D593C* ++ ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH ++ ++OUI:70B3D593D* ++ ID_OUI_FROM_DATABASE=Elmeasure India Pvt Ltd ++ + OUI:70B3D593E* + ID_OUI_FROM_DATABASE=Systems With Intelligence Inc. + ++OUI:70B3D593F* ++ ID_OUI_FROM_DATABASE=Vision Sensing Co., Ltd. ++ + OUI:70B3D5940* + ID_OUI_FROM_DATABASE=Paradigm Technology Services B.V. + +@@ -62291,27 +74249,48 @@ OUI:70B3D5942* + OUI:70B3D5943* + ID_OUI_FROM_DATABASE=Abbott Medical Optics Inc. + ++OUI:70B3D5944* ++ ID_OUI_FROM_DATABASE=Chromateq ++ + OUI:70B3D5945* + ID_OUI_FROM_DATABASE=Symboticware Incorporated + ++OUI:70B3D5946* ++ ID_OUI_FROM_DATABASE=GREATWALL Infotech Co., Ltd. ++ + OUI:70B3D5947* + ID_OUI_FROM_DATABASE=Checkbill Co,Ltd. + + OUI:70B3D5948* + ID_OUI_FROM_DATABASE=VISION SYSTEMS AURTOMOTIVE (SAFETY TECH) + ++OUI:70B3D5949* ++ ID_OUI_FROM_DATABASE=National Radio & Telecommunication Corporation - NRTC ++ + OUI:70B3D594A* + ID_OUI_FROM_DATABASE=SHENZHEN WISEWING INTERNET TECHNOLOGY CO.,LTD + ++OUI:70B3D594B* ++ ID_OUI_FROM_DATABASE=RF Code ++ ++OUI:70B3D594C* ++ ID_OUI_FROM_DATABASE=Honeywell/Intelligrated ++ + OUI:70B3D594D* + ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY + ++OUI:70B3D594E* ++ ID_OUI_FROM_DATABASE=BP Lubricants USA, Inc. ++ + OUI:70B3D594F* + ID_OUI_FROM_DATABASE=MART NETWORK SOLUTIONS LTD + + OUI:70B3D5950* + ID_OUI_FROM_DATABASE=CMT Medical technologies + ++OUI:70B3D5951* ++ ID_OUI_FROM_DATABASE=Trident Systems Inc ++ + OUI:70B3D5952* + ID_OUI_FROM_DATABASE=REQUEA + +@@ -62345,18 +74324,36 @@ OUI:70B3D595B* + OUI:70B3D595C* + ID_OUI_FROM_DATABASE=Wilson Electronics + ++OUI:70B3D595D* ++ ID_OUI_FROM_DATABASE=GIORDANO CONTROLS SPA ++ + OUI:70B3D595E* + ID_OUI_FROM_DATABASE=BLOCKSI LLC + ++OUI:70B3D595F* ++ ID_OUI_FROM_DATABASE=WiFi Nation Ltd ++ + OUI:70B3D5960* + ID_OUI_FROM_DATABASE=HORIZON TELECOM + + OUI:70B3D5961* + ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA + ++OUI:70B3D5962* ++ ID_OUI_FROM_DATABASE=Senquire Pte. Ltd ++ + OUI:70B3D5963* + ID_OUI_FROM_DATABASE=Triax A/S + ++OUI:70B3D5964* ++ ID_OUI_FROM_DATABASE=Visility ++ ++OUI:70B3D5965* ++ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., ++ ++OUI:70B3D5966* ++ ID_OUI_FROM_DATABASE=dA Tomato Limited ++ + OUI:70B3D5967* + ID_OUI_FROM_DATABASE=TATTILE SRL + +@@ -62366,15 +74363,33 @@ OUI:70B3D5968* + OUI:70B3D5969* + ID_OUI_FROM_DATABASE=Emtel System Sp. z o.o. + ++OUI:70B3D596A* ++ ID_OUI_FROM_DATABASE=Anello Photonics ++ + OUI:70B3D596B* + ID_OUI_FROM_DATABASE=FOCAL-JMLab + ++OUI:70B3D596C* ++ ID_OUI_FROM_DATABASE=Weble Sàrl ++ + OUI:70B3D596D* + ID_OUI_FROM_DATABASE=MSB Elektronik und Gerätebau GmbH + ++OUI:70B3D596E* ++ ID_OUI_FROM_DATABASE=Myostat Motion Control Inc ++ + OUI:70B3D596F* + ID_OUI_FROM_DATABASE=4CAM GmbH + ++OUI:70B3D5970* ++ ID_OUI_FROM_DATABASE=Bintel AB ++ ++OUI:70B3D5971* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ ++OUI:70B3D5972* ++ ID_OUI_FROM_DATABASE=AixControl GmbH ++ + OUI:70B3D5973* + ID_OUI_FROM_DATABASE=Autonomic Controls, Inc. + +@@ -62387,15 +74402,45 @@ OUI:70B3D5975* + OUI:70B3D5976* + ID_OUI_FROM_DATABASE=Atonarp Micro-Systems India Pvt. Ltd. + ++OUI:70B3D5977* ++ ID_OUI_FROM_DATABASE=Engage Technologies ++ ++OUI:70B3D5978* ++ ID_OUI_FROM_DATABASE=Satixfy Israel Ltd. ++ ++OUI:70B3D5979* ++ ID_OUI_FROM_DATABASE=eSMART Technologies SA ++ ++OUI:70B3D597A* ++ ID_OUI_FROM_DATABASE=Orion Corporation ++ ++OUI:70B3D597B* ++ ID_OUI_FROM_DATABASE=WIKA Alexander Wiegand SE & Co. KG ++ + OUI:70B3D597C* + ID_OUI_FROM_DATABASE=Nu-Tek Power Controls and Automation + ++OUI:70B3D597D* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ ++OUI:70B3D597E* ++ ID_OUI_FROM_DATABASE=Public Joint Stock Company Morion ++ + OUI:70B3D597F* + ID_OUI_FROM_DATABASE=BISTOS.,Co.,Ltd + ++OUI:70B3D5980* ++ ID_OUI_FROM_DATABASE=Beijing Yourong Runda Rechnology Development Co.Ltd. ++ + OUI:70B3D5981* + ID_OUI_FROM_DATABASE=Zamir Recognition Systems Ltd. + ++OUI:70B3D5982* ++ ID_OUI_FROM_DATABASE=3S - Sensors, Signal Processing, Systems GmbH ++ ++OUI:70B3D5983* ++ ID_OUI_FROM_DATABASE=ENS Engineered Network Systems ++ + OUI:70B3D5984* + ID_OUI_FROM_DATABASE=Sanmina Israel + +@@ -62408,24 +74453,39 @@ OUI:70B3D5986* + OUI:70B3D5987* + ID_OUI_FROM_DATABASE=AXIS CORPORATION + ++OUI:70B3D5988* ++ ID_OUI_FROM_DATABASE=Arris ++ + OUI:70B3D5989* + ID_OUI_FROM_DATABASE=DCNS + ++OUI:70B3D598A* ++ ID_OUI_FROM_DATABASE=vision systems safety tech ++ + OUI:70B3D598B* + ID_OUI_FROM_DATABASE=Richard Paul Russell Ltd + + OUI:70B3D598C* + ID_OUI_FROM_DATABASE=University of Wisconsin Madison - Department of High Energy Physics + ++OUI:70B3D598D* ++ ID_OUI_FROM_DATABASE=Motohaus Powersports Limited ++ + OUI:70B3D598E* + ID_OUI_FROM_DATABASE=Autocom Diagnostic Partner AB + + OUI:70B3D598F* + ID_OUI_FROM_DATABASE=Spaceflight Industries + ++OUI:70B3D5990* ++ ID_OUI_FROM_DATABASE=Energy Wall ++ + OUI:70B3D5991* + ID_OUI_FROM_DATABASE=Javasparrow Inc. + ++OUI:70B3D5992* ++ ID_OUI_FROM_DATABASE=KAEONIT ++ + OUI:70B3D5993* + ID_OUI_FROM_DATABASE=ioThings + +@@ -62441,15 +74501,24 @@ OUI:70B3D5996* + OUI:70B3D5997* + ID_OUI_FROM_DATABASE=ProTom International + ++OUI:70B3D5998* ++ ID_OUI_FROM_DATABASE=Kita Kirmizi Takim Bilgi Guvenligi Danismanlik ve Egitim A.S. ++ + OUI:70B3D5999* + ID_OUI_FROM_DATABASE=LOGICUBE INC + + OUI:70B3D599A* + ID_OUI_FROM_DATABASE=KEVIC. inc, + ++OUI:70B3D599B* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ + OUI:70B3D599C* + ID_OUI_FROM_DATABASE=Enerwise Solutions Ltd. + ++OUI:70B3D599D* ++ ID_OUI_FROM_DATABASE=Opsys-Tech ++ + OUI:70B3D599E* + ID_OUI_FROM_DATABASE=Trinity College Dublin + +@@ -62462,21 +74531,51 @@ OUI:70B3D59A0* + OUI:70B3D59A1* + ID_OUI_FROM_DATABASE=ITS Industrial Turbine Services GmbH + ++OUI:70B3D59A2* ++ ID_OUI_FROM_DATABASE=O-Net Communications(Shenzhen)Limited ++ ++OUI:70B3D59A3* ++ ID_OUI_FROM_DATABASE=Shanghai Hourui Technology Co., Ltd. ++ ++OUI:70B3D59A4* ++ ID_OUI_FROM_DATABASE=Nordmann International GmbH ++ ++OUI:70B3D59A5* ++ ID_OUI_FROM_DATABASE=Softel ++ ++OUI:70B3D59A6* ++ ID_OUI_FROM_DATABASE=QUNU LABS PRIVATE LIMITED ++ + OUI:70B3D59A7* + ID_OUI_FROM_DATABASE=Honeywell + ++OUI:70B3D59A8* ++ ID_OUI_FROM_DATABASE=Egag, LLC ++ ++OUI:70B3D59A9* ++ ID_OUI_FROM_DATABASE=PABLO AIR Co., LTD ++ + OUI:70B3D59AA* + ID_OUI_FROM_DATABASE=Tecsys do Brasil Industrial Ltda + + OUI:70B3D59AB* + ID_OUI_FROM_DATABASE=Groupe Paris-Turf + ++OUI:70B3D59AC* ++ ID_OUI_FROM_DATABASE=Suzhou Sapa Automotive Technology Co.,Ltd ++ + OUI:70B3D59AD* + ID_OUI_FROM_DATABASE=Fortuna Impex Pvt ltd + + OUI:70B3D59AE* + ID_OUI_FROM_DATABASE=Volansys technologies pvt ltd + ++OUI:70B3D59AF* ++ ID_OUI_FROM_DATABASE=Shanghai Brellet Telecommunication Technology Co., Ltd. ++ ++OUI:70B3D59B0* ++ ID_OUI_FROM_DATABASE=Clearly IP Inc ++ + OUI:70B3D59B1* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +@@ -62495,21 +74594,51 @@ OUI:70B3D59B5* + OUI:70B3D59B6* + ID_OUI_FROM_DATABASE=Intercomp S.p.A. + ++OUI:70B3D59B7* ++ ID_OUI_FROM_DATABASE=Itronics Ltd ++ + OUI:70B3D59B8* +- ID_OUI_FROM_DATABASE=Loma Systems ++ ID_OUI_FROM_DATABASE=Loma Systems s.r.o. ++ ++OUI:70B3D59B9* ++ ID_OUI_FROM_DATABASE=Aethera Technologies + + OUI:70B3D59BA* + ID_OUI_FROM_DATABASE=ATIM Radiocommunication + ++OUI:70B3D59BB* ++ ID_OUI_FROM_DATABASE=Jinga-hi, Inc. ++ ++OUI:70B3D59BC* ++ ID_OUI_FROM_DATABASE=Radian Research, Inc. ++ + OUI:70B3D59BD* + ID_OUI_FROM_DATABASE=Signal Processing Devices Sweden AB + ++OUI:70B3D59BE* ++ ID_OUI_FROM_DATABASE=Izome ++ ++OUI:70B3D59BF* ++ ID_OUI_FROM_DATABASE=Xiris Automation Inc. ++ + OUI:70B3D59C0* + ID_OUI_FROM_DATABASE=Schneider Displaytechnik GmbH + + OUI:70B3D59C1* + ID_OUI_FROM_DATABASE=Zeroplus Technology Co.,Ltd. + ++OUI:70B3D59C2* ++ ID_OUI_FROM_DATABASE=Sportsbeams Lighting, Inc. ++ ++OUI:70B3D59C3* ++ ID_OUI_FROM_DATABASE=Sevensense Robotics AG ++ ++OUI:70B3D59C4* ++ ID_OUI_FROM_DATABASE=aelettronica group srl ++ ++OUI:70B3D59C5* ++ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD., ++ + OUI:70B3D59C6* + ID_OUI_FROM_DATABASE=Overspeed SARL + +@@ -62528,9 +74657,18 @@ OUI:70B3D59CA* + OUI:70B3D59CB* + ID_OUI_FROM_DATABASE=Alligator Communications + ++OUI:70B3D59CC* ++ ID_OUI_FROM_DATABASE=Zaxcom Inc ++ ++OUI:70B3D59CD* ++ ID_OUI_FROM_DATABASE=WEPTECH elektronik GmbH ++ + OUI:70B3D59CE* + ID_OUI_FROM_DATABASE=Terragene S.A + ++OUI:70B3D59CF* ++ ID_OUI_FROM_DATABASE=IOTIZE ++ + OUI:70B3D59D0* + ID_OUI_FROM_DATABASE=RJ45 Technologies + +@@ -62544,17 +74682,26 @@ OUI:70B3D59D3* + ID_OUI_FROM_DATABASE=Communication Technology Ltd. + + OUI:70B3D59D4* +- ID_OUI_FROM_DATABASE=Transas Marine Limited ++ ID_OUI_FROM_DATABASE=Wartsila Voyage Limited + + OUI:70B3D59D5* + ID_OUI_FROM_DATABASE=Southern Tier Technologies + ++OUI:70B3D59D6* ++ ID_OUI_FROM_DATABASE=Crown Solar Power Fencing Systems ++ + OUI:70B3D59D7* + ID_OUI_FROM_DATABASE=KM OptoElektronik GmbH + ++OUI:70B3D59D8* ++ ID_OUI_FROM_DATABASE=JOLANYEE Technology Co., Ltd. ++ + OUI:70B3D59D9* + ID_OUI_FROM_DATABASE=ATX Networks Corp + ++OUI:70B3D59DA* ++ ID_OUI_FROM_DATABASE=Blake UK ++ + OUI:70B3D59DB* + ID_OUI_FROM_DATABASE=CAS Medical Systems, Inc + +@@ -62567,21 +74714,42 @@ OUI:70B3D59DD* + OUI:70B3D59DE* + ID_OUI_FROM_DATABASE=System 11 Sp. z o.o. + ++OUI:70B3D59DF* ++ ID_OUI_FROM_DATABASE=DOBE Computing ++ + OUI:70B3D59E0* + ID_OUI_FROM_DATABASE=ES Industrial Systems Co., Ltd. + ++OUI:70B3D59E1* ++ ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc. ++ + OUI:70B3D59E2* + ID_OUI_FROM_DATABASE=Ofil USA + + OUI:70B3D59E3* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:70B3D59E4* ++ ID_OUI_FROM_DATABASE=K&A Electronics Inc. ++ ++OUI:70B3D59E5* ++ ID_OUI_FROM_DATABASE=Antek Technology ++ + OUI:70B3D59E6* + ID_OUI_FROM_DATABASE=BLOCKSI LLC + + OUI:70B3D59E7* + ID_OUI_FROM_DATABASE=Xiamen Maxincom Technologies Co., Ltd. + ++OUI:70B3D59E8* ++ ID_OUI_FROM_DATABASE=Zerospace ICT Services B.V. ++ ++OUI:70B3D59E9* ++ ID_OUI_FROM_DATABASE=LiveCopper Inc. ++ ++OUI:70B3D59EA* ++ ID_OUI_FROM_DATABASE=Blue Storm Associates, Inc. ++ + OUI:70B3D59EB* + ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience + +@@ -62591,6 +74759,9 @@ OUI:70B3D59EC* + OUI:70B3D59ED* + ID_OUI_FROM_DATABASE=Benchmark Electronics BV + ++OUI:70B3D59EE* ++ ID_OUI_FROM_DATABASE=Lockheed Martin - THAAD ++ + OUI:70B3D59EF* + ID_OUI_FROM_DATABASE=Cottonwood Creek Technologies, Inc. + +@@ -62615,29 +74786,50 @@ OUI:70B3D59F5* + OUI:70B3D59F6* + ID_OUI_FROM_DATABASE=Edgeware AB + ++OUI:70B3D59F7* ++ ID_OUI_FROM_DATABASE=Foerster-Technik GmbH ++ + OUI:70B3D59F8* + ID_OUI_FROM_DATABASE=Asymmetric Technologies + ++OUI:70B3D59F9* ++ ID_OUI_FROM_DATABASE=Fluid Components Intl ++ + OUI:70B3D59FA* + ID_OUI_FROM_DATABASE=Ideas srl + + OUI:70B3D59FB* + ID_OUI_FROM_DATABASE=Unicom Global, Inc. + ++OUI:70B3D59FC* ++ ID_OUI_FROM_DATABASE=Truecom Telesoft Private Limited ++ ++OUI:70B3D59FD* ++ ID_OUI_FROM_DATABASE=amakidenki ++ ++OUI:70B3D59FE* ++ ID_OUI_FROM_DATABASE=SURUGA SEIKI CO., LTD. ++ ++OUI:70B3D59FF* ++ ID_OUI_FROM_DATABASE=Network Integrity Systems ++ + OUI:70B3D5A00* + ID_OUI_FROM_DATABASE=ATX NETWORKS LTD + + OUI:70B3D5A01* + ID_OUI_FROM_DATABASE=FeldTech GmbH + ++OUI:70B3D5A02* ++ ID_OUI_FROM_DATABASE=GreenFlux ++ + OUI:70B3D5A03* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Proemion GmbH + + OUI:70B3D5A04* + ID_OUI_FROM_DATABASE=Galea Electric S.L. + + OUI:70B3D5A05* +- ID_OUI_FROM_DATABASE=Transas Marine Limited ++ ID_OUI_FROM_DATABASE=Wartsila Voyage Limited + + OUI:70B3D5A06* + ID_OUI_FROM_DATABASE=Kopis Mobile LLC +@@ -62648,30 +74840,48 @@ OUI:70B3D5A07* + OUI:70B3D5A08* + ID_OUI_FROM_DATABASE=BioBusiness + ++OUI:70B3D5A09* ++ ID_OUI_FROM_DATABASE=Smart Embedded Systems ++ + OUI:70B3D5A0A* + ID_OUI_FROM_DATABASE=CAPSYS + + OUI:70B3D5A0B* + ID_OUI_FROM_DATABASE=ambiHome GmbH + ++OUI:70B3D5A0C* ++ ID_OUI_FROM_DATABASE=Lumiplan Duhamel ++ + OUI:70B3D5A0D* + ID_OUI_FROM_DATABASE=Globalcom Engineering SPA + + OUI:70B3D5A0E* + ID_OUI_FROM_DATABASE=Vetaphone A/S + ++OUI:70B3D5A0F* ++ ID_OUI_FROM_DATABASE=OSAKI DATATECH CO., LTD. ++ + OUI:70B3D5A10* + ID_OUI_FROM_DATABASE=w-tec AG + ++OUI:70B3D5A11* ++ ID_OUI_FROM_DATABASE=TRIOPTICS ++ + OUI:70B3D5A12* + ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. + + OUI:70B3D5A13* + ID_OUI_FROM_DATABASE=Uplevel Systems Inc + ++OUI:70B3D5A14* ++ ID_OUI_FROM_DATABASE=aelettronica group srl ++ + OUI:70B3D5A15* + ID_OUI_FROM_DATABASE=Intercore GmbH + ++OUI:70B3D5A16* ++ ID_OUI_FROM_DATABASE=devAIs s.r.l. ++ + OUI:70B3D5A17* + ID_OUI_FROM_DATABASE=Tunstall A/S + +@@ -62681,6 +74891,9 @@ OUI:70B3D5A18* + OUI:70B3D5A19* + ID_OUI_FROM_DATABASE=Qualitronix Madrass Pvt Ltd + ++OUI:70B3D5A1A* ++ ID_OUI_FROM_DATABASE=Nueon - The COR ++ + OUI:70B3D5A1B* + ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC + +@@ -62690,6 +74903,9 @@ OUI:70B3D5A1C* + OUI:70B3D5A1D* + ID_OUI_FROM_DATABASE=Fluid Components International + ++OUI:70B3D5A1E* ++ ID_OUI_FROM_DATABASE=Monnit Corporation ++ + OUI:70B3D5A1F* + ID_OUI_FROM_DATABASE=GlobalTest LLC + +@@ -62699,6 +74915,15 @@ OUI:70B3D5A20* + OUI:70B3D5A21* + ID_OUI_FROM_DATABASE=PPI Inc. + ++OUI:70B3D5A22* ++ ID_OUI_FROM_DATABASE=eSys Solutions Sweden AB ++ ++OUI:70B3D5A23* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ ++OUI:70B3D5A24* ++ ID_OUI_FROM_DATABASE=Booz Allen Hamilton ++ + OUI:70B3D5A25* + ID_OUI_FROM_DATABASE=PulseTor LLC + +@@ -62717,9 +74942,15 @@ OUI:70B3D5A29* + OUI:70B3D5A2A* + ID_OUI_FROM_DATABASE=Redwood Systems + ++OUI:70B3D5A2B* ++ ID_OUI_FROM_DATABASE=Clever Devices ++ + OUI:70B3D5A2C* + ID_OUI_FROM_DATABASE=TLV CO., LTD. + ++OUI:70B3D5A2D* ++ ID_OUI_FROM_DATABASE=Project Service S.r.l. ++ + OUI:70B3D5A2E* + ID_OUI_FROM_DATABASE=Kokam Co., Ltd + +@@ -62729,12 +74960,18 @@ OUI:70B3D5A2F* + OUI:70B3D5A30* + ID_OUI_FROM_DATABASE=SHEN ZHEN HUAWANG TECHNOLOGY CO; LTD + ++OUI:70B3D5A31* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:70B3D5A32* + ID_OUI_FROM_DATABASE=Toughdog Security Systems + + OUI:70B3D5A33* + ID_OUI_FROM_DATABASE=TIAMA + ++OUI:70B3D5A34* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ + OUI:70B3D5A35* + ID_OUI_FROM_DATABASE=Sicon srl + +@@ -62744,6 +74981,12 @@ OUI:70B3D5A36* + OUI:70B3D5A37* + ID_OUI_FROM_DATABASE=MITSUBISHI HEAVY INDUSTRIES THERMAL SYSTEMS, LTD. + ++OUI:70B3D5A38* ++ ID_OUI_FROM_DATABASE=Aditec GmbH ++ ++OUI:70B3D5A39* ++ ID_OUI_FROM_DATABASE=SPETSSTROY-SVYAZ Ltd ++ + OUI:70B3D5A3A* + ID_OUI_FROM_DATABASE=EPSOFT Co., Ltd + +@@ -62753,17 +74996,32 @@ OUI:70B3D5A3B* + OUI:70B3D5A3C* + ID_OUI_FROM_DATABASE=Wave Music Ltd + ++OUI:70B3D5A3D* ++ ID_OUI_FROM_DATABASE=SMART IN OVATION GmbH ++ ++OUI:70B3D5A3E* ++ ID_OUI_FROM_DATABASE=Vigorcloud Co., Ltd. ++ + OUI:70B3D5A3F* + ID_OUI_FROM_DATABASE=PHPower Srl + + OUI:70B3D5A40* + ID_OUI_FROM_DATABASE=STRACK LIFT AUTOMATION GmbH + ++OUI:70B3D5A41* ++ ID_OUI_FROM_DATABASE=THELIGHT Luminary for Cine and TV S.L. ++ ++OUI:70B3D5A42* ++ ID_OUI_FROM_DATABASE=iMAR Navigation GmbH ++ + OUI:70B3D5A43* + ID_OUI_FROM_DATABASE=OLEDCOMM + + OUI:70B3D5A44* +- ID_OUI_FROM_DATABASE=FSR Inc ++ ID_OUI_FROM_DATABASE=FSR, INC. ++ ++OUI:70B3D5A45* ++ ID_OUI_FROM_DATABASE=Viper Innovations Ltd + + OUI:70B3D5A46* + ID_OUI_FROM_DATABASE=Foxconn 4Tech +@@ -62774,6 +75032,9 @@ OUI:70B3D5A47* + OUI:70B3D5A48* + ID_OUI_FROM_DATABASE=Applied Satellite Engineering + ++OUI:70B3D5A49* ++ ID_OUI_FROM_DATABASE=Unipower AB ++ + OUI:70B3D5A4A* + ID_OUI_FROM_DATABASE=Beijing Arrow SEED Technology Co,.Ltd. + +@@ -62783,6 +75044,9 @@ OUI:70B3D5A4B* + OUI:70B3D5A4C* + ID_OUI_FROM_DATABASE=Alere Technologies AS + ++OUI:70B3D5A4D* ++ ID_OUI_FROM_DATABASE=LANSITEC TECHNOLOGY CO., LTD ++ + OUI:70B3D5A4E* + ID_OUI_FROM_DATABASE=Array Technologies Inc. + +@@ -62795,6 +75059,9 @@ OUI:70B3D5A50* + OUI:70B3D5A51* + ID_OUI_FROM_DATABASE=RF Code + ++OUI:70B3D5A52* ++ ID_OUI_FROM_DATABASE=APEX Stabilizations GmbH ++ + OUI:70B3D5A53* + ID_OUI_FROM_DATABASE=GS Industrie-Elektronik GmbH + +@@ -62825,21 +75092,54 @@ OUI:70B3D5A5B* + OUI:70B3D5A5C* + ID_OUI_FROM_DATABASE=Molekule + ++OUI:70B3D5A5D* ++ ID_OUI_FROM_DATABASE=Position Imaging ++ + OUI:70B3D5A5E* + ID_OUI_FROM_DATABASE=ConectaIP Tecnologia S.L. + ++OUI:70B3D5A5F* ++ ID_OUI_FROM_DATABASE=Daatrics LTD ++ ++OUI:70B3D5A60* ++ ID_OUI_FROM_DATABASE=Pneumax S.p.A. ++ ++OUI:70B3D5A61* ++ ID_OUI_FROM_DATABASE=Omsk Manufacturing Association named after A.S. Popov ++ + OUI:70B3D5A62* + ID_OUI_FROM_DATABASE=Environexus + ++OUI:70B3D5A63* ++ ID_OUI_FROM_DATABASE=DesignA Electronics Limited ++ + OUI:70B3D5A64* + ID_OUI_FROM_DATABASE=Newshine + ++OUI:70B3D5A65* ++ ID_OUI_FROM_DATABASE=CREATIVE ++ + OUI:70B3D5A66* + ID_OUI_FROM_DATABASE=Trapeze Software Group Inc + ++OUI:70B3D5A67* ++ ID_OUI_FROM_DATABASE=Gstar Creation Co .,Ltd ++ ++OUI:70B3D5A68* ++ ID_OUI_FROM_DATABASE=Zhejiang Zhaolong Interconnect Technology Co.,Ltd ++ + OUI:70B3D5A69* + ID_OUI_FROM_DATABASE=Leviathan Solutions Ltd. + ++OUI:70B3D5A6A* ++ ID_OUI_FROM_DATABASE=Privafy, Inc ++ ++OUI:70B3D5A6B* ++ ID_OUI_FROM_DATABASE=xmi systems ++ ++OUI:70B3D5A6C* ++ ID_OUI_FROM_DATABASE=Controles S.A. ++ + OUI:70B3D5A6D* + ID_OUI_FROM_DATABASE=Metek Meteorologische Messtechnik GmbH + +@@ -62849,33 +75149,69 @@ OUI:70B3D5A6E* + OUI:70B3D5A6F* + ID_OUI_FROM_DATABASE=8Cups + ++OUI:70B3D5A70* ++ ID_OUI_FROM_DATABASE=Gateview Technologies ++ ++OUI:70B3D5A71* ++ ID_OUI_FROM_DATABASE=Samwell International Inc ++ + OUI:70B3D5A72* + ID_OUI_FROM_DATABASE=Business Marketers Group, Inc. + + OUI:70B3D5A73* + ID_OUI_FROM_DATABASE=MobiPromo + ++OUI:70B3D5A74* ++ ID_OUI_FROM_DATABASE=Sadel S.p.A. ++ ++OUI:70B3D5A75* ++ ID_OUI_FROM_DATABASE=Taejin InfoTech ++ + OUI:70B3D5A76* + ID_OUI_FROM_DATABASE=Pietro Fiorentini + ++OUI:70B3D5A77* ++ ID_OUI_FROM_DATABASE=SPX Radiodetection ++ + OUI:70B3D5A78* + ID_OUI_FROM_DATABASE=Bionics co.,ltd. + ++OUI:70B3D5A79* ++ ID_OUI_FROM_DATABASE=NOREYA Technology e.U. ++ + OUI:70B3D5A7A* + ID_OUI_FROM_DATABASE=Fluid Management Technology + ++OUI:70B3D5A7B* ++ ID_OUI_FROM_DATABASE=SmartSafe ++ + OUI:70B3D5A7C* + ID_OUI_FROM_DATABASE=Transelektronik Messgeräte GmbH + ++OUI:70B3D5A7D* ++ ID_OUI_FROM_DATABASE=Prior Scientific Instruments Ltd ++ + OUI:70B3D5A7E* + ID_OUI_FROM_DATABASE=QUICCO SOUND Corporation + ++OUI:70B3D5A7F* ++ ID_OUI_FROM_DATABASE=AUDIO VISUAL DIGITAL SYSTEMS ++ ++OUI:70B3D5A80* ++ ID_OUI_FROM_DATABASE=EVCO SPA ++ + OUI:70B3D5A81* + ID_OUI_FROM_DATABASE=Sienda New Media Technologies GmbH + + OUI:70B3D5A82* + ID_OUI_FROM_DATABASE=Telefrank GmbH + ++OUI:70B3D5A83* ++ ID_OUI_FROM_DATABASE=SHENZHEN HUINENGYUAN Technology Co., Ltd ++ ++OUI:70B3D5A84* ++ ID_OUI_FROM_DATABASE=SOREL GmbH Mikroelektronik ++ + OUI:70B3D5A85* + ID_OUI_FROM_DATABASE=exceet electronics GesmbH + +@@ -62891,15 +75227,24 @@ OUI:70B3D5A88* + OUI:70B3D5A89* + ID_OUI_FROM_DATABASE=GBS COMMUNICATIONS, LLC + ++OUI:70B3D5A8A* ++ ID_OUI_FROM_DATABASE=JSC VIST Group ++ + OUI:70B3D5A8B* + ID_OUI_FROM_DATABASE=Giant Power Technology Biomedical Corporation + ++OUI:70B3D5A8C* ++ ID_OUI_FROM_DATABASE=CYG CONTRON CO.LTD ++ + OUI:70B3D5A8D* + ID_OUI_FROM_DATABASE=Code Blue Corporation + + OUI:70B3D5A8E* + ID_OUI_FROM_DATABASE=OMESH CITY GROUP + ++OUI:70B3D5A8F* ++ ID_OUI_FROM_DATABASE=VK Integrated Systems ++ + OUI:70B3D5A90* + ID_OUI_FROM_DATABASE=ERA a.s. + +@@ -62924,12 +75269,21 @@ OUI:70B3D5A96* + OUI:70B3D5A97* + ID_OUI_FROM_DATABASE=Bizwerks, LLC + ++OUI:70B3D5A98* ++ ID_OUI_FROM_DATABASE=Pantec AG ++ + OUI:70B3D5A99* + ID_OUI_FROM_DATABASE=Bandelin electronic GmbH & Co. KG + + OUI:70B3D5A9A* + ID_OUI_FROM_DATABASE=Amphenol Advanced Sensors + ++OUI:70B3D5A9B* ++ ID_OUI_FROM_DATABASE=OSMOZIS ++ ++OUI:70B3D5A9C* ++ ID_OUI_FROM_DATABASE=Veo Technologies ++ + OUI:70B3D5A9D* + ID_OUI_FROM_DATABASE=VITEC MULTIMEDIA + +@@ -62937,7 +75291,7 @@ OUI:70B3D5A9E* + ID_OUI_FROM_DATABASE=Argon ST + + OUI:70B3D5A9F* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Master Meter Inc. + + OUI:70B3D5AA0* + ID_OUI_FROM_DATABASE=Simple Works, Inc. +@@ -62954,6 +75308,9 @@ OUI:70B3D5AA3* + OUI:70B3D5AA4* + ID_OUI_FROM_DATABASE=Pullnet Technology,S.L. + ++OUI:70B3D5AA5* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ + OUI:70B3D5AA6* + ID_OUI_FROM_DATABASE=Proximus + +@@ -62963,9 +75320,15 @@ OUI:70B3D5AA7* + OUI:70B3D5AA8* + ID_OUI_FROM_DATABASE=West-Com Nurse Call Systems, Inc. + ++OUI:70B3D5AA9* ++ ID_OUI_FROM_DATABASE=Datamars SA ++ + OUI:70B3D5AAA* + ID_OUI_FROM_DATABASE=Xemex NV + ++OUI:70B3D5AAB* ++ ID_OUI_FROM_DATABASE=QUISS GmbH ++ + OUI:70B3D5AAC* + ID_OUI_FROM_DATABASE=SensoTec GmbH + +@@ -62981,6 +75344,12 @@ OUI:70B3D5AAF* + OUI:70B3D5AB0* + ID_OUI_FROM_DATABASE=OSR R&D ISRAEL LTD + ++OUI:70B3D5AB1* ++ ID_OUI_FROM_DATABASE=ISRV Zrt. ++ ++OUI:70B3D5AB2* ++ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. ++ + OUI:70B3D5AB3* + ID_OUI_FROM_DATABASE=MICAS AG + +@@ -62990,6 +75359,9 @@ OUI:70B3D5AB4* + OUI:70B3D5AB5* + ID_OUI_FROM_DATABASE=BroadSoft Inc + ++OUI:70B3D5AB6* ++ ID_OUI_FROM_DATABASE=SmartD Technologies Inc ++ + OUI:70B3D5AB7* + ID_OUI_FROM_DATABASE=SIGLEAD INC + +@@ -63002,18 +75374,30 @@ OUI:70B3D5AB9* + OUI:70B3D5ABA* + ID_OUI_FROM_DATABASE=CL International + ++OUI:70B3D5ABB* ++ ID_OUI_FROM_DATABASE=David Horn Communications Ltd ++ + OUI:70B3D5ABC* + ID_OUI_FROM_DATABASE=BKM-Micronic Richtfunkanlagen GmbH + ++OUI:70B3D5ABD* ++ ID_OUI_FROM_DATABASE=wtec GmbH ++ + OUI:70B3D5ABE* + ID_OUI_FROM_DATABASE=MART NETWORK SOLUTIONS LTD + + OUI:70B3D5ABF* + ID_OUI_FROM_DATABASE=AGR International + ++OUI:70B3D5AC0* ++ ID_OUI_FROM_DATABASE=RITEC ++ + OUI:70B3D5AC1* + ID_OUI_FROM_DATABASE=AEM Singapore Pte. Ltd. + ++OUI:70B3D5AC2* ++ ID_OUI_FROM_DATABASE=Wisebox.,Co.Ltd ++ + OUI:70B3D5AC3* + ID_OUI_FROM_DATABASE=Novoptel GmbH + +@@ -63035,33 +75419,63 @@ OUI:70B3D5AC8* + OUI:70B3D5AC9* + ID_OUI_FROM_DATABASE=Trinity Solutions LLC + ++OUI:70B3D5ACA* ++ ID_OUI_FROM_DATABASE=Tecnint HTE SRL ++ + OUI:70B3D5ACB* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D5ACC* ++ ID_OUI_FROM_DATABASE=Schneider Electric Motion USA ++ + OUI:70B3D5ACD* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D5ACE* ++ ID_OUI_FROM_DATABASE=FARHO DOMOTICA SL ++ ++OUI:70B3D5ACF* ++ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC ++ ++OUI:70B3D5AD0* ++ ID_OUI_FROM_DATABASE=REO AG ++ + OUI:70B3D5AD1* + ID_OUI_FROM_DATABASE=Sensile Technologies SA + + OUI:70B3D5AD2* + ID_OUI_FROM_DATABASE=Wart-Elektronik + ++OUI:70B3D5AD3* ++ ID_OUI_FROM_DATABASE=WARECUBE,INC ++ ++OUI:70B3D5AD4* ++ ID_OUI_FROM_DATABASE=INVISSYS ++ + OUI:70B3D5AD5* + ID_OUI_FROM_DATABASE=Birdland Audio + + OUI:70B3D5AD6* + ID_OUI_FROM_DATABASE=Lemonade Lab Inc + ++OUI:70B3D5AD7* ++ ID_OUI_FROM_DATABASE=Octopus IoT srl ++ + OUI:70B3D5AD8* + ID_OUI_FROM_DATABASE=Euklis by GSG International + ++OUI:70B3D5AD9* ++ ID_OUI_FROM_DATABASE=aelettronica group srl ++ + OUI:70B3D5ADA* + ID_OUI_FROM_DATABASE=Private + + OUI:70B3D5ADB* + ID_OUI_FROM_DATABASE=RF Code + ++OUI:70B3D5ADC* ++ ID_OUI_FROM_DATABASE=SODAQ ++ + OUI:70B3D5ADD* + ID_OUI_FROM_DATABASE=GHL Systems Berhad + +@@ -63078,17 +75492,26 @@ OUI:70B3D5AE1* + ID_OUI_FROM_DATABASE=DimoCore Corporation + + OUI:70B3D5AE2* +- ID_OUI_FROM_DATABASE=Transas Marine Limited ++ ID_OUI_FROM_DATABASE=Wartsila Voyage Limited + + OUI:70B3D5AE3* + ID_OUI_FROM_DATABASE=Zhejiang Wellsun Electric Meter Co.,Ltd + ++OUI:70B3D5AE4* ++ ID_OUI_FROM_DATABASE=Nuance Hearing Ltd. ++ + OUI:70B3D5AE5* + ID_OUI_FROM_DATABASE=BeatCraft, Inc. + ++OUI:70B3D5AE6* ++ ID_OUI_FROM_DATABASE=Ya Batho Trading (Pty) Ltd ++ + OUI:70B3D5AE7* + ID_OUI_FROM_DATABASE=E-T-A Elektrotechnische Apparate GmbH + ++OUI:70B3D5AE8* ++ ID_OUI_FROM_DATABASE=Innoknight ++ + OUI:70B3D5AE9* + ID_OUI_FROM_DATABASE=Cari Electronic + +@@ -63098,6 +75521,12 @@ OUI:70B3D5AEA* + OUI:70B3D5AEB* + ID_OUI_FROM_DATABASE=Association Romandix + ++OUI:70B3D5AEC* ++ ID_OUI_FROM_DATABASE=Paratec Ltd. ++ ++OUI:70B3D5AED* ++ ID_OUI_FROM_DATABASE=Cubitech ++ + OUI:70B3D5AEE* + ID_OUI_FROM_DATABASE=DiTEST Fahrzeugdiagnose GmbH + +@@ -63128,6 +75557,9 @@ OUI:70B3D5AF6* + OUI:70B3D5AF7* + ID_OUI_FROM_DATABASE=DimoSystems BV + ++OUI:70B3D5AF8* ++ ID_OUI_FROM_DATABASE=boekel ++ + OUI:70B3D5AF9* + ID_OUI_FROM_DATABASE=Critical Link LLC + +@@ -63137,21 +75569,39 @@ OUI:70B3D5AFA* + OUI:70B3D5AFB* + ID_OUI_FROM_DATABASE=Shanghai Tianhe Automation Instrumentation Co., Ltd. + ++OUI:70B3D5AFC* ++ ID_OUI_FROM_DATABASE=BAE Systems ++ ++OUI:70B3D5AFD* ++ ID_OUI_FROM_DATABASE=dongsheng ++ + OUI:70B3D5AFE* + ID_OUI_FROM_DATABASE=MESOTECHNIC + + OUI:70B3D5AFF* + ID_OUI_FROM_DATABASE=digital-spice + ++OUI:70B3D5B00* ++ ID_OUI_FROM_DATABASE=HORIBA ABX SAS ++ ++OUI:70B3D5B01* ++ ID_OUI_FROM_DATABASE=G.S.D GROUP INC. ++ + OUI:70B3D5B02* + ID_OUI_FROM_DATABASE=Nordic Automation Systems AS + ++OUI:70B3D5B03* ++ ID_OUI_FROM_DATABASE=Sprintshield d.o.o. ++ + OUI:70B3D5B04* + ID_OUI_FROM_DATABASE=Herrmann Datensysteme GmbH + + OUI:70B3D5B05* + ID_OUI_FROM_DATABASE=E-PLUS TECHNOLOGY CO., LTD + ++OUI:70B3D5B06* ++ ID_OUI_FROM_DATABASE=MULTIVOICE LLC ++ + OUI:70B3D5B07* + ID_OUI_FROM_DATABASE=Arrowvale Electronics + +@@ -63167,12 +75617,30 @@ OUI:70B3D5B0B* + OUI:70B3D5B0C* + ID_OUI_FROM_DATABASE=Vigilate srl + ++OUI:70B3D5B0D* ++ ID_OUI_FROM_DATABASE=ALFI ++ ++OUI:70B3D5B0E* ++ ID_OUI_FROM_DATABASE=Servotronix Motion Control ++ ++OUI:70B3D5B0F* ++ ID_OUI_FROM_DATABASE=merkur Funksysteme AG ++ ++OUI:70B3D5B10* ++ ID_OUI_FROM_DATABASE=Zumbach Electronic AG ++ + OUI:70B3D5B11* + ID_OUI_FROM_DATABASE=CAB S.R.L. + ++OUI:70B3D5B12* ++ ID_OUI_FROM_DATABASE=VTEQ ++ + OUI:70B3D5B13* + ID_OUI_FROM_DATABASE=Omwave + ++OUI:70B3D5B14* ++ ID_OUI_FROM_DATABASE=Pantherun Technologies Pvt Ltd ++ + OUI:70B3D5B15* + ID_OUI_FROM_DATABASE=Eta Beta Srl + +@@ -63185,9 +75653,18 @@ OUI:70B3D5B17* + OUI:70B3D5B18* + ID_OUI_FROM_DATABASE=Abbas, a.s. + ++OUI:70B3D5B19* ++ ID_OUI_FROM_DATABASE=Brayden Automation Corp ++ + OUI:70B3D5B1A* + ID_OUI_FROM_DATABASE=Aaronia AG + ++OUI:70B3D5B1B* ++ ID_OUI_FROM_DATABASE=Technology Link Corporation ++ ++OUI:70B3D5B1C* ++ ID_OUI_FROM_DATABASE=Serveron / Qualitrol ++ + OUI:70B3D5B1D* + ID_OUI_FROM_DATABASE=Safelet BV + +@@ -63197,18 +75674,30 @@ OUI:70B3D5B1E* + OUI:70B3D5B1F* + ID_OUI_FROM_DATABASE=TECNOWATT + ++OUI:70B3D5B20* ++ ID_OUI_FROM_DATABASE=ICT BUSINESS GROUP of Humanrights Center for disabled people ++ + OUI:70B3D5B21* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D5B22* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5B23* + ID_OUI_FROM_DATABASE=Supervision Test et Pilotage + + OUI:70B3D5B24* + ID_OUI_FROM_DATABASE=Datasat Digital Entertainment + ++OUI:70B3D5B25* ++ ID_OUI_FROM_DATABASE=Hifocus Electronics India Private Limited ++ + OUI:70B3D5B26* + ID_OUI_FROM_DATABASE=INTEC International GmbH + ++OUI:70B3D5B27* ++ ID_OUI_FROM_DATABASE=Naval Group ++ + OUI:70B3D5B28* + ID_OUI_FROM_DATABASE=HUSTY M.Styczen J.Hupert sp.j. + +@@ -63221,9 +75710,18 @@ OUI:70B3D5B2A* + OUI:70B3D5B2B* + ID_OUI_FROM_DATABASE=Vtron Pty Ltd + ++OUI:70B3D5B2C* ++ ID_OUI_FROM_DATABASE=Elman srl ++ ++OUI:70B3D5B2D* ++ ID_OUI_FROM_DATABASE=Plexus ++ + OUI:70B3D5B2E* + ID_OUI_FROM_DATABASE=Green Access Ltd + ++OUI:70B3D5B2F* ++ ID_OUI_FROM_DATABASE=Hermann Automation GmbH ++ + OUI:70B3D5B30* + ID_OUI_FROM_DATABASE=Systolé Hardware B.V. + +@@ -63239,9 +75737,15 @@ OUI:70B3D5B34* + OUI:70B3D5B35* + ID_OUI_FROM_DATABASE=Rexxam Co.,Ltd. + ++OUI:70B3D5B36* ++ ID_OUI_FROM_DATABASE=Cetitec GmbH ++ + OUI:70B3D5B37* + ID_OUI_FROM_DATABASE=CODEC Co., Ltd. + ++OUI:70B3D5B38* ++ ID_OUI_FROM_DATABASE=GoTrustID Inc. ++ + OUI:70B3D5B39* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + +@@ -63266,72 +75770,180 @@ OUI:70B3D5B3F* + OUI:70B3D5B40* + ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd + ++OUI:70B3D5B41* ++ ID_OUI_FROM_DATABASE=T&M Media Pty Ltd ++ ++OUI:70B3D5B42* ++ ID_OUI_FROM_DATABASE=Samwell International Inc ++ + OUI:70B3D5B43* + ID_OUI_FROM_DATABASE=ZAO ZEO + + OUI:70B3D5B44* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. + ++OUI:70B3D5B45* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision IND.CO.,LTD ++ ++OUI:70B3D5B46* ++ ID_OUI_FROM_DATABASE=FAS Electronics (Fujian) Co.,LTD. ++ + OUI:70B3D5B47* + ID_OUI_FROM_DATABASE=DSIT Solutions LTD + + OUI:70B3D5B48* + ID_OUI_FROM_DATABASE=DWQ Informatikai Tanacsado es Vezerlestechnikai KFT + ++OUI:70B3D5B49* ++ ID_OUI_FROM_DATABASE=ANALOGICS TECH INDIA LTD ++ + OUI:70B3D5B4A* + ID_OUI_FROM_DATABASE=MEDEX + ++OUI:70B3D5B4B* ++ ID_OUI_FROM_DATABASE=Network Customizing Technologies Inc ++ ++OUI:70B3D5B4C* ++ ID_OUI_FROM_DATABASE=AmericanPharma Technologies ++ ++OUI:70B3D5B4D* ++ ID_OUI_FROM_DATABASE=Avidbots Corporation ++ ++OUI:70B3D5B4F* ++ ID_OUI_FROM_DATABASE=AvMap srlu ++ ++OUI:70B3D5B50* ++ ID_OUI_FROM_DATABASE=iGrid T&D ++ + OUI:70B3D5B51* + ID_OUI_FROM_DATABASE=Critical Link LLC + ++OUI:70B3D5B52* ++ ID_OUI_FROM_DATABASE=AEye, Inc. ++ + OUI:70B3D5B53* + ID_OUI_FROM_DATABASE=Revolution Retail Systems, LLC + ++OUI:70B3D5B54* ++ ID_OUI_FROM_DATABASE=Packet Power ++ + OUI:70B3D5B55* + ID_OUI_FROM_DATABASE=CTAG - ESG36871424 + + OUI:70B3D5B56* + ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. + ++OUI:70B3D5B57* ++ ID_OUI_FROM_DATABASE=Shanghai Qinyue Communication Technology Co., Ltd. ++ ++OUI:70B3D5B58* ++ ID_OUI_FROM_DATABASE=INTERNET PROTOCOLO LOGICA SL ++ + OUI:70B3D5B59* + ID_OUI_FROM_DATABASE=FutureTechnologyLaboratories INC. + ++OUI:70B3D5B5A* ++ ID_OUI_FROM_DATABASE=GTI Technologies Inc ++ ++OUI:70B3D5B5B* ++ ID_OUI_FROM_DATABASE=DynaMount LLC ++ + OUI:70B3D5B5C* + ID_OUI_FROM_DATABASE=Prozess Technologie + ++OUI:70B3D5B5D* ++ ID_OUI_FROM_DATABASE=SHANDHAI LANDLEAF ARCHITECTURE TECHNOLOGY CO.,LTD ++ ++OUI:70B3D5B5E* ++ ID_OUI_FROM_DATABASE=Dynics ++ ++OUI:70B3D5B5F* ++ ID_OUI_FROM_DATABASE=CRDMDEVEOPPEMENTS ++ ++OUI:70B3D5B60* ++ ID_OUI_FROM_DATABASE=ZAO ZEO ++ ++OUI:70B3D5B61* ++ ID_OUI_FROM_DATABASE=WuXi anktech Co., Ltd ++ + OUI:70B3D5B62* + ID_OUI_FROM_DATABASE=Sakura Seiki Co.,Ltd. + ++OUI:70B3D5B63* ++ ID_OUI_FROM_DATABASE=Ideas srl ++ + OUI:70B3D5B64* + ID_OUI_FROM_DATABASE=OSUNG LST CO.,LTD. + ++OUI:70B3D5B65* ++ ID_OUI_FROM_DATABASE=Rotem Industry LTD ++ ++OUI:70B3D5B66* ++ ID_OUI_FROM_DATABASE=Silent Gliss International Ltd ++ + OUI:70B3D5B67* + ID_OUI_FROM_DATABASE=RedWave Labs Ltd + ++OUI:70B3D5B68* ++ ID_OUI_FROM_DATABASE=S-Rain Control A/S ++ ++OUI:70B3D5B69* ++ ID_OUI_FROM_DATABASE=Daatrics LTD ++ + OUI:70B3D5B6A* + ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd + ++OUI:70B3D5B6B* ++ ID_OUI_FROM_DATABASE=Cambria Corporation ++ + OUI:70B3D5B6C* + ID_OUI_FROM_DATABASE=GHM-Messtechnik GmbH (Standort IMTRON) + + OUI:70B3D5B6D* + ID_OUI_FROM_DATABASE=Movis + ++OUI:70B3D5B6E* ++ ID_OUI_FROM_DATABASE=Edgeware AB ++ ++OUI:70B3D5B6F* ++ ID_OUI_FROM_DATABASE=Integra Metering SAS ++ ++OUI:70B3D5B70* ++ ID_OUI_FROM_DATABASE=Torion Plasma Corporation ++ ++OUI:70B3D5B71* ++ ID_OUI_FROM_DATABASE=Optiver Pty Ltd ++ + OUI:70B3D5B72* + ID_OUI_FROM_DATABASE=UB330.net d.o.o. + ++OUI:70B3D5B73* ++ ID_OUI_FROM_DATABASE=Cetto Industries ++ + OUI:70B3D5B74* + ID_OUI_FROM_DATABASE=OnYield Inc Ltd + ++OUI:70B3D5B75* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ ++OUI:70B3D5B76* ++ ID_OUI_FROM_DATABASE=ATL-SD ++ + OUI:70B3D5B77* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + + OUI:70B3D5B78* + ID_OUI_FROM_DATABASE=HOERMANN GmbH + ++OUI:70B3D5B79* ++ ID_OUI_FROM_DATABASE=Dadacon GmbH ++ + OUI:70B3D5B7A* + ID_OUI_FROM_DATABASE=MAHLE + ++OUI:70B3D5B7B* ++ ID_OUI_FROM_DATABASE=Doosan Digital Innovation America ++ + OUI:70B3D5B7C* + ID_OUI_FROM_DATABASE=Electronic Navigation Ltd + +@@ -63339,20 +75951,35 @@ OUI:70B3D5B7D* + ID_OUI_FROM_DATABASE=LOGIX ITS Inc + + OUI:70B3D5B7E* +- ID_OUI_FROM_DATABASE=Elbit Systems of America - Fort Worth Operations ++ ID_OUI_FROM_DATABASE=Elbit Systems of America + + OUI:70B3D5B7F* + ID_OUI_FROM_DATABASE=JSK System + ++OUI:70B3D5B80* ++ ID_OUI_FROM_DATABASE=BIGHOUSE.,INC. ++ + OUI:70B3D5B81* + ID_OUI_FROM_DATABASE=Instro Precision Limited + + OUI:70B3D5B82* + ID_OUI_FROM_DATABASE=Lookout Portable Security + ++OUI:70B3D5B83* ++ ID_OUI_FROM_DATABASE=Matrix Telematics Limited ++ ++OUI:70B3D5B84* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ + OUI:70B3D5B85* + ID_OUI_FROM_DATABASE=Fenotech Inc. + ++OUI:70B3D5B86* ++ ID_OUI_FROM_DATABASE=Hilo ++ ++OUI:70B3D5B87* ++ ID_OUI_FROM_DATABASE=CAITRON GmbH ++ + OUI:70B3D5B88* + ID_OUI_FROM_DATABASE=ARP Corporation + +@@ -63371,18 +75998,30 @@ OUI:70B3D5B8C* + OUI:70B3D5B8D* + ID_OUI_FROM_DATABASE=JungwooEng Co., Ltd + ++OUI:70B3D5B8E* ++ ID_OUI_FROM_DATABASE=UR FOG S.R.L. ++ + OUI:70B3D5B8F* + ID_OUI_FROM_DATABASE=Assembly Contracts Ltd + ++OUI:70B3D5B90* ++ ID_OUI_FROM_DATABASE=Amico Corporation ++ + OUI:70B3D5B91* + ID_OUI_FROM_DATABASE=Dynetics, Inc. + ++OUI:70B3D5B92* ++ ID_OUI_FROM_DATABASE=N A Communications LLC ++ + OUI:70B3D5B93* + ID_OUI_FROM_DATABASE=INTERNET PROTOCOLO LOGICA SL + + OUI:70B3D5B94* + ID_OUI_FROM_DATABASE=Cygnetic Technologies (Pty) Ltd + ++OUI:70B3D5B96* ++ ID_OUI_FROM_DATABASE=Oculii ++ + OUI:70B3D5B97* + ID_OUI_FROM_DATABASE=Canam Technology, Inc. + +@@ -63392,15 +76031,27 @@ OUI:70B3D5B98* + OUI:70B3D5B99* + ID_OUI_FROM_DATABASE=DomoSafety S.A. + ++OUI:70B3D5B9A* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ + OUI:70B3D5B9B* + ID_OUI_FROM_DATABASE=Elektronik Art + + OUI:70B3D5B9C* + ID_OUI_FROM_DATABASE=EDCO Technology 1993 ltd + ++OUI:70B3D5B9D* ++ ID_OUI_FROM_DATABASE=Conclusive Engineering ++ + OUI:70B3D5B9E* + ID_OUI_FROM_DATABASE=POLSYSTEM SI SP. Z O.O., S.K.A. + ++OUI:70B3D5B9F* ++ ID_OUI_FROM_DATABASE=Yuksek Kapasite Radyolink Sistemleri San. ve Tic. A.S. ++ ++OUI:70B3D5BA0* ++ ID_OUI_FROM_DATABASE=Season Electronics Ltd ++ + OUI:70B3D5BA1* + ID_OUI_FROM_DATABASE=Cathwell AS + +@@ -63413,9 +76064,18 @@ OUI:70B3D5BA3* + OUI:70B3D5BA4* + ID_OUI_FROM_DATABASE=EIWA GIKEN INC. + ++OUI:70B3D5BA5* ++ ID_OUI_FROM_DATABASE=fpgalabs.com ++ ++OUI:70B3D5BA6* ++ ID_OUI_FROM_DATABASE=Gluon Solutions Inc. ++ + OUI:70B3D5BA7* + ID_OUI_FROM_DATABASE=Digital Yacht Ltd + ++OUI:70B3D5BA8* ++ ID_OUI_FROM_DATABASE=Controlled Power Company ++ + OUI:70B3D5BA9* + ID_OUI_FROM_DATABASE=Alma + +@@ -63437,8 +76097,14 @@ OUI:70B3D5BAE* + OUI:70B3D5BAF* + ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH + ++OUI:70B3D5BB0* ++ ID_OUI_FROM_DATABASE=WICELL TECHNOLOGY ++ ++OUI:70B3D5BB1* ++ ID_OUI_FROM_DATABASE=Lumiplan Duhamel ++ + OUI:70B3D5BB2* +- ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed ++ ID_OUI_FROM_DATABASE=Mettler Toledo + + OUI:70B3D5BB3* + ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC +@@ -63446,6 +76112,12 @@ OUI:70B3D5BB3* + OUI:70B3D5BB4* + ID_OUI_FROM_DATABASE=Integritech + ++OUI:70B3D5BB5* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ ++OUI:70B3D5BB6* ++ ID_OUI_FROM_DATABASE=Franke Aquarotter GmbH ++ + OUI:70B3D5BB7* + ID_OUI_FROM_DATABASE=Innoflight, Inc. + +@@ -63455,6 +76127,15 @@ OUI:70B3D5BB8* + OUI:70B3D5BB9* + ID_OUI_FROM_DATABASE=KOSMEK.Ltd + ++OUI:70B3D5BBA* ++ ID_OUI_FROM_DATABASE=Samriddi Automations Pvt. Ltd. ++ ++OUI:70B3D5BBB* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ ++OUI:70B3D5BBC* ++ ID_OUI_FROM_DATABASE=Boundary Technologies Ltd ++ + OUI:70B3D5BBD* + ID_OUI_FROM_DATABASE=Providius Corp + +@@ -63464,15 +76145,36 @@ OUI:70B3D5BBE* + OUI:70B3D5BBF* + ID_OUI_FROM_DATABASE=Ensys srl + ++OUI:70B3D5BC0* ++ ID_OUI_FROM_DATABASE=SENSO2ME ++ + OUI:70B3D5BC1* + ID_OUI_FROM_DATABASE=Abionic + + OUI:70B3D5BC2* + ID_OUI_FROM_DATABASE=DWEWOONG ELECTRIC Co., Ltd. + ++OUI:70B3D5BC3* ++ ID_OUI_FROM_DATABASE=eWireless ++ ++OUI:70B3D5BC4* ++ ID_OUI_FROM_DATABASE=Digital Media Professionals ++ ++OUI:70B3D5BC5* ++ ID_OUI_FROM_DATABASE=U&R GmbH Hardware- und Systemdesign ++ + OUI:70B3D5BC6* + ID_OUI_FROM_DATABASE=Hatteland Display AS + ++OUI:70B3D5BC7* ++ ID_OUI_FROM_DATABASE=Autonomic Controls, Inc. ++ ++OUI:70B3D5BC8* ++ ID_OUI_FROM_DATABASE=Loma Systems s.r.o. ++ ++OUI:70B3D5BC9* ++ ID_OUI_FROM_DATABASE=Yite technology ++ + OUI:70B3D5BCA* + ID_OUI_FROM_DATABASE=Deymed Diagnostic + +@@ -63482,9 +76184,18 @@ OUI:70B3D5BCB* + OUI:70B3D5BCC* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D5BCD* ++ ID_OUI_FROM_DATABASE=Sasken Technologies Ltd ++ + OUI:70B3D5BCE* + ID_OUI_FROM_DATABASE=YAWATA ELECTRIC INDUSTRIAL CO.,LTD. + ++OUI:70B3D5BCF* ++ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC ++ ++OUI:70B3D5BD0* ++ ID_OUI_FROM_DATABASE=SHS SRL ++ + OUI:70B3D5BD1* + ID_OUI_FROM_DATABASE=CableLabs + +@@ -63494,21 +76205,51 @@ OUI:70B3D5BD2* + OUI:70B3D5BD3* + ID_OUI_FROM_DATABASE=FOTONA D.D. + ++OUI:70B3D5BD4* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5BD5* + ID_OUI_FROM_DATABASE=Synics AG + ++OUI:70B3D5BD6* ++ ID_OUI_FROM_DATABASE=Consarc Corporation ++ ++OUI:70B3D5BD7* ++ ID_OUI_FROM_DATABASE=TT Group SRL ++ ++OUI:70B3D5BD8* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ + OUI:70B3D5BD9* + ID_OUI_FROM_DATABASE=SolwayTech + + OUI:70B3D5BDA* + ID_OUI_FROM_DATABASE=5-D Systems, Inc. + ++OUI:70B3D5BDB* ++ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. ++ ++OUI:70B3D5BDC* ++ ID_OUI_FROM_DATABASE=EDF Lab ++ + OUI:70B3D5BDD* + ID_OUI_FROM_DATABASE=CDR SRL + ++OUI:70B3D5BDE* ++ ID_OUI_FROM_DATABASE=CAST Group of Companies Inc. ++ ++OUI:70B3D5BDF* ++ ID_OUI_FROM_DATABASE=H2O-YUG LLC ++ ++OUI:70B3D5BE0* ++ ID_OUI_FROM_DATABASE=Cognosos, Inc. ++ + OUI:70B3D5BE1* + ID_OUI_FROM_DATABASE=FeCon GmbH + ++OUI:70B3D5BE2* ++ ID_OUI_FROM_DATABASE=Nocix, LLC ++ + OUI:70B3D5BE3* + ID_OUI_FROM_DATABASE=Saratov Electrounit Production Plant named after Sergo Ordzhonikidze, OJSC + +@@ -63521,6 +76262,9 @@ OUI:70B3D5BE5* + OUI:70B3D5BE6* + ID_OUI_FROM_DATABASE=CCII Systems (Pty) Ltd + ++OUI:70B3D5BE7* ++ ID_OUI_FROM_DATABASE=Syscom Instruments SA ++ + OUI:70B3D5BE8* + ID_OUI_FROM_DATABASE=AndFun Co.,Ltd. + +@@ -63530,15 +76274,24 @@ OUI:70B3D5BE9* + OUI:70B3D5BEA* + ID_OUI_FROM_DATABASE=Virtuosys Ltd + ++OUI:70B3D5BEB* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ + OUI:70B3D5BEC* + ID_OUI_FROM_DATABASE=Tokyo Communication Equipment MFG Co.,ltd. + + OUI:70B3D5BED* + ID_OUI_FROM_DATABASE=Itrinegy Ltd. + ++OUI:70B3D5BEE* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ + OUI:70B3D5BEF* + ID_OUI_FROM_DATABASE=Sensortech Systems Inc. + ++OUI:70B3D5BF0* ++ ID_OUI_FROM_DATABASE=Alfa Elettronica srl ++ + OUI:70B3D5BF1* + ID_OUI_FROM_DATABASE=Flashnet SRL + +@@ -63548,12 +76301,21 @@ OUI:70B3D5BF2* + OUI:70B3D5BF3* + ID_OUI_FROM_DATABASE=CG-WIRELESS + ++OUI:70B3D5BF4* ++ ID_OUI_FROM_DATABASE=CreevX ++ + OUI:70B3D5BF5* + ID_OUI_FROM_DATABASE=Acacia Research + + OUI:70B3D5BF6* + ID_OUI_FROM_DATABASE=comtac AG + ++OUI:70B3D5BF7* ++ ID_OUI_FROM_DATABASE=Fischer Connectors ++ ++OUI:70B3D5BF8* ++ ID_OUI_FROM_DATABASE=RCH ITALIA SPA ++ + OUI:70B3D5BF9* + ID_OUI_FROM_DATABASE=Okolab Srl + +@@ -63563,15 +76325,33 @@ OUI:70B3D5BFA* + OUI:70B3D5BFB* + ID_OUI_FROM_DATABASE=Sensor 42 + ++OUI:70B3D5BFC* ++ ID_OUI_FROM_DATABASE=Vishay Nobel AB ++ ++OUI:70B3D5BFD* ++ ID_OUI_FROM_DATABASE=Lumentum ++ + OUI:70B3D5BFE* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + ++OUI:70B3D5BFF* ++ ID_OUI_FROM_DATABASE=Sunsa, Inc ++ ++OUI:70B3D5C00* ++ ID_OUI_FROM_DATABASE=BESO sp. z o.o. ++ + OUI:70B3D5C01* + ID_OUI_FROM_DATABASE=SmartGuard LLC + ++OUI:70B3D5C02* ++ ID_OUI_FROM_DATABASE=Garmo Instruments S.L. ++ + OUI:70B3D5C03* + ID_OUI_FROM_DATABASE=XAVi Technologies Corp. + ++OUI:70B3D5C04* ++ ID_OUI_FROM_DATABASE=Prolan Zrt. ++ + OUI:70B3D5C05* + ID_OUI_FROM_DATABASE=KST technology + +@@ -63581,6 +76361,12 @@ OUI:70B3D5C06* + OUI:70B3D5C07* + ID_OUI_FROM_DATABASE=ARECO + ++OUI:70B3D5C08* ++ ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA ++ ++OUI:70B3D5C09* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ + OUI:70B3D5C0A* + ID_OUI_FROM_DATABASE=Infosocket Co., Ltd. + +@@ -63590,18 +76376,27 @@ OUI:70B3D5C0B* + OUI:70B3D5C0C* + ID_OUI_FROM_DATABASE=Tech4Race + ++OUI:70B3D5C0D* ++ ID_OUI_FROM_DATABASE=Clarity Medical Pvt Ltd ++ + OUI:70B3D5C0E* + ID_OUI_FROM_DATABASE=SYSDEV Srl + + OUI:70B3D5C0F* + ID_OUI_FROM_DATABASE=Honeywell Safety Products USA, Inc + ++OUI:70B3D5C10* ++ ID_OUI_FROM_DATABASE=Scanvaegt Systems A/S ++ + OUI:70B3D5C11* + ID_OUI_FROM_DATABASE=Ariston Thermo s.p.a. + + OUI:70B3D5C12* + ID_OUI_FROM_DATABASE=Beijing Wisetone Information Technology Co.,Ltd. + ++OUI:70B3D5C13* ++ ID_OUI_FROM_DATABASE=Guangzhou Xianhe Technology Engineering Co., Ltd ++ + OUI:70B3D5C14* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + +@@ -63614,6 +76409,12 @@ OUI:70B3D5C16* + OUI:70B3D5C17* + ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC + ++OUI:70B3D5C18* ++ ID_OUI_FROM_DATABASE=Sanmina Israel ++ ++OUI:70B3D5C19* ++ ID_OUI_FROM_DATABASE=Zumbach Electronic AG ++ + OUI:70B3D5C1A* + ID_OUI_FROM_DATABASE=Xylon + +@@ -63626,6 +76427,12 @@ OUI:70B3D5C1C* + OUI:70B3D5C1D* + ID_OUI_FROM_DATABASE=Kranze Technology Solutions + ++OUI:70B3D5C1E* ++ ID_OUI_FROM_DATABASE=Kron Medidores ++ ++OUI:70B3D5C1F* ++ ID_OUI_FROM_DATABASE=Behr Technologies Inc ++ + OUI:70B3D5C20* + ID_OUI_FROM_DATABASE=Mipot S.p.a. + +@@ -63635,8 +76442,11 @@ OUI:70B3D5C21* + OUI:70B3D5C22* + ID_OUI_FROM_DATABASE=Skyriver Communications Inc. + ++OUI:70B3D5C23* ++ ID_OUI_FROM_DATABASE=Sumitomo Heavy Industries, Ltd. ++ + OUI:70B3D5C24* +- ID_OUI_FROM_DATABASE=Elbit Systems of America - Fort Worth Operations ++ ID_OUI_FROM_DATABASE=Elbit Systems of America + + OUI:70B3D5C25* + ID_OUI_FROM_DATABASE=speedsignal GmbH +@@ -63647,18 +76457,36 @@ OUI:70B3D5C26* + OUI:70B3D5C27* + ID_OUI_FROM_DATABASE=GD Mission Systems + ++OUI:70B3D5C28* ++ ID_OUI_FROM_DATABASE=Mitech Integrated Systems Inc. ++ ++OUI:70B3D5C29* ++ ID_OUI_FROM_DATABASE=SOFTLAND INDIA LTD ++ + OUI:70B3D5C2A* + ID_OUI_FROM_DATABASE=Array Telepresence + ++OUI:70B3D5C2B* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5C2C* + ID_OUI_FROM_DATABASE=Dromont S.p.A. + ++OUI:70B3D5C2D* ++ ID_OUI_FROM_DATABASE=Ensotech Limited ++ + OUI:70B3D5C2E* + ID_OUI_FROM_DATABASE=Triax A/S + + OUI:70B3D5C2F* + ID_OUI_FROM_DATABASE=ATBiS Co.,Ltd + ++OUI:70B3D5C30* ++ ID_OUI_FROM_DATABASE=Polskie Sady Nowe Podole Sp. z o.o. ++ ++OUI:70B3D5C31* ++ ID_OUI_FROM_DATABASE=German Power GmbH ++ + OUI:70B3D5C32* + ID_OUI_FROM_DATABASE=INFRASAFE/ ADVANTOR SYSTEMS + +@@ -63671,6 +76499,9 @@ OUI:70B3D5C34* + OUI:70B3D5C35* + ID_OUI_FROM_DATABASE=Vibrationmaster + ++OUI:70B3D5C36* ++ ID_OUI_FROM_DATABASE=Knowledge Resources GmbH ++ + OUI:70B3D5C37* + ID_OUI_FROM_DATABASE=Keycom Corp. + +@@ -63680,6 +76511,9 @@ OUI:70B3D5C38* + OUI:70B3D5C39* + ID_OUI_FROM_DATABASE=MeshWorks Wireless Oy + ++OUI:70B3D5C3A* ++ ID_OUI_FROM_DATABASE=HAN CHANG ++ + OUI:70B3D5C3B* + ID_OUI_FROM_DATABASE=Vironova AB + +@@ -63695,6 +76529,9 @@ OUI:70B3D5C3E* + OUI:70B3D5C3F* + ID_OUI_FROM_DATABASE=Code Blue Corporation + ++OUI:70B3D5C40* ++ ID_OUI_FROM_DATABASE=HongSeok Ltd. ++ + OUI:70B3D5C41* + ID_OUI_FROM_DATABASE=Merlin CSI + +@@ -63704,33 +76541,72 @@ OUI:70B3D5C42* + OUI:70B3D5C43* + ID_OUI_FROM_DATABASE=Future Skies + ++OUI:70B3D5C44* ++ ID_OUI_FROM_DATABASE=Franz Kessler GmbH ++ + OUI:70B3D5C45* + ID_OUI_FROM_DATABASE=Stiebel Eltron GmbH + ++OUI:70B3D5C46* ++ ID_OUI_FROM_DATABASE=eumig industrie-TV GmbH. ++ ++OUI:70B3D5C47* ++ ID_OUI_FROM_DATABASE=ABB ++ ++OUI:70B3D5C48* ++ ID_OUI_FROM_DATABASE=Weltek Technologies Co. Ltd. ++ + OUI:70B3D5C49* + ID_OUI_FROM_DATABASE=BTG Instruments AB + ++OUI:70B3D5C4A* ++ ID_OUI_FROM_DATABASE=TIAMA ++ + OUI:70B3D5C4B* + ID_OUI_FROM_DATABASE=ANKER-EAST + ++OUI:70B3D5C4C* ++ ID_OUI_FROM_DATABASE=VTC Digicom ++ + OUI:70B3D5C4D* + ID_OUI_FROM_DATABASE=RADA Electronics Industries Ltd. + ++OUI:70B3D5C4E* ++ ID_OUI_FROM_DATABASE=ARKRAY, Inc. Kyoto Laboratory ++ + OUI:70B3D5C4F* + ID_OUI_FROM_DATABASE=AE Van de Vliet BVBA + ++OUI:70B3D5C50* ++ ID_OUI_FROM_DATABASE=Combilent ++ ++OUI:70B3D5C51* ++ ID_OUI_FROM_DATABASE=Innotas Elektronik GmbH ++ ++OUI:70B3D5C52* ++ ID_OUI_FROM_DATABASE=sensorway ++ + OUI:70B3D5C53* + ID_OUI_FROM_DATABASE=S Labs sp. z o.o. + ++OUI:70B3D5C54* ++ ID_OUI_FROM_DATABASE=Flexsolution APS ++ + OUI:70B3D5C55* + ID_OUI_FROM_DATABASE=Intelligent Energy Ltd + + OUI:70B3D5C56* + ID_OUI_FROM_DATABASE=TELETASK + ++OUI:70B3D5C57* ++ ID_OUI_FROM_DATABASE=eBZ GmbH ++ + OUI:70B3D5C58* + ID_OUI_FROM_DATABASE=RMI Laser LLC + ++OUI:70B3D5C59* ++ ID_OUI_FROM_DATABASE=R Cubed Engineering, LLC ++ + OUI:70B3D5C5A* + ID_OUI_FROM_DATABASE=Commsignia Ltd. + +@@ -63743,6 +76619,12 @@ OUI:70B3D5C5C* + OUI:70B3D5C5D* + ID_OUI_FROM_DATABASE=FOSHAN SHILANTIAN NETWORK S.T. CO., LTD. + ++OUI:70B3D5C5E* ++ ID_OUI_FROM_DATABASE=Frog Cellsat Limited ++ ++OUI:70B3D5C5F* ++ ID_OUI_FROM_DATABASE=Clean-Lasersysteme GmbH ++ + OUI:70B3D5C60* + ID_OUI_FROM_DATABASE=Gogo BA + +@@ -63770,9 +76652,15 @@ OUI:70B3D5C67* + OUI:70B3D5C68* + ID_OUI_FROM_DATABASE=Mini Solution Co. Ltd. + ++OUI:70B3D5C69* ++ ID_OUI_FROM_DATABASE=AZ-TECHNOLOGY SDN BHD ++ + OUI:70B3D5C6A* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D5C6B* ++ ID_OUI_FROM_DATABASE=Herholdt Controls srl ++ + OUI:70B3D5C6C* + ID_OUI_FROM_DATABASE=McQ Inc + +@@ -63785,12 +76673,27 @@ OUI:70B3D5C6E* + OUI:70B3D5C6F* + ID_OUI_FROM_DATABASE=nyantec GmbH + ++OUI:70B3D5C70* ++ ID_OUI_FROM_DATABASE=Magnetek ++ ++OUI:70B3D5C71* ++ ID_OUI_FROM_DATABASE=The Engineerix Group ++ ++OUI:70B3D5C72* ++ ID_OUI_FROM_DATABASE=Scharco Elektronik GmbH ++ + OUI:70B3D5C73* + ID_OUI_FROM_DATABASE=C.D.N.CORPORATION + + OUI:70B3D5C74* + ID_OUI_FROM_DATABASE=Qtechnology A/S + ++OUI:70B3D5C75* ++ ID_OUI_FROM_DATABASE=BIT Group USA, Inc. ++ ++OUI:70B3D5C76* ++ ID_OUI_FROM_DATABASE=ELA INNOVATION ++ + OUI:70B3D5C77* + ID_OUI_FROM_DATABASE=Yönnet Akıllı Bina ve Otomasyon Sistemleri + +@@ -63800,6 +76703,15 @@ OUI:70B3D5C78* + OUI:70B3D5C79* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D5C7A* ++ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. ++ ++OUI:70B3D5C7B* ++ ID_OUI_FROM_DATABASE=EM Clarity Pty Ltd ++ ++OUI:70B3D5C7C* ++ ID_OUI_FROM_DATABASE=Beijing Aumiwalker technology CO.,LTD ++ + OUI:70B3D5C7D* + ID_OUI_FROM_DATABASE=Metatronics B.V. + +@@ -63815,6 +76727,15 @@ OUI:70B3D5C80* + OUI:70B3D5C81* + ID_OUI_FROM_DATABASE=DSP DESIGN + ++OUI:70B3D5C82* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ ++OUI:70B3D5C83* ++ ID_OUI_FROM_DATABASE=CertusNet Inc. ++ ++OUI:70B3D5C84* ++ ID_OUI_FROM_DATABASE=Linc Technology Corporation dba Data-Linc Group ++ + OUI:70B3D5C85* + ID_OUI_FROM_DATABASE=Solid State Disks Ltd + +@@ -63830,6 +76751,9 @@ OUI:70B3D5C88* + OUI:70B3D5C89* + ID_OUI_FROM_DATABASE=ARD + ++OUI:70B3D5C8A* ++ ID_OUI_FROM_DATABASE=WTE Limited ++ + OUI:70B3D5C8B* + ID_OUI_FROM_DATABASE=Asia Pacific Satellite Coummunication Inc. + +@@ -63839,26 +76763,53 @@ OUI:70B3D5C8C* + OUI:70B3D5C8D* + ID_OUI_FROM_DATABASE=KST technology + ++OUI:70B3D5C8E* ++ ID_OUI_FROM_DATABASE=Coral Telecom Limited ++ + OUI:70B3D5C8F* + ID_OUI_FROM_DATABASE=TRIDENT INFOSOL PVT LTD + ++OUI:70B3D5C90* ++ ID_OUI_FROM_DATABASE=Diretta ++ + OUI:70B3D5C91* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + + OUI:70B3D5C92* + ID_OUI_FROM_DATABASE=Unitro Fleischmann + ++OUI:70B3D5C93* ++ ID_OUI_FROM_DATABASE=GMI Ltd ++ ++OUI:70B3D5C94* ++ ID_OUI_FROM_DATABASE=Vars Technology ++ ++OUI:70B3D5C95* ++ ID_OUI_FROM_DATABASE=Chengdu Meihuan Technology Co., Ltd ++ + OUI:70B3D5C96* + ID_OUI_FROM_DATABASE=UNI DIMENXI SDN BHD + + OUI:70B3D5C97* + ID_OUI_FROM_DATABASE=CSINFOTEL + ++OUI:70B3D5C98* ++ ID_OUI_FROM_DATABASE=Trust Automation ++ ++OUI:70B3D5C99* ++ ID_OUI_FROM_DATABASE=Remote Diagnostic Technologies Ltd ++ ++OUI:70B3D5C9A* ++ ID_OUI_FROM_DATABASE=Todd Digital Limited ++ + OUI:70B3D5C9B* + ID_OUI_FROM_DATABASE=Tieto Sweden AB + ++OUI:70B3D5C9C* ++ ID_OUI_FROM_DATABASE=Connected Response ++ + OUI:70B3D5C9D* +- ID_OUI_FROM_DATABASE=APG Cash Drawer ++ ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC + + OUI:70B3D5C9E* + ID_OUI_FROM_DATABASE=FUKUDA SANGYO CO., LTD. +@@ -63866,6 +76817,12 @@ OUI:70B3D5C9E* + OUI:70B3D5C9F* + ID_OUI_FROM_DATABASE=Triax A/S + ++OUI:70B3D5CA0* ++ ID_OUI_FROM_DATABASE=Xirgo Technologies LLC ++ ++OUI:70B3D5CA1* ++ ID_OUI_FROM_DATABASE=Waldo System ++ + OUI:70B3D5CA2* + ID_OUI_FROM_DATABASE=De Haardt bv + +@@ -63875,6 +76832,15 @@ OUI:70B3D5CA3* + OUI:70B3D5CA4* + ID_OUI_FROM_DATABASE=Netemera Sp. z o.o. + ++OUI:70B3D5CA5* ++ ID_OUI_FROM_DATABASE=PTS Technologies Pte Ltd ++ ++OUI:70B3D5CA6* ++ ID_OUI_FROM_DATABASE=AXING AG ++ ++OUI:70B3D5CA7* ++ ID_OUI_FROM_DATABASE=i-View Communication Inc. ++ + OUI:70B3D5CA8* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + +@@ -63890,9 +76856,21 @@ OUI:70B3D5CAB* + OUI:70B3D5CAC* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D5CAD* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5CAE* + ID_OUI_FROM_DATABASE=THEMA + ++OUI:70B3D5CAF* ++ ID_OUI_FROM_DATABASE=DAVE SRL ++ ++OUI:70B3D5CB0* ++ ID_OUI_FROM_DATABASE=Ossiaco ++ ++OUI:70B3D5CB1* ++ ID_OUI_FROM_DATABASE=RADAR ++ + OUI:70B3D5CB2* + ID_OUI_FROM_DATABASE=SECLAB + +@@ -63902,6 +76880,9 @@ OUI:70B3D5CB3* + OUI:70B3D5CB4* + ID_OUI_FROM_DATABASE=Planewave Instruments + ++OUI:70B3D5CB5* ++ ID_OUI_FROM_DATABASE=Atlas Lighting Products ++ + OUI:70B3D5CB6* + ID_OUI_FROM_DATABASE=Kuebrich Ingeniergesellschaft mbh & Co. KG + +@@ -63911,21 +76892,51 @@ OUI:70B3D5CB7* + OUI:70B3D5CB8* + ID_OUI_FROM_DATABASE=Verti Tecnologia + ++OUI:70B3D5CB9* ++ ID_OUI_FROM_DATABASE=JSC «SATIS-TL-94» ++ ++OUI:70B3D5CBA* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ ++OUI:70B3D5CBB* ++ ID_OUI_FROM_DATABASE=Postmark Incorporated ++ + OUI:70B3D5CBC* + ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd + ++OUI:70B3D5CBD* ++ ID_OUI_FROM_DATABASE=Preo Industries Far East Limited ++ + OUI:70B3D5CBE* + ID_OUI_FROM_DATABASE=Ensura Solutions BV + ++OUI:70B3D5CBF* ++ ID_OUI_FROM_DATABASE=Cubic ITS, Inc. dba GRIDSMART Technologies ++ ++OUI:70B3D5CC0* ++ ID_OUI_FROM_DATABASE=Avionica ++ + OUI:70B3D5CC1* + ID_OUI_FROM_DATABASE=BEEcube Inc. + ++OUI:70B3D5CC2* ++ ID_OUI_FROM_DATABASE=LSC Lighting Systems (Aust) Pty Ltd ++ + OUI:70B3D5CC3* + ID_OUI_FROM_DATABASE=Fidalia Networks Inc + ++OUI:70B3D5CC4* ++ ID_OUI_FROM_DATABASE=Benchmark Electronics BV ++ + OUI:70B3D5CC5* + ID_OUI_FROM_DATABASE=Intecom + ++OUI:70B3D5CC6* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:70B3D5CC7* ++ ID_OUI_FROM_DATABASE=SOtM ++ + OUI:70B3D5CC8* + ID_OUI_FROM_DATABASE=PROFEN COMMUNICATIONS + +@@ -63962,24 +76973,45 @@ OUI:70B3D5CD2* + OUI:70B3D5CD3* + ID_OUI_FROM_DATABASE=Controlrad + ++OUI:70B3D5CD4* ++ ID_OUI_FROM_DATABASE=Southern Ground Audio LLC ++ + OUI:70B3D5CD5* + ID_OUI_FROM_DATABASE=Apantac LLC + + OUI:70B3D5CD6* + ID_OUI_FROM_DATABASE=VideoRay LLC + ++OUI:70B3D5CD7* ++ ID_OUI_FROM_DATABASE=AutomationX GmbH ++ ++OUI:70B3D5CD8* ++ ID_OUI_FROM_DATABASE=Nexus Electric S.A. ++ + OUI:70B3D5CD9* + ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau GmbH + + OUI:70B3D5CDA* + ID_OUI_FROM_DATABASE=VITEC + ++OUI:70B3D5CDB* ++ ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd ++ ++OUI:70B3D5CDC* ++ ID_OUI_FROM_DATABASE=Dat-Con d.o.o. ++ ++OUI:70B3D5CDD* ++ ID_OUI_FROM_DATABASE=Teneo IoT B.V. ++ + OUI:70B3D5CDE* + ID_OUI_FROM_DATABASE=Multipure International + + OUI:70B3D5CDF* + ID_OUI_FROM_DATABASE=3D Printing Specialists + ++OUI:70B3D5CE0* ++ ID_OUI_FROM_DATABASE=M.S. CONTROL ++ + OUI:70B3D5CE1* + ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG + +@@ -63989,21 +77021,45 @@ OUI:70B3D5CE2* + OUI:70B3D5CE3* + ID_OUI_FROM_DATABASE=Dalcnet srl + ++OUI:70B3D5CE4* ++ ID_OUI_FROM_DATABASE=WAVES SYSTEM ++ + OUI:70B3D5CE5* + ID_OUI_FROM_DATABASE=GridBridge Inc + ++OUI:70B3D5CE6* ++ ID_OUI_FROM_DATABASE=Dynim Oy ++ + OUI:70B3D5CE7* + ID_OUI_FROM_DATABASE=June Automation Singapore Pte. Ltd. + ++OUI:70B3D5CE8* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ + OUI:70B3D5CE9* + ID_OUI_FROM_DATABASE=KINEMETRICS + + OUI:70B3D5CEA* + ID_OUI_FROM_DATABASE=Computerwise, Inc. + ++OUI:70B3D5CEB* ++ ID_OUI_FROM_DATABASE=Xirgo Technologies LLC ++ ++OUI:70B3D5CEC* ++ ID_OUI_FROM_DATABASE=Deltronic Security AB ++ + OUI:70B3D5CED* + ID_OUI_FROM_DATABASE=Advanced Products Corporation Pte Ltd + ++OUI:70B3D5CEE* ++ ID_OUI_FROM_DATABASE=ACRIOS Systems s.r.o. ++ ++OUI:70B3D5CEF* ++ ID_OUI_FROM_DATABASE=Ellego Powertec Oy ++ ++OUI:70B3D5CF0* ++ ID_OUI_FROM_DATABASE=SHENZHEN WITLINK CO.,LTD. ++ + OUI:70B3D5CF1* + ID_OUI_FROM_DATABASE=LightDec GmbH & Co. KG + +@@ -64022,6 +77078,24 @@ OUI:70B3D5CF5* + OUI:70B3D5CF6* + ID_OUI_FROM_DATABASE=Tornado Modular Systems + ++OUI:70B3D5CF7* ++ ID_OUI_FROM_DATABASE=GENTEC ELECTRO-OPTICS ++ ++OUI:70B3D5CF8* ++ ID_OUI_FROM_DATABASE=Idneo Technologies S.A.U. ++ ++OUI:70B3D5CF9* ++ ID_OUI_FROM_DATABASE=Breas Medical AB ++ ++OUI:70B3D5CFA* ++ ID_OUI_FROM_DATABASE=SCHEIBER ++ ++OUI:70B3D5CFB* ++ ID_OUI_FROM_DATABASE=Screen Innovations ++ ++OUI:70B3D5CFC* ++ ID_OUI_FROM_DATABASE=VEILUX INC. ++ + OUI:70B3D5CFD* + ID_OUI_FROM_DATABASE=iLOQ Oy + +@@ -64031,9 +77105,27 @@ OUI:70B3D5CFE* + OUI:70B3D5CFF* + ID_OUI_FROM_DATABASE=DTECH Labs, Inc. + ++OUI:70B3D5D00* ++ ID_OUI_FROM_DATABASE=DKI Technology Co., Ltd ++ ++OUI:70B3D5D01* ++ ID_OUI_FROM_DATABASE=Vision4ce Ltd ++ ++OUI:70B3D5D02* ++ ID_OUI_FROM_DATABASE=Arctos Showlasertechnik GmbH ++ ++OUI:70B3D5D03* ++ ID_OUI_FROM_DATABASE=Digitella Inc. ++ ++OUI:70B3D5D04* ++ ID_OUI_FROM_DATABASE=Plenty Unlimited Inc ++ + OUI:70B3D5D05* + ID_OUI_FROM_DATABASE=Colmek + ++OUI:70B3D5D06* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ + OUI:70B3D5D07* + ID_OUI_FROM_DATABASE=Waversa Systems + +@@ -64046,6 +77138,9 @@ OUI:70B3D5D09* + OUI:70B3D5D0A* + ID_OUI_FROM_DATABASE=Private + ++OUI:70B3D5D0B* ++ ID_OUI_FROM_DATABASE=Vendanor AS ++ + OUI:70B3D5D0C* + ID_OUI_FROM_DATABASE=Connor Winfield LTD + +@@ -64055,8 +77150,11 @@ OUI:70B3D5D0D* + OUI:70B3D5D0E* + ID_OUI_FROM_DATABASE=Beijing Aumiwalker technology CO.,LTD + ++OUI:70B3D5D0F* ++ ID_OUI_FROM_DATABASE=Alto Aviation ++ + OUI:70B3D5D10* +- ID_OUI_FROM_DATABASE=Contec DTx ++ ID_OUI_FROM_DATABASE=Contec Americas Inc. + + OUI:70B3D5D11* + ID_OUI_FROM_DATABASE=EREE Electronique +@@ -64064,12 +77162,39 @@ OUI:70B3D5D11* + OUI:70B3D5D12* + ID_OUI_FROM_DATABASE=FIDELTRONIK POLAND SP. Z O.O. + ++OUI:70B3D5D13* ++ ID_OUI_FROM_DATABASE=IRT Technologies ++ ++OUI:70B3D5D14* ++ ID_OUI_FROM_DATABASE=LIGPT ++ ++OUI:70B3D5D15* ++ ID_OUI_FROM_DATABASE=3DGence sp. z o.o. ++ ++OUI:70B3D5D16* ++ ID_OUI_FROM_DATABASE=Monnit Corporation ++ ++OUI:70B3D5D17* ++ ID_OUI_FROM_DATABASE=Power Element ++ ++OUI:70B3D5D18* ++ ID_OUI_FROM_DATABASE=MetCom Solutions GmbH ++ ++OUI:70B3D5D19* ++ ID_OUI_FROM_DATABASE=Senior Group LLC ++ ++OUI:70B3D5D1A* ++ ID_OUI_FROM_DATABASE=Monnit Corporation ++ + OUI:70B3D5D1B* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + + OUI:70B3D5D1C* + ID_OUI_FROM_DATABASE=Specialised Imaging Limited + ++OUI:70B3D5D1D* ++ ID_OUI_FROM_DATABASE=Stuyts Engineering Haarlem BV ++ + OUI:70B3D5D1E* + ID_OUI_FROM_DATABASE=Houston Radar LLC + +@@ -64079,9 +77204,15 @@ OUI:70B3D5D1F* + OUI:70B3D5D20* + ID_OUI_FROM_DATABASE=Rheonics GmbH + ++OUI:70B3D5D21* ++ ID_OUI_FROM_DATABASE=biosilver .co.,ltd ++ + OUI:70B3D5D22* + ID_OUI_FROM_DATABASE=DEK Technologies + ++OUI:70B3D5D23* ++ ID_OUI_FROM_DATABASE=COTT Electronics ++ + OUI:70B3D5D24* + ID_OUI_FROM_DATABASE=Microtronics Engineering GmbH + +@@ -64091,12 +77222,24 @@ OUI:70B3D5D25* + OUI:70B3D5D26* + ID_OUI_FROM_DATABASE=MI Inc. + ++OUI:70B3D5D27* ++ ID_OUI_FROM_DATABASE=Light field Lab ++ ++OUI:70B3D5D28* ++ ID_OUI_FROM_DATABASE=Toshiba Electron Tubes & Devices Co., Ltd. ++ + OUI:70B3D5D29* + ID_OUI_FROM_DATABASE=Sportzcast + ++OUI:70B3D5D2A* ++ ID_OUI_FROM_DATABASE=ITsynergy Ltd ++ + OUI:70B3D5D2B* + ID_OUI_FROM_DATABASE=StreamPlay Oy Ltd + ++OUI:70B3D5D2C* ++ ID_OUI_FROM_DATABASE=microWerk GmbH ++ + OUI:70B3D5D2D* + ID_OUI_FROM_DATABASE=Evolute Systems Private Limited + +@@ -64106,24 +77249,51 @@ OUI:70B3D5D2E* + OUI:70B3D5D2F* + ID_OUI_FROM_DATABASE=L.I.F.E. Corporation SA + ++OUI:70B3D5D30* ++ ID_OUI_FROM_DATABASE=Leica Microsystems Ltd. Shanghai ++ ++OUI:70B3D5D31* ++ ID_OUI_FROM_DATABASE=Solace Systems Inc. ++ + OUI:70B3D5D32* + ID_OUI_FROM_DATABASE=Euklis by GSG International + ++OUI:70B3D5D33* ++ ID_OUI_FROM_DATABASE=VECTOR.CO.,LTD. ++ + OUI:70B3D5D34* + ID_OUI_FROM_DATABASE=G-PHILOS CO.,LTD + ++OUI:70B3D5D35* ++ ID_OUI_FROM_DATABASE=King-On Technology Ltd. ++ ++OUI:70B3D5D36* ++ ID_OUI_FROM_DATABASE=Insitu Inc. ++ + OUI:70B3D5D37* + ID_OUI_FROM_DATABASE=Sicon srl + + OUI:70B3D5D38* + ID_OUI_FROM_DATABASE=Vista Research, Inc. + ++OUI:70B3D5D39* ++ ID_OUI_FROM_DATABASE=ASHIDA Electronics Pvt. Ltd ++ ++OUI:70B3D5D3A* ++ ID_OUI_FROM_DATABASE=PROMOMED RUS LLC ++ + OUI:70B3D5D3B* + ID_OUI_FROM_DATABASE=NimbeLink Corp + + OUI:70B3D5D3C* + ID_OUI_FROM_DATABASE=HRT + ++OUI:70B3D5D3D* ++ ID_OUI_FROM_DATABASE=Netzikon GmbH ++ ++OUI:70B3D5D3E* ++ ID_OUI_FROM_DATABASE=enders GmbH ++ + OUI:70B3D5D3F* + ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SPA + +@@ -64142,6 +77312,9 @@ OUI:70B3D5D43* + OUI:70B3D5D44* + ID_OUI_FROM_DATABASE=ic-automation GmbH + ++OUI:70B3D5D45* ++ ID_OUI_FROM_DATABASE=Vemco Sp. z o. o. ++ + OUI:70B3D5D46* + ID_OUI_FROM_DATABASE=Contineo s.r.o. + +@@ -64151,6 +77324,9 @@ OUI:70B3D5D47* + OUI:70B3D5D48* + ID_OUI_FROM_DATABASE=HEADROOM Broadcast GmbH + ++OUI:70B3D5D49* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ + OUI:70B3D5D4A* + ID_OUI_FROM_DATABASE=OÜ ELIKO Tehnoloogia Arenduskeskus + +@@ -64166,15 +77342,30 @@ OUI:70B3D5D4D* + OUI:70B3D5D4E* + ID_OUI_FROM_DATABASE=FLSmidth + ++OUI:70B3D5D4F* ++ ID_OUI_FROM_DATABASE=C-COM Satellite Systems Inc. ++ ++OUI:70B3D5D50* ++ ID_OUI_FROM_DATABASE=Cubic ITS, Inc. dba GRIDSMART Technologies ++ + OUI:70B3D5D51* + ID_OUI_FROM_DATABASE=Azcom Technology S.r.l. + ++OUI:70B3D5D52* ++ ID_OUI_FROM_DATABASE=Sensoronic Co.,Ltd ++ ++OUI:70B3D5D53* ++ ID_OUI_FROM_DATABASE=BeiLi eTek (Zhangjiagang) Co., Ltd. ++ + OUI:70B3D5D54* + ID_OUI_FROM_DATABASE=JL World Corporation Limited + + OUI:70B3D5D55* + ID_OUI_FROM_DATABASE=WM Design s.r.o + ++OUI:70B3D5D56* ++ ID_OUI_FROM_DATABASE=KRONOTECH SRL ++ + OUI:70B3D5D57* + ID_OUI_FROM_DATABASE=TRIUMPH BOARD a.s. + +@@ -64193,6 +77384,12 @@ OUI:70B3D5D5B* + OUI:70B3D5D5C* + ID_OUI_FROM_DATABASE=Critical Link LLC + ++OUI:70B3D5D5D* ++ ID_OUI_FROM_DATABASE=SEASONS 4 INC ++ ++OUI:70B3D5D5E* ++ ID_OUI_FROM_DATABASE=Barcelona Smart Technologies ++ + OUI:70B3D5D5F* + ID_OUI_FROM_DATABASE=Core Balance Co., Ltd. + +@@ -64209,7 +77406,7 @@ OUI:70B3D5D63* + ID_OUI_FROM_DATABASE=CRDE + + OUI:70B3D5D64* +- ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed ++ ID_OUI_FROM_DATABASE=Mettler Toledo + + OUI:70B3D5D65* + ID_OUI_FROM_DATABASE=CRDE +@@ -64220,6 +77417,9 @@ OUI:70B3D5D66* + OUI:70B3D5D67* + ID_OUI_FROM_DATABASE=ALPHA Corporation + ++OUI:70B3D5D68* ++ ID_OUI_FROM_DATABASE=Tobi Tribe Inc. ++ + OUI:70B3D5D69* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific + +@@ -64232,6 +77432,9 @@ OUI:70B3D5D6B* + OUI:70B3D5D6C* + ID_OUI_FROM_DATABASE=GP Systems GmbH + ++OUI:70B3D5D6D* ++ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH ++ + OUI:70B3D5D6E* + ID_OUI_FROM_DATABASE=ard sa + +@@ -64259,6 +77462,12 @@ OUI:70B3D5D75* + OUI:70B3D5D76* + ID_OUI_FROM_DATABASE=attocube systems AG + ++OUI:70B3D5D77* ++ ID_OUI_FROM_DATABASE=Portrait Displays, Inc. ++ ++OUI:70B3D5D78* ++ ID_OUI_FROM_DATABASE=Nxvi Microelectronics Technology (Jinan) Co., Ltd. ++ + OUI:70B3D5D79* + ID_OUI_FROM_DATABASE=GOMA ELETTRONICA SpA + +@@ -64271,6 +77480,9 @@ OUI:70B3D5D7B* + OUI:70B3D5D7C* + ID_OUI_FROM_DATABASE=D.T.S Illuminazione Srl + ++OUI:70B3D5D7D* ++ ID_OUI_FROM_DATABASE=BESO sp. z o.o. ++ + OUI:70B3D5D7E* + ID_OUI_FROM_DATABASE=Triax A/S + +@@ -64283,18 +77495,33 @@ OUI:70B3D5D80* + OUI:70B3D5D81* + ID_OUI_FROM_DATABASE=PDD Group Ltd + ++OUI:70B3D5D82* ++ ID_OUI_FROM_DATABASE=SUN ELECTRONICS CO.,LTD. ++ ++OUI:70B3D5D83* ++ ID_OUI_FROM_DATABASE=AKASAKATEC INC. ++ + OUI:70B3D5D84* + ID_OUI_FROM_DATABASE=Sentry360 + ++OUI:70B3D5D85* ++ ID_OUI_FROM_DATABASE=BTG Instruments AB ++ + OUI:70B3D5D86* + ID_OUI_FROM_DATABASE=WPGSYS Pte Ltd + + OUI:70B3D5D87* + ID_OUI_FROM_DATABASE=Zigen Corp + ++OUI:70B3D5D88* ++ ID_OUI_FROM_DATABASE=Nidec asi spa ++ + OUI:70B3D5D89* + ID_OUI_FROM_DATABASE=Resolution Systems + ++OUI:70B3D5D8A* ++ ID_OUI_FROM_DATABASE=JIANGSU HORAINTEL CO.,LTD ++ + OUI:70B3D5D8B* + ID_OUI_FROM_DATABASE=Lenoxi Automation s.r.o. + +@@ -64328,12 +77555,18 @@ OUI:70B3D5D94* + OUI:70B3D5D95* + ID_OUI_FROM_DATABASE=SANO SERVICE Co.,Ltd + ++OUI:70B3D5D96* ++ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific Inc. ++ + OUI:70B3D5D97* +- ID_OUI_FROM_DATABASE=BRS Sistemas Eletronicos ++ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos + + OUI:70B3D5D98* + ID_OUI_FROM_DATABASE=ACD Elekronik GmbH + ++OUI:70B3D5D99* ++ ID_OUI_FROM_DATABASE=Nilar AB ++ + OUI:70B3D5D9A* + ID_OUI_FROM_DATABASE=Wuhan Xingtuxinke ELectronic Co.,Ltd + +@@ -64349,9 +77582,21 @@ OUI:70B3D5D9D* + OUI:70B3D5D9E* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + ++OUI:70B3D5D9F* ++ ID_OUI_FROM_DATABASE=Digital Solutions JSC ++ ++OUI:70B3D5DA0* ++ ID_OUI_FROM_DATABASE=Jiangsu Etern Compamy Limited ++ + OUI:70B3D5DA1* + ID_OUI_FROM_DATABASE=Qprel srl + ++OUI:70B3D5DA2* ++ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH ++ ++OUI:70B3D5DA3* ++ ID_OUI_FROM_DATABASE=Voleatech GmbH ++ + OUI:70B3D5DA4* + ID_OUI_FROM_DATABASE=CRDE + +@@ -64361,15 +77606,33 @@ OUI:70B3D5DA5* + OUI:70B3D5DA6* + ID_OUI_FROM_DATABASE=Redfish Group Pty Ltd + ++OUI:70B3D5DA7* ++ ID_OUI_FROM_DATABASE=Network Innovations ++ + OUI:70B3D5DA8* + ID_OUI_FROM_DATABASE=Tagarno AS + ++OUI:70B3D5DA9* ++ ID_OUI_FROM_DATABASE=RCH Vietnam Limited Liability Company ++ + OUI:70B3D5DAA* + ID_OUI_FROM_DATABASE=AmTote Australasia + ++OUI:70B3D5DAB* ++ ID_OUI_FROM_DATABASE=SET Power Systems GmbH ++ ++OUI:70B3D5DAC* ++ ID_OUI_FROM_DATABASE=Dalian Laike Technology Development Co., Ltd ++ + OUI:70B3D5DAD* + ID_OUI_FROM_DATABASE=GD Mission Systems + ++OUI:70B3D5DAE* ++ ID_OUI_FROM_DATABASE=LGE ++ ++OUI:70B3D5DAF* ++ ID_OUI_FROM_DATABASE=INNOVATIVE CONCEPTS AND DESIGN LLC ++ + OUI:70B3D5DB0* + ID_OUI_FROM_DATABASE=Arnouse Digital Devices Corp + +@@ -64379,6 +77642,9 @@ OUI:70B3D5DB1* + OUI:70B3D5DB2* + ID_OUI_FROM_DATABASE=Micro Electroninc Products + ++OUI:70B3D5DB3* ++ ID_OUI_FROM_DATABASE=Klaxoon ++ + OUI:70B3D5DB4* + ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd + +@@ -64388,21 +77654,57 @@ OUI:70B3D5DB5* + OUI:70B3D5DB6* + ID_OUI_FROM_DATABASE=csintech + ++OUI:70B3D5DB7* ++ ID_OUI_FROM_DATABASE=Pengo Technology Co., Ltd ++ + OUI:70B3D5DB8* + ID_OUI_FROM_DATABASE=SISTEM SA + ++OUI:70B3D5DB9* ++ ID_OUI_FROM_DATABASE=PULOON Tech ++ ++OUI:70B3D5DBA* ++ ID_OUI_FROM_DATABASE=KODENSHI CORP. ++ ++OUI:70B3D5DBB* ++ ID_OUI_FROM_DATABASE=Fuhr GmbH Filtertechnik ++ ++OUI:70B3D5DBC* ++ ID_OUI_FROM_DATABASE=Gamber Johnson-LLC ++ ++OUI:70B3D5DBD* ++ ID_OUI_FROM_DATABASE=TRANSLITE GLOBAL LLC ++ ++OUI:70B3D5DBE* ++ ID_OUI_FROM_DATABASE=Hiber ++ + OUI:70B3D5DBF* + ID_OUI_FROM_DATABASE=Infodev Electronic Designers Intl. + + OUI:70B3D5DC0* + ID_OUI_FROM_DATABASE=ATEME + ++OUI:70B3D5DC1* ++ ID_OUI_FROM_DATABASE=Metralight, Inc. ++ ++OUI:70B3D5DC2* ++ ID_OUI_FROM_DATABASE=SwineTech, Inc. ++ ++OUI:70B3D5DC3* ++ ID_OUI_FROM_DATABASE=Fath Mechatronics ++ ++OUI:70B3D5DC4* ++ ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau AG ++ + OUI:70B3D5DC5* + ID_OUI_FROM_DATABASE=Excel Medical Electronics LLC + + OUI:70B3D5DC6* + ID_OUI_FROM_DATABASE=IDEM INC. + ++OUI:70B3D5DC7* ++ ID_OUI_FROM_DATABASE=NUBURU Inc. ++ + OUI:70B3D5DC8* + ID_OUI_FROM_DATABASE=Enertex Bayern GmbH + +@@ -64412,24 +77714,54 @@ OUI:70B3D5DC9* + OUI:70B3D5DCA* + ID_OUI_FROM_DATABASE=DSan Corporation + ++OUI:70B3D5DCB* ++ ID_OUI_FROM_DATABASE=MIJIENETRTECH CO.,LTD ++ + OUI:70B3D5DCC* + ID_OUI_FROM_DATABASE=Eutron SPA + ++OUI:70B3D5DCD* ++ ID_OUI_FROM_DATABASE=C TECH BILISIM TEKNOLOJILERI SAN. VE TIC. A.S. ++ + OUI:70B3D5DCE* + ID_OUI_FROM_DATABASE=Stahl GmbH + + OUI:70B3D5DCF* + ID_OUI_FROM_DATABASE=KLS Netherlands B.V. + ++OUI:70B3D5DD0* ++ ID_OUI_FROM_DATABASE=Deep Secure Limited ++ + OUI:70B3D5DD1* + ID_OUI_FROM_DATABASE=em-tec GmbH + ++OUI:70B3D5DD2* ++ ID_OUI_FROM_DATABASE=Insitu, Inc ++ ++OUI:70B3D5DD3* ++ ID_OUI_FROM_DATABASE=VITEC ++ ++OUI:70B3D5DD4* ++ ID_OUI_FROM_DATABASE=ResIOT UBLSOFTWARE SRL ++ ++OUI:70B3D5DD5* ++ ID_OUI_FROM_DATABASE=Cooltera Limited ++ ++OUI:70B3D5DD6* ++ ID_OUI_FROM_DATABASE=Umweltanalytik Holbach GmbH ++ + OUI:70B3D5DD7* + ID_OUI_FROM_DATABASE=DETECT Australia + + OUI:70B3D5DD8* + ID_OUI_FROM_DATABASE=EMSCAN Corp. + ++OUI:70B3D5DD9* ++ ID_OUI_FROM_DATABASE=MaNima Technologies BV ++ ++OUI:70B3D5DDA* ++ ID_OUI_FROM_DATABASE=Hubbell Power Systems ++ + OUI:70B3D5DDB* + ID_OUI_FROM_DATABASE=Intra Corporation + +@@ -64439,18 +77771,30 @@ OUI:70B3D5DDC* + OUI:70B3D5DDD* + ID_OUI_FROM_DATABASE=BIO RAD LABORATORIES + ++OUI:70B3D5DDE* ++ ID_OUI_FROM_DATABASE=Abbott Diagnostics Technologies AS ++ + OUI:70B3D5DDF* + ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc. + + OUI:70B3D5DE0* + ID_OUI_FROM_DATABASE=eCozy GmbH + ++OUI:70B3D5DE1* ++ ID_OUI_FROM_DATABASE=Duplomatic MS spa ++ + OUI:70B3D5DE2* + ID_OUI_FROM_DATABASE=ACD Elekronik GmbH + ++OUI:70B3D5DE3* ++ ID_OUI_FROM_DATABASE=ETL Elektrotechnik Lauter GmbH ++ + OUI:70B3D5DE4* + ID_OUI_FROM_DATABASE=MAVILI ELEKTRONIK TIC. VE SAN. A.S. + ++OUI:70B3D5DE5* ++ ID_OUI_FROM_DATABASE=ASML ++ + OUI:70B3D5DE6* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + +@@ -64461,17 +77805,26 @@ OUI:70B3D5DE8* + ID_OUI_FROM_DATABASE=Nation-E Ltd. + + OUI:70B3D5DE9* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=EkspertStroyProekt LLC + + OUI:70B3D5DEA* + ID_OUI_FROM_DATABASE=Advanced Ventilation Applications, Inc. + ++OUI:70B3D5DEB* ++ ID_OUI_FROM_DATABASE=DORLET SAU ++ + OUI:70B3D5DEC* + ID_OUI_FROM_DATABASE=Condev-Automation GmbH + ++OUI:70B3D5DED* ++ ID_OUI_FROM_DATABASE=Simpulse ++ + OUI:70B3D5DEE* + ID_OUI_FROM_DATABASE=CRDE + ++OUI:70B3D5DEF* ++ ID_OUI_FROM_DATABASE=ISG Nordic AB ++ + OUI:70B3D5DF0* + ID_OUI_FROM_DATABASE=astozi consulting Tomasz Zieba + +@@ -64484,11 +77837,17 @@ OUI:70B3D5DF2* + OUI:70B3D5DF3* + ID_OUI_FROM_DATABASE=SPC Bioclinicum + ++OUI:70B3D5DF4* ++ ID_OUI_FROM_DATABASE=Heim- & Bürokommunikation Ilmert e.K. ++ ++OUI:70B3D5DF5* ++ ID_OUI_FROM_DATABASE=Beijing Huanyu Zhilian Science &Technology Co., Ltd. ++ + OUI:70B3D5DF6* + ID_OUI_FROM_DATABASE=Tiab Limited + + OUI:70B3D5DF7* +- ID_OUI_FROM_DATABASE=Refecor Oy ++ ID_OUI_FROM_DATABASE=ScopeSensor Oy + + OUI:70B3D5DF8* + ID_OUI_FROM_DATABASE=RMA Mess- und Regeltechnik GmbH & Co.KG +@@ -64499,21 +77858,42 @@ OUI:70B3D5DF9* + OUI:70B3D5DFA* + ID_OUI_FROM_DATABASE=Newtouch Electronics (Shanghai) Co.,Ltd. + ++OUI:70B3D5DFB* ++ ID_OUI_FROM_DATABASE=Yamamoto Works Ltd. ++ + OUI:70B3D5DFC* + ID_OUI_FROM_DATABASE=ELECTRONIC SYSTEMS DESIGN SPRL + + OUI:70B3D5DFD* + ID_OUI_FROM_DATABASE=Contiweb + ++OUI:70B3D5DFE* ++ ID_OUI_FROM_DATABASE=microtec Sicherheitstechnik GmbH ++ + OUI:70B3D5DFF* + ID_OUI_FROM_DATABASE=Spanawave Corporation + ++OUI:70B3D5E00* ++ ID_OUI_FROM_DATABASE=Jeaway CCTV Security Ltd,. ++ ++OUI:70B3D5E01* ++ ID_OUI_FROM_DATABASE=EarTex ++ + OUI:70B3D5E02* + ID_OUI_FROM_DATABASE=YEHL & JORDAN LLC + ++OUI:70B3D5E03* ++ ID_OUI_FROM_DATABASE=MBJ ++ + OUI:70B3D5E04* + ID_OUI_FROM_DATABASE=Combilent + ++OUI:70B3D5E05* ++ ID_OUI_FROM_DATABASE=Lobaro GmbH ++ ++OUI:70B3D5E06* ++ ID_OUI_FROM_DATABASE=System West dba ICS Electronics ++ + OUI:70B3D5E07* + ID_OUI_FROM_DATABASE=Baader Planetarium GmbH + +@@ -64523,24 +77903,54 @@ OUI:70B3D5E08* + OUI:70B3D5E09* + ID_OUI_FROM_DATABASE=L-3 communications ComCept Division + ++OUI:70B3D5E0A* ++ ID_OUI_FROM_DATABASE=Acouva, Inc. ++ + OUI:70B3D5E0B* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. + ++OUI:70B3D5E0C* ++ ID_OUI_FROM_DATABASE=Communication Systems Solutions ++ + OUI:70B3D5E0D* + ID_OUI_FROM_DATABASE=Sigma Connectivity AB + ++OUI:70B3D5E0E* ++ ID_OUI_FROM_DATABASE=VulcanForms ++ + OUI:70B3D5E0F* + ID_OUI_FROM_DATABASE=Vtron Pty Ltd + ++OUI:70B3D5E10* ++ ID_OUI_FROM_DATABASE=Leidos ++ ++OUI:70B3D5E11* ++ ID_OUI_FROM_DATABASE=Engage Technologies ++ ++OUI:70B3D5E12* ++ ID_OUI_FROM_DATABASE=SNK, Inc. ++ ++OUI:70B3D5E13* ++ ID_OUI_FROM_DATABASE=Suzhou ZhiCai Co.,Ltd. ++ ++OUI:70B3D5E14* ++ ID_OUI_FROM_DATABASE=Automata Spa ++ ++OUI:70B3D5E15* ++ ID_OUI_FROM_DATABASE=Benetel ++ + OUI:70B3D5E16* + ID_OUI_FROM_DATABASE=China Entropy Co., Ltd. + + OUI:70B3D5E17* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=SA Photonics + + OUI:70B3D5E18* + ID_OUI_FROM_DATABASE=Plasmapp Co.,Ltd. + ++OUI:70B3D5E19* ++ ID_OUI_FROM_DATABASE=BAB TECHNOLOGIE GmbH ++ + OUI:70B3D5E1A* + ID_OUI_FROM_DATABASE=BIZERBA LUCEO + +@@ -64548,7 +77958,16 @@ OUI:70B3D5E1B* + ID_OUI_FROM_DATABASE=Neuron GmbH + + OUI:70B3D5E1C* +- ID_OUI_FROM_DATABASE=Xcenter AS ++ ID_OUI_FROM_DATABASE=RoomMate AS ++ ++OUI:70B3D5E1D* ++ ID_OUI_FROM_DATABASE=Galaxy Next Generation, Inc. ++ ++OUI:70B3D5E1E* ++ ID_OUI_FROM_DATABASE=Umano Medical Inc. ++ ++OUI:70B3D5E1F* ++ ID_OUI_FROM_DATABASE=THETA432 + + OUI:70B3D5E20* + ID_OUI_FROM_DATABASE=Signature Control Systems, LLC. +@@ -64557,11 +77976,17 @@ OUI:70B3D5E21* + ID_OUI_FROM_DATABASE=LLVISION TECHNOLOGY CO.,LTD + + OUI:70B3D5E22* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Federated Wireless, Inc. + + OUI:70B3D5E23* + ID_OUI_FROM_DATABASE=Smith Meter, Inc. + ++OUI:70B3D5E24* ++ ID_OUI_FROM_DATABASE=Gogo Business Aviation ++ ++OUI:70B3D5E25* ++ ID_OUI_FROM_DATABASE=GJD Manufacturing ++ + OUI:70B3D5E26* + ID_OUI_FROM_DATABASE=FEITIAN CO.,LTD. + +@@ -64571,24 +77996,54 @@ OUI:70B3D5E27* + OUI:70B3D5E28* + ID_OUI_FROM_DATABASE=iotec GmbH + ++OUI:70B3D5E29* ++ ID_OUI_FROM_DATABASE=Invent Vision - iVision Sistemas de Imagem e Visão S.A. ++ ++OUI:70B3D5E2A* ++ ID_OUI_FROM_DATABASE=CONTES, spol. s r.o. ++ + OUI:70B3D5E2B* + ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. + + OUI:70B3D5E2C* + ID_OUI_FROM_DATABASE=Fourth Frontier Technologies Private Limited + ++OUI:70B3D5E2D* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:70B3D5E2E* + ID_OUI_FROM_DATABASE=Merz s.r.o. + ++OUI:70B3D5E2F* ++ ID_OUI_FROM_DATABASE=Flextronics International Kft. ++ + OUI:70B3D5E30* + ID_OUI_FROM_DATABASE=QUISS AG + ++OUI:70B3D5E31* ++ ID_OUI_FROM_DATABASE=NEUROPHET, Inc. ++ ++OUI:70B3D5E32* ++ ID_OUI_FROM_DATABASE=HERUTU ELECTRONICS CORPORATION ++ ++OUI:70B3D5E33* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ ++OUI:70B3D5E34* ++ ID_OUI_FROM_DATABASE=Gamber Johnson-LLC ++ + OUI:70B3D5E35* + ID_OUI_FROM_DATABASE=Nanospeed Technologies Limited + + OUI:70B3D5E36* + ID_OUI_FROM_DATABASE=Guidance Navigation Limited + ++OUI:70B3D5E37* ++ ID_OUI_FROM_DATABASE=Eurotempest AB ++ ++OUI:70B3D5E38* ++ ID_OUI_FROM_DATABASE=Cursor Systems NV ++ + OUI:70B3D5E39* + ID_OUI_FROM_DATABASE=Thinnect, Inc, + +@@ -64598,6 +78053,9 @@ OUI:70B3D5E3A* + OUI:70B3D5E3B* + ID_OUI_FROM_DATABASE=ComNav Technology Ltd. + ++OUI:70B3D5E3C* ++ ID_OUI_FROM_DATABASE=Densitron Technologies Ltd ++ + OUI:70B3D5E3D* + ID_OUI_FROM_DATABASE=Leo Bodnar Electronics Ltd + +@@ -64607,12 +78065,30 @@ OUI:70B3D5E3E* + OUI:70B3D5E3F* + ID_OUI_FROM_DATABASE=BESTCODE LLC + ++OUI:70B3D5E40* ++ ID_OUI_FROM_DATABASE=Siemens Mobility GmbH - MO TI SPA ++ ++OUI:70B3D5E41* ++ ID_OUI_FROM_DATABASE=4neXt S.r.l.s. ++ ++OUI:70B3D5E42* ++ ID_OUI_FROM_DATABASE=Neusoft Reach Automotive Technology (Shenyang) Co.,Ltd ++ + OUI:70B3D5E43* + ID_OUI_FROM_DATABASE=SL Audio A/S + ++OUI:70B3D5E44* ++ ID_OUI_FROM_DATABASE=BrainboxAI Inc ++ + OUI:70B3D5E45* + ID_OUI_FROM_DATABASE=Momentum Data Systems + ++OUI:70B3D5E46* ++ ID_OUI_FROM_DATABASE=7thSense Design Limited ++ ++OUI:70B3D5E47* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ + OUI:70B3D5E48* + ID_OUI_FROM_DATABASE=TDI. Co., LTD + +@@ -64628,6 +78104,9 @@ OUI:70B3D5E4B* + OUI:70B3D5E4C* + ID_OUI_FROM_DATABASE=IAI-Israel Aerospace Industries MBT + ++OUI:70B3D5E4D* ++ ID_OUI_FROM_DATABASE=Vulcan Wireless Inc. ++ + OUI:70B3D5E4E* + ID_OUI_FROM_DATABASE=Midfin Systems + +@@ -64637,15 +78116,24 @@ OUI:70B3D5E4F* + OUI:70B3D5E50* + ID_OUI_FROM_DATABASE=Advanced Vision Technology Ltd + ++OUI:70B3D5E51* ++ ID_OUI_FROM_DATABASE=NooliTIC ++ + OUI:70B3D5E52* + ID_OUI_FROM_DATABASE=Guangzhou Moblin Technology Co., Ltd. + + OUI:70B3D5E53* + ID_OUI_FROM_DATABASE=MI INC. + ++OUI:70B3D5E54* ++ ID_OUI_FROM_DATABASE=Beijing PanGu Company ++ + OUI:70B3D5E55* + ID_OUI_FROM_DATABASE=BELT S.r.l. + ++OUI:70B3D5E56* ++ ID_OUI_FROM_DATABASE=HIPODROMO DE AGUA CALIENTE, S.A. DE C.V. ++ + OUI:70B3D5E57* + ID_OUI_FROM_DATABASE=Iradimed + +@@ -64655,18 +78143,60 @@ OUI:70B3D5E58* + OUI:70B3D5E59* + ID_OUI_FROM_DATABASE=Fracarro srl + ++OUI:70B3D5E5A* ++ ID_OUI_FROM_DATABASE=Cardinal Scales Manufacturing Co ++ ++OUI:70B3D5E5B* ++ ID_OUI_FROM_DATABASE=Argosy Labs Inc. ++ ++OUI:70B3D5E5C* ++ ID_OUI_FROM_DATABASE=Walton Hi-Tech Industries Ltd. ++ ++OUI:70B3D5E5D* ++ ID_OUI_FROM_DATABASE=Boffins Technologies AB ++ + OUI:70B3D5E5E* + ID_OUI_FROM_DATABASE=Critical Link LLC + ++OUI:70B3D5E5F* ++ ID_OUI_FROM_DATABASE=CesiumAstro Inc. ++ ++OUI:70B3D5E60* ++ ID_OUI_FROM_DATABASE=Davitor AB ++ + OUI:70B3D5E61* + ID_OUI_FROM_DATABASE=Adeli + ++OUI:70B3D5E62* ++ ID_OUI_FROM_DATABASE=Eon ++ ++OUI:70B3D5E63* ++ ID_OUI_FROM_DATABASE=Potomac Electric Corporation ++ ++OUI:70B3D5E64* ++ ID_OUI_FROM_DATABASE=HONG JIANG ELECTRONICS CO., LTD. ++ ++OUI:70B3D5E65* ++ ID_OUI_FROM_DATABASE=BIRTECH TECHNOLOGY ++ ++OUI:70B3D5E66* ++ ID_OUI_FROM_DATABASE=Eneon sp. z o.o. ++ + OUI:70B3D5E67* + ID_OUI_FROM_DATABASE=APPLIED PROCESSING + ++OUI:70B3D5E68* ++ ID_OUI_FROM_DATABASE=Transit Solutions, LLC. ++ + OUI:70B3D5E69* + ID_OUI_FROM_DATABASE=Fire4 Systems UK Ltd + ++OUI:70B3D5E6A* ++ ID_OUI_FROM_DATABASE=MAC Solutions (UK) Ltd ++ ++OUI:70B3D5E6B* ++ ID_OUI_FROM_DATABASE=Shenzhen Shi Fang Communication Technology Co., Ltd ++ + OUI:70B3D5E6C* + ID_OUI_FROM_DATABASE=Fusar Technologies inc + +@@ -64676,12 +78206,21 @@ OUI:70B3D5E6D* + OUI:70B3D5E6E* + ID_OUI_FROM_DATABASE=Lieron BVBA + ++OUI:70B3D5E6F* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:70B3D5E70* + ID_OUI_FROM_DATABASE=DISK Multimedia s.r.o. + + OUI:70B3D5E71* + ID_OUI_FROM_DATABASE=SiS Technology + ++OUI:70B3D5E72* ++ ID_OUI_FROM_DATABASE=KDT Corp. ++ ++OUI:70B3D5E73* ++ ID_OUI_FROM_DATABASE=Zeus Control Systems Ltd ++ + OUI:70B3D5E74* + ID_OUI_FROM_DATABASE=Exfrontier Co., Ltd. + +@@ -64694,6 +78233,12 @@ OUI:70B3D5E76* + OUI:70B3D5E77* + ID_OUI_FROM_DATABASE=OPTIX JSC + ++OUI:70B3D5E78* ++ ID_OUI_FROM_DATABASE=Camwell India LLP ++ ++OUI:70B3D5E79* ++ ID_OUI_FROM_DATABASE=Acrodea, Inc. ++ + OUI:70B3D5E7A* + ID_OUI_FROM_DATABASE=ART SPA + +@@ -64709,18 +78254,51 @@ OUI:70B3D5E7D* + OUI:70B3D5E7E* + ID_OUI_FROM_DATABASE=Groupe Citypassenger Inc + ++OUI:70B3D5E7F* ++ ID_OUI_FROM_DATABASE=Sankyo Intec Co,ltd ++ ++OUI:70B3D5E80* ++ ID_OUI_FROM_DATABASE=Changzhou Rapid Information Technology Co,Ltd ++ ++OUI:70B3D5E81* ++ ID_OUI_FROM_DATABASE=SLAT ++ + OUI:70B3D5E82* + ID_OUI_FROM_DATABASE=RF Track + ++OUI:70B3D5E83* ++ ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA ++ ++OUI:70B3D5E84* ++ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. ++ + OUI:70B3D5E85* + ID_OUI_FROM_DATABASE=Explorer Inc. + + OUI:70B3D5E86* + ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd + ++OUI:70B3D5E87* ++ ID_OUI_FROM_DATABASE=STACKFORCE GmbH ++ + OUI:70B3D5E88* + ID_OUI_FROM_DATABASE=Breas Medical AB + ++OUI:70B3D5E89* ++ ID_OUI_FROM_DATABASE=JSC Kaluga Astral ++ ++OUI:70B3D5E8A* ++ ID_OUI_FROM_DATABASE=Melecs EWS GmbH ++ ++OUI:70B3D5E8B* ++ ID_OUI_FROM_DATABASE=Dream D&S Co.,Ltd ++ ++OUI:70B3D5E8C* ++ ID_OUI_FROM_DATABASE=Fracarro srl ++ ++OUI:70B3D5E8D* ++ ID_OUI_FROM_DATABASE=Natav Services Ltd. ++ + OUI:70B3D5E8E* + ID_OUI_FROM_DATABASE=Macnica Technology + +@@ -64739,12 +78317,18 @@ OUI:70B3D5E92* + OUI:70B3D5E93* + ID_OUI_FROM_DATABASE=ECON Technology Co.Ltd + ++OUI:70B3D5E94* ++ ID_OUI_FROM_DATABASE=Lumiplan Duhamel ++ + OUI:70B3D5E95* + ID_OUI_FROM_DATABASE=BroadSoft Inc + + OUI:70B3D5E96* + ID_OUI_FROM_DATABASE=Cellier Domesticus inc + ++OUI:70B3D5E97* ++ ID_OUI_FROM_DATABASE=Toptech Systems, Inc. ++ + OUI:70B3D5E98* + ID_OUI_FROM_DATABASE=JSC Kaluga Astral + +@@ -64760,12 +78344,21 @@ OUI:70B3D5E9B* + OUI:70B3D5E9C* + ID_OUI_FROM_DATABASE=ATG UV Technology + ++OUI:70B3D5E9D* ++ ID_OUI_FROM_DATABASE=INTECH ++ + OUI:70B3D5E9E* + ID_OUI_FROM_DATABASE=MSB Elektronik und Gerätebau GmbH + ++OUI:70B3D5E9F* ++ ID_OUI_FROM_DATABASE=Gigaband IP LLC ++ + OUI:70B3D5EA0* + ID_OUI_FROM_DATABASE=PARK24 + ++OUI:70B3D5EA1* ++ ID_OUI_FROM_DATABASE=Qntra Technology ++ + OUI:70B3D5EA2* + ID_OUI_FROM_DATABASE=Transportal Solutions Ltd + +@@ -64775,6 +78368,9 @@ OUI:70B3D5EA3* + OUI:70B3D5EA4* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + ++OUI:70B3D5EA5* ++ ID_OUI_FROM_DATABASE=LOTES TM OOO ++ + OUI:70B3D5EA6* + ID_OUI_FROM_DATABASE=Galios + +@@ -64784,15 +78380,27 @@ OUI:70B3D5EA7* + OUI:70B3D5EA8* + ID_OUI_FROM_DATABASE=Dia-Stron Limited + ++OUI:70B3D5EA9* ++ ID_OUI_FROM_DATABASE=Zhuhai Lonl electric Co.,Ltd. ++ ++OUI:70B3D5EAA* ++ ID_OUI_FROM_DATABASE=Druck Ltd. ++ + OUI:70B3D5EAB* + ID_OUI_FROM_DATABASE=APEN GROUP SpA (VAT IT08767740155) + + OUI:70B3D5EAC* + ID_OUI_FROM_DATABASE=Kentech Instruments Limited + ++OUI:70B3D5EAD* ++ ID_OUI_FROM_DATABASE=Cobo, Inc. ++ + OUI:70B3D5EAE* + ID_OUI_FROM_DATABASE=Orlaco Products B.V. + ++OUI:70B3D5EAF* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ + OUI:70B3D5EB0* + ID_OUI_FROM_DATABASE=Nautel Limted + +@@ -64811,12 +78419,21 @@ OUI:70B3D5EB4* + OUI:70B3D5EB5* + ID_OUI_FROM_DATABASE=JUSTEK INC + ++OUI:70B3D5EB6* ++ ID_OUI_FROM_DATABASE=EnergizeEV ++ + OUI:70B3D5EB7* + ID_OUI_FROM_DATABASE=Skreens + ++OUI:70B3D5EB8* ++ ID_OUI_FROM_DATABASE=Emporia Renewable Energy Corp ++ + OUI:70B3D5EB9* + ID_OUI_FROM_DATABASE=Thiel Audio Products Company, LLC + ++OUI:70B3D5EBA* ++ ID_OUI_FROM_DATABASE=Last Mile Gear ++ + OUI:70B3D5EBB* + ID_OUI_FROM_DATABASE=Beijing Wing ICT Technology Co., Ltd. + +@@ -64829,9 +78446,27 @@ OUI:70B3D5EBD* + OUI:70B3D5EBE* + ID_OUI_FROM_DATABASE=Sierra Pacific Innovations Corp + ++OUI:70B3D5EBF* ++ ID_OUI_FROM_DATABASE=AUTOMATICA Y REGULACION S.A. ++ ++OUI:70B3D5EC0* ++ ID_OUI_FROM_DATABASE=ProtoConvert Pty Ltd ++ + OUI:70B3D5EC1* + ID_OUI_FROM_DATABASE=Xafax Nederland bv + ++OUI:70B3D5EC2* ++ ID_OUI_FROM_DATABASE=Lightside Instruments AS ++ ++OUI:70B3D5EC3* ++ ID_OUI_FROM_DATABASE=Virtual Control Systems Ltd ++ ++OUI:70B3D5EC4* ++ ID_OUI_FROM_DATABASE=hmt telematik GmbH ++ ++OUI:70B3D5EC5* ++ ID_OUI_FROM_DATABASE=TATTILE SRL ++ + OUI:70B3D5EC6* + ID_OUI_FROM_DATABASE=ESII + +@@ -64839,7 +78474,10 @@ OUI:70B3D5EC7* + ID_OUI_FROM_DATABASE=Neoptix Inc. + + OUI:70B3D5EC8* +- ID_OUI_FROM_DATABASE=Viko Elektrik-Elektronik A.Ş. ++ ID_OUI_FROM_DATABASE=PANASONIC LIFE SOLUTIONS ELEKTRİK SANAYİ VE TİCARE ++ ++OUI:70B3D5EC9* ++ ID_OUI_FROM_DATABASE=Qlinx Technologies + + OUI:70B3D5ECA* + ID_OUI_FROM_DATABASE=Transtronic AB +@@ -64847,6 +78485,9 @@ OUI:70B3D5ECA* + OUI:70B3D5ECB* + ID_OUI_FROM_DATABASE=Re spa - Controlli Industriali - IT01782300154 + ++OUI:70B3D5ECC* ++ ID_OUI_FROM_DATABASE=Digifocus Technology Inc. ++ + OUI:70B3D5ECD* + ID_OUI_FROM_DATABASE=SBS-Feintechnik GmbH & Co. KG + +@@ -64862,9 +78503,33 @@ OUI:70B3D5ED0* + OUI:70B3D5ED1* + ID_OUI_FROM_DATABASE=Przemyslowy Instytut Automatyki i Pomiarow + ++OUI:70B3D5ED2* ++ ID_OUI_FROM_DATABASE=PCTEL, Inc. ++ ++OUI:70B3D5ED3* ++ ID_OUI_FROM_DATABASE=Beijing Lihong Create Co., Ltd. ++ ++OUI:70B3D5ED4* ++ ID_OUI_FROM_DATABASE=WILMORE ELECTRONICS COMPANY ++ + OUI:70B3D5ED5* + ID_OUI_FROM_DATABASE=hangzhou battle link technology Co.,Ltd + ++OUI:70B3D5ED6* ++ ID_OUI_FROM_DATABASE=Metrasens Limited ++ ++OUI:70B3D5ED7* ++ ID_OUI_FROM_DATABASE=WAVE ++ ++OUI:70B3D5ED8* ++ ID_OUI_FROM_DATABASE=Wartsila Voyage Limited ++ ++OUI:70B3D5ED9* ++ ID_OUI_FROM_DATABASE=AADONA Communication Pvt Ltd ++ ++OUI:70B3D5EDA* ++ ID_OUI_FROM_DATABASE=Breas Medical AB ++ + OUI:70B3D5EDB* + ID_OUI_FROM_DATABASE=Netfort Solutions + +@@ -64874,12 +78539,21 @@ OUI:70B3D5EDC* + OUI:70B3D5EDD* + ID_OUI_FROM_DATABASE=Solar Network & Partners + ++OUI:70B3D5EDE* ++ ID_OUI_FROM_DATABASE=Agrident GmbH ++ + OUI:70B3D5EDF* + ID_OUI_FROM_DATABASE=GridNavigator + ++OUI:70B3D5EE0* ++ ID_OUI_FROM_DATABASE=Stecomp ++ + OUI:70B3D5EE1* + ID_OUI_FROM_DATABASE=allora Factory BVBA + ++OUI:70B3D5EE2* ++ ID_OUI_FROM_DATABASE=MONTRADE SPA ++ + OUI:70B3D5EE3* + ID_OUI_FROM_DATABASE=Lithe Technology, LLC + +@@ -64889,9 +78563,24 @@ OUI:70B3D5EE4* + OUI:70B3D5EE5* + ID_OUI_FROM_DATABASE=Beijing Hzhytech Technology Co.Ltd + ++OUI:70B3D5EE6* ++ ID_OUI_FROM_DATABASE=Vaunix Technology Corporation ++ ++OUI:70B3D5EE7* ++ ID_OUI_FROM_DATABASE=BLUE-SOLUTIONS CANADA INC. ++ ++OUI:70B3D5EE8* ++ ID_OUI_FROM_DATABASE=robert juliat ++ ++OUI:70B3D5EE9* ++ ID_OUI_FROM_DATABASE=SC3 Automation ++ + OUI:70B3D5EEA* + ID_OUI_FROM_DATABASE=Dameca a/s + ++OUI:70B3D5EEB* ++ ID_OUI_FROM_DATABASE=shenzhen suofeixiang technology Co.,Ltd ++ + OUI:70B3D5EEC* + ID_OUI_FROM_DATABASE=Impolux GmbH + +@@ -64904,6 +78593,12 @@ OUI:70B3D5EEE* + OUI:70B3D5EEF* + ID_OUI_FROM_DATABASE=TATTILE SRL + ++OUI:70B3D5EF0* ++ ID_OUI_FROM_DATABASE=PNETWORKS ++ ++OUI:70B3D5EF1* ++ ID_OUI_FROM_DATABASE=Nanotok LLC ++ + OUI:70B3D5EF2* + ID_OUI_FROM_DATABASE=Kongsberg Intergrated Tactical Systems + +@@ -64934,18 +78629,33 @@ OUI:70B3D5EFA* + OUI:70B3D5EFB* + ID_OUI_FROM_DATABASE=PXM sp.k. + ++OUI:70B3D5EFC* ++ ID_OUI_FROM_DATABASE=Absolent AB ++ ++OUI:70B3D5EFD* ++ ID_OUI_FROM_DATABASE=Cambridge Technology, Inc. ++ + OUI:70B3D5EFE* + ID_OUI_FROM_DATABASE=MEIDEN SYSTEM SOLUTIONS + ++OUI:70B3D5EFF* ++ ID_OUI_FROM_DATABASE=Carlo Gavazzi Industri ++ + OUI:70B3D5F00* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + + OUI:70B3D5F01* + ID_OUI_FROM_DATABASE=Software Systems Plus + ++OUI:70B3D5F02* ++ ID_OUI_FROM_DATABASE=ABECO Industrie Computer GmbH ++ + OUI:70B3D5F03* + ID_OUI_FROM_DATABASE=GMI Ltd + ++OUI:70B3D5F04* ++ ID_OUI_FROM_DATABASE=Scame Sistemi srl ++ + OUI:70B3D5F05* + ID_OUI_FROM_DATABASE=Motomuto Aps + +@@ -64958,6 +78668,12 @@ OUI:70B3D5F07* + OUI:70B3D5F08* + ID_OUI_FROM_DATABASE=Szabo Software & Engineering UK Ltd + ++OUI:70B3D5F09* ++ ID_OUI_FROM_DATABASE=Mictrotrac Retsch GmbH ++ ++OUI:70B3D5F0A* ++ ID_OUI_FROM_DATABASE=Neuronal Innovation Control S.L. ++ + OUI:70B3D5F0B* + ID_OUI_FROM_DATABASE=RF Industries + +@@ -64967,6 +78683,12 @@ OUI:70B3D5F0C* + OUI:70B3D5F0D* + ID_OUI_FROM_DATABASE=MeQ Inc. + ++OUI:70B3D5F0E* ++ ID_OUI_FROM_DATABASE=TextSpeak Corporation ++ ++OUI:70B3D5F0F* ++ ID_OUI_FROM_DATABASE=Kyoto Denkiki ++ + OUI:70B3D5F10* + ID_OUI_FROM_DATABASE=Riegl Laser Measurement Systems GmbH + +@@ -64982,15 +78704,30 @@ OUI:70B3D5F13* + OUI:70B3D5F14* + ID_OUI_FROM_DATABASE=SANYU SWITCH CO., LTD. + ++OUI:70B3D5F15* ++ ID_OUI_FROM_DATABASE=ARECA EMBEDDED SYSTEMS PVT LTD ++ ++OUI:70B3D5F16* ++ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos ++ + OUI:70B3D5F17* + ID_OUI_FROM_DATABASE=VITEC + ++OUI:70B3D5F18* ++ ID_OUI_FROM_DATABASE=HD Vision Systems GmbH ++ + OUI:70B3D5F19* + ID_OUI_FROM_DATABASE=Vitro Technology Corporation + + OUI:70B3D5F1A* + ID_OUI_FROM_DATABASE=Sator Controls s.r.o. + ++OUI:70B3D5F1B* ++ ID_OUI_FROM_DATABASE=RoyalShield Technologies India Private Limited ++ ++OUI:70B3D5F1C* ++ ID_OUI_FROM_DATABASE=Bavaria Digital Technik GmbH ++ + OUI:70B3D5F1D* + ID_OUI_FROM_DATABASE=Critical Link LLC + +@@ -65000,12 +78737,33 @@ OUI:70B3D5F1E* + OUI:70B3D5F1F* + ID_OUI_FROM_DATABASE=HKC Limited + ++OUI:70B3D5F21* ++ ID_OUI_FROM_DATABASE=dds ++ ++OUI:70B3D5F22* ++ ID_OUI_FROM_DATABASE=Shengli Financial Software Development ++ ++OUI:70B3D5F23* ++ ID_OUI_FROM_DATABASE=Lyse AS ++ + OUI:70B3D5F24* + ID_OUI_FROM_DATABASE=Daavlin + + OUI:70B3D5F25* + ID_OUI_FROM_DATABASE=JSC “Scientific Industrial Enterprise Rubin + ++OUI:70B3D5F26* ++ ID_OUI_FROM_DATABASE=XJ ELECTRIC CO., LTD. ++ ++OUI:70B3D5F27* ++ ID_OUI_FROM_DATABASE=NIRIT- Xinwei Telecom Technology Co., Ltd. ++ ++OUI:70B3D5F28* ++ ID_OUI_FROM_DATABASE=Yi An Electronics Co., Ltd ++ ++OUI:70B3D5F29* ++ ID_OUI_FROM_DATABASE=SamabaNova Systems ++ + OUI:70B3D5F2A* + ID_OUI_FROM_DATABASE=WIBOND Informationssysteme GmbH + +@@ -65021,9 +78779,21 @@ OUI:70B3D5F2D* + OUI:70B3D5F2E* + ID_OUI_FROM_DATABASE=Shanghai JCY Technology Company + ++OUI:70B3D5F2F* ++ ID_OUI_FROM_DATABASE=TELEPLATFORMS ++ + OUI:70B3D5F30* + ID_OUI_FROM_DATABASE=ADE Technology Inc. + ++OUI:70B3D5F31* ++ ID_OUI_FROM_DATABASE=The-Box Development ++ ++OUI:70B3D5F32* ++ ID_OUI_FROM_DATABASE=Elektronik Art ++ ++OUI:70B3D5F33* ++ ID_OUI_FROM_DATABASE=Beijing Vizum Technology Co.,Ltd. ++ + OUI:70B3D5F34* + ID_OUI_FROM_DATABASE=MacGray Services + +@@ -65042,30 +78812,84 @@ OUI:70B3D5F38* + OUI:70B3D5F39* + ID_OUI_FROM_DATABASE=Zenros ApS + ++OUI:70B3D5F3A* ++ ID_OUI_FROM_DATABASE=OOO Research and Production Center Computer Technologies ++ + OUI:70B3D5F3B* + ID_OUI_FROM_DATABASE=Epdm Pty Ltd + + OUI:70B3D5F3C* + ID_OUI_FROM_DATABASE=Gigaray + ++OUI:70B3D5F3D* ++ ID_OUI_FROM_DATABASE=KAYA Instruments ++ ++OUI:70B3D5F3E* ++ ID_OUI_FROM_DATABASE=ООО РОНЕКС ++ ++OUI:70B3D5F3F* ++ ID_OUI_FROM_DATABASE=comtac AG ++ ++OUI:70B3D5F40* ++ ID_OUI_FROM_DATABASE=HORIZON.INC ++ ++OUI:70B3D5F41* ++ ID_OUI_FROM_DATABASE=DUEVI SRL ++ + OUI:70B3D5F42* + ID_OUI_FROM_DATABASE=Matsuhisa Corporation + ++OUI:70B3D5F43* ++ ID_OUI_FROM_DATABASE=Divelbiss Corporation ++ ++OUI:70B3D5F44* ++ ID_OUI_FROM_DATABASE=Magneti Marelli S.p.A. Electronics ++ + OUI:70B3D5F45* + ID_OUI_FROM_DATABASE=Norbit ODM AS + ++OUI:70B3D5F46* ++ ID_OUI_FROM_DATABASE=Season Electronics Ltd ++ ++OUI:70B3D5F47* ++ ID_OUI_FROM_DATABASE=TXMission Ltd. ++ ++OUI:70B3D5F48* ++ ID_OUI_FROM_DATABASE=HEITEC AG ++ ++OUI:70B3D5F49* ++ ID_OUI_FROM_DATABASE=ZMBIZI APP LLC ++ ++OUI:70B3D5F4A* ++ ID_OUI_FROM_DATABASE=LACS SRL ++ ++OUI:70B3D5F4B* ++ ID_OUI_FROM_DATABASE=Chengdu Lingya Technology Co., Ltd. ++ + OUI:70B3D5F4C* +- ID_OUI_FROM_DATABASE=Global Lightning Protection Services A(S ++ ID_OUI_FROM_DATABASE=PolyTech A/S + + OUI:70B3D5F4D* + ID_OUI_FROM_DATABASE=Honeywell + ++OUI:70B3D5F4E* ++ ID_OUI_FROM_DATABASE=Hunan Lianzhong Technology Co.,Ltd. ++ + OUI:70B3D5F4F* + ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. + ++OUI:70B3D5F50* ++ ID_OUI_FROM_DATABASE=Vectology,Inc ++ ++OUI:70B3D5F51* ++ ID_OUI_FROM_DATABASE=IoT Routers Limited ++ + OUI:70B3D5F52* + ID_OUI_FROM_DATABASE=Alere Technologies AS + ++OUI:70B3D5F53* ++ ID_OUI_FROM_DATABASE=HighTechSystem Co.,Ltd. ++ + OUI:70B3D5F54* + ID_OUI_FROM_DATABASE=Revolution Retail Systems + +@@ -65081,6 +78905,9 @@ OUI:70B3D5F57* + OUI:70B3D5F58* + ID_OUI_FROM_DATABASE=CDR SRL + ++OUI:70B3D5F59* ++ ID_OUI_FROM_DATABASE=KOREA SPECTRAL PRODUCTS ++ + OUI:70B3D5F5A* + ID_OUI_FROM_DATABASE=HAMEG GmbH + +@@ -65090,12 +78917,18 @@ OUI:70B3D5F5B* + OUI:70B3D5F5C* + ID_OUI_FROM_DATABASE=Nable Communications, Inc. + ++OUI:70B3D5F5D* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC ++ + OUI:70B3D5F5E* + ID_OUI_FROM_DATABASE=Selex ES Inc. + + OUI:70B3D5F5F* + ID_OUI_FROM_DATABASE=RFRain LLC + ++OUI:70B3D5F60* ++ ID_OUI_FROM_DATABASE=MPM Micro Präzision Marx GmbH ++ + OUI:70B3D5F61* + ID_OUI_FROM_DATABASE=Power Diagnostic Service + +@@ -65105,27 +78938,57 @@ OUI:70B3D5F62* + OUI:70B3D5F63* + ID_OUI_FROM_DATABASE=Ars Products + ++OUI:70B3D5F64* ++ ID_OUI_FROM_DATABASE=silicom ++ + OUI:70B3D5F65* + ID_OUI_FROM_DATABASE=MARKUS LABS + ++OUI:70B3D5F66* ++ ID_OUI_FROM_DATABASE=Seznam.cz, a.s., CZ26168685 ++ ++OUI:70B3D5F67* ++ ID_OUI_FROM_DATABASE=winsun AG ++ + OUI:70B3D5F68* + ID_OUI_FROM_DATABASE=AL ZAJEL MODERN TELECOMM + ++OUI:70B3D5F69* ++ ID_OUI_FROM_DATABASE=Copper Labs, Inc. ++ ++OUI:70B3D5F6A* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ ++OUI:70B3D5F6B* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ ++OUI:70B3D5F6C* ++ ID_OUI_FROM_DATABASE=VisioGreen ++ + OUI:70B3D5F6D* + ID_OUI_FROM_DATABASE=Qowisio + + OUI:70B3D5F6E* + ID_OUI_FROM_DATABASE=Streambox Inc + ++OUI:70B3D5F6F* ++ ID_OUI_FROM_DATABASE=Smashtag Ltd ++ + OUI:70B3D5F70* + ID_OUI_FROM_DATABASE=Honeywell + ++OUI:70B3D5F71* ++ ID_OUI_FROM_DATABASE=Sonel S.A. ++ + OUI:70B3D5F72* + ID_OUI_FROM_DATABASE=Hanshin Electronics + + OUI:70B3D5F73* + ID_OUI_FROM_DATABASE=ASL Holdings + ++OUI:70B3D5F74* ++ ID_OUI_FROM_DATABASE=TESSA AGRITECH SRL ++ + OUI:70B3D5F75* + ID_OUI_FROM_DATABASE=Enlaps + +@@ -65147,12 +79010,27 @@ OUI:70B3D5F7A* + OUI:70B3D5F7B* + ID_OUI_FROM_DATABASE=KST technology + ++OUI:70B3D5F7C* ++ ID_OUI_FROM_DATABASE=Medicomp, Inc ++ ++OUI:70B3D5F7D* ++ ID_OUI_FROM_DATABASE=2M Technology ++ + OUI:70B3D5F7E* + ID_OUI_FROM_DATABASE=Alpha Elettronica s.r.l. + ++OUI:70B3D5F7F* ++ ID_OUI_FROM_DATABASE=ABL Space Systems ++ ++OUI:70B3D5F80* ++ ID_OUI_FROM_DATABASE=Guan Show Technologe Co., Ltd. ++ + OUI:70B3D5F81* + ID_OUI_FROM_DATABASE=Littlemore Scientific + ++OUI:70B3D5F82* ++ ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience ++ + OUI:70B3D5F83* + ID_OUI_FROM_DATABASE=Tata Communications Ltd. + +@@ -65162,9 +79040,18 @@ OUI:70B3D5F84* + OUI:70B3D5F85* + ID_OUI_FROM_DATABASE=Solystic + ++OUI:70B3D5F86* ++ ID_OUI_FROM_DATABASE=Wireless Systems Solutions LLC ++ + OUI:70B3D5F87* + ID_OUI_FROM_DATABASE=SHINWA INDUSTRIES, INC. + ++OUI:70B3D5F88* ++ ID_OUI_FROM_DATABASE=ODAWARAKIKI AUTO-MACHINE MFG.CO.,LTD ++ ++OUI:70B3D5F89* ++ ID_OUI_FROM_DATABASE=Soehnle Industrial Solutions GmbH ++ + OUI:70B3D5F8A* + ID_OUI_FROM_DATABASE=FRS GmbH & Co. KG + +@@ -65183,18 +79070,30 @@ OUI:70B3D5F8E* + OUI:70B3D5F8F* + ID_OUI_FROM_DATABASE=DIMASTEC GESTAO DE PONTO E ACESSO EIRELI-ME + ++OUI:70B3D5F90* ++ ID_OUI_FROM_DATABASE=Atman Tecnologia Ltda ++ ++OUI:70B3D5F91* ++ ID_OUI_FROM_DATABASE=Solid State Disks Ltd ++ + OUI:70B3D5F92* + ID_OUI_FROM_DATABASE=TechOne + + OUI:70B3D5F93* + ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH + ++OUI:70B3D5F94* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ + OUI:70B3D5F95* + ID_OUI_FROM_DATABASE=Get SAT + + OUI:70B3D5F96* + ID_OUI_FROM_DATABASE=Ecologicsense + ++OUI:70B3D5F97* ++ ID_OUI_FROM_DATABASE=Typhon Treatment Systems Ltd ++ + OUI:70B3D5F98* + ID_OUI_FROM_DATABASE=Metrum Sweden AB + +@@ -65204,12 +79103,21 @@ OUI:70B3D5F99* + OUI:70B3D5F9A* + ID_OUI_FROM_DATABASE=Krabbenhøft og Ingolfsson + ++OUI:70B3D5F9B* ++ ID_OUI_FROM_DATABASE=EvoLogics GmbH ++ + OUI:70B3D5F9C* + ID_OUI_FROM_DATABASE=SureFlap Ltd + ++OUI:70B3D5F9D* ++ ID_OUI_FROM_DATABASE=Teledyne API ++ + OUI:70B3D5F9E* + ID_OUI_FROM_DATABASE=International Center for Elementary Particle Physics, The University of Tokyo + ++OUI:70B3D5F9F* ++ ID_OUI_FROM_DATABASE=M.A.C. Solutions (UK) Ltd ++ + OUI:70B3D5FA0* + ID_OUI_FROM_DATABASE=TIAMA + +@@ -65225,15 +79133,30 @@ OUI:70B3D5FA3* + OUI:70B3D5FA4* + ID_OUI_FROM_DATABASE=Energybox Limited + ++OUI:70B3D5FA5* ++ ID_OUI_FROM_DATABASE=Shenzhen Hui Rui Tianyan Technology Co., Ltd. ++ + OUI:70B3D5FA6* + ID_OUI_FROM_DATABASE=RFL Electronics, Inc. + + OUI:70B3D5FA7* + ID_OUI_FROM_DATABASE=Nordson Corporation + ++OUI:70B3D5FA8* ++ ID_OUI_FROM_DATABASE=Munters ++ ++OUI:70B3D5FA9* ++ ID_OUI_FROM_DATABASE=CorDes, LLC ++ + OUI:70B3D5FAA* + ID_OUI_FROM_DATABASE=LogiM GmbH Software und Entwicklung + ++OUI:70B3D5FAB* ++ ID_OUI_FROM_DATABASE=Open System Solutions Limited ++ ++OUI:70B3D5FAC* ++ ID_OUI_FROM_DATABASE=Integrated Protein Technologies, Inc. ++ + OUI:70B3D5FAD* + ID_OUI_FROM_DATABASE=ARC Technology Solutions, LLC + +@@ -65246,9 +79169,18 @@ OUI:70B3D5FAF* + OUI:70B3D5FB0* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + ++OUI:70B3D5FB1* ++ ID_OUI_FROM_DATABASE=TOMEI TSUSHIN KOGYO CO,.LTD ++ ++OUI:70B3D5FB2* ++ ID_OUI_FROM_DATABASE=KJ3 Elektronik AB ++ + OUI:70B3D5FB3* + ID_OUI_FROM_DATABASE=3PS Inc + ++OUI:70B3D5FB4* ++ ID_OUI_FROM_DATABASE=Array Technologies Inc. ++ + OUI:70B3D5FB5* + ID_OUI_FROM_DATABASE=Orange Tree Technologies Ltd + +@@ -65258,6 +79190,12 @@ OUI:70B3D5FB6* + OUI:70B3D5FB7* + ID_OUI_FROM_DATABASE=SAICE + ++OUI:70B3D5FB8* ++ ID_OUI_FROM_DATABASE=Hyannis Port Research ++ ++OUI:70B3D5FB9* ++ ID_OUI_FROM_DATABASE=EYEDEA ++ + OUI:70B3D5FBA* + ID_OUI_FROM_DATABASE=Apogee Applied Research, Inc. + +@@ -65276,18 +79214,30 @@ OUI:70B3D5FBE* + OUI:70B3D5FBF* + ID_OUI_FROM_DATABASE=SenSys (Design Electronics Ltd) + ++OUI:70B3D5FC0* ++ ID_OUI_FROM_DATABASE=CODESYSTEM Co.,Ltd ++ + OUI:70B3D5FC1* + ID_OUI_FROM_DATABASE=InDiCor + + OUI:70B3D5FC2* + ID_OUI_FROM_DATABASE=HUNTER LIBERTY CORPORATION + ++OUI:70B3D5FC3* ++ ID_OUI_FROM_DATABASE=myUpTech AB ++ ++OUI:70B3D5FC4* ++ ID_OUI_FROM_DATABASE=AERIAL CAMERA SYSTEMS Ltd ++ + OUI:70B3D5FC5* + ID_OUI_FROM_DATABASE=Eltwin A/S + + OUI:70B3D5FC6* + ID_OUI_FROM_DATABASE=Tecnint HTE SRL + ++OUI:70B3D5FC7* ++ ID_OUI_FROM_DATABASE=Invert Robotics Ltd. ++ + OUI:70B3D5FC8* + ID_OUI_FROM_DATABASE=Moduware PTY LTD + +@@ -65297,15 +79247,24 @@ OUI:70B3D5FC9* + OUI:70B3D5FCA* + ID_OUI_FROM_DATABASE=M2M Cybernetics Pvt Ltd + ++OUI:70B3D5FCB* ++ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd ++ + OUI:70B3D5FCC* + ID_OUI_FROM_DATABASE=DIgSILENT GmbH + + OUI:70B3D5FCD* + ID_OUI_FROM_DATABASE=Engage Technologies + ++OUI:70B3D5FCE* ++ ID_OUI_FROM_DATABASE=FX TECHNOLOGY LIMITED ++ + OUI:70B3D5FCF* + ID_OUI_FROM_DATABASE=Acc+Ess Ltd + ++OUI:70B3D5FD0* ++ ID_OUI_FROM_DATABASE=Alcohol Countermeasure Systems ++ + OUI:70B3D5FD1* + ID_OUI_FROM_DATABASE=RedRat Ltd + +@@ -65315,24 +79274,48 @@ OUI:70B3D5FD2* + OUI:70B3D5FD3* + ID_OUI_FROM_DATABASE=AKIS technologies + ++OUI:70B3D5FD4* ++ ID_OUI_FROM_DATABASE=GETRALINE ++ ++OUI:70B3D5FD5* ++ ID_OUI_FROM_DATABASE=OCEANCCTV LTD ++ + OUI:70B3D5FD6* + ID_OUI_FROM_DATABASE=Visual Fan + ++OUI:70B3D5FD7* ++ ID_OUI_FROM_DATABASE=Centum Adetel Group ++ + OUI:70B3D5FD8* + ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme + ++OUI:70B3D5FD9* ++ ID_OUI_FROM_DATABASE=eSight ++ + OUI:70B3D5FDA* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + + OUI:70B3D5FDB* + ID_OUI_FROM_DATABASE=Design SHIFT + ++OUI:70B3D5FDC* ++ ID_OUI_FROM_DATABASE=Tapdn ++ ++OUI:70B3D5FDD* ++ ID_OUI_FROM_DATABASE=Laser Imagineering Vertriebs GmbH ++ + OUI:70B3D5FDE* + ID_OUI_FROM_DATABASE=AERONAUTICAL & GENERAL INSTRUMENTS LTD. + + OUI:70B3D5FDF* + ID_OUI_FROM_DATABASE=NARA CONTROLS INC. + ++OUI:70B3D5FE0* ++ ID_OUI_FROM_DATABASE=Blueprint Lab ++ ++OUI:70B3D5FE1* ++ ID_OUI_FROM_DATABASE=Shenzhen Zhiting Technology Co.,Ltd ++ + OUI:70B3D5FE2* + ID_OUI_FROM_DATABASE=Galileo Tıp Teknolojileri San. ve Tic. A.S. + +@@ -65342,6 +79325,9 @@ OUI:70B3D5FE3* + OUI:70B3D5FE4* + ID_OUI_FROM_DATABASE=CARE PVT LTD + ++OUI:70B3D5FE5* ++ ID_OUI_FROM_DATABASE=Malin Space Science System ++ + OUI:70B3D5FE6* + ID_OUI_FROM_DATABASE=SHIZUKI ELECTRIC CO.,INC + +@@ -65363,6 +79349,12 @@ OUI:70B3D5FEB* + OUI:70B3D5FEC* + ID_OUI_FROM_DATABASE=Finder SpA + ++OUI:70B3D5FED* ++ ID_OUI_FROM_DATABASE=Niron systems & Projects ++ ++OUI:70B3D5FEE* ++ ID_OUI_FROM_DATABASE=Kawasaki Robot Service,Ltd. ++ + OUI:70B3D5FEF* + ID_OUI_FROM_DATABASE=HANGZHOU HUALAN MICROELECTRONIQUE CO.,LTD + +@@ -65372,6 +79364,9 @@ OUI:70B3D5FF0* + OUI:70B3D5FF1* + ID_OUI_FROM_DATABASE=Data Strategy Limited + ++OUI:70B3D5FF2* ++ ID_OUI_FROM_DATABASE=tiga.eleven GmbH ++ + OUI:70B3D5FF3* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +@@ -65381,6 +79376,9 @@ OUI:70B3D5FF4* + OUI:70B3D5FF5* + ID_OUI_FROM_DATABASE=Prolan Process Control Co. + ++OUI:70B3D5FF6* ++ ID_OUI_FROM_DATABASE=Elektro Adrian ++ + OUI:70B3D5FF7* + ID_OUI_FROM_DATABASE=Cybercom AB + +@@ -65390,9 +79388,15 @@ OUI:70B3D5FF8* + OUI:70B3D5FF9* + ID_OUI_FROM_DATABASE=InOut Communication Systems + ++OUI:70B3D5FFA* ++ ID_OUI_FROM_DATABASE=Barracuda Measurement Solutions ++ + OUI:70B3D5FFC* + ID_OUI_FROM_DATABASE=Symetrics Industries d.b.a. Extant Aerospace + ++OUI:70B3D5FFD* ++ ID_OUI_FROM_DATABASE=i2Systems ++ + OUI:70B3D5FFE* + ID_OUI_FROM_DATABASE=Private + +@@ -65402,6 +79406,9 @@ OUI:70B3D5FFF* + OUI:70B599* + ID_OUI_FROM_DATABASE=Embedded Technologies s.r.o. + ++OUI:70B5E8* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:70B7AA* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +@@ -65411,36 +79418,72 @@ OUI:70B7E2* + OUI:70B921* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:70B950* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:70BAEF* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:70BBE9* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:70BC10* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:70BF3E* + ID_OUI_FROM_DATABASE=Charles River Laboratories + ++OUI:70BF92* ++ ID_OUI_FROM_DATABASE=GN Audio A/S ++ + OUI:70C6AC* + ID_OUI_FROM_DATABASE=Bosch Automotive Aftermarket + + OUI:70C76F* + ID_OUI_FROM_DATABASE=INNO S + ++OUI:70C7F2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:70C833* + ID_OUI_FROM_DATABASE=Wirepas Oy + + OUI:70C94E* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:70C9C6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:70CA4D* + ID_OUI_FROM_DATABASE=Shenzhen lnovance Technology Co.,Ltd. + ++OUI:70CA97* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:70CA9B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:70CD0D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:70CD60* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:70CD91* ++ ID_OUI_FROM_DATABASE=TERACOM TELEMATICA S.A ++ ++OUI:70CE8C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:70CF49* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:70D081* + ID_OUI_FROM_DATABASE=Beijing Netpower Technologies Inc. + ++OUI:70D313* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:70D379* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -65465,6 +79508,9 @@ OUI:70D923* + OUI:70D931* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:70DA17* ++ ID_OUI_FROM_DATABASE=Austrian Audio GmbH ++ + OUI:70DA9C* + ID_OUI_FROM_DATABASE=TECSEN + +@@ -65474,6 +79520,12 @@ OUI:70DB98* + OUI:70DDA1* + ID_OUI_FROM_DATABASE=Tellabs + ++OUI:70DDA8* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:70DDEF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:70DEE2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -65483,6 +79535,9 @@ OUI:70DEF9* + OUI:70DF2F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:70DFF7* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:70E027* + ID_OUI_FROM_DATABASE=HONGYU COMMUNICATION TECHNOLOGY LIMITED + +@@ -65510,6 +79565,12 @@ OUI:70E72C* + OUI:70E843* + ID_OUI_FROM_DATABASE=Beijing C&W Optical Communication Technology Co.,Ltd. + ++OUI:70EA1A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:70EA5A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:70ECE4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -65525,6 +79586,12 @@ OUI:70EF00* + OUI:70F087* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:70F088* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:70F096* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:70F11C* + ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co.,Ltd + +@@ -65549,6 +79616,12 @@ OUI:70F35A* + OUI:70F395* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:70F754* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ ++OUI:70F82B* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ + OUI:70F8E70* + ID_OUI_FROM_DATABASE=SHENZHEN Xin JiuNing Electronics Co Ltd + +@@ -65603,6 +79676,12 @@ OUI:70F96D* + OUI:70FC8C* + ID_OUI_FROM_DATABASE=OneAccess SA + ++OUI:70FC8F* ++ ID_OUI_FROM_DATABASE=FREEBOX SAS ++ ++OUI:70FD45* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:70FD46* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -65618,21 +79697,39 @@ OUI:7403BD* + OUI:74042B* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication (Wuhan) Company Limited + ++OUI:7404F0* ++ ID_OUI_FROM_DATABASE=Mobiwire Mobiles (NingBo) Co., LTD ++ + OUI:7405A5* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:7409AC* ++ ID_OUI_FROM_DATABASE=Quext, LLC ++ + OUI:740ABC* + ID_OUI_FROM_DATABASE=LightwaveRF Technology Ltd + ++OUI:740AE1* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:740CEE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:740EDB* + ID_OUI_FROM_DATABASE=Optowiz Co., Ltd + ++OUI:7412B3* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:7412BB* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + + OUI:741489* + ID_OUI_FROM_DATABASE=SRT Wireless + ++OUI:741575* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:7415E2* + ID_OUI_FROM_DATABASE=Tri-Sen Systems Corporation + +@@ -65747,6 +79844,9 @@ OUI:741F4A* + OUI:741F79* + ID_OUI_FROM_DATABASE=YOUNGKOOK ELECTRONICS CO.,LTD + ++OUI:7422BB* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:742344* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -65777,6 +79877,9 @@ OUI:742B62* + OUI:742D0A* + ID_OUI_FROM_DATABASE=Norfolk Elektronik AG + ++OUI:742EDB* ++ ID_OUI_FROM_DATABASE=Perinet GmbH ++ + OUI:742EFC* + ID_OUI_FROM_DATABASE=DirectPacket Research, Inc, + +@@ -65789,9 +79892,18 @@ OUI:743170* + OUI:743256* + ID_OUI_FROM_DATABASE=NT-ware Systemprg GmbH + ++OUI:7432C2* ++ ID_OUI_FROM_DATABASE=KYOLIS ++ + OUI:743400* + ID_OUI_FROM_DATABASE=MTG Co., Ltd. + ++OUI:7434AE* ++ ID_OUI_FROM_DATABASE=this is engineering Inc. ++ ++OUI:74366D* ++ ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. ++ + OUI:74372F* + ID_OUI_FROM_DATABASE=Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd + +@@ -65801,9 +79913,21 @@ OUI:74373B* + OUI:743889* + ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH + ++OUI:7438B7* ++ ID_OUI_FROM_DATABASE=CANON INC. ++ ++OUI:743A20* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:743A65* + ID_OUI_FROM_DATABASE=NEC Corporation + ++OUI:743AEF* ++ ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. ++ ++OUI:743C18* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:743E2B* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -65813,12 +79937,27 @@ OUI:743ECB* + OUI:7440BB* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:7440BE* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ ++OUI:74427F* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ ++OUI:74428B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:744401* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:74452D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:74458A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7445CE* ++ ID_OUI_FROM_DATABASE=CRESYN ++ + OUI:7446A0* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -65828,9 +79967,18 @@ OUI:744AA4* + OUI:744BE9* + ID_OUI_FROM_DATABASE=EXPLORER HYPERTECH CO.,LTD + ++OUI:744CA1* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ ++OUI:744D28* ++ ID_OUI_FROM_DATABASE=Routerboard.com ++ + OUI:744D79* + ID_OUI_FROM_DATABASE=Arrive Systems Inc. + ++OUI:74504E* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:7451BA* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -65849,33 +79997,102 @@ OUI:745612* + OUI:745798* + ID_OUI_FROM_DATABASE=TRUMPF Laser GmbH + Co. KG + ++OUI:7458F3* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:745909* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:745933* + ID_OUI_FROM_DATABASE=Danal Entertainment + + OUI:745AAA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:745BC50* ++ ID_OUI_FROM_DATABASE=IRS Systementwicklung GmbH ++ ++OUI:745BC51* ++ ID_OUI_FROM_DATABASE=Beijing Inspiry Technology Co., Ltd. ++ ++OUI:745BC52* ++ ID_OUI_FROM_DATABASE=SIGLENT TECHNOLOGIES CO., LTD. ++ ++OUI:745BC53* ++ ID_OUI_FROM_DATABASE=OXON AG ++ ++OUI:745BC54* ++ ID_OUI_FROM_DATABASE=uGrid Network Inc. ++ ++OUI:745BC55* ++ ID_OUI_FROM_DATABASE=SpringCard ++ ++OUI:745BC56* ++ ID_OUI_FROM_DATABASE=Yekani Manufacturing PTY Ltd ++ ++OUI:745BC57* ++ ID_OUI_FROM_DATABASE=SHENZHEN ATX TECHNOLOGY CO.,LTD ++ ++OUI:745BC58* ++ ID_OUI_FROM_DATABASE=EDOMO Systems GmbH ++ ++OUI:745BC59* ++ ID_OUI_FROM_DATABASE=Haikou Frun Flash&Mcu Microcontrol Technology Development Co.,Ltd ++ ++OUI:745BC5A* ++ ID_OUI_FROM_DATABASE=Fournie Grospaud Energie SASU ++ ++OUI:745BC5B* ++ ID_OUI_FROM_DATABASE=Smartiply Inc. ++ ++OUI:745BC5C* ++ ID_OUI_FROM_DATABASE=ComNot ++ ++OUI:745BC5D* ++ ID_OUI_FROM_DATABASE=CELYSS SAS ++ ++OUI:745BC5E* ++ ID_OUI_FROM_DATABASE=Qingdao Wintec System Co., Ltd ++ + OUI:745C4B* + ID_OUI_FROM_DATABASE=GN Audio A/S + + OUI:745C9F* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:745CFA* ++ ID_OUI_FROM_DATABASE=Shenzhen Shunrui Gaojie Technology Co., Ltd. ++ ++OUI:745D43* ++ ID_OUI_FROM_DATABASE=BSH Hausgeraete GmbH ++ ++OUI:745D68* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:745E1C* + ID_OUI_FROM_DATABASE=PIONEER CORPORATION + + OUI:745F00* + ID_OUI_FROM_DATABASE=Samsung Semiconductor Inc. + ++OUI:745F90* ++ ID_OUI_FROM_DATABASE=LAM Technologies ++ + OUI:745FAE* + ID_OUI_FROM_DATABASE=TSL PPL + ++OUI:7460FA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:74614B* + ID_OUI_FROM_DATABASE=Chongqing Huijiatong Information Technology Co., Ltd. + + OUI:7463DF* + ID_OUI_FROM_DATABASE=VTS GmbH + ++OUI:74650C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7465D1* + ID_OUI_FROM_DATABASE=Atlinks + +@@ -65924,15 +80141,27 @@ OUI:7472B0* + OUI:7472F2* + ID_OUI_FROM_DATABASE=Chipsip Technology Co., Ltd. + ++OUI:74731D* ++ ID_OUI_FROM_DATABASE=ifm electronic gmbh ++ + OUI:747336* + ID_OUI_FROM_DATABASE=MICRODIGTAL Inc + + OUI:747548* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:74765B* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co.,Ltd. ++ + OUI:747818* + ID_OUI_FROM_DATABASE=Jurumani Solutions + ++OUI:747827* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:747A90* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:747B7A* + ID_OUI_FROM_DATABASE=ETH Inc. + +@@ -65960,9 +80189,15 @@ OUI:7483C2* + OUI:7483EF* + ID_OUI_FROM_DATABASE=Arista Networks + ++OUI:7484E1* ++ ID_OUI_FROM_DATABASE=Dongguan Haoyuan Electronics Co.,Ltd ++ + OUI:74852A* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + ++OUI:7485C4* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:74860B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -65981,9 +80216,24 @@ OUI:74882A* + OUI:74888B* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + ++OUI:7488BB* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:748A0D* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:748A28* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:748A69* + ID_OUI_FROM_DATABASE=Korea Image Technology Co., Ltd + ++OUI:748B29* ++ ID_OUI_FROM_DATABASE=Micobiomed ++ ++OUI:748B34* ++ ID_OUI_FROM_DATABASE=Shanghai Smart System Technology Co., Ltd ++ + OUI:748D08* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -65991,13 +80241,19 @@ OUI:748E08* + ID_OUI_FROM_DATABASE=Bestek Corp. + + OUI:748EF8* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:748F1B* + ID_OUI_FROM_DATABASE=MasterImage 3D + ++OUI:748F3C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:748F4D* +- ID_OUI_FROM_DATABASE=MEN Mikro Elektronik GmbH ++ ID_OUI_FROM_DATABASE=duagon Germany GmbH ++ ++OUI:74901F* ++ ID_OUI_FROM_DATABASE=Ragile Networks Inc. + + OUI:749050* + ID_OUI_FROM_DATABASE=Renesas Electronics Corporation +@@ -66015,7 +80271,7 @@ OUI:74943D* + ID_OUI_FROM_DATABASE=AgJunction + + OUI:7495EC* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:749637* + ID_OUI_FROM_DATABASE=Todaair Electronic Co., Ltd +@@ -66026,21 +80282,36 @@ OUI:749781* + OUI:749975* + ID_OUI_FROM_DATABASE=IBM Corporation + ++OUI:749AC0* ++ ID_OUI_FROM_DATABASE=Cachengo, Inc. ++ ++OUI:749BE8* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:749C52* + ID_OUI_FROM_DATABASE=Huizhou Desay SV Automotive Co., Ltd. + + OUI:749CE3* + ID_OUI_FROM_DATABASE=KodaCloud Canada, Inc + ++OUI:749D79* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:749D8F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:749DDC* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:749EA5* ++ ID_OUI_FROM_DATABASE=OHSUNG ++ + OUI:749EAF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:749EF5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:74A02F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -66068,9 +80339,21 @@ OUI:74A722* + OUI:74A78E* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:74A7EA* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:74AB93* ++ ID_OUI_FROM_DATABASE=Blink by Amazon ++ + OUI:74AC5F* + ID_OUI_FROM_DATABASE=Qiku Internet Network Scientific (Shenzhen) Co., Ltd. + ++OUI:74ACB9* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ ++OUI:74AD98* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:74ADB7* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + +@@ -66086,6 +80369,15 @@ OUI:74B472* + OUI:74B57E* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:74B587* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:74B6B6* ++ ID_OUI_FROM_DATABASE=eero inc. ++ ++OUI:74B7B3* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:74B91E* + ID_OUI_FROM_DATABASE=Nanjing Bestway Automation System Co., Ltd + +@@ -66107,9 +80399,15 @@ OUI:74BFA1* + OUI:74BFB7* + ID_OUI_FROM_DATABASE=Nusoft Corporation + ++OUI:74BFC0* ++ ID_OUI_FROM_DATABASE=CANON INC. ++ + OUI:74C14F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:74C17D* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ + OUI:74C246* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -66122,6 +80420,9 @@ OUI:74C621* + OUI:74C63B* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:74C929* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:74C99A* + ID_OUI_FROM_DATABASE=Ericsson AB + +@@ -66131,6 +80432,9 @@ OUI:74C9A3* + OUI:74CA25* + ID_OUI_FROM_DATABASE=Calxeda, Inc. + ++OUI:74CBF3* ++ ID_OUI_FROM_DATABASE=Lava international limited ++ + OUI:74CC39* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -66140,6 +80444,9 @@ OUI:74CD0C* + OUI:74CE56* + ID_OUI_FROM_DATABASE=Packet Force Technology Limited Company + ++OUI:74CF00* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:74D02B* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +@@ -66149,24 +80456,42 @@ OUI:74D0DC* + OUI:74D21D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:74D285* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:74D435* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + ++OUI:74D637* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:74D654* ++ ID_OUI_FROM_DATABASE=GINT ++ + OUI:74D675* + ID_OUI_FROM_DATABASE=WYMA Tecnologia + ++OUI:74D6CB* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:74D6EA* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:74D7CA* + ID_OUI_FROM_DATABASE=Panasonic Corporation Automotive + ++OUI:74D83E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:74D850* + ID_OUI_FROM_DATABASE=Evrisko Systems + + OUI:74DA38* + ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd. + ++OUI:74DA88* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:74DADA* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -66242,6 +80567,9 @@ OUI:74E19A* + OUI:74E1B6* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:74E20C* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:74E277* + ID_OUI_FROM_DATABASE=Vizmonet Pte Ltd + +@@ -66275,6 +80603,9 @@ OUI:74E6E2* + OUI:74E7C6* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:74E9BF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:74EA3A* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -66293,9 +80624,15 @@ OUI:74EB80* + OUI:74EC42* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:74ECB2* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:74ECF1* + ID_OUI_FROM_DATABASE=Acumen + ++OUI:74EE2A* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ + OUI:74F06D* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + +@@ -66320,6 +80657,12 @@ OUI:74F661* + OUI:74F726* + ID_OUI_FROM_DATABASE=Neuron Robotics + ++OUI:74F737* ++ ID_OUI_FROM_DATABASE=KCE ++ ++OUI:74F7F6* ++ ID_OUI_FROM_DATABASE=Shanghai Sunmi Technology Co.,Ltd. ++ + OUI:74F85D* + ID_OUI_FROM_DATABASE=Berkeley Nucleonics Corp + +@@ -66374,6 +80717,9 @@ OUI:74F8DBF* + OUI:74F91A* + ID_OUI_FROM_DATABASE=Onface + ++OUI:74F9CA* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:74FDA0* + ID_OUI_FROM_DATABASE=Compupal (Group) Corporation + +@@ -66404,12 +80750,21 @@ OUI:7802F8* + OUI:780473* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:7804E3* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:780541* + ID_OUI_FROM_DATABASE=Queclink Wireless Solutions Co., Ltd + + OUI:78055F* + ID_OUI_FROM_DATABASE=Shenzhen WYC Technology Co., Ltd. + ++OUI:78058C* ++ ID_OUI_FROM_DATABASE=mMax Communications, Inc. ++ ++OUI:7806C9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:780738* + ID_OUI_FROM_DATABASE=Z.U.K. Elzab S.A. + +@@ -66422,9 +80777,18 @@ OUI:780CB8* + OUI:780CF0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:780ED1* ++ ID_OUI_FROM_DATABASE=TRUMPF Werkzeugmaschinen GmbH+Co.KG ++ + OUI:780F77* + ID_OUI_FROM_DATABASE=HangZhou Gubei Electronics Technology Co.,Ltd + ++OUI:781053* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:781100* ++ ID_OUI_FROM_DATABASE=Quantumsolution ++ + OUI:781185* + ID_OUI_FROM_DATABASE=NBS Payment Solutions Inc. + +@@ -66434,9 +80798,63 @@ OUI:7811DC* + OUI:7812B8* + ID_OUI_FROM_DATABASE=ORANTEK LIMITED + ++OUI:7813050* ++ ID_OUI_FROM_DATABASE=InnoSenT ++ ++OUI:7813051* ++ ID_OUI_FROM_DATABASE=Global Media Streaming LLC ++ ++OUI:7813052* ++ ID_OUI_FROM_DATABASE=LEAFF ENGINEERING SRL ++ ++OUI:7813053* ++ ID_OUI_FROM_DATABASE=microtec Sicherheitstechnik GmbH ++ ++OUI:7813054* ++ ID_OUI_FROM_DATABASE=Jiangxi Winsky Intelligence Technology Co., Ltd ++ ++OUI:7813055* ++ ID_OUI_FROM_DATABASE=ATS-CONVERS,LLC ++ ++OUI:7813056* ++ ID_OUI_FROM_DATABASE=CRRC Nangjing Puzhen Haitai Brake Equipment Co., LTD ++ ++OUI:7813057* ++ ID_OUI_FROM_DATABASE=Equipmentshare.com Inc ++ ++OUI:7813058* ++ ID_OUI_FROM_DATABASE=Shenzhen AV-Display Co.,Ltd ++ ++OUI:7813059* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ ++OUI:781305A* ++ ID_OUI_FROM_DATABASE=Leonardo SpA - Montevarchi ++ ++OUI:781305B* ++ ID_OUI_FROM_DATABASE=Bithouse Oy ++ ++OUI:781305C* ++ ID_OUI_FROM_DATABASE=Brigates Microelectronics Co., Ltd. ++ ++OUI:781305D* ++ ID_OUI_FROM_DATABASE=Shanghai Siminics Optoelectronic Technology Co., Ltd ++ ++OUI:781305E* ++ ID_OUI_FROM_DATABASE=Dongguan zhenxing electronic technology co.,limited ++ ++OUI:781735* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ ++OUI:7817BE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:781881* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:7818A8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:78192E* + ID_OUI_FROM_DATABASE=NASCENT Technology + +@@ -66455,6 +80873,9 @@ OUI:781DBA* + OUI:781DFD* + ID_OUI_FROM_DATABASE=Jabil Inc + ++OUI:781F11* ++ ID_OUI_FROM_DATABASE=RAB Lighting ++ + OUI:781FDB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -66464,6 +80885,9 @@ OUI:782079* + OUI:78223D* + ID_OUI_FROM_DATABASE=Affirmed Networks + ++OUI:782327* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:7823AE* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -66485,12 +80909,27 @@ OUI:7828CA* + OUI:7829ED* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + ++OUI:782A79* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ ++OUI:782B46* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:782B64* ++ ID_OUI_FROM_DATABASE=Bose Corporation ++ + OUI:782BCB* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:782C29* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:782D7E* + ID_OUI_FROM_DATABASE=TRENDnet, Inc. + ++OUI:782E56* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:782EEF* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -66515,12 +80954,24 @@ OUI:78321B* + OUI:78324F* + ID_OUI_FROM_DATABASE=Millennium Group, Inc. + ++OUI:7835A0* ++ ID_OUI_FROM_DATABASE=Zurn Industries LLC ++ ++OUI:783607* ++ ID_OUI_FROM_DATABASE=Cermate Technologies Inc. ++ + OUI:783690* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd + + OUI:7836CC* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:783716* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:783A6C* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:783A84* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -66551,18 +81002,30 @@ OUI:7844FD* + OUI:784501* + ID_OUI_FROM_DATABASE=Biamp Systems + ++OUI:784558* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ + OUI:784561* + ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. + ++OUI:7845B3* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:7845C4* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:7846C4* + ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH + ++OUI:7846D4* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:78471D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7847E3* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:784859* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -66578,6 +81041,15 @@ OUI:784B87* + OUI:784F43* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:784F9B* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:785005* ++ ID_OUI_FROM_DATABASE=MOKO TECHNOLOGY Ltd ++ ++OUI:78507C* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:78510C* + ID_OUI_FROM_DATABASE=LiveU Ltd. + +@@ -66585,16 +81057,19 @@ OUI:78521A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:78524A* +- ID_OUI_FROM_DATABASE=Ensenso GmbH ++ ID_OUI_FROM_DATABASE=Optonic GmbH + + OUI:785262* + ID_OUI_FROM_DATABASE=Shenzhen Hojy Software Co., Ltd. + ++OUI:78530D* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:785364* + ID_OUI_FROM_DATABASE=SHIFT GmbH + + OUI:7853F2* +- ID_OUI_FROM_DATABASE=ROXTON Ltd. ++ ID_OUI_FROM_DATABASE=Roxton Systems Ltd. + + OUI:78542E* + ID_OUI_FROM_DATABASE=D-Link International +@@ -66605,6 +81080,9 @@ OUI:785517* + OUI:785712* + ID_OUI_FROM_DATABASE=Mobile Integration Workgroup + ++OUI:785773* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:785860* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -66629,6 +81107,45 @@ OUI:785C72* + OUI:785DC8* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:785EA2* ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd ++ ++OUI:785EE80* ++ ID_OUI_FROM_DATABASE=Youtransactor ++ ++OUI:785EE81* ++ ID_OUI_FROM_DATABASE=RIKEN KEIKI NARA MFG. Co., Ltd. ++ ++OUI:785EE82* ++ ID_OUI_FROM_DATABASE=Vega-Absolute ++ ++OUI:785EE84* ++ ID_OUI_FROM_DATABASE=beijing Areospace Hongda optoelectronics technology co.,ltd ++ ++OUI:785EE86* ++ ID_OUI_FROM_DATABASE=Guangdong COROS Sports Technology Co., Ltd ++ ++OUI:785EE87* ++ ID_OUI_FROM_DATABASE=MT B?LG? TEKNOLOJ?LER? VE DI? T?C. A.?. ++ ++OUI:785EE88* ++ ID_OUI_FROM_DATABASE=Jiangxi guoxuan radio and television technology Co.,Ltd ++ ++OUI:785EE89* ++ ID_OUI_FROM_DATABASE=TOPDON TECHNOLOGY Co.,Ltd. ++ ++OUI:785EE8A* ++ ID_OUI_FROM_DATABASE=Yake (Tianjin) Technology Co.,Ltd. ++ ++OUI:785EE8B* ++ ID_OUI_FROM_DATABASE=Lantern Engineering (Pty) Ltd ++ ++OUI:785EE8C* ++ ID_OUI_FROM_DATABASE=FINETOOLING TECHNOLOGY(HONG KONG)CO.,LIMITED ++ ++OUI:785F36* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:785F4C* + ID_OUI_FROM_DATABASE=Argox Information Co., Ltd. + +@@ -66638,9 +81155,18 @@ OUI:78617C* + OUI:786256* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:7864C0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7864E6* + ID_OUI_FROM_DATABASE=Green Motive Technology Limited + ++OUI:78653B* ++ ID_OUI_FROM_DATABASE=Shaoxing Ourten Electronics Co., Ltd. ++ ++OUI:786559* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:7866AE* + ID_OUI_FROM_DATABASE=ZTEC Instruments, Inc. + +@@ -66650,6 +81176,12 @@ OUI:7867D7* + OUI:7868F7* + ID_OUI_FROM_DATABASE=YSTen Technology Co.,Ltd + ++OUI:7869D4* ++ ID_OUI_FROM_DATABASE=Shenyang Vibrotech Instruments Inc. ++ ++OUI:786A1F* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:786A89* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -66659,18 +81191,36 @@ OUI:786C1C* + OUI:786D94* + ID_OUI_FROM_DATABASE=Palo Alto Networks + ++OUI:786DEB* ++ ID_OUI_FROM_DATABASE=GE Lighting ++ ++OUI:787052* ++ ID_OUI_FROM_DATABASE=Welotec GmbH ++ + OUI:78719C* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:78725D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:7876D9* ++ ID_OUI_FROM_DATABASE=EXARA Group ++ ++OUI:787A6F* ++ ID_OUI_FROM_DATABASE=Juice Technology AG ++ + OUI:787B8A* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:787D48* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + ++OUI:787D53* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:787DF3* ++ ID_OUI_FROM_DATABASE=Sterlite Technologies Limited ++ + OUI:787E61* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -66686,12 +81236,21 @@ OUI:788102* + OUI:78818F* + ID_OUI_FROM_DATABASE=Server Racks Australia Pty Ltd + ++OUI:7881CE* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ + OUI:78843C* + ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:7884EE* + ID_OUI_FROM_DATABASE=INDRA ESPACIO S.A. + ++OUI:7885F4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:7886B6* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:78870D* + ID_OUI_FROM_DATABASE=Unifiedgateways India Private Limited + +@@ -66707,6 +81266,9 @@ OUI:788973* + OUI:788A20* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + ++OUI:788B2A* ++ ID_OUI_FROM_DATABASE=Zhen Shi Information Technology (Shanghai) Co., Ltd. ++ + OUI:788B77* + ID_OUI_FROM_DATABASE=Standar Telecom + +@@ -66716,12 +81278,18 @@ OUI:788C4D* + OUI:788C54* + ID_OUI_FROM_DATABASE=Ping Communication + ++OUI:788C77* ++ ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC. ++ + OUI:788DF7* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + + OUI:788E33* + ID_OUI_FROM_DATABASE=Jiangsu SEUIC Technology Co.,Ltd + ++OUI:7891E9* ++ ID_OUI_FROM_DATABASE=Raisecom Technology CO.,LTD ++ + OUI:78923E* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -66731,12 +81299,24 @@ OUI:78929C* + OUI:7894B4* + ID_OUI_FROM_DATABASE=Sercomm Corporation. + ++OUI:7894E8* ++ ID_OUI_FROM_DATABASE=Radio Bridge ++ ++OUI:7895EB* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:789682* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:789684* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:7897C3* ++ ID_OUI_FROM_DATABASE=DINGXIN INFORMATION TECHNOLOGY CO.,LTD ++ ++OUI:7898E8* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:7898FD* + ID_OUI_FROM_DATABASE=Q9 Networks Inc. + +@@ -66794,24 +81374,36 @@ OUI:78A5DD* + OUI:78A683* + ID_OUI_FROM_DATABASE=Precidata + ++OUI:78A6A0* ++ ID_OUI_FROM_DATABASE=Hangzhou Ezviz Software Co.,Ltd. ++ + OUI:78A6BD* + ID_OUI_FROM_DATABASE=DAEYEON Control&Instrument Co,.Ltd + + OUI:78A6E1* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:78A714* + ID_OUI_FROM_DATABASE=Amphenol + ++OUI:78A7EB* ++ ID_OUI_FROM_DATABASE=1MORE ++ + OUI:78A873* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:78AA82* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:78AB60* + ID_OUI_FROM_DATABASE=ABB Australia + + OUI:78ABBB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:78AC44* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:78ACBF* + ID_OUI_FROM_DATABASE=Igneous Systems + +@@ -66827,6 +81419,9 @@ OUI:78AF58* + OUI:78AFE4* + ID_OUI_FROM_DATABASE=Comau S.p.A + ++OUI:78B213* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ + OUI:78B28D* + ID_OUI_FROM_DATABASE=Beijing Tengling Technology CO.Ltd + +@@ -66836,6 +81431,12 @@ OUI:78B3B9* + OUI:78B3CE* + ID_OUI_FROM_DATABASE=Elo touch solutions + ++OUI:78B46A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:78B554* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:78B5D2* + ID_OUI_FROM_DATABASE=Ever Treasure Industrial Limited + +@@ -66849,7 +81450,10 @@ OUI:78B81A* + ID_OUI_FROM_DATABASE=INTER SALES A/S + + OUI:78B84B* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:78B8D6* ++ ID_OUI_FROM_DATABASE=Zebra Technologies Inc. + + OUI:78BAD0* + ID_OUI_FROM_DATABASE=Shinybow Technology Co. Ltd. +@@ -66857,6 +81461,9 @@ OUI:78BAD0* + OUI:78BAF9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:78BB88* ++ ID_OUI_FROM_DATABASE=Maxio Technology (Hangzhou) Ltd. ++ + OUI:78BC1A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -66891,7 +81498,7 @@ OUI:78C2C05* + ID_OUI_FROM_DATABASE=ShenZhen TuLing Robot CO.,LTD + + OUI:78C2C06* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:78C2C07* + ID_OUI_FROM_DATABASE=Guangzhou Hongcai Stage Equipment co.,ltd +@@ -66920,6 +81527,9 @@ OUI:78C2C0E* + OUI:78C2C0F* + ID_OUI_FROM_DATABASE=Private + ++OUI:78C313* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:78C3E9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -66932,9 +81542,18 @@ OUI:78C4AB* + OUI:78C5E5* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:78C5F8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:78C6BB* + ID_OUI_FROM_DATABASE=Innovasic, Inc. + ++OUI:78C881* ++ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. ++ ++OUI:78C95E* ++ ID_OUI_FROM_DATABASE=Midmark RTLS ++ + OUI:78CA04* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -66989,30 +81608,96 @@ OUI:78CA83D* + OUI:78CA83E* + ID_OUI_FROM_DATABASE=Konecranes + ++OUI:78CB2C* ++ ID_OUI_FROM_DATABASE=Join Digital, Inc. ++ + OUI:78CB33* + ID_OUI_FROM_DATABASE=DHC Software Co.,Ltd + + OUI:78CB68* + ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH + ++OUI:78CC2B* ++ ID_OUI_FROM_DATABASE=SINEWY TECHNOLOGY CO., LTD ++ + OUI:78CD8E* + ID_OUI_FROM_DATABASE=SMC Networks Inc + ++OUI:78CF2F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:78CFF9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:78D004* + ID_OUI_FROM_DATABASE=Neousys Technology Inc. + + OUI:78D129* + ID_OUI_FROM_DATABASE=Vicos + ++OUI:78D162* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:78D294* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:78D347* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ + OUI:78D34F* + ID_OUI_FROM_DATABASE=Pace-O-Matic, Inc. + + OUI:78D38D* + ID_OUI_FROM_DATABASE=HONGKONG YUNLINK TECHNOLOGY LIMITED + ++OUI:78D3ED* ++ ID_OUI_FROM_DATABASE=NORMA ++ ++OUI:78D4F10* ++ ID_OUI_FROM_DATABASE=Burisch Elektronik Bauteile GmbH ++ ++OUI:78D4F11* ++ ID_OUI_FROM_DATABASE=Cartender ++ ++OUI:78D4F12* ++ ID_OUI_FROM_DATABASE=Lyngsoe Systems ++ ++OUI:78D4F13* ++ ID_OUI_FROM_DATABASE=Ekoenergetyka - Polska S.A. ++ ++OUI:78D4F14* ++ ID_OUI_FROM_DATABASE=BYD Auto lndustry Co.,Ltd ++ ++OUI:78D4F15* ++ ID_OUI_FROM_DATABASE=Huaqin Telecom Technology Co.,Ltd. ++ ++OUI:78D4F16* ++ ID_OUI_FROM_DATABASE=Guangzhou Kingray information technology Co.,Ltd. ++ ++OUI:78D4F17* ++ ID_OUI_FROM_DATABASE=Famar Fueguina S.A. ++ ++OUI:78D4F18* ++ ID_OUI_FROM_DATABASE=Xiamen Cheerzing IOT Technology Co.,Ltd. ++ ++OUI:78D4F19* ++ ID_OUI_FROM_DATABASE=shanghai baudcom communication device co.,ltd ++ ++OUI:78D4F1A* ++ ID_OUI_FROM_DATABASE=BONENG TRANSMISSION(SUZHOU)CO.,LTD ++ ++OUI:78D4F1B* ++ ID_OUI_FROM_DATABASE=Jiangsu byzoro intelligent technology Co.,Ltd ++ ++OUI:78D4F1C* ++ ID_OUI_FROM_DATABASE=TNB ++ ++OUI:78D4F1D* ++ ID_OUI_FROM_DATABASE=Quidel Corporation ++ ++OUI:78D4F1E* ++ ID_OUI_FROM_DATABASE=Blue Sparq, Inc. ++ + OUI:78D5B5* + ID_OUI_FROM_DATABASE=NAVIELEKTRO KY + +@@ -67022,9 +81707,15 @@ OUI:78D66F* + OUI:78D6B2* + ID_OUI_FROM_DATABASE=Toshiba + ++OUI:78D6DC* ++ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. ++ + OUI:78D6F0* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + ++OUI:78D71A* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ + OUI:78D752* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -67079,18 +81770,33 @@ OUI:78D800E* + OUI:78D99F* + ID_OUI_FROM_DATABASE=NuCom HK Ltd. + ++OUI:78D9E9* ++ ID_OUI_FROM_DATABASE=MOMENTUM IOT ++ + OUI:78DA07* + ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. + + OUI:78DA6E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:78DAA2* ++ ID_OUI_FROM_DATABASE=Cynosure Technologies Co.,Ltd ++ + OUI:78DAB3* + ID_OUI_FROM_DATABASE=GBO Technology + ++OUI:78DB2F* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:78DD08* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:78DD12* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ ++OUI:78DD33* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:78DDD6* + ID_OUI_FROM_DATABASE=c-scape + +@@ -67103,9 +81809,21 @@ OUI:78DEE4* + OUI:78E103* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:78E22C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:78E2BD* ++ ID_OUI_FROM_DATABASE=Vodafone Automotive S.p.A. ++ ++OUI:78E36D* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:78E3B5* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:78E3DE* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:78E400* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -67118,6 +81836,9 @@ OUI:78E8B6* + OUI:78E980* + ID_OUI_FROM_DATABASE=RainUs Co.,Ltd + ++OUI:78E9CF* ++ ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO ++ + OUI:78EB14* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD + +@@ -67133,6 +81854,12 @@ OUI:78EC74* + OUI:78EF4C* + ID_OUI_FROM_DATABASE=Unetconvergence Co., Ltd. + ++OUI:78F09B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:78F235* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:78F29E* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +@@ -67154,11 +81881,14 @@ OUI:78F7D0* + OUI:78F882* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:78F8B8* ++ ID_OUI_FROM_DATABASE=Rako Controls Ltd ++ + OUI:78F944* + ID_OUI_FROM_DATABASE=Private + + OUI:78F9B4* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:78FC14* + ID_OUI_FROM_DATABASE=Family Zone Cyber Safety Ltd +@@ -67181,6 +81911,9 @@ OUI:78FF57* + OUI:78FFCA* + ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + ++OUI:7C004D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:7C010A* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -67196,6 +81929,9 @@ OUI:7C02BC* + OUI:7C034C* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:7C035E* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:7C03AB* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -67223,18 +81959,27 @@ OUI:7C08D9* + OUI:7C092B* + ID_OUI_FROM_DATABASE=Bekey A/S + ++OUI:7C0A3F* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:7C0A50* + ID_OUI_FROM_DATABASE=J-MEX Inc. + + OUI:7C0BC6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7C0CF6* ++ ID_OUI_FROM_DATABASE=Guangdong Huiwei High-tech Co., Ltd. ++ + OUI:7C0ECE* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:7C1015* + ID_OUI_FROM_DATABASE=Brilliant Home Technology, Inc. + ++OUI:7C10C9* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:7C11BE* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -67256,9 +82001,15 @@ OUI:7C18CD* + OUI:7C1A03* + ID_OUI_FROM_DATABASE=8Locations Co., Ltd. + ++OUI:7C1AC0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:7C1AFC* + ID_OUI_FROM_DATABASE=Dalian Co-Edifice Video Technology Co., Ltd + ++OUI:7C1B93* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:7C1C4E* + ID_OUI_FROM_DATABASE=LG Innotek + +@@ -67271,6 +82022,9 @@ OUI:7C1CF1* + OUI:7C1DD9* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:7C1E06* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:7C1E52* + ID_OUI_FROM_DATABASE=Microsoft + +@@ -67283,24 +82037,48 @@ OUI:7C2048* + OUI:7C2064* + ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD + ++OUI:7C210D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:7C210E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:7C21D8* ++ ID_OUI_FROM_DATABASE=Shenzhen Think Will Communication Technology co., LTD. ++ ++OUI:7C2302* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:7C240C* + ID_OUI_FROM_DATABASE=Telechips, Inc. + ++OUI:7C2499* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7C2586* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:7C2587* + ID_OUI_FROM_DATABASE=chaowifi.com + ++OUI:7C25DA* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:7C2634* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:7C2664* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:7C27BC* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:7C2A31* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:7C2ADB* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:7C2BE1* + ID_OUI_FROM_DATABASE=Shenzhen Ferex Electrical Co.,Ltd + +@@ -67319,6 +82097,9 @@ OUI:7C2EDD* + OUI:7C2F80* + ID_OUI_FROM_DATABASE=Gigaset Communications GmbH + ++OUI:7C310E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:7C336E* + ID_OUI_FROM_DATABASE=MEG Electronics Inc. + +@@ -67331,18 +82112,30 @@ OUI:7C3866* + OUI:7C386C* + ID_OUI_FROM_DATABASE=Real Time Logic + ++OUI:7C38AD* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:7C3920* + ID_OUI_FROM_DATABASE=SSOMA SECURITY + + OUI:7C3953* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:7C3985* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:7C3BD5* + ID_OUI_FROM_DATABASE=Imago Group + + OUI:7C3CB6* + ID_OUI_FROM_DATABASE=Shenzhen Homecare Technology Co.,Ltd. + ++OUI:7C3D2B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:7C3E74* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:7C3E9D* + ID_OUI_FROM_DATABASE=PATECH + +@@ -67395,7 +82188,7 @@ OUI:7C477CB* + ID_OUI_FROM_DATABASE=Hangzhou Yiyitaidi Information Technology Co., Ltd. + + OUI:7C477CC* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:7C477CD* + ID_OUI_FROM_DATABASE=Speedifi Inc +@@ -67403,6 +82196,9 @@ OUI:7C477CD* + OUI:7C477CE* + ID_OUI_FROM_DATABASE=I-Convergence.com + ++OUI:7C48B2* ++ ID_OUI_FROM_DATABASE=Vida Resources Lte Ltd ++ + OUI:7C49B9* + ID_OUI_FROM_DATABASE=Plexus Manufacturing Sdn Bhd + +@@ -67424,6 +82220,9 @@ OUI:7C4C58* + OUI:7C4CA5* + ID_OUI_FROM_DATABASE=BSkyB Ltd + ++OUI:7C4E09* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Wireless Technology Co.,Ltd ++ + OUI:7C4F7D* + ID_OUI_FROM_DATABASE=Sawwave + +@@ -67433,12 +82232,30 @@ OUI:7C4FB5* + OUI:7C5049* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:7C5079* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:7C50DA* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:7C5189* ++ ID_OUI_FROM_DATABASE=SG Wireless Limited ++ ++OUI:7C5259* ++ ID_OUI_FROM_DATABASE=Sichuan Jiuzhou Electronic Technology Co., Ltd. ++ + OUI:7C534A* + ID_OUI_FROM_DATABASE=Metamako + ++OUI:7C55A7* ++ ID_OUI_FROM_DATABASE=Kastle Systems ++ + OUI:7C55E7* + ID_OUI_FROM_DATABASE=YSI, Inc. + ++OUI:7C573C* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:7C574E* + ID_OUI_FROM_DATABASE=COBI GmbH + +@@ -67451,9 +82268,15 @@ OUI:7C5A67* + OUI:7C5CF8* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:7C604A* ++ ID_OUI_FROM_DATABASE=Avelon ++ + OUI:7C6097* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:7C6166* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:7C6193* + ID_OUI_FROM_DATABASE=HTC Corporation + +@@ -67463,6 +82286,9 @@ OUI:7C6456* + OUI:7C669D* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:7C66EF* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision IND.CO.,LTD ++ + OUI:7C67A2* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -67565,6 +82391,9 @@ OUI:7C70BCE* + OUI:7C70BCF* + ID_OUI_FROM_DATABASE=Private + ++OUI:7C70DB* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:7C7176* + ID_OUI_FROM_DATABASE=Wuxi iData Technology Company Ltd. + +@@ -67574,6 +82403,9 @@ OUI:7C72E4* + OUI:7C738B* + ID_OUI_FROM_DATABASE=Cocoon Alarm Ltd + ++OUI:7C73EB* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:7C7630* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + +@@ -67589,6 +82421,9 @@ OUI:7C7673* + OUI:7C787E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7C78B2* ++ ID_OUI_FROM_DATABASE=Wyze Labs Inc ++ + OUI:7C79E8* + ID_OUI_FROM_DATABASE=PayRange Inc. + +@@ -67619,6 +82454,27 @@ OUI:7C8274* + OUI:7C8306* + ID_OUI_FROM_DATABASE=Glen Dimplex Nordic as + ++OUI:7C8437* ++ ID_OUI_FROM_DATABASE=China Post Communications Equipment Co., Ltd. ++ ++OUI:7C8530* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:7C87CE* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:7C8956* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:7C89C1* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ ++OUI:7C8AE1* ++ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. ++ ++OUI:7C8BB5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:7C8BCA* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -67628,14 +82484,20 @@ OUI:7C8D91* + OUI:7C8EE4* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:7C8FDE* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ + OUI:7C9122* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7C942A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:7C94B2* + ID_OUI_FROM_DATABASE=Philips Healthcare PCCI + + OUI:7C95B1* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:7C95F3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -67646,18 +82508,30 @@ OUI:7C96D2* + OUI:7C9763* + ID_OUI_FROM_DATABASE=Openmatics s.r.o. + ++OUI:7C9A1D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7C9A54* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + + OUI:7C9A9B* + ID_OUI_FROM_DATABASE=VSE valencia smart energy + ++OUI:7C9EBD* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:7C9F07* ++ ID_OUI_FROM_DATABASE=CIG SHANGHAI CO LTD ++ + OUI:7CA15D* + ID_OUI_FROM_DATABASE=GN ReSound A/S + + OUI:7CA177* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:7CA1AE* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7CA237* + ID_OUI_FROM_DATABASE=King Slide Technology CO., LTD. + +@@ -67670,21 +82544,36 @@ OUI:7CA29B* + OUI:7CA61D* + ID_OUI_FROM_DATABASE=MHL, LLC + ++OUI:7CA7B0* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ ++OUI:7CA96B* ++ ID_OUI_FROM_DATABASE=Syrotech Networks. Ltd. ++ + OUI:7CA97D* + ID_OUI_FROM_DATABASE=Objenious + + OUI:7CAB25* + ID_OUI_FROM_DATABASE=MESMO TECHNOLOGY INC. + ++OUI:7CAB60* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7CACB2* + ID_OUI_FROM_DATABASE=Bosch Software Innovations GmbH + ++OUI:7CAD4F* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:7CAD74* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:7CB03E* + ID_OUI_FROM_DATABASE=OSRAM GmbH + ++OUI:7CB073* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:7CB0C2* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -67703,15 +82592,27 @@ OUI:7CB232* + OUI:7CB25C* + ID_OUI_FROM_DATABASE=Acacia Communications + ++OUI:7CB27D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:7CB37B* ++ ID_OUI_FROM_DATABASE=Qingdao Intelligent&Precise Electronics Co.,Ltd. ++ + OUI:7CB542* + ID_OUI_FROM_DATABASE=ACES Technology + ++OUI:7CB59B* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:7CB733* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + + OUI:7CB77B* + ID_OUI_FROM_DATABASE=Paradigm Electronics Inc + ++OUI:7CB94C* ++ ID_OUI_FROM_DATABASE=Bouffalo Lab (Nanjing) Co., Ltd. ++ + OUI:7CB960* + ID_OUI_FROM_DATABASE=Shanghai X-Cheng telecom LTD + +@@ -67746,7 +82647,7 @@ OUI:7CBACC9* + ID_OUI_FROM_DATABASE=Yongguan Electronic Technology (D.G)LTD + + OUI:7CBACCA* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:7CBACCB* + ID_OUI_FROM_DATABASE=Briowireless Inc. +@@ -67766,6 +82667,51 @@ OUI:7CBB6F* + OUI:7CBB8A* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:7CBC840* ++ ID_OUI_FROM_DATABASE=AG Neovo ++ ++OUI:7CBC841* ++ ID_OUI_FROM_DATABASE=Xiamen Mage Information Technology Co.,Ltd. ++ ++OUI:7CBC842* ++ ID_OUI_FROM_DATABASE=3S Technology Co., Ltd. ++ ++OUI:7CBC843* ++ ID_OUI_FROM_DATABASE=Shanghai Yitu Technology Co. Ltd ++ ++OUI:7CBC844* ++ ID_OUI_FROM_DATABASE=CONTINENTAL ++ ++OUI:7CBC845* ++ ID_OUI_FROM_DATABASE=Nanning auto digital technology co.,LTD ++ ++OUI:7CBC846* ++ ID_OUI_FROM_DATABASE=Société de Transport de Montréal ++ ++OUI:7CBC847* ++ ID_OUI_FROM_DATABASE=Xuji Changnan Communication Equipment Co., Ltd. ++ ++OUI:7CBC848* ++ ID_OUI_FROM_DATABASE=Shenzhen Kuang-chi Space Technology Co., Ltd. ++ ++OUI:7CBC849* ++ ID_OUI_FROM_DATABASE=HITIQ LIMITED ++ ++OUI:7CBC84A* ++ ID_OUI_FROM_DATABASE=OPNT BV ++ ++OUI:7CBC84B* ++ ID_OUI_FROM_DATABASE=Guangzhou Puppyrobot Technology Co.Ltd Beijing Branch ++ ++OUI:7CBC84C* ++ ID_OUI_FROM_DATABASE=Tibit Communications ++ ++OUI:7CBC84D* ++ ID_OUI_FROM_DATABASE=VANTAGE INTEGRATED SECURITY SOLUTIONS PVT LTD ++ ++OUI:7CBC84E* ++ ID_OUI_FROM_DATABASE=Beijing Topnew Group Co., Ltd ++ + OUI:7CBD06* + ID_OUI_FROM_DATABASE=AE REFUsol + +@@ -67775,6 +82721,21 @@ OUI:7CBF88* + OUI:7CBFB1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:7CC177* ++ ID_OUI_FROM_DATABASE=INGRAM MICRO SERVICES ++ ++OUI:7CC255* ++ ID_OUI_FROM_DATABASE=Super Micro Computer, Inc. ++ ++OUI:7CC294* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:7CC2C6* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ ++OUI:7CC385* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:7CC3A1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -67790,6 +82751,9 @@ OUI:7CC6C4* + OUI:7CC709* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + ++OUI:7CC77E* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:7CC8AB* + ID_OUI_FROM_DATABASE=Acro Associates, Inc. + +@@ -67799,6 +82763,9 @@ OUI:7CC8D0* + OUI:7CC8D7* + ID_OUI_FROM_DATABASE=Damalisk + ++OUI:7CC926* ++ ID_OUI_FROM_DATABASE=Wuhan GreeNet Information Service Co.,Ltd. ++ + OUI:7CC95A* + ID_OUI_FROM_DATABASE=Dell EMC + +@@ -67851,7 +82818,7 @@ OUI:7CCBE2E* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + + OUI:7CCC1F* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:7CCCB8* + ID_OUI_FROM_DATABASE=Intel Corporate +@@ -67871,18 +82838,36 @@ OUI:7CD1C3* + OUI:7CD30A* + ID_OUI_FROM_DATABASE=INVENTEC CORPORATION + ++OUI:7CD566* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:7CD661* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:7CD762* + ID_OUI_FROM_DATABASE=Freestyle Technology Pty Ltd + + OUI:7CD844* + ID_OUI_FROM_DATABASE=Enmotus Inc + ++OUI:7CD95C* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:7CD9A0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:7CD9F4* ++ ID_OUI_FROM_DATABASE=UAB Teltonika Telematics ++ + OUI:7CD9FE* + ID_OUI_FROM_DATABASE=New Cosmos Electric Co., Ltd. + + OUI:7CDA84* + ID_OUI_FROM_DATABASE=Dongnian Networks Inc. + ++OUI:7CDB98* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ + OUI:7CDD11* + ID_OUI_FROM_DATABASE=Chongqing MAS SCI&TECH.Co.,Ltd + +@@ -67895,6 +82880,12 @@ OUI:7CDD76* + OUI:7CDD90* + ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co., Ltd. + ++OUI:7CDDE9* ++ ID_OUI_FROM_DATABASE=ATOM tech Inc. ++ ++OUI:7CDFA1* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:7CE044* + ID_OUI_FROM_DATABASE=NEON Inc + +@@ -67931,12 +82922,18 @@ OUI:7CEBEA* + OUI:7CEC79* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:7CEC9B* ++ ID_OUI_FROM_DATABASE=Fuzhou Teraway Information Technology Co.,Ltd ++ + OUI:7CED8D* + ID_OUI_FROM_DATABASE=Microsoft + + OUI:7CEF18* + ID_OUI_FROM_DATABASE=Creative Product Design Pty. Ltd. + ++OUI:7CEF61* ++ ID_OUI_FROM_DATABASE=STR Elektronik Josef Schlechtinger GmbH ++ + OUI:7CEF8A* + ID_OUI_FROM_DATABASE=Inhon International Ltd. + +@@ -67949,24 +82946,51 @@ OUI:7CF098* + OUI:7CF0BA* + ID_OUI_FROM_DATABASE=Linkwell Telesystems Pvt Ltd + ++OUI:7CF2DD* ++ ID_OUI_FROM_DATABASE=Vence Corp ++ ++OUI:7CF31B* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:7CF429* + ID_OUI_FROM_DATABASE=NUUO Inc. + ++OUI:7CF462* ++ ID_OUI_FROM_DATABASE=BEIJING HUAWOO TECHNOLOGIES CO.LTD ++ ++OUI:7CF666* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:7CF854* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:7CF880* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:7CF90E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:7CF95C* + ID_OUI_FROM_DATABASE=U.I. Lapp GmbH + ++OUI:7CF9A0* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:7CFADF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:7CFC16* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:7CFC3C* + ID_OUI_FROM_DATABASE=Visteon Corporation + ++OUI:7CFD6B* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:7CFD82* ++ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO., LTD. ++ + OUI:7CFE28* + ID_OUI_FROM_DATABASE=Salutron Inc. + +@@ -68000,12 +83024,18 @@ OUI:80029C* + OUI:8002DF* + ID_OUI_FROM_DATABASE=ORA Inc. + ++OUI:800384* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:800588* + ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD + + OUI:8005DF* + ID_OUI_FROM_DATABASE=Montage Technology Group Limited + ++OUI:80071B* ++ ID_OUI_FROM_DATABASE=VSOLUTION TELECOMMUNICATION TECHNOLOGY CO.,LTD. ++ + OUI:8007A2* + ID_OUI_FROM_DATABASE=Esson Technology Inc. + +@@ -68042,12 +83072,18 @@ OUI:800A80F* + OUI:800B51* + ID_OUI_FROM_DATABASE=Chengdu XGimi Technology Co.,Ltd + ++OUI:800C67* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:800DD7* + ID_OUI_FROM_DATABASE=Latticework, Inc + + OUI:800E24* + ID_OUI_FROM_DATABASE=ForgetBox + ++OUI:8012DF* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:801382* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -68057,6 +83093,12 @@ OUI:801440* + OUI:8014A8* + ID_OUI_FROM_DATABASE=Guangzhou V-SOLUTION Electronic Technology Co., Ltd. + ++OUI:801605* ++ ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. ++ ++OUI:801609* ++ ID_OUI_FROM_DATABASE=Sleep Number ++ + OUI:8016B7* + ID_OUI_FROM_DATABASE=Brunel University + +@@ -68090,9 +83132,30 @@ OUI:801F12* + OUI:8020AF* + ID_OUI_FROM_DATABASE=Trade FIDES, a.s. + ++OUI:8020DA* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:8020E1* ++ ID_OUI_FROM_DATABASE=BVBA DPTechnics ++ ++OUI:8020FD* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:802275* + ID_OUI_FROM_DATABASE=Beijing Beny Wave Technology Co Ltd + ++OUI:802278* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ ++OUI:8022A7* ++ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. ++ ++OUI:80248F* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:802511* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:802689* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -68108,6 +83171,9 @@ OUI:802AFA* + OUI:802BF9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:802DBF* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:802DE1* + ID_OUI_FROM_DATABASE=Solarbridge Technologies + +@@ -68117,12 +83183,24 @@ OUI:802E14* + OUI:802FDE* + ID_OUI_FROM_DATABASE=Zurich Instruments AG + ++OUI:803049* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:8030DC* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:8030E0* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + ++OUI:8031F0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:803253* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:803428* ++ ID_OUI_FROM_DATABASE=Microchip Technology Inc. ++ + OUI:803457* + ID_OUI_FROM_DATABASE=OT Systems Limited + +@@ -68138,6 +83216,9 @@ OUI:803896* + OUI:8038BC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:8038FB* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:8038FD* + ID_OUI_FROM_DATABASE=LeapFrog Enterprises, Inc. + +@@ -68162,6 +83243,9 @@ OUI:803B9A* + OUI:803BF6* + ID_OUI_FROM_DATABASE=LOOK EASY INTERNATIONAL LIMITED + ++OUI:803E48* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:803F5D* + ID_OUI_FROM_DATABASE=Winstars Technology Ltd + +@@ -68177,18 +83261,33 @@ OUI:80414E* + OUI:80427C* + ID_OUI_FROM_DATABASE=Adolf Tedsen GmbH & Co. KG + ++OUI:8044FD* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ ++OUI:8045DD* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:804731* + ID_OUI_FROM_DATABASE=Packet Design, Inc. + ++OUI:804786* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:8048A5* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:804971* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:804A14* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:804B20* + ID_OUI_FROM_DATABASE=Ventilation Control + ++OUI:804B50* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:804E70* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -68207,6 +83306,9 @@ OUI:805067* + OUI:8050F6* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + ++OUI:80546A* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:8056F2* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -68234,9 +83336,15 @@ OUI:805E4F* + OUI:805EC0* + ID_OUI_FROM_DATABASE=YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD. + ++OUI:805FC5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:806007* + ID_OUI_FROM_DATABASE=RIM + ++OUI:8060B7* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:80615F* + ID_OUI_FROM_DATABASE=Beijing Sinead Technology Co., Ltd. + +@@ -68246,6 +83354,12 @@ OUI:80618F* + OUI:806459* + ID_OUI_FROM_DATABASE=Nimbus Inc. + ++OUI:80647A* ++ ID_OUI_FROM_DATABASE=Ola Sense Inc ++ ++OUI:806559* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:80656D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -68255,6 +83369,15 @@ OUI:8065E9* + OUI:806629* + ID_OUI_FROM_DATABASE=Prescope Technologies CO.,LTD. + ++OUI:806933* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:806940* ++ ID_OUI_FROM_DATABASE=LEXAR CO.,LIMITED ++ ++OUI:806A10* ++ ID_OUI_FROM_DATABASE=Whisker Labs - Ting ++ + OUI:806AB0* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + +@@ -68267,6 +83390,15 @@ OUI:806C8B* + OUI:806CBC* + ID_OUI_FROM_DATABASE=NET New Electronic Technology GmbH + ++OUI:806D71* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:806D97* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:806F1C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:806FB0* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -68276,15 +83408,33 @@ OUI:80711F* + OUI:80717A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:807215* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:807264* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:80739F* + ID_OUI_FROM_DATABASE=KYOCERA CORPORATION + + OUI:807459* + ID_OUI_FROM_DATABASE=K's Co.,Ltd. + ++OUI:807484* ++ ID_OUI_FROM_DATABASE=ALL Winner (Hong Kong) Limited ++ ++OUI:80751F* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:807693* + ID_OUI_FROM_DATABASE=Newag SA + ++OUI:807871* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ ++OUI:80795D* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ + OUI:8079AE* + ID_OUI_FROM_DATABASE=ShanDong Tecsunrise Co.,Ltd + +@@ -68295,7 +83445,10 @@ OUI:807ABF* + ID_OUI_FROM_DATABASE=HTC Corporation + + OUI:807B1E* +- ID_OUI_FROM_DATABASE=Corsair Components ++ ID_OUI_FROM_DATABASE=Corsair Memory, Inc. ++ ++OUI:807B3E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:807B850* + ID_OUI_FROM_DATABASE=Shiroshita Industrial Co., Ltd. +@@ -68345,27 +83498,57 @@ OUI:807B85E* + OUI:807B85F* + ID_OUI_FROM_DATABASE=Private + ++OUI:807D14* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:807D1B* + ID_OUI_FROM_DATABASE=Neosystem Co. Ltd. + ++OUI:807D3A* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:807DE3* + ID_OUI_FROM_DATABASE=Chongqing Sichuan Instrument Microcircuit Co.LTD. + ++OUI:807EB4* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ ++OUI:807FF8* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:8081A5* + ID_OUI_FROM_DATABASE=TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd + ++OUI:808223* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:808287* + ID_OUI_FROM_DATABASE=ATCOM Technology Co.Ltd. + ++OUI:8084A9* ++ ID_OUI_FROM_DATABASE=oshkosh Corporation ++ + OUI:808698* + ID_OUI_FROM_DATABASE=Netronics Technologies Inc. + ++OUI:8086D9* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:8086F2* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:808917* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:808A8B* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:808ABD* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:808AF7* ++ ID_OUI_FROM_DATABASE=Nanoleaf ++ + OUI:808B5C* + ID_OUI_FROM_DATABASE=Shenzhen Runhuicheng Technology Co., Ltd + +@@ -68375,9 +83558,18 @@ OUI:808C97* + OUI:808DB7* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + ++OUI:808F1D* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:808FE8* ++ ID_OUI_FROM_DATABASE=Intelbras ++ + OUI:80912A* + ID_OUI_FROM_DATABASE=Lih Rong electronic Enterprise Co., Ltd. + ++OUI:809133* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:8091C0* + ID_OUI_FROM_DATABASE=AgileMesh, Inc. + +@@ -68405,9 +83597,15 @@ OUI:80971B* + OUI:809B20* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:809F9B* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:809FAB* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:809FF5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:80A036* + ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd. + +@@ -68417,6 +83615,9 @@ OUI:80A1AB* + OUI:80A1D7* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd + ++OUI:80A235* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:80A589* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + +@@ -68429,6 +83630,9 @@ OUI:80A85D* + OUI:80AAA4* + ID_OUI_FROM_DATABASE=USAG + ++OUI:80AC7C* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:80ACAC* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -68441,6 +83645,9 @@ OUI:80AD67* + OUI:80B03D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:80B07B* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:80B219* + ID_OUI_FROM_DATABASE=ELEKTRON TECHNOLOGY UK LIMITED + +@@ -68459,6 +83666,9 @@ OUI:80B575* + OUI:80B624* + ID_OUI_FROM_DATABASE=IVS + ++OUI:80B655* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:80B686* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -68471,6 +83681,9 @@ OUI:80B709* + OUI:80B95C* + ID_OUI_FROM_DATABASE=ELFTECH Co., Ltd. + ++OUI:80B97A* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:80BAAC* + ID_OUI_FROM_DATABASE=TeleAdapt Ltd + +@@ -68486,6 +83699,12 @@ OUI:80BE05* + OUI:80C16E* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:80C3BA* ++ ID_OUI_FROM_DATABASE=Sennheiser electronic GmbH & Co. KG ++ ++OUI:80C501* ++ ID_OUI_FROM_DATABASE=OctoGate IT Security Systems GmbH ++ + OUI:80C548* + ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co.,Ltd + +@@ -68513,6 +83732,21 @@ OUI:80C7C5* + OUI:80C862* + ID_OUI_FROM_DATABASE=Openpeak, Inc + ++OUI:80C955* ++ ID_OUI_FROM_DATABASE=Redpine Signals, Inc. ++ ++OUI:80CA4B* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LTD ++ ++OUI:80CBBC* ++ ID_OUI_FROM_DATABASE=Qingdao Intelligent&Precise Electronics Co.,Ltd. ++ ++OUI:80CC12* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:80CC9C* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:80CE62* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -68525,9 +83759,18 @@ OUI:80CEB9* + OUI:80CF41* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + ++OUI:80CFA2* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:80D019* + ID_OUI_FROM_DATABASE=Embed, Inc + ++OUI:80D04A* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:80D065* ++ ID_OUI_FROM_DATABASE=CKS Corporation ++ + OUI:80D09B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -68540,6 +83783,12 @@ OUI:80D18B* + OUI:80D21D* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:80D2E5* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:80D336* ++ ID_OUI_FROM_DATABASE=CERN ++ + OUI:80D433* + ID_OUI_FROM_DATABASE=LzLabs GmbH + +@@ -68552,12 +83801,24 @@ OUI:80D605* + OUI:80D733* + ID_OUI_FROM_DATABASE=QSR Automations, Inc. + ++OUI:80DA13* ++ ID_OUI_FROM_DATABASE=eero inc. ++ ++OUI:80DABC* ++ ID_OUI_FROM_DATABASE=Megafone Limited ++ + OUI:80DB31* + ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd. + + OUI:80E01D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:80E1BF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:80E455* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:80E4DA0* + ID_OUI_FROM_DATABASE=Wheatstone Corporation + +@@ -68606,12 +83867,21 @@ OUI:80E4DAE* + OUI:80E4DAF* + ID_OUI_FROM_DATABASE=Private + ++OUI:80E540* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:80E650* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:80E82C* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:80E86F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:80EA07* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:80EA23* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + +@@ -68627,18 +83897,30 @@ OUI:80EB77* + OUI:80ED2C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:80EE25* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:80EE73* + ID_OUI_FROM_DATABASE=Shuttle Inc. + ++OUI:80F1F1* ++ ID_OUI_FROM_DATABASE=Tech4home, Lda ++ + OUI:80F25E* + ID_OUI_FROM_DATABASE=Kyynel + ++OUI:80F3EF* ++ ID_OUI_FROM_DATABASE=Facebook Technologies, LLC ++ + OUI:80F503* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:80F593* + ID_OUI_FROM_DATABASE=IRCO Sistemas de Telecomunicación S.A. + ++OUI:80F5B5* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:80F62E* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +@@ -68651,6 +83933,15 @@ OUI:80FA5B* + OUI:80FB06* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:80FBF0* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ ++OUI:80FBF1* ++ ID_OUI_FROM_DATABASE=Freescale Semiconductor (China) Ltd. ++ ++OUI:80FD7A* ++ ID_OUI_FROM_DATABASE=BLU Products Inc ++ + OUI:80FFA8* + ID_OUI_FROM_DATABASE=UNIDIS + +@@ -68658,17 +83949,32 @@ OUI:84002D* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + + OUI:8400D2* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:840112* ++ ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. + + OUI:8401A7* + ID_OUI_FROM_DATABASE=Greyware Automation Products, Inc + ++OUI:840283* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ ++OUI:840328* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:8404D2* + ID_OUI_FROM_DATABASE=Kirale Technologies SL + ++OUI:8406FA* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:840B2D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + ++OUI:840B7C* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:840D8E* + ID_OUI_FROM_DATABASE=Espressif Inc. + +@@ -68681,6 +83987,57 @@ OUI:84100D* + OUI:84119E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:8411C20* ++ ID_OUI_FROM_DATABASE=Kazdream Technologies LLP ++ ++OUI:8411C21* ++ ID_OUI_FROM_DATABASE=Beijing Dayu Technology Co., Ltd. ++ ++OUI:8411C22* ++ ID_OUI_FROM_DATABASE=Futurecom Systems Group ++ ++OUI:8411C23* ++ ID_OUI_FROM_DATABASE=Hitachi,Ltd. ++ ++OUI:8411C24* ++ ID_OUI_FROM_DATABASE=LLC STC MZTA ++ ++OUI:8411C25* ++ ID_OUI_FROM_DATABASE=AIBIoT GmbH ++ ++OUI:8411C26* ++ ID_OUI_FROM_DATABASE=KESSEL AG ++ ++OUI:8411C27* ++ ID_OUI_FROM_DATABASE=Ei3 Corporation ++ ++OUI:8411C28* ++ ID_OUI_FROM_DATABASE=Leybold GmbH ++ ++OUI:8411C29* ++ ID_OUI_FROM_DATABASE=C TECH BILISIM TEKNOLOJILERI SAN. VE TIC. A.S. ++ ++OUI:8411C2A* ++ ID_OUI_FROM_DATABASE=igus GmbH ++ ++OUI:8411C2B* ++ ID_OUI_FROM_DATABASE=Guangdong Creator&Flyaudio Electronic Technology Co.,LTD ++ ++OUI:8411C2C* ++ ID_OUI_FROM_DATABASE=Provision-ISR ++ ++OUI:8411C2D* ++ ID_OUI_FROM_DATABASE=Goldmund Switzerland ++ ++OUI:8411C2E* ++ ID_OUI_FROM_DATABASE=Dangerous Music Group, LLC ++ ++OUI:84139F* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:84144D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:8416F9* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -68708,9 +84065,18 @@ OUI:841B38* + OUI:841B5E* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:841B77* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:841C70* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:841E26* + ID_OUI_FROM_DATABASE=KERNEL-I Co.,LTD + ++OUI:841EA3* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:842096* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + +@@ -68720,6 +84086,12 @@ OUI:842141* + OUI:8421F1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:84225E* ++ ID_OUI_FROM_DATABASE=SHENZHEN TECHNEWCHIP TECHNOLOGY CO.,LTD. ++ ++OUI:842388* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:84248D* + ID_OUI_FROM_DATABASE=Zebra Technologies Inc + +@@ -68741,9 +84113,15 @@ OUI:842615* + OUI:84262B* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:84267A* ++ ID_OUI_FROM_DATABASE=GUANGDONG TAIDE ZHILIAN TECHNOLOGY CO.,LTD ++ + OUI:842690* + ID_OUI_FROM_DATABASE=BEIJING THOUGHT SCIENCE CO.,LTD. + ++OUI:8427B6* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:8427CE* + ID_OUI_FROM_DATABASE=Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints + +@@ -68756,6 +84134,9 @@ OUI:842914* + OUI:842999* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:842AFD* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:842B2B* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -68768,15 +84149,24 @@ OUI:842BBC* + OUI:842C80* + ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. + ++OUI:842E14* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:842E27* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:842F75* + ID_OUI_FROM_DATABASE=Innokas Group + ++OUI:843095* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision IND.CO.,LTD ++ + OUI:8430E5* + ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC + ++OUI:84326F* ++ ID_OUI_FROM_DATABASE=GUANGZHOU AVA ELECTRONICS TECHNOLOGY CO.,LTD ++ + OUI:8432EA* + ID_OUI_FROM_DATABASE=ANHUI WANZTEN P&T CO., LTD + +@@ -68786,6 +84176,9 @@ OUI:843497* + OUI:843611* + ID_OUI_FROM_DATABASE=hyungseul publishing networks + ++OUI:8437D5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:843835* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -68834,9 +84227,21 @@ OUI:8439BED* + OUI:843A4B* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:843A5B* ++ ID_OUI_FROM_DATABASE=Inventec(Chongqing) Corporation ++ ++OUI:843B10* ++ ID_OUI_FROM_DATABASE=Lv switch Inc. ++ + OUI:843DC6* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:843E79* ++ ID_OUI_FROM_DATABASE=Shenzhen Belon Technology CO.,LTD ++ ++OUI:843E92* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:843F4E* + ID_OUI_FROM_DATABASE=Tri-Tech Manufacturing, Inc. + +@@ -68849,6 +84254,15 @@ OUI:844167* + OUI:844464* + ID_OUI_FROM_DATABASE=ServerU Inc + ++OUI:8444AF* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ ++OUI:8446FE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:844709* ++ ID_OUI_FROM_DATABASE=Shenzhen IP3 Century Intelligent Technology CO.,Ltd ++ + OUI:844765* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -68873,12 +84287,18 @@ OUI:84509A* + OUI:845181* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:8454DF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:8455A5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:84569C* + ID_OUI_FROM_DATABASE=Coho Data, Inc., + ++OUI:845733* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:845787* + ID_OUI_FROM_DATABASE=DVR C&C Co., Ltd. + +@@ -68891,9 +84311,15 @@ OUI:845B12* + OUI:845C93* + ID_OUI_FROM_DATABASE=Chabrier Services + ++OUI:845CF3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:845DD7* + ID_OUI_FROM_DATABASE=Shenzhen Netcom Electronics Co.,Ltd + ++OUI:846082* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:8461A0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -68906,21 +84332,42 @@ OUI:8462A6* + OUI:8463D6* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:846569* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:84683E* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:846878* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8468C8* ++ ID_OUI_FROM_DATABASE=TOTOLINK TECHNOLOGY INT‘L LIMITED ++ ++OUI:846991* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:846A66* + ID_OUI_FROM_DATABASE=Sumitomo Kizai Co.,Ltd. + + OUI:846AED* + ID_OUI_FROM_DATABASE=Wireless Tsukamoto.,co.LTD + ++OUI:846B48* ++ ID_OUI_FROM_DATABASE=ShenZhen EepuLink Co., Ltd. ++ + OUI:846EB1* + ID_OUI_FROM_DATABASE=Park Assist LLC + ++OUI:846FCE* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:847127* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:84716A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:847207* + ID_OUI_FROM_DATABASE=I&C Technology + +@@ -68936,6 +84383,9 @@ OUI:847460* + OUI:847616* + ID_OUI_FROM_DATABASE=Addat s.r.o. + ++OUI:847637* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:847778* + ID_OUI_FROM_DATABASE=Cochlear Limited + +@@ -68954,18 +84404,30 @@ OUI:847973* + OUI:847A88* + ID_OUI_FROM_DATABASE=HTC Corporation + ++OUI:847AB6* ++ ID_OUI_FROM_DATABASE=AltoBeam (China) Inc. ++ + OUI:847BEB* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:847C9B* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ + OUI:847D50* + ID_OUI_FROM_DATABASE=Holley Metering Limited + + OUI:847E40* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:847F3D* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:84802D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:848094* ++ ID_OUI_FROM_DATABASE=Meter, Inc. ++ + OUI:8482F4* + ID_OUI_FROM_DATABASE=Beijing Huasun Unicreate Technology Co., Ltd + +@@ -68987,6 +84449,9 @@ OUI:848506* + OUI:84850A* + ID_OUI_FROM_DATABASE=Hella Sonnen- und Wetterschutztechnik GmbH + ++OUI:8485E6* ++ ID_OUI_FROM_DATABASE=Guangdong Asano Technology CO.,Ltd. ++ + OUI:8486F3* + ID_OUI_FROM_DATABASE=Greenvity Communications + +@@ -69041,6 +84506,54 @@ OUI:8489ECE* + OUI:848A8D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:848BCD0* ++ ID_OUI_FROM_DATABASE=SouXin Corporate ++ ++OUI:848BCD1* ++ ID_OUI_FROM_DATABASE=Shenzhen LTIME In-Vehicle Entertainment System Company Limited ++ ++OUI:848BCD2* ++ ID_OUI_FROM_DATABASE=CCX Technologies Inc. ++ ++OUI:848BCD3* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:848BCD4* ++ ID_OUI_FROM_DATABASE=Logic Supply ++ ++OUI:848BCD5* ++ ID_OUI_FROM_DATABASE=exodraft a/s ++ ++OUI:848BCD6* ++ ID_OUI_FROM_DATABASE=TWTG R&D B.V. ++ ++OUI:848BCD7* ++ ID_OUI_FROM_DATABASE=Smart Code (Shenzhen) Technology Co.,Ltd ++ ++OUI:848BCD8* ++ ID_OUI_FROM_DATABASE=Dunst tronic GmbH ++ ++OUI:848BCD9* ++ ID_OUI_FROM_DATABASE=NORALSY ++ ++OUI:848BCDA* ++ ID_OUI_FROM_DATABASE=Sphera Telecom ++ ++OUI:848BCDB* ++ ID_OUI_FROM_DATABASE=CHONGQING HUAYI KANGDAO TECHNOLOGY CO.,LTD. ++ ++OUI:848BCDC* ++ ID_OUI_FROM_DATABASE=WORMIT ++ ++OUI:848BCDD* ++ ID_OUI_FROM_DATABASE=ENGISAT LDA ++ ++OUI:848BCDE* ++ ID_OUI_FROM_DATABASE=Emotiv Inc ++ ++OUI:848C8D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:848D84* + ID_OUI_FROM_DATABASE=Rajant Corporation + +@@ -69054,17 +84567,20 @@ OUI:848E96* + ID_OUI_FROM_DATABASE=Embertec Pty Ltd + + OUI:848EDF* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:848F69* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:849000* +- ID_OUI_FROM_DATABASE=Arnold & Richter Cine Technik ++ ID_OUI_FROM_DATABASE=Arnold&Richter Cine Technik GmbH & Co. Betriebs KG + + OUI:84930C* + ID_OUI_FROM_DATABASE=InCoax Networks Europe AB + ++OUI:8493A0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:84948C* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +@@ -69080,18 +84596,27 @@ OUI:8497B8* + OUI:849866* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:849A40* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:849CA6* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + + OUI:849D64* + ID_OUI_FROM_DATABASE=SMC Corporation + ++OUI:849DC2* ++ ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd. ++ + OUI:849DC5* + ID_OUI_FROM_DATABASE=Centera Photonics Inc. + + OUI:849FB5* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:84A06E* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:84A134* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -69101,6 +84626,9 @@ OUI:84A1D1* + OUI:84A24D* + ID_OUI_FROM_DATABASE=Birds Eye Systems Private Limited + ++OUI:84A3B5* ++ ID_OUI_FROM_DATABASE=Propulsion systems ++ + OUI:84A423* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -69119,15 +84647,33 @@ OUI:84A788* + OUI:84A8E4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:84A938* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:84A93E* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:84A991* + ID_OUI_FROM_DATABASE=Cyber Trans Japan Co.,Ltd. + + OUI:84A9C4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:84A9EA* ++ ID_OUI_FROM_DATABASE=Career Technologies USA ++ + OUI:84AA9C* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + ++OUI:84AB1A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:84AB26* ++ ID_OUI_FROM_DATABASE=Tiinlab Corporation ++ ++OUI:84AC16* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:84ACA4* + ID_OUI_FROM_DATABASE=Beijing Novel Super Digital TV Technology Co., Ltd + +@@ -69137,6 +84683,9 @@ OUI:84ACFB* + OUI:84AD58* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:84AD8D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:84AF1F* + ID_OUI_FROM_DATABASE=Beat System Service Co,. Ltd. + +@@ -69164,9 +84713,18 @@ OUI:84B59C* + OUI:84B802* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:84B866* ++ ID_OUI_FROM_DATABASE=Beijing XiaoLu technology co. LTD ++ ++OUI:84B8B8* ++ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. ++ + OUI:84BA3B* + ID_OUI_FROM_DATABASE=CANON INC. + ++OUI:84BB69* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:84BE52* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -69182,14 +84740,23 @@ OUI:84C2E4* + OUI:84C3E8* + ID_OUI_FROM_DATABASE=Vaillant GmbH + ++OUI:84C5A6* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:84C727* + ID_OUI_FROM_DATABASE=Gnodal Ltd + ++OUI:84C78F* ++ ID_OUI_FROM_DATABASE=APS Networks GmbH ++ + OUI:84C7A9* + ID_OUI_FROM_DATABASE=C3PO S.A. + + OUI:84C7EA* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:84C807* ++ ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd. + + OUI:84C8B1* + ID_OUI_FROM_DATABASE=Incognito Software Systems Inc. +@@ -69200,24 +84767,48 @@ OUI:84C9B2* + OUI:84C9C6* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:84CC63* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:84CCA8* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:84CD62* + ID_OUI_FROM_DATABASE=ShenZhen IDWELL Technology CO.,Ltd + + OUI:84CFBF* + ID_OUI_FROM_DATABASE=Fairphone + ++OUI:84D15A* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:84D32A* + ID_OUI_FROM_DATABASE=IEEE 1905.1 + ++OUI:84D343* ++ ID_OUI_FROM_DATABASE=Calix Inc. ++ ++OUI:84D412* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ + OUI:84D47E* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:84D4C8* + ID_OUI_FROM_DATABASE=Widex A/S + ++OUI:84D608* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co., Ltd. ++ ++OUI:84D6C5* ++ ID_OUI_FROM_DATABASE=SolarEdge Technologies ++ + OUI:84D6D0* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:84D81B* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:84D931* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +@@ -69225,10 +84816,10 @@ OUI:84D9C8* + ID_OUI_FROM_DATABASE=Unipattern Co., + + OUI:84DB2F* +- ID_OUI_FROM_DATABASE=Sierra Wireless Inc ++ ID_OUI_FROM_DATABASE=Sierra Wireless + + OUI:84DB9E* +- ID_OUI_FROM_DATABASE=Aifloo AB ++ ID_OUI_FROM_DATABASE=Pink Nectarine Health AB + + OUI:84DBAC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -69305,21 +84896,45 @@ OUI:84E323* + OUI:84E327* + ID_OUI_FROM_DATABASE=TAILYN TECHNOLOGIES INC + ++OUI:84E342* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:84E4D9* + ID_OUI_FROM_DATABASE=Shenzhen NEED technology Ltd. + ++OUI:84E5D8* ++ ID_OUI_FROM_DATABASE=Guangdong UNIPOE IoT Technology Co.,Ltd. ++ + OUI:84E629* + ID_OUI_FROM_DATABASE=Bluwan SA + + OUI:84E714* + ID_OUI_FROM_DATABASE=Liang Herng Enterprise,Co.Ltd. + ++OUI:84E892* ++ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc ++ ++OUI:84E986* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:84EA97* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ + OUI:84EA99* + ID_OUI_FROM_DATABASE=Vieworks + ++OUI:84EAED* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:84EB18* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:84EB3E* ++ ID_OUI_FROM_DATABASE=Vivint Smart Home ++ ++OUI:84EBEF* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:84ED33* + ID_OUI_FROM_DATABASE=BBMC Co.,Ltd + +@@ -69329,6 +84944,9 @@ OUI:84EF18* + OUI:84F129* + ID_OUI_FROM_DATABASE=Metrascale Inc. + ++OUI:84F147* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:84F3EB* + ID_OUI_FROM_DATABASE=Espressif Inc. + +@@ -69341,12 +84959,24 @@ OUI:84F64C* + OUI:84F6FA* + ID_OUI_FROM_DATABASE=Miovision Technologies Incorporated + ++OUI:84F703* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:84F883* ++ ID_OUI_FROM_DATABASE=Luminar Technologies ++ + OUI:84FCAC* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:84FCFE* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:84FD27* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:84FDD1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:84FE9E* + ID_OUI_FROM_DATABASE=RTC Industries, Inc. + +@@ -69362,6 +84992,9 @@ OUI:8801F2* + OUI:880355* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + ++OUI:8803E9* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:88074B* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -69389,6 +85022,9 @@ OUI:88108F* + OUI:881196* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:88123D* ++ ID_OUI_FROM_DATABASE=Suzhou Aquila Solutions Inc. ++ + OUI:88124E* + ID_OUI_FROM_DATABASE=Qualcomm Inc. + +@@ -69398,6 +85034,9 @@ OUI:88142B* + OUI:881544* + ID_OUI_FROM_DATABASE=Cisco Meraki + ++OUI:8815C5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:8817A3* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + +@@ -69410,6 +85049,9 @@ OUI:881908* + OUI:881B99* + ID_OUI_FROM_DATABASE=SHENZHEN XIN FEI JIA ELECTRONIC CO. LTD. + ++OUI:881C95* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:881DFC* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -69425,6 +85067,9 @@ OUI:8821E3* + OUI:882364* + ID_OUI_FROM_DATABASE=Watchnet DVR Inc + ++OUI:88238C* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:8823FE* + ID_OUI_FROM_DATABASE=TTTech Computertechnik AG + +@@ -69437,9 +85082,21 @@ OUI:882593* + OUI:8828B3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:882949* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:882950* + ID_OUI_FROM_DATABASE=Netmoon Technology Co., Ltd + ++OUI:88299C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:882A5E* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:882B94* ++ ID_OUI_FROM_DATABASE=MADOKA SYSTEM Co.,Ltd. ++ + OUI:882BD7* + ID_OUI_FROM_DATABASE=ADDÉNERGIE TECHNOLOGIES + +@@ -69479,6 +85136,12 @@ OUI:88365F* + OUI:88366C* + ID_OUI_FROM_DATABASE=EFM Networks + ++OUI:8836CF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:883A30* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:883B8B* + ID_OUI_FROM_DATABASE=Cheering Connection Co. Ltd. + +@@ -69497,6 +85160,15 @@ OUI:883F99* + OUI:883FD3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:884033* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:88403B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:884067* ++ ID_OUI_FROM_DATABASE=infomark ++ + OUI:884157* + ID_OUI_FROM_DATABASE=Shenzhen Atsmart Technology Co.,Ltd. + +@@ -69515,9 +85187,18 @@ OUI:884477* + OUI:8844F6* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:884604* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:88462A* + ID_OUI_FROM_DATABASE=Telechips Inc. + ++OUI:884A18* ++ ID_OUI_FROM_DATABASE=Opulinks ++ ++OUI:884A70* ++ ID_OUI_FROM_DATABASE=Wacom Co.,Ltd. ++ + OUI:884AEA* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -69530,6 +85211,12 @@ OUI:884CCF* + OUI:8850DD* + ID_OUI_FROM_DATABASE=Infiniband Trade Association + ++OUI:8850F6* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ ++OUI:88517A* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:8851FB* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -69542,17 +85229,29 @@ OUI:885395* + OUI:8853D4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:88541F* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:88571D* ++ ID_OUI_FROM_DATABASE=Seongji Industry Company ++ + OUI:88576D* + ID_OUI_FROM_DATABASE=XTA Electronics Ltd + + OUI:8857EE* + ID_OUI_FROM_DATABASE=BUFFALO.INC + ++OUI:885A06* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:885A85* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:885A92* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:885BDD* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:885C47* + ID_OUI_FROM_DATABASE=Alcatel Lucent +@@ -69659,9 +85358,15 @@ OUI:88615A* + OUI:8863DF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:886440* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:886639* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:88665A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:8866A5* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -69686,6 +85391,9 @@ OUI:886B6E* + OUI:886B76* + ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD + ++OUI:886FD4* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:887033* + ID_OUI_FROM_DATABASE=Hangzhou Silan Microelectronic Inc + +@@ -69695,6 +85403,9 @@ OUI:88708C* + OUI:8870EF* + ID_OUI_FROM_DATABASE=SC Professional Trading Co., Ltd. + ++OUI:8871B1* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:8871E5* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -69725,6 +85436,9 @@ OUI:88797E* + OUI:887A31* + ID_OUI_FROM_DATABASE=Velankani Electronics Pvt. Ltd. + ++OUI:887E25* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:887F03* + ID_OUI_FROM_DATABASE=Comper Technology Investment Limited + +@@ -69755,6 +85469,9 @@ OUI:8887DD* + OUI:888914* + ID_OUI_FROM_DATABASE=All Components Incorporated + ++OUI:88892F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:888964* + ID_OUI_FROM_DATABASE=GSI Electronics Inc. + +@@ -69764,6 +85481,15 @@ OUI:888B5D* + OUI:888C19* + ID_OUI_FROM_DATABASE=Brady Corp Asia Pacific Ltd + ++OUI:888E68* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:888E7F* ++ ID_OUI_FROM_DATABASE=ATOP CORPORATION ++ ++OUI:889009* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:88908D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -69774,11 +85500,14 @@ OUI:8891DD* + ID_OUI_FROM_DATABASE=Racktivity + + OUI:889471* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:88947E* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:88948F* ++ ID_OUI_FROM_DATABASE=Xi'an Zhisensor Technologies Co.,Ltd ++ + OUI:8894F9* + ID_OUI_FROM_DATABASE=Gemicom Technology, Inc. + +@@ -69788,6 +85517,9 @@ OUI:8895B9* + OUI:88964E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:889655* ++ ID_OUI_FROM_DATABASE=Zitte corporation ++ + OUI:889676* + ID_OUI_FROM_DATABASE=TTC MARCONI s.r.o. + +@@ -69797,6 +85529,9 @@ OUI:8896B6* + OUI:8896F2* + ID_OUI_FROM_DATABASE=Valeo Schalter und Sensoren GmbH + ++OUI:889746* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:889765* + ID_OUI_FROM_DATABASE=exands + +@@ -69812,24 +85547,45 @@ OUI:889B39* + OUI:889CA6* + ID_OUI_FROM_DATABASE=BTB Korea INC + ++OUI:889D98* ++ ID_OUI_FROM_DATABASE=Allied-telesisK.K. ++ ++OUI:889E33* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ ++OUI:889E68* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:889F6F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:889FAA* ++ ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH ++ + OUI:889FFA* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:88A084* + ID_OUI_FROM_DATABASE=Formation Data Systems + ++OUI:88A0BE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:88A25E* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:88A2D7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:88A303* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:88A3CC* + ID_OUI_FROM_DATABASE=Amatis Controls + ++OUI:88A479* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:88A5BD* + ID_OUI_FROM_DATABASE=QPCOM INC. + +@@ -69884,6 +85640,15 @@ OUI:88A9A7D* + OUI:88A9A7E* + ID_OUI_FROM_DATABASE=Impact Distribution + ++OUI:88A9B7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:88AC9E* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ ++OUI:88ACC0* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:88ACC1* + ID_OUI_FROM_DATABASE=Generiton Co., Ltd. + +@@ -69899,6 +85664,9 @@ OUI:88AE07* + OUI:88AE1D* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:88AEDD* ++ ID_OUI_FROM_DATABASE=EliteGroup Computer Systems Co., LTD ++ + OUI:88B111* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -69908,8 +85676,14 @@ OUI:88B168* + OUI:88B1E1* + ID_OUI_FROM_DATABASE=Mojo Networks, Inc. + ++OUI:88B291* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:88B362* +- ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co. Ltd.) ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ ++OUI:88B436* ++ ID_OUI_FROM_DATABASE=Private + + OUI:88B4A6* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company +@@ -69926,9 +85700,15 @@ OUI:88B6EE* + OUI:88B8D0* + ID_OUI_FROM_DATABASE=Dongguan Koppo Electronic Co.,Ltd + ++OUI:88B945* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:88BA7F* + ID_OUI_FROM_DATABASE=Qfiednet Co., Ltd. + ++OUI:88BCC1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:88BD45* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -69941,6 +85721,9 @@ OUI:88BFD5* + OUI:88BFE4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:88C08B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:88C242* + ID_OUI_FROM_DATABASE=Poynt Co. + +@@ -69950,15 +85733,66 @@ OUI:88C255* + OUI:88C36E* + ID_OUI_FROM_DATABASE=Beijing Ereneben lnformation Technology Limited + ++OUI:88C397* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:88C3B3* + ID_OUI_FROM_DATABASE=SOVICO + ++OUI:88C3E5* ++ ID_OUI_FROM_DATABASE=Betop Techonologies ++ + OUI:88C626* + ID_OUI_FROM_DATABASE=Logitech, Inc + + OUI:88C663* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:88C9B30* ++ ID_OUI_FROM_DATABASE=ADOPT NETTECH PVT LTD ++ ++OUI:88C9B31* ++ ID_OUI_FROM_DATABASE=Cervoz Technology Co; Ltd. ++ ++OUI:88C9B32* ++ ID_OUI_FROM_DATABASE=shenzhen franklin ESS technology CO.,Ltd ++ ++OUI:88C9B33* ++ ID_OUI_FROM_DATABASE=Fortive Setra-ICG(Tianjin)Co.,Ltd ++ ++OUI:88C9B34* ++ ID_OUI_FROM_DATABASE=Hasbro Inc ++ ++OUI:88C9B35* ++ ID_OUI_FROM_DATABASE=Brabender Technologie GmbH & Co, KG ++ ++OUI:88C9B36* ++ ID_OUI_FROM_DATABASE=Hugo Techno ++ ++OUI:88C9B37* ++ ID_OUI_FROM_DATABASE=Robert Bosch JuP1 ++ ++OUI:88C9B38* ++ ID_OUI_FROM_DATABASE=Divelbiss Corporation ++ ++OUI:88C9B39* ++ ID_OUI_FROM_DATABASE=Richbeam (Beijing) Technology Co., Ltd. ++ ++OUI:88C9B3A* ++ ID_OUI_FROM_DATABASE=Gefran Drive & Motion srl ++ ++OUI:88C9B3B* ++ ID_OUI_FROM_DATABASE=Shenzhen MMUI Co.,Ltd ++ ++OUI:88C9B3C* ++ ID_OUI_FROM_DATABASE=Shenzhen Viewsmart Technology Co.,Ltd ++ ++OUI:88C9B3D* ++ ID_OUI_FROM_DATABASE=Origins Technology Limited ++ ++OUI:88C9B3E* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:88C9D0* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -69983,6 +85817,12 @@ OUI:88D039* + OUI:88D171* + ID_OUI_FROM_DATABASE=BEGHELLI S.P.A + ++OUI:88D199* ++ ID_OUI_FROM_DATABASE=Vencer Co., Ltd. ++ ++OUI:88D211* ++ ID_OUI_FROM_DATABASE=Eko Devices, Inc. ++ + OUI:88D274* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -69995,6 +85835,9 @@ OUI:88D37B* + OUI:88D50C* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:88D5A8* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:88D652* + ID_OUI_FROM_DATABASE=AMERGINT Technologies + +@@ -70007,9 +85850,15 @@ OUI:88D7F6* + OUI:88D962* + ID_OUI_FROM_DATABASE=Canopus Systems US LLC + ++OUI:88D98F* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:88DA1A* + ID_OUI_FROM_DATABASE=Redpine Signals, Inc. + ++OUI:88DA33* ++ ID_OUI_FROM_DATABASE=Beijing Xiaoyuer Network Technology Co., Ltd ++ + OUI:88DC96* + ID_OUI_FROM_DATABASE=SENAO Networks, Inc. + +@@ -70025,6 +85874,12 @@ OUI:88DEA9* + OUI:88DF9E* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + ++OUI:88E034* ++ ID_OUI_FROM_DATABASE=Shinwa industries(China) ltd. ++ ++OUI:88E056* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:88E0A0* + ID_OUI_FROM_DATABASE=Shenzhen VisionSTOR Technologies Co., Ltd + +@@ -70043,6 +85898,9 @@ OUI:88E603* + OUI:88E628* + ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co.,Ltd + ++OUI:88E64B* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:88E712* + ID_OUI_FROM_DATABASE=Whirlpool Corporation + +@@ -70061,12 +85919,18 @@ OUI:88E90F* + OUI:88E917* + ID_OUI_FROM_DATABASE=Tamaggo + ++OUI:88E9A4* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:88E9FE* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:88ED1C* + ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd. + ++OUI:88EF16* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:88F031* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -70079,12 +85943,21 @@ OUI:88F488* + OUI:88F490* + ID_OUI_FROM_DATABASE=Jetmobile Pte Ltd + ++OUI:88F56E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:88F7BF* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:88F7C7* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:88F872* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:88FCA6* ++ ID_OUI_FROM_DATABASE=devolo AG ++ + OUI:88FD15* + ID_OUI_FROM_DATABASE=LINEEYE CO., LTD + +@@ -70094,6 +85967,12 @@ OUI:88FED6* + OUI:8C006D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8C02FA* ++ ID_OUI_FROM_DATABASE=COMMANDO Networks Limited ++ ++OUI:8C04BA* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:8C04FF* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + +@@ -70109,6 +85988,9 @@ OUI:8C088B* + OUI:8C09F4* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:8C0C87* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:8C0C90* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -70118,6 +86000,9 @@ OUI:8C0CA3* + OUI:8C0D76* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:8C0E60* ++ ID_OUI_FROM_DATABASE=Nanjing Juplink Intelligent Technologies Co., Ltd. ++ + OUI:8C0EE3* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + +@@ -70127,6 +86012,15 @@ OUI:8C0F6F* + OUI:8C0F83* + ID_OUI_FROM_DATABASE=Angie Hospitality LLC + ++OUI:8C0FA0* ++ ID_OUI_FROM_DATABASE=di-soric GmbH & Co. KG ++ ++OUI:8C0FC9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:8C0FFA* ++ ID_OUI_FROM_DATABASE=Hutec co.,ltd ++ + OUI:8C10D4* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -70187,6 +86081,9 @@ OUI:8C15C7* + OUI:8C1645* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd + ++OUI:8C1850* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ + OUI:8C18D9* + ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co., Ltd + +@@ -70235,6 +86132,9 @@ OUI:8C192DD* + OUI:8C192DE* + ID_OUI_FROM_DATABASE=Elcon AB + ++OUI:8C19B5* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:8C1ABF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -70283,6 +86183,411 @@ OUI:8C1CDAD* + OUI:8C1CDAE* + ID_OUI_FROM_DATABASE=Electronic Controlled Systems, Inc. + ++OUI:8C1D96* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:8C1ED9* ++ ID_OUI_FROM_DATABASE=Beijing Unigroup Tsingteng Microsystem Co., LTD. ++ ++OUI:8C1F64000* ++ ID_OUI_FROM_DATABASE=Suzhou Xingxiangyi Precision Manufacturing Co.,Ltd. ++ ++OUI:8C1F640A8* ++ ID_OUI_FROM_DATABASE=SamabaNova Systems ++ ++OUI:8C1F640E0* ++ ID_OUI_FROM_DATABASE=Autopharma ++ ++OUI:8C1F64101* ++ ID_OUI_FROM_DATABASE=ASW-ATI Srl ++ ++OUI:8C1F6410F* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ ++OUI:8C1F64128* ++ ID_OUI_FROM_DATABASE=YULISTA INTEGRATED SOLUTION ++ ++OUI:8C1F64135* ++ ID_OUI_FROM_DATABASE=Yuval Fichman ++ ++OUI:8C1F64144* ++ ID_OUI_FROM_DATABASE=Langfang ENN lntelligent Technology Co.,Ltd. ++ ++OUI:8C1F64151* ++ ID_OUI_FROM_DATABASE=Gogo Business Aviation ++ ++OUI:8C1F64166* ++ ID_OUI_FROM_DATABASE=Hikari Alphax Inc. ++ ++OUI:8C1F64193* ++ ID_OUI_FROM_DATABASE=Sicon srl ++ ++OUI:8C1F6419C* ++ ID_OUI_FROM_DATABASE=Aton srl ++ ++OUI:8C1F641B6* ++ ID_OUI_FROM_DATABASE=Red Sensors Limited ++ ++OUI:8C1F641E3* ++ ID_OUI_FROM_DATABASE=WBNet ++ ++OUI:8C1F64204* ++ ID_OUI_FROM_DATABASE=castcore ++ ++OUI:8C1F64219* ++ ID_OUI_FROM_DATABASE=Guangzhou Desam Audio Co.,Ltd ++ ++OUI:8C1F6421C* ++ ID_OUI_FROM_DATABASE=LLC EMS-Expert ++ ++OUI:8C1F64242* ++ ID_OUI_FROM_DATABASE=GIORDANO CONTROLS SPA ++ ++OUI:8C1F6425E* ++ ID_OUI_FROM_DATABASE=R2Sonic, LLC ++ ++OUI:8C1F64264* ++ ID_OUI_FROM_DATABASE=BR. Voss Ingenjörsfirma AB ++ ++OUI:8C1F64270* ++ ID_OUI_FROM_DATABASE=Xi‘an Hangguang Satellite and Control Technology Co.,Ltd ++ ++OUI:8C1F6428A* ++ ID_OUI_FROM_DATABASE=Arcopie ++ ++OUI:8C1F64296* ++ ID_OUI_FROM_DATABASE=Roog zhi tong Technology(Beijing) Co.,Ltd ++ ++OUI:8C1F6429F* ++ ID_OUI_FROM_DATABASE=NAGTECH LLC ++ ++OUI:8C1F642A5* ++ ID_OUI_FROM_DATABASE=Nonet Inc ++ ++OUI:8C1F642C8* ++ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos ++ ++OUI:8C1F642E8* ++ ID_OUI_FROM_DATABASE=Sonora Network Solutions ++ ++OUI:8C1F642EF* ++ ID_OUI_FROM_DATABASE=Invisense AB ++ ++OUI:8C1F642F5* ++ ID_OUI_FROM_DATABASE=Florida R&D Associates LLC ++ ++OUI:8C1F64304* ++ ID_OUI_FROM_DATABASE=Jemac Sweden AB ++ ++OUI:8C1F64330* ++ ID_OUI_FROM_DATABASE=Vision Systems Safety Tech ++ ++OUI:8C1F64370* ++ ID_OUI_FROM_DATABASE=WOLF Advanced Technology ++ ++OUI:8C1F64372* ++ ID_OUI_FROM_DATABASE=WINK Streaming ++ ++OUI:8C1F64391* ++ ID_OUI_FROM_DATABASE=CPC (UK) ++ ++OUI:8C1F64397* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:8C1F643A4* ++ ID_OUI_FROM_DATABASE=QLM Technology Ltd ++ ++OUI:8C1F643AD* ++ ID_OUI_FROM_DATABASE=TowerIQ ++ ++OUI:8C1F643B5* ++ ID_OUI_FROM_DATABASE=SVMS ++ ++OUI:8C1F643C4* ++ ID_OUI_FROM_DATABASE=NavSys Technology Inc. ++ ++OUI:8C1F643E0* ++ ID_OUI_FROM_DATABASE=YPP Corporation ++ ++OUI:8C1F643E8* ++ ID_OUI_FROM_DATABASE=Ruichuangte ++ ++OUI:8C1F64414* ++ ID_OUI_FROM_DATABASE=INSEVIS GmbH ++ ++OUI:8C1F6442B* ++ ID_OUI_FROM_DATABASE=Gamber Johnson-LLC ++ ++OUI:8C1F64438* ++ ID_OUI_FROM_DATABASE=Integer.pl S.A. ++ ++OUI:8C1F64445* ++ ID_OUI_FROM_DATABASE=Figment Design Laboratories ++ ++OUI:8C1F64460* ++ ID_OUI_FROM_DATABASE=Solace Systems Inc. ++ ++OUI:8C1F64466* ++ ID_OUI_FROM_DATABASE=Intamsys Technology Co.Ltd ++ ++OUI:8C1F64493* ++ ID_OUI_FROM_DATABASE=Security Products International, LLC ++ ++OUI:8C1F644B0* ++ ID_OUI_FROM_DATABASE=U -MEI-DAH INT'L ENTERPRISE CO.,LTD. ++ ++OUI:8C1F644C7* ++ ID_OUI_FROM_DATABASE=SBS SpA ++ ++OUI:8C1F644DD* ++ ID_OUI_FROM_DATABASE=Griffyn Robotech Private Limited ++ ++OUI:8C1F644FA* ++ ID_OUI_FROM_DATABASE=Sanskruti ++ ++OUI:8C1F6453D* ++ ID_OUI_FROM_DATABASE=NEXCONTECH ++ ++OUI:8C1F64542* ++ ID_OUI_FROM_DATABASE=Landis+Gyr Equipamentos de Medição Ltda ++ ++OUI:8C1F64549* ++ ID_OUI_FROM_DATABASE=Brad Technology ++ ++OUI:8C1F64572* ++ ID_OUI_FROM_DATABASE=ZMBIZI APP LLC ++ ++OUI:8C1F64575* ++ ID_OUI_FROM_DATABASE=Yu-Heng Electric Co., LTD ++ ++OUI:8C1F645D3* ++ ID_OUI_FROM_DATABASE=Eloy Water ++ ++OUI:8C1F6460E* ++ ID_OUI_FROM_DATABASE=ICT International ++ ++OUI:8C1F64611* ++ ID_OUI_FROM_DATABASE=Siemens Industry Software Inc. ++ ++OUI:8C1F646AE* ++ ID_OUI_FROM_DATABASE=Bray International ++ ++OUI:8C1F64712* ++ ID_OUI_FROM_DATABASE=Nexion Data Systems P/L ++ ++OUI:8C1F64726* ++ ID_OUI_FROM_DATABASE=DAVE SRL ++ ++OUI:8C1F6472C* ++ ID_OUI_FROM_DATABASE=Antai technology Co.,Ltd ++ ++OUI:8C1F6473D* ++ ID_OUI_FROM_DATABASE=NewAgeMicro ++ ++OUI:8C1F6473F* ++ ID_OUI_FROM_DATABASE=UBISCALE ++ ++OUI:8C1F64768* ++ ID_OUI_FROM_DATABASE=mapna group ++ ++OUI:8C1F6479D* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ ++OUI:8C1F6479E* ++ ID_OUI_FROM_DATABASE=Accemic Technologies GmbH ++ ++OUI:8C1F647A6* ++ ID_OUI_FROM_DATABASE=OTMetric ++ ++OUI:8C1F647C8* ++ ID_OUI_FROM_DATABASE=Jacquet Dechaume ++ ++OUI:8C1F647D6* ++ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl ++ ++OUI:8C1F647F1* ++ ID_OUI_FROM_DATABASE=AEM Singapore Pte Ltd ++ ++OUI:8C1F64801* ++ ID_OUI_FROM_DATABASE=Zhejiang Laolan Information Technology Co., Ltd ++ ++OUI:8C1F6483A* ++ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG ++ ++OUI:8C1F6483C* ++ ID_OUI_FROM_DATABASE=Xtend Technologies Pvt Ltd ++ ++OUI:8C1F64856* ++ ID_OUI_FROM_DATABASE=Garten Automation ++ ++OUI:8C1F64878* ++ ID_OUI_FROM_DATABASE=Green Access Ltd ++ ++OUI:8C1F648C2* ++ ID_OUI_FROM_DATABASE=Cirrus Systems, Inc. ++ ++OUI:8C1F64903* ++ ID_OUI_FROM_DATABASE=Portrait Displays, Inc. ++ ++OUI:8C1F6490E* ++ ID_OUI_FROM_DATABASE=Xacti Corporation ++ ++OUI:8C1F64918* ++ ID_OUI_FROM_DATABASE=Abbott Diagnostics Technologies AS ++ ++OUI:8C1F64947* ++ ID_OUI_FROM_DATABASE=LLC TC Vympel ++ ++OUI:8C1F6495A* ++ ID_OUI_FROM_DATABASE=Shenzhen Longyun Lighting Electric Appliances Co., Ltd ++ ++OUI:8C1F64984* ++ ID_OUI_FROM_DATABASE=Abacus Peripherals Pvt Ltd ++ ++OUI:8C1F64991* ++ ID_OUI_FROM_DATABASE=DB Systel GmbH ++ ++OUI:8C1F64998* ++ ID_OUI_FROM_DATABASE=EVLO Stockage Énergie ++ ++OUI:8C1F649C1* ++ ID_OUI_FROM_DATABASE=RealWear ++ ++OUI:8C1F649CF* ++ ID_OUI_FROM_DATABASE=ASAP Electronics GmbH ++ ++OUI:8C1F649FD* ++ ID_OUI_FROM_DATABASE=Vishay Nobel AB ++ ++OUI:8C1F64A29* ++ ID_OUI_FROM_DATABASE=Ringtail Security ++ ++OUI:8C1F64A4E* ++ ID_OUI_FROM_DATABASE=Syscom Instruments SA ++ ++OUI:8C1F64A57* ++ ID_OUI_FROM_DATABASE=EkspertStroyProekt ++ ++OUI:8C1F64A5C* ++ ID_OUI_FROM_DATABASE=Prosys ++ ++OUI:8C1F64AA4* ++ ID_OUI_FROM_DATABASE=HEINEN ELEKTRONIK GmbH ++ ++OUI:8C1F64AAB* ++ ID_OUI_FROM_DATABASE=BlueSword Intelligent Technology Co., Ltd. ++ ++OUI:8C1F64AB5* ++ ID_OUI_FROM_DATABASE=JUSTMORPH PTE. LTD. ++ ++OUI:8C1F64ACE* ++ ID_OUI_FROM_DATABASE=Rayhaan Networks ++ ++OUI:8C1F64AE1* ++ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd ++ ++OUI:8C1F64AED* ++ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme ++ ++OUI:8C1F64AF7* ++ ID_OUI_FROM_DATABASE=ard sa ++ ++OUI:8C1F64B03* ++ ID_OUI_FROM_DATABASE=Shenzhen Pisoftware Technology Co.,Ltd. ++ ++OUI:8C1F64B64* ++ ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH ++ ++OUI:8C1F64B9A* ++ ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. ++ ++OUI:8C1F64BA3* ++ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH ++ ++OUI:8C1F64BC0* ++ ID_OUI_FROM_DATABASE=GS Elektromedizinsiche Geräte G. Stemple GmbH ++ ++OUI:8C1F64C03* ++ ID_OUI_FROM_DATABASE=Abiman Engineering ++ ++OUI:8C1F64C1F* ++ ID_OUI_FROM_DATABASE=Esys Srl ++ ++OUI:8C1F64C2F* ++ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L. ++ ++OUI:8C1F64C41* ++ ID_OUI_FROM_DATABASE=Katronic AG & Co. KG ++ ++OUI:8C1F64C50* ++ ID_OUI_FROM_DATABASE=Spacee ++ ++OUI:8C1F64CE3* ++ ID_OUI_FROM_DATABASE=Pixel Design & Manufacturing Sdn. Bhd. ++ ++OUI:8C1F64CF1* ++ ID_OUI_FROM_DATABASE=ROBOfiber, Inc. ++ ++OUI:8C1F64CF3* ++ ID_OUI_FROM_DATABASE=ABB S.p.A. ++ ++OUI:8C1F64D29* ++ ID_OUI_FROM_DATABASE=Secure Bits ++ ++OUI:8C1F64D3C* ++ ID_OUI_FROM_DATABASE=KIB Energo LLC ++ ++OUI:8C1F64D4A* ++ ID_OUI_FROM_DATABASE=Caproc Oy ++ ++OUI:8C1F64D54* ++ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. ++ ++OUI:8C1F64D7E* ++ ID_OUI_FROM_DATABASE=Thales Belgium ++ ++OUI:8C1F64DBD* ++ ID_OUI_FROM_DATABASE=GIORDANO CONTROLS SPA ++ ++OUI:8C1F64DC9* ++ ID_OUI_FROM_DATABASE=Peter Huber Kaeltemaschinenbau AG ++ ++OUI:8C1F64DE1* ++ ID_OUI_FROM_DATABASE=Franke Aquarotter GmbH ++ ++OUI:8C1F64E43* ++ ID_OUI_FROM_DATABASE=Daedalean AG ++ ++OUI:8C1F64E5C* ++ ID_OUI_FROM_DATABASE=Scientific Lightning Solutions ++ ++OUI:8C1F64EAC* ++ ID_OUI_FROM_DATABASE=Miracle Healthcare, Inc. ++ ++OUI:8C1F64EC1* ++ ID_OUI_FROM_DATABASE=Actronika SAS ++ ++OUI:8C1F64EE8* ++ ID_OUI_FROM_DATABASE=Global Organ Group B.V. ++ ++OUI:8C1F64EEF* ++ ID_OUI_FROM_DATABASE=AiUnion Co.,Ltd ++ ++OUI:8C1F64EF1* ++ ID_OUI_FROM_DATABASE=BIOTAGE GB LTD ++ ++OUI:8C1F64F41* ++ ID_OUI_FROM_DATABASE=AUTOMATIZACION Y CONECTIVIDAD SA DE CV ++ ++OUI:8C1F64F86* ++ ID_OUI_FROM_DATABASE=INFOSTECH Co., Ltd. ++ ++OUI:8C1F64FD1* ++ ID_OUI_FROM_DATABASE=Edgeware AB ++ ++OUI:8C1F64FE0* ++ ID_OUI_FROM_DATABASE=Potter Electric Signal Company ++ + OUI:8C1F94* + ID_OUI_FROM_DATABASE=RF Surgical System Inc. + +@@ -70301,6 +86606,9 @@ OUI:8C278A* + OUI:8C2937* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8C2A8E* ++ ID_OUI_FROM_DATABASE=DongGuan Ramaxel Memory Technology ++ + OUI:8C2DAA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -70310,24 +86618,42 @@ OUI:8C2F39* + OUI:8C2FA6* + ID_OUI_FROM_DATABASE=Solid Optics B.V. + ++OUI:8C31E2* ++ ID_OUI_FROM_DATABASE=DAYOUPLUS ++ + OUI:8C3330* + ID_OUI_FROM_DATABASE=EmFirst Co., Ltd. + + OUI:8C3357* + ID_OUI_FROM_DATABASE=HiteVision Digital Media Technology Co.,Ltd. + ++OUI:8C3401* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:8C3446* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:8C34FD* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:8C3579* + ID_OUI_FROM_DATABASE=QDIQO Sp. z o.o. + ++OUI:8C367A* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ + OUI:8C395C* + ID_OUI_FROM_DATABASE=Bit4id Srl + ++OUI:8C3A7E* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:8C3AE3* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:8C3B32* ++ ID_OUI_FROM_DATABASE=Microfan B.V. ++ + OUI:8C3BAD* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -70337,21 +86663,87 @@ OUI:8C3C07* + OUI:8C3C4A* + ID_OUI_FROM_DATABASE=NAKAYO Inc + ++OUI:8C3DB1* ++ ID_OUI_FROM_DATABASE=Beijing H-IoT Technology Co., Ltd. ++ + OUI:8C41F2* + ID_OUI_FROM_DATABASE=RDA Technologies Ltd. + + OUI:8C41F4* + ID_OUI_FROM_DATABASE=IPmotion GmbH + ++OUI:8C426D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:8C4361* ++ ID_OUI_FROM_DATABASE=Hailo Digital Hub GmbH & Co. KG ++ + OUI:8C4435* + ID_OUI_FROM_DATABASE=Shanghai BroadMobi Communication Technology Co., Ltd. + ++OUI:8C444F* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ + OUI:8C4500* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:8C476E0* ++ ID_OUI_FROM_DATABASE=Chipsafer Pte. Ltd. ++ ++OUI:8C476E1* ++ ID_OUI_FROM_DATABASE=TelWare Corporation ++ ++OUI:8C476E2* ++ ID_OUI_FROM_DATABASE=HuiZhou MIKI Communication Equipment Co.,LTD ++ ++OUI:8C476E3* ++ ID_OUI_FROM_DATABASE=Shanghai Satellite Communication Technology Co.,Ltd ++ ++OUI:8C476E4* ++ ID_OUI_FROM_DATABASE=Shenzhen Juding Electronics Co., Ltd. ++ ++OUI:8C476E5* ++ ID_OUI_FROM_DATABASE=Square Inc. ++ ++OUI:8C476E6* ++ ID_OUI_FROM_DATABASE=Oxford Nanopore Technologies Ltd. ++ ++OUI:8C476E7* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:8C476E8* ++ ID_OUI_FROM_DATABASE=IntelliVIX Co. Ltd. ++ ++OUI:8C476E9* ++ ID_OUI_FROM_DATABASE=Xertified AB ++ ++OUI:8C476EA* ++ ID_OUI_FROM_DATABASE=AU Optronics Corporation ++ ++OUI:8C476EB* ++ ID_OUI_FROM_DATABASE=Faravid Communication&Data Analysis ++ ++OUI:8C476EC* ++ ID_OUI_FROM_DATABASE=Edge Networks Inc ++ ++OUI:8C476ED* ++ ID_OUI_FROM_DATABASE=innolectric AG ++ ++OUI:8C476EE* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:8C47BE* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:8C4962* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:8C4AEE* + ID_OUI_FROM_DATABASE=GIGA TMS INC + ++OUI:8C4B14* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:8C4B59* + ID_OUI_FROM_DATABASE=3D Imaging & Simulations Corp + +@@ -70370,12 +86762,24 @@ OUI:8C4DEA* + OUI:8C5105* + ID_OUI_FROM_DATABASE=Shenzhen ireadygo Information Technology CO.,LTD. + ++OUI:8C53C3* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:8C53D2* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:8C53F7* + ID_OUI_FROM_DATABASE=A&D ENGINEERING CO., LTD. + + OUI:8C541D* + ID_OUI_FROM_DATABASE=LGE + ++OUI:8C554A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:8C55BB* ++ ID_OUI_FROM_DATABASE=Songwoo Information & Technology Co., Ltd ++ + OUI:8C569D* + ID_OUI_FROM_DATABASE=Imaging Solutions Group + +@@ -70391,6 +86795,51 @@ OUI:8C57FD* + OUI:8C5877* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8C593C0* ++ ID_OUI_FROM_DATABASE=Fujian Chaozhi Group Co., Ltd. ++ ++OUI:8C593C1* ++ ID_OUI_FROM_DATABASE=Future Robot Technology Co., Limited ++ ++OUI:8C593C2* ++ ID_OUI_FROM_DATABASE=Beida Jade Bird Universal Fire Alarm Device CO.,LTD. ++ ++OUI:8C593C3* ++ ID_OUI_FROM_DATABASE=Chongqing beimoting technology co.ltd ++ ++OUI:8C593C4* ++ ID_OUI_FROM_DATABASE=Guralp Systems Limited ++ ++OUI:8C593C5* ++ ID_OUI_FROM_DATABASE=Spectranetix ++ ++OUI:8C593C6* ++ ID_OUI_FROM_DATABASE=Qbic Technology Co., Ltd ++ ++OUI:8C593C7* ++ ID_OUI_FROM_DATABASE=OBO Pro.2 Inc. ++ ++OUI:8C593C8* ++ ID_OUI_FROM_DATABASE=Nanonord A/S ++ ++OUI:8C593C9* ++ ID_OUI_FROM_DATABASE=GENIS ++ ++OUI:8C593CA* ++ ID_OUI_FROM_DATABASE=ecom instruments GmbH ++ ++OUI:8C593CB* ++ ID_OUI_FROM_DATABASE=Scharfe-Sicht GmbH ++ ++OUI:8C593CC* ++ ID_OUI_FROM_DATABASE=Dantherm Cooling Inc. ++ ++OUI:8C593CD* ++ ID_OUI_FROM_DATABASE=IDRO-ELETTRICA S.P.A. ++ ++OUI:8C593CE* ++ ID_OUI_FROM_DATABASE=Shenzhen Tian-Power Technology Co.,Ltd. ++ + OUI:8C5973* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + +@@ -70400,9 +86849,21 @@ OUI:8C598B* + OUI:8C59C3* + ID_OUI_FROM_DATABASE=ADB Italia + ++OUI:8C59DC* ++ ID_OUI_FROM_DATABASE=ASR Microelectronics (Shanghai) Co., Ltd. ++ ++OUI:8C5A25* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:8C5AC1* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:8C5AF0* + ID_OUI_FROM_DATABASE=Exeltech Solar Products + ++OUI:8C5AF8* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ + OUI:8C5BF0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -70412,15 +86873,24 @@ OUI:8C5CA1* + OUI:8C5D60* + ID_OUI_FROM_DATABASE=UCI Corporation Co.,Ltd. + ++OUI:8C5EBD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:8C5F48* + ID_OUI_FROM_DATABASE=Continental Intelligent Transportation Systems LLC + ++OUI:8C5FAD* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:8C5FDF* + ID_OUI_FROM_DATABASE=Beijing Railway Signal Factory + + OUI:8C604F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:8C6078* ++ ID_OUI_FROM_DATABASE=Swissbit AG ++ + OUI:8C60E7* + ID_OUI_FROM_DATABASE=MPGIO CO.,LTD + +@@ -70434,11 +86904,29 @@ OUI:8C640B* + ID_OUI_FROM_DATABASE=Beyond Devices d.o.o. + + OUI:8C6422* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:8C64A2* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ ++OUI:8C64D4* ++ ID_OUI_FROM_DATABASE=Hyeco Smart Tech Co.,Ltd ++ ++OUI:8C6794* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:8C683A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:8C6878* + ID_OUI_FROM_DATABASE=Nortek-AS + ++OUI:8C68C8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:8C6A8D* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:8C6AE4* + ID_OUI_FROM_DATABASE=Viogem Limited + +@@ -70448,15 +86936,24 @@ OUI:8C6D50* + OUI:8C6D77* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:8C6DC4* ++ ID_OUI_FROM_DATABASE=Megapixel VR ++ + OUI:8C705A* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:8C7086* ++ ID_OUI_FROM_DATABASE=Gesellschaft für Sonder-EDV-Anlagen mbH ++ + OUI:8C71F8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:8C736E* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + ++OUI:8C73A0* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:8C76C1* + ID_OUI_FROM_DATABASE=Goden Tech Limited + +@@ -70472,9 +86969,24 @@ OUI:8C78D7* + OUI:8C7967* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:8C79F5* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:8C7A15* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ ++OUI:8C7A3D* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:8C7AAA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:8C7B9D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8C7BF0* ++ ID_OUI_FROM_DATABASE=Xufeng Development Limited ++ + OUI:8C7C92* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -70482,7 +86994,7 @@ OUI:8C7CB5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:8C7CFF* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:8C7EB3* + ID_OUI_FROM_DATABASE=Lytro, Inc. +@@ -70493,15 +87005,24 @@ OUI:8C7F3B* + OUI:8C8126* + ID_OUI_FROM_DATABASE=ARCOM + ++OUI:8C8172* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:8C82A8* + ID_OUI_FROM_DATABASE=Insigma Technology Co.,Ltd + + OUI:8C839D* + ID_OUI_FROM_DATABASE=SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD + ++OUI:8C83DF* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:8C83E1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:8C83FC* ++ ID_OUI_FROM_DATABASE=Axioma Metering UAB ++ + OUI:8C8401* + ID_OUI_FROM_DATABASE=Private + +@@ -70511,6 +87032,15 @@ OUI:8C8580* + OUI:8C8590* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8C85C1* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:8C85E6* ++ ID_OUI_FROM_DATABASE=Cleondris GmbH ++ ++OUI:8C861E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:8C873B* + ID_OUI_FROM_DATABASE=Leica Camera AG + +@@ -70520,6 +87050,9 @@ OUI:8C897A* + OUI:8C89A5* + ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD + ++OUI:8C89FA* ++ ID_OUI_FROM_DATABASE=Zhejiang Hechuan Technology Co., Ltd. ++ + OUI:8C8A6E* + ID_OUI_FROM_DATABASE=ESTUN AUTOMATION TECHNOLOY CO., LTD + +@@ -70529,6 +87062,12 @@ OUI:8C8ABB* + OUI:8C8B83* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:8C8CAA* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:8C8D28* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:8C8E76* + ID_OUI_FROM_DATABASE=taskit GmbH + +@@ -70556,9 +87095,21 @@ OUI:8C9246* + OUI:8C9351* + ID_OUI_FROM_DATABASE=Jigowatts Inc. + ++OUI:8C941F* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:8C94CC* ++ ID_OUI_FROM_DATABASE=SFR ++ + OUI:8C94CF* + ID_OUI_FROM_DATABASE=Encell Technology, Inc. + ++OUI:8C965F* ++ ID_OUI_FROM_DATABASE=Shandong Zhongan Technology Co., Ltd. ++ ++OUI:8C97EA* ++ ID_OUI_FROM_DATABASE=FREEBOX SAS ++ + OUI:8C99E6* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -70571,24 +87122,84 @@ OUI:8CA048* + OUI:8CA2FD* + ID_OUI_FROM_DATABASE=Starry, Inc. + ++OUI:8CA399* ++ ID_OUI_FROM_DATABASE=SERVERCOM (INDIA) PRIVATE LIMITED ++ + OUI:8CA5A1* + ID_OUI_FROM_DATABASE=Oregano Systems - Design & Consulting GmbH + + OUI:8CA6DF* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:8CA96F* ++ ID_OUI_FROM_DATABASE=D&M Holdings Inc. ++ + OUI:8CA982* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:8CAAB5* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:8CAACE* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:8CAB8E* + ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd. + ++OUI:8CAE490* ++ ID_OUI_FROM_DATABASE=Ouman Oy ++ ++OUI:8CAE491* ++ ID_OUI_FROM_DATABASE=H3 Platform ++ ++OUI:8CAE492* ++ ID_OUI_FROM_DATABASE=SEVERIN Elektrogeräte GmbH ++ ++OUI:8CAE493* ++ ID_OUI_FROM_DATABASE=BERTIN TECHNOLOGIES ++ ++OUI:8CAE494* ++ ID_OUI_FROM_DATABASE=Jiangsu Sixingda Information Technology Co., Ltd. ++ ++OUI:8CAE495* ++ ID_OUI_FROM_DATABASE=Gati Information Technolog(Kunshan)Co.,Ltd. ++ ++OUI:8CAE496* ++ ID_OUI_FROM_DATABASE=Chengdu BillDTE Technology Co., Ltd ++ ++OUI:8CAE497* ++ ID_OUI_FROM_DATABASE=Precitec Optronik GmbH ++ ++OUI:8CAE498* ++ ID_OUI_FROM_DATABASE=LLC Taipit - Measuring Equipment ++ ++OUI:8CAE499* ++ ID_OUI_FROM_DATABASE=TTR Corporation ++ ++OUI:8CAE49A* ++ ID_OUI_FROM_DATABASE=Gigawave ++ ++OUI:8CAE49B* ++ ID_OUI_FROM_DATABASE=Suzhou Guowang Electronics Technology Co., Ltd. ++ ++OUI:8CAE49C* ++ ID_OUI_FROM_DATABASE=Parametric GmbH ++ ++OUI:8CAE49D* ++ ID_OUI_FROM_DATABASE=Larch Networks ++ ++OUI:8CAE49E* ++ ID_OUI_FROM_DATABASE=Shenzhen C & D Electronics Co., Ltd. ++ + OUI:8CAE4C* + ID_OUI_FROM_DATABASE=Plugable Technologies + + OUI:8CAE89* + ID_OUI_FROM_DATABASE=Y-cam Solutions Ltd + ++OUI:8CAEDB* ++ ID_OUI_FROM_DATABASE=NAGTECH LLC ++ + OUI:8CB094* + ID_OUI_FROM_DATABASE=Airtech I&C Co., Ltd + +@@ -70604,9 +87215,18 @@ OUI:8CB7F7* + OUI:8CB82C* + ID_OUI_FROM_DATABASE=IPitomy Communications + ++OUI:8CB84A* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ + OUI:8CB864* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + ++OUI:8CBA25* ++ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD ++ ++OUI:8CBE24* ++ ID_OUI_FROM_DATABASE=Tashang Semiconductor(Shanghai) Co., Ltd. ++ + OUI:8CBEBE* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -70619,18 +87239,27 @@ OUI:8CBFA6* + OUI:8CC121* + ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company + ++OUI:8CC5B4* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:8CC5E1* + ID_OUI_FROM_DATABASE=ShenZhen Konka Telecommunication Technology Co.,Ltd + + OUI:8CC661* + ID_OUI_FROM_DATABASE=Current, powered by GE + ++OUI:8CC681* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:8CC7AA* + ID_OUI_FROM_DATABASE=Radinet Communications Inc. + + OUI:8CC7D0* + ID_OUI_FROM_DATABASE=zhejiang ebang communication co.,ltd + ++OUI:8CC84B* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:8CC8CD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -70685,12 +87314,21 @@ OUI:8CCDA2* + OUI:8CCDE8* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:8CCE4E* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:8CCEFD* ++ ID_OUI_FROM_DATABASE=Shenzhen zhouhai technology co.,LTD ++ + OUI:8CCF09* + ID_OUI_FROM_DATABASE=Dell EMC + + OUI:8CCF5C* + ID_OUI_FROM_DATABASE=BEFEGA GmbH + ++OUI:8CCF8F* ++ ID_OUI_FROM_DATABASE=ITC Systems ++ + OUI:8CD17B* + ID_OUI_FROM_DATABASE=CG Mobile + +@@ -70706,9 +87344,18 @@ OUI:8CD48E* + OUI:8CD628* + ID_OUI_FROM_DATABASE=Ikor Metering + ++OUI:8CD67F* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ ++OUI:8CD9D6* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:8CDB25* + ID_OUI_FROM_DATABASE=ESG Solutions + ++OUI:8CDC02* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:8CDCD4* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -70721,6 +87368,12 @@ OUI:8CDE52* + OUI:8CDE99* + ID_OUI_FROM_DATABASE=Comlab Inc. + ++OUI:8CDEE6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:8CDEF9* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:8CDF9D* + ID_OUI_FROM_DATABASE=NEC Corporation + +@@ -70734,10 +87387,19 @@ OUI:8CE2DA* + ID_OUI_FROM_DATABASE=Circle Media Inc + + OUI:8CE38E* +- ID_OUI_FROM_DATABASE=Toshiba Memory Corporation ++ ID_OUI_FROM_DATABASE=Kioxia Corporation ++ ++OUI:8CE468* ++ ID_OUI_FROM_DATABASE=Guangzhou Sageran Technology Co., Ltd. ++ ++OUI:8CE5C0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:8CE5EF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:8CE748* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + + OUI:8CE78C* + ID_OUI_FROM_DATABASE=DK Networks +@@ -70745,24 +87407,42 @@ OUI:8CE78C* + OUI:8CE7B3* + ID_OUI_FROM_DATABASE=Sonardyne International Ltd + ++OUI:8CE9B4* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:8CEA1B* + ID_OUI_FROM_DATABASE=Edgecore Networks Corporation + ++OUI:8CEA48* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:8CEBC6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:8CEC4B* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:8CEC7B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:8CEEC6* + ID_OUI_FROM_DATABASE=Precepscion Pty. Ltd. + ++OUI:8CF112* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:8CF228* + ID_OUI_FROM_DATABASE=MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + ++OUI:8CF319* ++ ID_OUI_FROM_DATABASE=Siemens Industrial Automation Products Ltd., Chengdu ++ + OUI:8CF5A3* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:8CF681* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:8CF710* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + +@@ -70784,9 +87464,24 @@ OUI:8CF9C9* + OUI:8CFABA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:8CFCA0* ++ ID_OUI_FROM_DATABASE=Shenzhen Smart Device Technology Co., LTD. ++ ++OUI:8CFD15* ++ ID_OUI_FROM_DATABASE=Imagine Marketing Private Limited ++ ++OUI:8CFD18* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:8CFDDE* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:8CFDF0* + ID_OUI_FROM_DATABASE=Qualcomm Inc. + ++OUI:8CFE57* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:8CFE74* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -70802,6 +87497,12 @@ OUI:9000DB* + OUI:90013B* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:900218* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:90027A* ++ ID_OUI_FROM_DATABASE=Shenzhen Sworix Techonlogy Co., Ltd ++ + OUI:90028A* + ID_OUI_FROM_DATABASE=Shenzhen Shidean Legrand Electronic Products Co.,Ltd + +@@ -70823,6 +87524,9 @@ OUI:900628* + OUI:900917* + ID_OUI_FROM_DATABASE=Far-sighted mobile + ++OUI:9009D0* ++ ID_OUI_FROM_DATABASE=Synology Incorporated ++ + OUI:900A1A* + ID_OUI_FROM_DATABASE=Taicang T&W Electronics + +@@ -70832,12 +87536,18 @@ OUI:900A39* + OUI:900A3A* + ID_OUI_FROM_DATABASE=PSG Plastic Service GmbH + ++OUI:900A84* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ + OUI:900BC1* + ID_OUI_FROM_DATABASE=Sprocomm Technologies CO.,Ltd + + OUI:900CB4* + ID_OUI_FROM_DATABASE=Alinket Electronic Technology Co., Ltd + ++OUI:900CC8* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:900D66* + ID_OUI_FROM_DATABASE=Digimore Electronics Co., Ltd + +@@ -70847,15 +87557,39 @@ OUI:900DCB* + OUI:900E83* + ID_OUI_FROM_DATABASE=Monico Monitoring, Inc. + ++OUI:900EB3* ++ ID_OUI_FROM_DATABASE=Shenzhen Amediatech Technology Co., Ltd. ++ ++OUI:900F0C* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ ++OUI:901234* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ ++OUI:9012A1* ++ ID_OUI_FROM_DATABASE=We Corporation Inc. ++ ++OUI:9013DA* ++ ID_OUI_FROM_DATABASE=Athom B.V. ++ ++OUI:9016BA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:901711* + ID_OUI_FROM_DATABASE=Hagenuk Marinekommunikation GmbH + ++OUI:90173F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:90179B* + ID_OUI_FROM_DATABASE=Nanomegas + + OUI:9017AC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9017C8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:90185E* + ID_OUI_FROM_DATABASE=Apex Tool Group GmbH & Co OHG + +@@ -70868,6 +87602,9 @@ OUI:9018AE* + OUI:901900* + ID_OUI_FROM_DATABASE=SCS SA + ++OUI:901A4F* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:901ACA* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -70886,6 +87623,9 @@ OUI:90203A* + OUI:902083* + ID_OUI_FROM_DATABASE=General Engine Management Systems Ltd. + ++OUI:9020C2* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:902106* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +@@ -70895,9 +87635,15 @@ OUI:902155* + OUI:902181* + ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd + ++OUI:9023B4* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:9023EC* + ID_OUI_FROM_DATABASE=Availink, Inc. + ++OUI:90272B* ++ ID_OUI_FROM_DATABASE=Algorab S.r.l. ++ + OUI:9027E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -70910,6 +87656,9 @@ OUI:902BD2* + OUI:902CC7* + ID_OUI_FROM_DATABASE=C-MAX Asia Limited + ++OUI:902E16* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ + OUI:902E1C* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -70952,6 +87701,9 @@ OUI:903C92* + OUI:903CAE* + ID_OUI_FROM_DATABASE=Yunnan KSEC Digital Technology Co.,Ltd. + ++OUI:903CB3* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ + OUI:903D5A* + ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited + +@@ -70967,6 +87719,12 @@ OUI:903DBD* + OUI:903EAB* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:903FEA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:9043E2* ++ ID_OUI_FROM_DATABASE=Cornami, Inc ++ + OUI:904506* + ID_OUI_FROM_DATABASE=Tokyo Boeki Medisys Inc. + +@@ -70979,6 +87737,9 @@ OUI:9046B7* + OUI:904716* + ID_OUI_FROM_DATABASE=RORZE CORPORATION + ++OUI:90473C* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:90489A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -70994,6 +87755,9 @@ OUI:904CE5* + OUI:904D4A* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:904DC3* ++ ID_OUI_FROM_DATABASE=Flonidan A/S ++ + OUI:904E2B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -71060,18 +87824,36 @@ OUI:905446* + OUI:9055AE* + ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K + ++OUI:9055DE* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:905682* + ID_OUI_FROM_DATABASE=Lenbrook Industries Limited + + OUI:905692* + ID_OUI_FROM_DATABASE=Autotalks Ltd. + ++OUI:9056FC* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ ++OUI:905851* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:90593C* ++ ID_OUI_FROM_DATABASE=AZ-TECHNOLOGY SDN BHD ++ + OUI:9059AF* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:905C34* ++ ID_OUI_FROM_DATABASE=Sirius Electronic Systems Srl ++ + OUI:905C44* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + ++OUI:905D7C* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:905F2E* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -71087,6 +87869,9 @@ OUI:90610C* + OUI:9061AE* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:90633B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:906717* + ID_OUI_FROM_DATABASE=Alphion India Private Limited + +@@ -71102,9 +87887,18 @@ OUI:9067F3* + OUI:9068C3* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:906976* ++ ID_OUI_FROM_DATABASE=Withrobot Inc. ++ ++OUI:906A94* ++ ID_OUI_FROM_DATABASE=hangzhou huacheng network technology co., ltd ++ + OUI:906CAC* + ID_OUI_FROM_DATABASE=Fortinet, Inc. + ++OUI:906D05* ++ ID_OUI_FROM_DATABASE=BXB ELECTRONICS CO., LTD ++ + OUI:906DC8* + ID_OUI_FROM_DATABASE=DLG Automação Industrial Ltda + +@@ -71129,6 +87923,24 @@ OUI:907240* + OUI:907282* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:90735A* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:90749D* ++ ID_OUI_FROM_DATABASE=IRay Technology Co., Ltd. ++ ++OUI:90769F* ++ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. ++ ++OUI:9077EE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:907841* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:9078B2* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:907910* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + +@@ -71141,15 +87953,33 @@ OUI:907A0A* + OUI:907A28* + ID_OUI_FROM_DATABASE=Beijing Morncloud Information And Technology Co. Ltd. + ++OUI:907A58* ++ ID_OUI_FROM_DATABASE=Zegna-Daidong Limited ++ + OUI:907AF1* + ID_OUI_FROM_DATABASE=Wally + ++OUI:907E30* ++ ID_OUI_FROM_DATABASE=LARS ++ + OUI:907EBA* + ID_OUI_FROM_DATABASE=UTEK TECHNOLOGY (SHENZHEN) CO.,LTD + + OUI:907F61* + ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. + ++OUI:908060* ++ ID_OUI_FROM_DATABASE=Nilfisk A/S ++ ++OUI:90808F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:90812A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:908158* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:908260* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + +@@ -71169,14 +87999,23 @@ OUI:90848B* + ID_OUI_FROM_DATABASE=HDR10+ Technologies, LLC + + OUI:908674* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:90869B* ++ ID_OUI_FROM_DATABASE=zte corporation + + OUI:9088A2* + ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA + ++OUI:90895F* ++ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD ++ + OUI:908C09* + ID_OUI_FROM_DATABASE=Total Phase + ++OUI:908C43* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:908C44* + ID_OUI_FROM_DATABASE=H.K ZONGMU TECHNOLOGY CO., LTD. + +@@ -71201,27 +88040,48 @@ OUI:90903C* + OUI:909060* + ID_OUI_FROM_DATABASE=RSI VIDEO TECHNOLOGIES + ++OUI:909164* ++ ID_OUI_FROM_DATABASE=ChongQing Lavid Technology Co., Ltd. ++ + OUI:9092B4* + ID_OUI_FROM_DATABASE=Diehl BGT Defence GmbH & Co. KG + ++OUI:90940A* ++ ID_OUI_FROM_DATABASE=Analog Devices, Inc ++ + OUI:909497* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:9094E4* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:9096F3* ++ ID_OUI_FROM_DATABASE=BUFFALO.INC ++ + OUI:9097D5* + ID_OUI_FROM_DATABASE=Espressif Inc. + + OUI:9097F3* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:909838* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:909864* + ID_OUI_FROM_DATABASE=Impex-Sat GmbH&Co KG + + OUI:909916* + ID_OUI_FROM_DATABASE=ELVEES NeoTek OJSC + ++OUI:909A4A* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:909A77* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:909C4A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:909D7D* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -71240,6 +88100,9 @@ OUI:90A137* + OUI:90A210* + ID_OUI_FROM_DATABASE=United Telecoms Ltd + ++OUI:90A25B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:90A2DA* + ID_OUI_FROM_DATABASE=GHEO SA + +@@ -71252,6 +88115,9 @@ OUI:90A46A* + OUI:90A4DE* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + ++OUI:90A5AF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:90A62F* + ID_OUI_FROM_DATABASE=NAVER + +@@ -71261,15 +88127,30 @@ OUI:90A783* + OUI:90A7C1* + ID_OUI_FROM_DATABASE=Pakedge Device and Software Inc. + ++OUI:90A822* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:90A935* ++ ID_OUI_FROM_DATABASE=JWEntertainment ++ ++OUI:90AAC3* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:90AC3F* + ID_OUI_FROM_DATABASE=BrightSign LLC + + OUI:90ADF7* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:90ADFC* ++ ID_OUI_FROM_DATABASE=Telechips, Inc. ++ + OUI:90AE1B* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:90AFD1* ++ ID_OUI_FROM_DATABASE=netKTI Co., Ltd ++ + OUI:90B0ED* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -71279,26 +88160,50 @@ OUI:90B11C* + OUI:90B134* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:90B144* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:90B1E0* + ID_OUI_FROM_DATABASE=Beijing Nebula Link Technology Co., Ltd + + OUI:90B21F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:90B4DD* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:90B57F* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ ++OUI:90B67A* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:90B686* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:90B832* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:90B8D0* + ID_OUI_FROM_DATABASE=Joyent, Inc. + ++OUI:90B8E0* ++ ID_OUI_FROM_DATABASE=SHENZHEN YANRAY TECHNOLOGY CO.,LTD ++ + OUI:90B931* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:90B97D* + ID_OUI_FROM_DATABASE=Johnson Outdoors Marine Electronics d/b/a Minnkota + ++OUI:90BDE6* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ + OUI:90C115* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:90C119* ++ ID_OUI_FROM_DATABASE=Nokia + + OUI:90C1C6* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -71306,6 +88211,9 @@ OUI:90C1C6* + OUI:90C35F* + ID_OUI_FROM_DATABASE=Nanjing Jiahao Technology Co., Ltd. + ++OUI:90C54A* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:90C6820* + ID_OUI_FROM_DATABASE=Shenzhen Lencotion Technology Co.,Ltd + +@@ -71361,11 +88269,14 @@ OUI:90C7D8* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:90C99B* +- ID_OUI_FROM_DATABASE=Recore Systems ++ ID_OUI_FROM_DATABASE=Tesorion Nederland B.V. + + OUI:90CC24* + ID_OUI_FROM_DATABASE=Synaptics, Inc + ++OUI:90CCDF* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:90CDB6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -71411,6 +88322,9 @@ OUI:90DB46* + OUI:90DD5D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:90DE80* ++ ID_OUI_FROM_DATABASE=Shenzhen Century Xinyang Technology Co., Ltd ++ + OUI:90DFB7* + ID_OUI_FROM_DATABASE=s.m.s smart microwave sensors GmbH + +@@ -71420,21 +88334,84 @@ OUI:90DFFB* + OUI:90E0F0* + ID_OUI_FROM_DATABASE=IEEE 1722a Working Group + ++OUI:90E17B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:90E202* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:90E2BA* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:90E2FC0* ++ ID_OUI_FROM_DATABASE=Pars Ertebat Afzar Co. ++ ++OUI:90E2FC1* ++ ID_OUI_FROM_DATABASE=Yite technology ++ ++OUI:90E2FC2* ++ ID_OUI_FROM_DATABASE=ShenZhen Temwey Innovation Technology Co.,Ltd. ++ ++OUI:90E2FC3* ++ ID_OUI_FROM_DATABASE=Shenzhen Hisource Technology Development CO.,Ltd. ++ ++OUI:90E2FC4* ++ ID_OUI_FROM_DATABASE=Dongguan Kangyong electronics technology Co. Ltd ++ ++OUI:90E2FC5* ++ ID_OUI_FROM_DATABASE=TOTALONE TECHNOLOGY CO., LTD. ++ ++OUI:90E2FC6* ++ ID_OUI_FROM_DATABASE=Sindoh Techno Co., Ltd. ++ ++OUI:90E2FC7* ++ ID_OUI_FROM_DATABASE=Fair Winds Digital srl ++ ++OUI:90E2FC8* ++ ID_OUI_FROM_DATABASE=bitsensing Inc. ++ ++OUI:90E2FC9* ++ ID_OUI_FROM_DATABASE=Huddly AS ++ ++OUI:90E2FCA* ++ ID_OUI_FROM_DATABASE=Power Engineering & Manufacturing, Inc. ++ ++OUI:90E2FCB* ++ ID_OUI_FROM_DATABASE=Shenzhen Dingsheng Intelligent Technology Co., Ltd ++ ++OUI:90E2FCC* ++ ID_OUI_FROM_DATABASE=Stanley Security ++ ++OUI:90E2FCD* ++ ID_OUI_FROM_DATABASE=Beijing Lanxum Computer Technology CO.,LTD. ++ ++OUI:90E2FCE* ++ ID_OUI_FROM_DATABASE=DevCom spol. s r.o. ++ + OUI:90E6BA* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:90E710* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:90E7C4* + ID_OUI_FROM_DATABASE=HTC Corporation + ++OUI:90E868* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:90EA60* + ID_OUI_FROM_DATABASE=SPI Lasers Ltd + + OUI:90EC50* + ID_OUI_FROM_DATABASE=C.O.B.O. SPA + ++OUI:90EC77* ++ ID_OUI_FROM_DATABASE=silicom ++ ++OUI:90EEC7* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:90EED9* + ID_OUI_FROM_DATABASE=UNIVERSAL DE DESARROLLOS ELECTRÓNICOS, SA + +@@ -71444,6 +88421,9 @@ OUI:90EF68* + OUI:90F052* + ID_OUI_FROM_DATABASE=MEIZU Technology Co., Ltd. + ++OUI:90F157* ++ ID_OUI_FROM_DATABASE=Garmin International ++ + OUI:90F1AA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -71462,12 +88442,21 @@ OUI:90F3B7* + OUI:90F4C1* + ID_OUI_FROM_DATABASE=Rand McNally + ++OUI:90F644* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:90F652* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:90F72F* + ID_OUI_FROM_DATABASE=Phillips Machine & Welding Co., Inc. + ++OUI:90F891* ++ ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. ++ ++OUI:90F9B7* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:90FB5B* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -71477,33 +88466,102 @@ OUI:90FBA6* + OUI:90FD61* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:90FD73* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:90FD9F* + ID_OUI_FROM_DATABASE=Silicon Laboratories + + OUI:90FF79* + ID_OUI_FROM_DATABASE=Metro Ethernet Forum + ++OUI:90FFD6* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:940006* + ID_OUI_FROM_DATABASE=jinyoung + + OUI:940070* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:9400B0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:940149* + ID_OUI_FROM_DATABASE=AutoHotBox + + OUI:9401C2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:94026B* ++ ID_OUI_FROM_DATABASE=Optictimes Co.,Ltd ++ + OUI:94049C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:9405B6* + ID_OUI_FROM_DATABASE=Liling FullRiver Electronics & Technology Ltd + ++OUI:9405BB0* ++ ID_OUI_FROM_DATABASE=Qingdao Maotran Electronics co., ltd ++ ++OUI:9405BB1* ++ ID_OUI_FROM_DATABASE=Dongguan Kingtron Electronics Tech Co., Ltd ++ ++OUI:9405BB2* ++ ID_OUI_FROM_DATABASE=Dongguan CXWE Technology Co.,Ltd. ++ ++OUI:9405BB3* ++ ID_OUI_FROM_DATABASE=Neutrik AG ++ ++OUI:9405BB4* ++ ID_OUI_FROM_DATABASE=Shenzhen Baolijie Technology Co., Ltd. ++ ++OUI:9405BB5* ++ ID_OUI_FROM_DATABASE=Chengdu Zhongheng Network Co.,Ltd. ++ ++OUI:9405BB6* ++ ID_OUI_FROM_DATABASE=ZIGPOS GmbH ++ ++OUI:9405BB7* ++ ID_OUI_FROM_DATABASE=LTE-X, Inc ++ ++OUI:9405BB8* ++ ID_OUI_FROM_DATABASE=iungo ++ ++OUI:9405BB9* ++ ID_OUI_FROM_DATABASE=Zimmer GmbH ++ ++OUI:9405BBA* ++ ID_OUI_FROM_DATABASE=SolarEdge Technologies ++ ++OUI:9405BBB* ++ ID_OUI_FROM_DATABASE=AUSTAR HEARING SCIENCE AND TECHNILIGY(XIAMEN)CO.,LTD ++ ++OUI:9405BBC* ++ ID_OUI_FROM_DATABASE=LAO INDUSTRIA LTDA ++ ++OUI:9405BBD* ++ ID_OUI_FROM_DATABASE=Sunthink S&T Development Co.,Ltd ++ ++OUI:9405BBE* ++ ID_OUI_FROM_DATABASE=BAE Systems ++ ++OUI:940853* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ ++OUI:9408C7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:940937* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:9409D3* ++ ID_OUI_FROM_DATABASE=shenzhen maxtopic technology co.,ltd ++ ++OUI:940B19* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:940B2D* + ID_OUI_FROM_DATABASE=NetView Technologies(Shenzhen) Co., Ltd + +@@ -71513,6 +88571,9 @@ OUI:940BD5* + OUI:940C6D* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:940C98* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:940E6B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -71525,18 +88586,30 @@ OUI:9411DA* + OUI:94147A* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:941625* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:941673* + ID_OUI_FROM_DATABASE=Point Core SARL + ++OUI:941700* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:941882* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:94193A* + ID_OUI_FROM_DATABASE=Elvaco AB + ++OUI:941C56* ++ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc ++ + OUI:941D1C* + ID_OUI_FROM_DATABASE=TLab West Systems AB + ++OUI:941F3A* ++ ID_OUI_FROM_DATABASE=Ambiq ++ + OUI:942053* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -71546,12 +88619,27 @@ OUI:942197* + OUI:94236E* + ID_OUI_FROM_DATABASE=Shenzhen Junlan Electronic Ltd + ++OUI:9424B8* ++ ID_OUI_FROM_DATABASE=GREE ELECTRIC APPLIANCES, INC. OF ZHUHAI ++ ++OUI:9424E1* ++ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise ++ ++OUI:942533* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:942790* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:94282E* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + + OUI:94290C* + ID_OUI_FROM_DATABASE=Shenyang wisdom Foundation Technology Development Co., Ltd. + ++OUI:94292F* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:94298D* + ID_OUI_FROM_DATABASE=Shanghai AdaptComm Technology Co., Ltd. + +@@ -71561,6 +88649,9 @@ OUI:942A3F* + OUI:942CB3* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:942DDC* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:942E17* + ID_OUI_FROM_DATABASE=Schneider Electric Canada Inc + +@@ -71579,15 +88670,27 @@ OUI:94350A* + OUI:9436E0* + ID_OUI_FROM_DATABASE=Sichuan Bihong Broadcast & Television New Technologies Co.,Ltd + ++OUI:9437F7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:9439E5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:943A91* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:943AF0* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:943BB0* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:943BB1* + ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. + ++OUI:943CC6* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:943DC9* + ID_OUI_FROM_DATABASE=Asahi Net, Inc. + +@@ -71597,9 +88700,15 @@ OUI:943FC2* + OUI:9440A2* + ID_OUI_FROM_DATABASE=Anywave Communication Technologies, Inc. + ++OUI:9440C9* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:9441C1* + ID_OUI_FROM_DATABASE=Mini-Cam Limited + ++OUI:94434D* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ + OUI:944444* + ID_OUI_FROM_DATABASE=LG Innotek + +@@ -71609,6 +88718,9 @@ OUI:944452* + OUI:944696* + ID_OUI_FROM_DATABASE=BaudTec Corporation + ++OUI:9447B0* ++ ID_OUI_FROM_DATABASE=BEIJING ESWIN COMPUTING TECHNOLOGY CO., LTD ++ + OUI:944996* + ID_OUI_FROM_DATABASE=WiSilica Inc + +@@ -71618,6 +88730,9 @@ OUI:944A09* + OUI:944A0C* + ID_OUI_FROM_DATABASE=Sercomm Corporation. + ++OUI:944F4C* ++ ID_OUI_FROM_DATABASE=Sound United LLC ++ + OUI:945047* + ID_OUI_FROM_DATABASE=Rechnerbetriebsgruppe + +@@ -71639,18 +88754,42 @@ OUI:945330* + OUI:945493* + ID_OUI_FROM_DATABASE=Rigado, LLC + ++OUI:9454CE* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:9454DF* ++ ID_OUI_FROM_DATABASE=YST CORP. ++ ++OUI:945641* ++ ID_OUI_FROM_DATABASE=Palo Alto Networks ++ + OUI:9457A5* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:9458CB* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:945907* + ID_OUI_FROM_DATABASE=Shanghai HITE-BELDEN Network Technology Co., Ltd. + + OUI:94592D* + ID_OUI_FROM_DATABASE=EKE Building Technology Systems Ltd + ++OUI:945AFC* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:945B7E* + ID_OUI_FROM_DATABASE=TRILOBIT LTDA. + ++OUI:945C9A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:945F34* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ ++OUI:946010* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:94611E* + ID_OUI_FROM_DATABASE=Wata Electronics Co.,Ltd. + +@@ -71666,6 +88805,9 @@ OUI:946372* + OUI:9463D1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:946424* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:94652D* + ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd + +@@ -71675,6 +88817,12 @@ OUI:94659C* + OUI:9466E7* + ID_OUI_FROM_DATABASE=WOM Engineering + ++OUI:94677E* ++ ID_OUI_FROM_DATABASE=Belden India Private Limited ++ ++OUI:946A77* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:946AB0* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + +@@ -71694,7 +88842,7 @@ OUI:94772B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:947BBE* +- ID_OUI_FROM_DATABASE=Ubicquia ++ ID_OUI_FROM_DATABASE=Ubicquia LLC + + OUI:947BE7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -71708,6 +88856,9 @@ OUI:947EB9* + OUI:9481A4* + ID_OUI_FROM_DATABASE=Azuray Technologies + ++OUI:9483C4* ++ ID_OUI_FROM_DATABASE=GL Technologies (Hong Kong) Limited ++ + OUI:94857A* + ID_OUI_FROM_DATABASE=Evantage Industries Corp + +@@ -71732,6 +88883,9 @@ OUI:948854* + OUI:94885E* + ID_OUI_FROM_DATABASE=Surfilter Network Technology Co., Ltd. + ++OUI:948AC6* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:948B03* + ID_OUI_FROM_DATABASE=EAGET Innovation and Technology Co., Ltd. + +@@ -71747,21 +88901,39 @@ OUI:948DEF* + OUI:948E89* + ID_OUI_FROM_DATABASE=INDUSTRIAS UNIDAS SA DE CV + ++OUI:948ED3* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ ++OUI:948FCF* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:948FEE* + ID_OUI_FROM_DATABASE=Verizon Telematics + ++OUI:949010* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:949034* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ + OUI:94917F* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + + OUI:9492BC* + ID_OUI_FROM_DATABASE=SYNTECH(HK) TECHNOLOGY LIMITED + ++OUI:9492D2* ++ ID_OUI_FROM_DATABASE=KCF Technologies, Inc. ++ + OUI:949426* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:9495A0* + ID_OUI_FROM_DATABASE=Google, Inc. + ++OUI:949869* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:9498A2* + ID_OUI_FROM_DATABASE=Shanghai LISTEN TECH.LTD + +@@ -71804,12 +88976,27 @@ OUI:94A1A2* + OUI:94A3CA* + ID_OUI_FROM_DATABASE=KonnectONE, LLC + ++OUI:94A408* ++ ID_OUI_FROM_DATABASE=Shenzhen Trolink Technology CO, LTD ++ ++OUI:94A40C* ++ ID_OUI_FROM_DATABASE=Diehl Metering GmbH ++ ++OUI:94A4F9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:94A67E* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:94A7B7* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:94A7BC* + ID_OUI_FROM_DATABASE=BodyMedia, Inc. + ++OUI:94AA0A* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:94AAB8* + ID_OUI_FROM_DATABASE=Joview(Beijing) Technology Co. Ltd. + +@@ -71825,14 +89012,23 @@ OUI:94AE61* + OUI:94AEE3* + ID_OUI_FROM_DATABASE=Belden Hirschmann Industries (Suzhou) Ltd. + ++OUI:94AEF0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:94B01F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:94B10A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:94B271* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:94B2CC* + ID_OUI_FROM_DATABASE=PIONEER CORPORATION + + OUI:94B40F* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:94B819* + ID_OUI_FROM_DATABASE=Nokia +@@ -71843,6 +89039,9 @@ OUI:94B86D* + OUI:94B8C5* + ID_OUI_FROM_DATABASE=RuggedCom Inc. + ++OUI:94B97E* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:94B9B4* + ID_OUI_FROM_DATABASE=Aptos Technology + +@@ -71855,15 +89054,27 @@ OUI:94BA56* + OUI:94BBAE* + ID_OUI_FROM_DATABASE=Husqvarna AB + ++OUI:94BE46* ++ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. ++ + OUI:94BF1E* + ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division + + OUI:94BF2D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:94BF80* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:94BF94* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:94BF95* + ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd + ++OUI:94BFC4* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:94C014* + ID_OUI_FROM_DATABASE=Sorter Sp. j. Konrad Grzeszczyk MichaA, Ziomek + +@@ -71873,6 +89084,9 @@ OUI:94C038* + OUI:94C150* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:94C2BD* ++ ID_OUI_FROM_DATABASE=TECNOBIT ++ + OUI:94C3E4* + ID_OUI_FROM_DATABASE=Atlas Copco IAS GmbH + +@@ -71897,6 +89111,51 @@ OUI:94C962* + OUI:94CA0F* + ID_OUI_FROM_DATABASE=Honeywell Analytics + ++OUI:94CC040* ++ ID_OUI_FROM_DATABASE=Hangzhou Yongkong Technology Co., Ltd. ++ ++OUI:94CC041* ++ ID_OUI_FROM_DATABASE=GOCOAX, INC ++ ++OUI:94CC042* ++ ID_OUI_FROM_DATABASE=Nanjing Yacer Communication Technology Co. Ltd. ++ ++OUI:94CC043* ++ ID_OUI_FROM_DATABASE=Shenzhen Link technology Co.,Ltd ++ ++OUI:94CC044* ++ ID_OUI_FROM_DATABASE=ProConnections, Inc. ++ ++OUI:94CC045* ++ ID_OUI_FROM_DATABASE=SHENZHEN SANRAY TECHNOLOGY CO.,LTD ++ ++OUI:94CC046* ++ ID_OUI_FROM_DATABASE=Sam Nazarko Trading Ltd ++ ++OUI:94CC047* ++ ID_OUI_FROM_DATABASE=Gowing Business And Contracting Wenzhou Co., LTD ++ ++OUI:94CC048* ++ ID_OUI_FROM_DATABASE=CircuitWerkes, Inc. ++ ++OUI:94CC049* ++ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. ++ ++OUI:94CC04A* ++ ID_OUI_FROM_DATABASE=hyBee Inc. ++ ++OUI:94CC04B* ++ ID_OUI_FROM_DATABASE=Shandong free optical technology co., ltd. ++ ++OUI:94CC04C* ++ ID_OUI_FROM_DATABASE=Shanxi Baixin Information Technology Co., Ltd. ++ ++OUI:94CC04D* ++ ID_OUI_FROM_DATABASE=Hanzhuo Information Technology(Shanghai) Ltd. ++ ++OUI:94CC04E* ++ ID_OUI_FROM_DATABASE=SynchronicIT BV ++ + OUI:94CCB9* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -71904,26 +89163,41 @@ OUI:94CDAC* + ID_OUI_FROM_DATABASE=Creowave Oy + + OUI:94CE2C* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:94CE31* + ID_OUI_FROM_DATABASE=CTS Limited + ++OUI:94D00D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:94D019* + ID_OUI_FROM_DATABASE=Cydle Corp. + + OUI:94D029* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:94D075* ++ ID_OUI_FROM_DATABASE=CIS Crypto ++ ++OUI:94D299* ++ ID_OUI_FROM_DATABASE=Techmation Co.,Ltd. ++ + OUI:94D417* + ID_OUI_FROM_DATABASE=GPI KOREA INC. + + OUI:94D469* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:94D505* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:94D60E* + ID_OUI_FROM_DATABASE=shenzhen yunmao information technologies co., ltd + ++OUI:94D6DB* ++ ID_OUI_FROM_DATABASE=NexFi ++ + OUI:94D723* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd + +@@ -71942,12 +89216,18 @@ OUI:94D9B3* + OUI:94DB49* + ID_OUI_FROM_DATABASE=SITCORP + ++OUI:94DB56* ++ ID_OUI_FROM_DATABASE=Sony Home Entertainment&Sound Products Inc ++ + OUI:94DBC9* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + + OUI:94DBDA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:94DC4E* ++ ID_OUI_FROM_DATABASE=AEV, spol. s r. o. ++ + OUI:94DD3F* + ID_OUI_FROM_DATABASE=A+V Link Technologies, Corp. + +@@ -71966,21 +89246,42 @@ OUI:94DF58* + OUI:94E0D0* + ID_OUI_FROM_DATABASE=HealthStream Taiwan Inc. + ++OUI:94E0D6* ++ ID_OUI_FROM_DATABASE=China Dragon Technology Limited ++ + OUI:94E1AC* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + + OUI:94E226* + ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC + ++OUI:94E23C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:94E2FD* + ID_OUI_FROM_DATABASE=Boge Kompressoren OTTO Boge GmbH & Co. KG + + OUI:94E36D* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:94E3EE* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:94E4BA* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:94E6F7* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:94E70B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:94E711* + ID_OUI_FROM_DATABASE=Xirka Dama Persada PT + ++OUI:94E7EA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:94E848* + ID_OUI_FROM_DATABASE=FYLDE MICRO LTD + +@@ -71996,12 +89297,24 @@ OUI:94E979* + OUI:94E98C* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:94E9EE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:94EA32* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:94EAEA* ++ ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO ++ + OUI:94EB2C* + ID_OUI_FROM_DATABASE=Google, Inc. + + OUI:94EBCD* + ID_OUI_FROM_DATABASE=BlackBerry RTS + ++OUI:94EE9F* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:94F128* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -72011,6 +89324,9 @@ OUI:94F19E* + OUI:94F278* + ID_OUI_FROM_DATABASE=Elma Electronic + ++OUI:94F2BB* ++ ID_OUI_FROM_DATABASE=Valeo Vision Systems ++ + OUI:94F551* + ID_OUI_FROM_DATABASE=Cadi Scientific Pte Ltd + +@@ -72023,15 +89339,66 @@ OUI:94F692* + OUI:94F6A3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:94F6D6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:94F720* + ID_OUI_FROM_DATABASE=Tianjin Deviser Electronics Instrument Co., Ltd + ++OUI:94F7AD* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:94FAE8* + ID_OUI_FROM_DATABASE=Shenzhen Eycom Technology Co., Ltd + + OUI:94FB29* + ID_OUI_FROM_DATABASE=Zebra Technologies Inc. + ++OUI:94FBA70* ++ ID_OUI_FROM_DATABASE=Reichert Inc. ++ ++OUI:94FBA71* ++ ID_OUI_FROM_DATABASE=Inaxsys Security Systems inc. ++ ++OUI:94FBA72* ++ ID_OUI_FROM_DATABASE=Beijing Leja Tech co., Ltd. ++ ++OUI:94FBA73* ++ ID_OUI_FROM_DATABASE=GUANG DONG TAKSTAR ELECTRONIC CO.,LTD. ++ ++OUI:94FBA74* ++ ID_OUI_FROM_DATABASE=UOI TECHNOLOGY CORPORATION ++ ++OUI:94FBA75* ++ ID_OUI_FROM_DATABASE=CAVITY EYE ++ ++OUI:94FBA76* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:94FBA77* ++ ID_OUI_FROM_DATABASE=Anvil Systems Group, Inc. ++ ++OUI:94FBA78* ++ ID_OUI_FROM_DATABASE=Silver-I Co.,LTD. ++ ++OUI:94FBA79* ++ ID_OUI_FROM_DATABASE=Shanghai Hyco Genyong Technology Co., Ltd. ++ ++OUI:94FBA7A* ++ ID_OUI_FROM_DATABASE=ELKRON ++ ++OUI:94FBA7B* ++ ID_OUI_FROM_DATABASE=Shenzhen Golden Star Technology Ltd ++ ++OUI:94FBA7C* ++ ID_OUI_FROM_DATABASE=Solaborate Inc. ++ ++OUI:94FBA7D* ++ ID_OUI_FROM_DATABASE=Rosenberger Technologies Co.,Ltd. ++ ++OUI:94FBA7E* ++ ID_OUI_FROM_DATABASE=Skyring Smart Technologies(Shenzhen) Co., Ltd. ++ + OUI:94FBB2* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + +@@ -72050,6 +89417,12 @@ OUI:94FE9D* + OUI:94FEF4* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:94FF61* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:98006A* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:980074* + ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD + +@@ -72122,9 +89495,63 @@ OUI:9803A0* + OUI:9803D8* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9806370* ++ ID_OUI_FROM_DATABASE=Zoleo Inc. ++ ++OUI:9806371* ++ ID_OUI_FROM_DATABASE=E. P. Schlumberger ++ ++OUI:9806372* ++ ID_OUI_FROM_DATABASE=Summa nv ++ ++OUI:9806373* ++ ID_OUI_FROM_DATABASE=Hangzhou Sanxin Network Technology Co.,Ltd ++ ++OUI:9806374* ++ ID_OUI_FROM_DATABASE=Chengdu Shuwei Communication Technology Co.,Ltd ++ ++OUI:9806375* ++ ID_OUI_FROM_DATABASE=GS GLOBAL SECURITY INC ++ ++OUI:9806376* ++ ID_OUI_FROM_DATABASE=BOEING SSG ++ ++OUI:9806377* ++ ID_OUI_FROM_DATABASE=SAMWONTECH ++ ++OUI:9806378* ++ ID_OUI_FROM_DATABASE=Shenzhen Y&D Electronics Information Co., Ltd ++ ++OUI:9806379* ++ ID_OUI_FROM_DATABASE=NAB co,.LTD ++ ++OUI:980637A* ++ ID_OUI_FROM_DATABASE=Angora Networks ++ ++OUI:980637B* ++ ID_OUI_FROM_DATABASE=Petersime ++ ++OUI:980637C* ++ ID_OUI_FROM_DATABASE=HwaCom Systems Inc. ++ ++OUI:980637D* ++ ID_OUI_FROM_DATABASE=VR Technology(Shenzhen) Limited ++ ++OUI:980637E* ++ ID_OUI_FROM_DATABASE=Shanghai Jinnian information technology Co. Ltd ++ ++OUI:98063A* ++ ID_OUI_FROM_DATABASE=Home Control Singapore Pte Ltd ++ ++OUI:98063C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:98072D* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:9809CF* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ + OUI:980C82* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + +@@ -72134,9 +89561,21 @@ OUI:980CA5* + OUI:980D2E* + ID_OUI_FROM_DATABASE=HTC Corporation + ++OUI:980D51* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:980D67* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ ++OUI:980E24* ++ ID_OUI_FROM_DATABASE=Phytium Technology Co.,Ltd. ++ + OUI:980EE4* + ID_OUI_FROM_DATABASE=Private + ++OUI:981082* ++ ID_OUI_FROM_DATABASE=Nsolution Co., Ltd. ++ + OUI:981094* + ID_OUI_FROM_DATABASE=Shenzhen Vsun communication technology Co.,ltd + +@@ -72152,12 +89591,24 @@ OUI:9814D2* + OUI:9816EC* + ID_OUI_FROM_DATABASE=IC Intracom + ++OUI:981888* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ ++OUI:981A35* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:981BB5* ++ ID_OUI_FROM_DATABASE=ASSA ABLOY Korea Co., Ltd iRevo ++ + OUI:981DFA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:981E0F* + ID_OUI_FROM_DATABASE=Jeelan (Shanghai Jeelan Technology Information Inc + ++OUI:981E19* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:981FB1* + ID_OUI_FROM_DATABASE=Shenzhen Lemon Network Technology Co.,Ltd + +@@ -72173,6 +89624,51 @@ OUI:98234E* + OUI:98262A* + ID_OUI_FROM_DATABASE=Applied Research Associates, Inc + ++OUI:9827820* ++ ID_OUI_FROM_DATABASE=SHENZHEN HEROFUN BIO-TECH CO., LTD ++ ++OUI:9827821* ++ ID_OUI_FROM_DATABASE=INFODAS GmbH ++ ++OUI:9827822* ++ ID_OUI_FROM_DATABASE=Anhui Shengren Electronic Technology Co., Ltd ++ ++OUI:9827823* ++ ID_OUI_FROM_DATABASE=Danfoss Power Solutions ++ ++OUI:9827824* ++ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc. ++ ++OUI:9827825* ++ ID_OUI_FROM_DATABASE=Guangzhou Wuzhou Technology Co, Ltd. ++ ++OUI:9827826* ++ ID_OUI_FROM_DATABASE=WESTERN SECURITY SOLUTIONS ++ ++OUI:9827827* ++ ID_OUI_FROM_DATABASE=KORTEK CORPORATION ++ ++OUI:9827828* ++ ID_OUI_FROM_DATABASE=CATS Power design ++ ++OUI:9827829* ++ ID_OUI_FROM_DATABASE=Wuxi GuoYiHaiJu Technology Co.,Ltd. ++ ++OUI:982782A* ++ ID_OUI_FROM_DATABASE=Nanjing BianYu Future Home Technology Co.Ltd ++ ++OUI:982782B* ++ ID_OUI_FROM_DATABASE=RayTron, INC. ++ ++OUI:982782C* ++ ID_OUI_FROM_DATABASE=KRISTECH Krzysztof Kajstura ++ ++OUI:982782D* ++ ID_OUI_FROM_DATABASE=Thorlabs GmbH ++ ++OUI:982782E* ++ ID_OUI_FROM_DATABASE=SureFlap Ltd ++ + OUI:9828A6* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +@@ -72185,6 +89681,9 @@ OUI:98293F* + OUI:9829A6* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:982CBC* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:982CBE* + ID_OUI_FROM_DATABASE=2Wire Inc + +@@ -72200,6 +89699,9 @@ OUI:982DBA* + OUI:982F3C* + ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. + ++OUI:982FF8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:983000* + ID_OUI_FROM_DATABASE=Beijing KEMACOM Technologies Co., Ltd. + +@@ -72215,33 +89717,84 @@ OUI:983571* + OUI:9835B8* + ID_OUI_FROM_DATABASE=Assembled Products Corporation + ++OUI:9835ED* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:983713* + ID_OUI_FROM_DATABASE=PT.Navicom Indonesia + ++OUI:98387D* ++ ID_OUI_FROM_DATABASE=ITRONIC TECHNOLOGY CO . , LTD . ++ + OUI:98398E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:983B16* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + ++OUI:983B67* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ ++OUI:983B8F* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:983F60* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:983F66* ++ ID_OUI_FROM_DATABASE=Wuhan Funshion Online Technologies Co.,Ltd ++ + OUI:983F9F* + ID_OUI_FROM_DATABASE=China SSJ (Suzhou) Network Technology Inc. + + OUI:9840BB* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:98415C* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:984246* + ID_OUI_FROM_DATABASE=SOL INDUSTRY PTE., LTD + ++OUI:984265* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:9843DA* + ID_OUI_FROM_DATABASE=INTERTECH + ++OUI:9843FA* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:9844B6* ++ ID_OUI_FROM_DATABASE=INFRANOR SAS ++ ++OUI:9844CE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:984562* + ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd. + ++OUI:98460A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:98473C* + ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD + ++OUI:984827* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:984874* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:984914* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ ++OUI:98499F* ++ ID_OUI_FROM_DATABASE=Domo Tactical Communications ++ ++OUI:9849E1* ++ ID_OUI_FROM_DATABASE=Boeing Defence Australia ++ + OUI:984A47* + ID_OUI_FROM_DATABASE=CHG Hospital Beds + +@@ -72263,6 +89816,15 @@ OUI:984E97* + OUI:984FEE* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:98502E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:98523D* ++ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd ++ ++OUI:98524A* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:9852B1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -72278,6 +89840,9 @@ OUI:98588A* + OUI:985945* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:985949* ++ ID_OUI_FROM_DATABASE=LUXOTTICA GROUP S.P.A. ++ + OUI:985AEB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -72290,6 +89855,9 @@ OUI:985C93* + OUI:985D46* + ID_OUI_FROM_DATABASE=PeopleNet Communication + ++OUI:985D82* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ + OUI:985DAD* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -72302,6 +89870,9 @@ OUI:985FD3* + OUI:986022* + ID_OUI_FROM_DATABASE=EMW Co., Ltd. + ++OUI:9860CA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:9866EA* + ID_OUI_FROM_DATABASE=Industrial Control Communications, Inc. + +@@ -72342,7 +89913,7 @@ OUI:986D358* + ID_OUI_FROM_DATABASE=Beijing 3CAVI Tech Co.,Ltd + + OUI:986D359* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Advanced Diagnostics LTD + + OUI:986D35A* + ID_OUI_FROM_DATABASE=iWave Japan, Inc. +@@ -72377,18 +89948,42 @@ OUI:98743D* + OUI:9874DA* + ID_OUI_FROM_DATABASE=Infinix mobility limited + ++OUI:98751A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:9876B6* + ID_OUI_FROM_DATABASE=Adafruit + + OUI:987770* + ID_OUI_FROM_DATABASE=Pep Digital Technology (Guangzhou) Co., Ltd + ++OUI:9877E7* ++ ID_OUI_FROM_DATABASE=Kaonmedia CO., LTD. ++ ++OUI:987A10* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ ++OUI:987A14* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:987BF3* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:987DDD* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:987E46* + ID_OUI_FROM_DATABASE=Emizon Networks Limited + ++OUI:987ECA* ++ ID_OUI_FROM_DATABASE=Inventus Power Eletronica do Brasil LTDA ++ ++OUI:987EE3* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:9880EE* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:988217* + ID_OUI_FROM_DATABASE=Disruptive Ltd + +@@ -72398,6 +89993,9 @@ OUI:988389* + OUI:9884E3* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:98865D* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:9886B1* + ID_OUI_FROM_DATABASE=Flyaudio corporation (China) + +@@ -72407,18 +90005,30 @@ OUI:988744* + OUI:9889ED* + ID_OUI_FROM_DATABASE=Anadem Information Inc. + ++OUI:988B0A* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:988B5D* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:988B69* ++ ID_OUI_FROM_DATABASE=Shenzhen hylitech Co.,LTD ++ + OUI:988BAD* + ID_OUI_FROM_DATABASE=Corintech Ltd. + ++OUI:988D46* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:988E34* + ID_OUI_FROM_DATABASE=ZHEJIANG BOXSAM ELECTRONIC CO.,LTD + + OUI:988E4A* + ID_OUI_FROM_DATABASE=NOXUS(BEIJING) TECHNOLOGY CO.,LTD + ++OUI:988E79* ++ ID_OUI_FROM_DATABASE=Qudelix, Inc. ++ + OUI:988ED4* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + +@@ -72440,9 +90050,18 @@ OUI:989449* + OUI:9897D1* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + ++OUI:989AB9* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:989BCB* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:989C57* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:989D5D* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:989E63* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -72455,6 +90074,9 @@ OUI:98A40E* + OUI:98A7B0* + ID_OUI_FROM_DATABASE=MCST ZAO + ++OUI:98A942* ++ ID_OUI_FROM_DATABASE=Guangzhou Tozed Kangwei Intelligent Technology Co., LTD ++ + OUI:98AA3C* + ID_OUI_FROM_DATABASE=Will i-tech Co., Ltd. + +@@ -72506,18 +90128,39 @@ OUI:98AAFCD* + OUI:98AAFCE* + ID_OUI_FROM_DATABASE=Comarch S.A. + ++OUI:98AD1D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:98AE71* + ID_OUI_FROM_DATABASE=VVDN Technologies Pvt Ltd + ++OUI:98AF65* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:98B039* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:98B177* ++ ID_OUI_FROM_DATABASE=LANDIS + GYR ++ ++OUI:98B3EF* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:98B6E9* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:98B8BA* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ ++OUI:98B8BC* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:98B8E3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:98BA39* ++ ID_OUI_FROM_DATABASE=Doro AB ++ + OUI:98BB1E* + ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd. + +@@ -72533,21 +90176,45 @@ OUI:98BC99* + OUI:98BE94* + ID_OUI_FROM_DATABASE=IBM + ++OUI:98BEDC* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:98C0EB* + ID_OUI_FROM_DATABASE=Global Regency Ltd + ++OUI:98C3D2* ++ ID_OUI_FROM_DATABASE=Ningbo Sanxing Medical Electric Co.,Ltd ++ + OUI:98C5DB* + ID_OUI_FROM_DATABASE=Ericsson AB + ++OUI:98C7A4* ++ ID_OUI_FROM_DATABASE=Shenzhen HS Fiber Communication Equipment CO., LTD ++ + OUI:98C845* + ID_OUI_FROM_DATABASE=PacketAccess + ++OUI:98C8B8* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:98C97C* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ + OUI:98CA33* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:98CB27* + ID_OUI_FROM_DATABASE=Galore Networks Pvt. Ltd. + ++OUI:98CBA4* ++ ID_OUI_FROM_DATABASE=Benchmark Electronics ++ ++OUI:98CC4D* ++ ID_OUI_FROM_DATABASE=Shenzhen mantunsci co., LTD ++ ++OUI:98CDAC* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:98CDB4* + ID_OUI_FROM_DATABASE=Virident Systems, Inc. + +@@ -72563,6 +90230,9 @@ OUI:98D331* + OUI:98D3D2* + ID_OUI_FROM_DATABASE=MEKRA Lang GmbH & Co. KG + ++OUI:98D3E7* ++ ID_OUI_FROM_DATABASE=Netafim L ++ + OUI:98D686* + ID_OUI_FROM_DATABASE=Chyi Lee industry Co., ltd. + +@@ -72581,15 +90251,24 @@ OUI:98D88C* + OUI:98DA92* + ID_OUI_FROM_DATABASE=Vuzix Corporation + ++OUI:98DAC4* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:98DCD9* + ID_OUI_FROM_DATABASE=UNITEC Co., Ltd. + ++OUI:98DD5B* ++ ID_OUI_FROM_DATABASE=TAKUMI JAPAN LTD ++ + OUI:98DDEA* + ID_OUI_FROM_DATABASE=Infinix mobility limited + + OUI:98DED0* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:98DF82* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:98E0D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -72599,6 +90278,9 @@ OUI:98E165* + OUI:98E476* + ID_OUI_FROM_DATABASE=Zentan + ++OUI:98E743* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:98E79A* + ID_OUI_FROM_DATABASE=Foxconn(NanJing) Communication Co.,Ltd. + +@@ -72611,9 +90293,18 @@ OUI:98E7F5* + OUI:98E848* + ID_OUI_FROM_DATABASE=Axiim + ++OUI:98E8FA* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:98EC65* + ID_OUI_FROM_DATABASE=Cosesy ApS + ++OUI:98ED5C* ++ ID_OUI_FROM_DATABASE=Tesla,Inc. ++ ++OUI:98ED7E* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:98EECB* + ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation + +@@ -72623,27 +90314,48 @@ OUI:98EF9B* + OUI:98F058* + ID_OUI_FROM_DATABASE=Lynxspring, Incl. + ++OUI:98F07B* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:98F083* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:98F0AB* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:98F170* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:98F181* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:98F199* + ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. + ++OUI:98F217* ++ ID_OUI_FROM_DATABASE=Castlenet Technology Inc. ++ + OUI:98F2B3* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:98F428* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:98F4AB* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:98F537* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:98F5A9* + ID_OUI_FROM_DATABASE=OHSUNG + ++OUI:98F621* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:98F781* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:98F7D7* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -72653,6 +90365,57 @@ OUI:98F8C1* + OUI:98F8DB* + ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l. + ++OUI:98F9C70* ++ ID_OUI_FROM_DATABASE=SHENZHEN HUNTKEY ELECTRIC CO., LTD. ++ ++OUI:98F9C71* ++ ID_OUI_FROM_DATABASE=HighSecLabs ++ ++OUI:98F9C72* ++ ID_OUI_FROM_DATABASE=Pozyx NV ++ ++OUI:98F9C73* ++ ID_OUI_FROM_DATABASE=Beijing Horizon Information Technology Co., Ltd ++ ++OUI:98F9C74* ++ ID_OUI_FROM_DATABASE=Promess GmbH ++ ++OUI:98F9C75* ++ ID_OUI_FROM_DATABASE=Tonycore Technology Co.,Ltd. ++ ++OUI:98F9C76* ++ ID_OUI_FROM_DATABASE=GoodBox ++ ++OUI:98F9C77* ++ ID_OUI_FROM_DATABASE=ARIMA Communications Corp. ++ ++OUI:98F9C78* ++ ID_OUI_FROM_DATABASE=Renalsense ++ ++OUI:98F9C79* ++ ID_OUI_FROM_DATABASE=Koala Technology CO., LTD. ++ ++OUI:98F9C7A* ++ ID_OUI_FROM_DATABASE=MSB Elektronik und Gerätebau GmbH ++ ++OUI:98F9C7B* ++ ID_OUI_FROM_DATABASE=HIROIA Communications Pte. Ltd. Taiwan Branch ++ ++OUI:98F9C7C* ++ ID_OUI_FROM_DATABASE=ShenZhen Chuangwei Electronic Appliance Co.,Ltd ++ ++OUI:98F9C7D* ++ ID_OUI_FROM_DATABASE=hangzhou soar security technologies limited liability company ++ ++OUI:98F9C7E* ++ ID_OUI_FROM_DATABASE=NC-LINK Technology Co., Ltd. ++ ++OUI:98FA9B* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ ++OUI:98FAA7* ++ ID_OUI_FROM_DATABASE=INNONET ++ + OUI:98FAE3* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -72662,6 +90425,51 @@ OUI:98FB12* + OUI:98FC11* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + ++OUI:98FC840* ++ ID_OUI_FROM_DATABASE=Leia, Inc ++ ++OUI:98FC841* ++ ID_OUI_FROM_DATABASE=go-e GmbH ++ ++OUI:98FC842* ++ ID_OUI_FROM_DATABASE=Juketek Co., Ltd. ++ ++OUI:98FC843* ++ ID_OUI_FROM_DATABASE=Shanghai ZeXin Information Technologies Co. Ltd. ++ ++OUI:98FC844* ++ ID_OUI_FROM_DATABASE=Sferrum GmbH ++ ++OUI:98FC845* ++ ID_OUI_FROM_DATABASE=Zymbit ++ ++OUI:98FC846* ++ ID_OUI_FROM_DATABASE=ZERONE CO., LTD. ++ ++OUI:98FC847* ++ ID_OUI_FROM_DATABASE=Broadtech Technologies Co., Ltd. ++ ++OUI:98FC848* ++ ID_OUI_FROM_DATABASE=Guangdong DE at science and technology co., LTD ++ ++OUI:98FC849* ++ ID_OUI_FROM_DATABASE=Fath Mechatronics ++ ++OUI:98FC84A* ++ ID_OUI_FROM_DATABASE=Shield Inc. ++ ++OUI:98FC84B* ++ ID_OUI_FROM_DATABASE=chiconypower ++ ++OUI:98FC84C* ++ ID_OUI_FROM_DATABASE=Shenzhen Incar Technology Co., Ltd. ++ ++OUI:98FC84D* ++ ID_OUI_FROM_DATABASE=Jazwares LLC ++ ++OUI:98FC84E* ++ ID_OUI_FROM_DATABASE=Dongguan Kingtron Electronics Tech Co., Ltd ++ + OUI:98FD74* + ID_OUI_FROM_DATABASE=ACT.CO.LTD + +@@ -72695,6 +90503,9 @@ OUI:9C0473* + OUI:9C04EB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9C0567* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:9C061B* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +@@ -72713,14 +90524,26 @@ OUI:9C0E4A* + OUI:9C13AB* + ID_OUI_FROM_DATABASE=Chanson Water Co., Ltd. + ++OUI:9C1463* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:9C1465* + ID_OUI_FROM_DATABASE=Edata Elektronik San. ve Tic. A.Ş. + + OUI:9C1874* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + ++OUI:9C19C2* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co., Ltd. ++ + OUI:9C1C12* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:9C1C37* ++ ID_OUI_FROM_DATABASE=AltoBeam (China) Inc. ++ ++OUI:9C1D36* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:9C1D58* + ID_OUI_FROM_DATABASE=Texas Instruments +@@ -72728,6 +90551,9 @@ OUI:9C1D58* + OUI:9C1E95* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + ++OUI:9C1EA4* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:9C1FDD* + ID_OUI_FROM_DATABASE=Accupix Inc. + +@@ -72740,27 +90566,45 @@ OUI:9C216A* + OUI:9C220E* + ID_OUI_FROM_DATABASE=TASCAN Systems GmbH + ++OUI:9C25BE* ++ ID_OUI_FROM_DATABASE=Wildlife Acoustics, Inc. ++ + OUI:9C2840* + ID_OUI_FROM_DATABASE=Discovery Technology,LTD.. + ++OUI:9C28B3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:9C28BF* + ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o. + + OUI:9C28EF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9C28F7* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:9C293F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9C2976* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:9C2A70* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:9C2A83* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:9C2DCF* ++ ID_OUI_FROM_DATABASE=Shishi Tongyun Technology(Chengdu)Co.,Ltd. ++ + OUI:9C2EA1* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:9C2F4E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:9C2F73* + ID_OUI_FROM_DATABASE=Universal Tiancheng Technology (Beijing) Co., Ltd. + +@@ -72776,8 +90620,11 @@ OUI:9C3178* + OUI:9C31B6* + ID_OUI_FROM_DATABASE=Kulite Semiconductor Products Inc + ++OUI:9C31C3* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:9C32A9* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:9C32CE* + ID_OUI_FROM_DATABASE=CANON INC. +@@ -72791,9 +90638,15 @@ OUI:9C3583* + OUI:9C35EB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9C36F8* ++ ID_OUI_FROM_DATABASE=Hyundai Kefico ++ + OUI:9C37F4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9C3A9A* ++ ID_OUI_FROM_DATABASE=Shenzhen Sundray Technologies Company Limited ++ + OUI:9C3AAF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -72803,6 +90656,9 @@ OUI:9C3DCF* + OUI:9C3EAA* + ID_OUI_FROM_DATABASE=EnvyLogic Co.,Ltd. + ++OUI:9C40CD* ++ ID_OUI_FROM_DATABASE=Synclayer Inc. ++ + OUI:9C417C* + ID_OUI_FROM_DATABASE=Hame Technology Co., Limited + +@@ -72849,7 +90705,7 @@ OUI:9C431ED* + ID_OUI_FROM_DATABASE=HK ELEPHONE Communication Tech Co.,Limited + + OUI:9C431EE* +- ID_OUI_FROM_DATABASE=Midas Technology DBA Phoenix Audio Technologies ++ ID_OUI_FROM_DATABASE=Phoenix Audio Technologies + + OUI:9C443D* + ID_OUI_FROM_DATABASE=CHENGDU XUGUANG TECHNOLOGY CO, LTD +@@ -72860,6 +90716,9 @@ OUI:9C44A6* + OUI:9C4563* + ID_OUI_FROM_DATABASE=DIMEP Sistemas + ++OUI:9C497F* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:9C4A7B* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -72878,12 +90737,18 @@ OUI:9C4E8E* + OUI:9C4EBF* + ID_OUI_FROM_DATABASE=BoxCast + ++OUI:9C4F5F* ++ ID_OUI_FROM_DATABASE=TAP Sound System ++ + OUI:9C4FCF* + ID_OUI_FROM_DATABASE=TCT mobile ltd + + OUI:9C4FDA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9C50D1* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:9C50EE* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + +@@ -72896,9 +90761,15 @@ OUI:9C53CD* + OUI:9C541C* + ID_OUI_FROM_DATABASE=Shenzhen My-power Technology Co.,Ltd + ++OUI:9C54C2* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:9C54CA* + ID_OUI_FROM_DATABASE=Zhengzhou VCOM Science and Technology Co.,Ltd + ++OUI:9C54DA* ++ ID_OUI_FROM_DATABASE=SkyBell Technologies Inc. ++ + OUI:9C55B4* + ID_OUI_FROM_DATABASE=I.S.E. S.r.l. + +@@ -72908,9 +90779,15 @@ OUI:9C5711* + OUI:9C57AD* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:9C583C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:9C5A44* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:9C5A81* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:9C5B96* + ID_OUI_FROM_DATABASE=NMR Corporation + +@@ -72921,10 +90798,10 @@ OUI:9C5C8E* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:9C5CF9* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:9C5D12* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:9C5D95* + ID_OUI_FROM_DATABASE=VTC Electronics Corp. +@@ -72932,11 +90809,17 @@ OUI:9C5D95* + OUI:9C5E73* + ID_OUI_FROM_DATABASE=Calibre UK LTD + ++OUI:9C5F5A* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:9C5FB0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:9C611D* +- ID_OUI_FROM_DATABASE=Omni-ID USA, Inc. ++ ID_OUI_FROM_DATABASE=Panasonic Corporation of North America + + OUI:9C6121* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:9C62AB* + ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd +@@ -72947,6 +90830,9 @@ OUI:9C63ED* + OUI:9C645E* + ID_OUI_FROM_DATABASE=Harman Consumer Group + ++OUI:9C648B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:9C65B0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -72962,9 +90848,72 @@ OUI:9C6650* + OUI:9C685B* + ID_OUI_FROM_DATABASE=Octonion SA + ++OUI:9C6865* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:9C6937* ++ ID_OUI_FROM_DATABASE=Qorvo International Pte. Ltd. ++ ++OUI:9C69B40* ++ ID_OUI_FROM_DATABASE=Suzhou Fitcan Technology Co.,LTD ++ ++OUI:9C69B41* ++ ID_OUI_FROM_DATABASE=EA Technology Ltd ++ ++OUI:9C69B42* ++ ID_OUI_FROM_DATABASE=MOZI (Shenzhen) Artificial Intelligence Technology Co., Ltd. ++ ++OUI:9C69B43* ++ ID_OUI_FROM_DATABASE=Appareo Systems, LLC ++ ++OUI:9C69B44* ++ ID_OUI_FROM_DATABASE=Globalcom Engineering SPA ++ ++OUI:9C69B45* ++ ID_OUI_FROM_DATABASE=Elesta GmbH ++ ++OUI:9C69B46* ++ ID_OUI_FROM_DATABASE=Shenzhen jiahua zhongli technology co.LTD ++ ++OUI:9C69B47* ++ ID_OUI_FROM_DATABASE=PCI Limited ++ ++OUI:9C69B48* ++ ID_OUI_FROM_DATABASE=Skydock do Brasil Ltda ++ ++OUI:9C69B49* ++ ID_OUI_FROM_DATABASE=Teptron AB ++ ++OUI:9C69B4A* ++ ID_OUI_FROM_DATABASE=BEIJING PICOHOOD TECHNOLOGY CO.,LTD ++ ++OUI:9C69B4B* ++ ID_OUI_FROM_DATABASE=Toughdog Security Systems ++ ++OUI:9C69B4C* ++ ID_OUI_FROM_DATABASE=Guangdong Hanwei intergration Co.,Ltd ++ ++OUI:9C69B4D* ++ ID_OUI_FROM_DATABASE=Intellect module LLC ++ ++OUI:9C69B4E* ++ ID_OUI_FROM_DATABASE=NINGBO SHEN LINK COMMUNICATION TECHNOLOGY CO., LTD ++ ++OUI:9C69D1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:9C6ABE* + ID_OUI_FROM_DATABASE=QEES ApS. + ++OUI:9C6B37* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ ++OUI:9C6B72* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ ++OUI:9C6BF0* ++ ID_OUI_FROM_DATABASE=Shenzhen Yipingfang Network Technology Co., Ltd. ++ + OUI:9C6C15* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +@@ -72974,12 +90923,24 @@ OUI:9C6F52* + OUI:9C713A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9C7370* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:9C741A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9C746F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:9C7514* + ID_OUI_FROM_DATABASE=Wildix srl + ++OUI:9C760E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:9C7613* ++ ID_OUI_FROM_DATABASE=Ring LLC ++ + OUI:9C77AA* + ID_OUI_FROM_DATABASE=NADASNV + +@@ -72992,18 +90953,33 @@ OUI:9C7A03* + OUI:9C7BD2* + ID_OUI_FROM_DATABASE=NEOLAB Convergence + ++OUI:9C7BEF* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:9C7DA3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:9C7F57* + ID_OUI_FROM_DATABASE=UNIC Memory Technology Co Ltd + ++OUI:9C7F81* ++ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD ++ + OUI:9C807D* + ID_OUI_FROM_DATABASE=SYSCABLE Korea Inc. + + OUI:9C80DF* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + ++OUI:9C823F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:9C8275* ++ ID_OUI_FROM_DATABASE=Yichip Microelectronics (Hangzhou) Co.,Ltd ++ ++OUI:9C8281* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:9C83BF* + ID_OUI_FROM_DATABASE=PRO-VISION, Inc. + +@@ -73019,6 +90995,9 @@ OUI:9C8888* + OUI:9C88AD* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:9C8ACB* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:9C8BA0* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -73028,11 +91007,14 @@ OUI:9C8BF1* + OUI:9C8C6E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:9C8CD8* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:9C8D1A* + ID_OUI_FROM_DATABASE=INTEG process group inc + + OUI:9C8D7C* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:9C8DD3* + ID_OUI_FROM_DATABASE=Leonton Technologies +@@ -73040,6 +91022,9 @@ OUI:9C8DD3* + OUI:9C8E99* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:9C8E9C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:9C8ECD* + ID_OUI_FROM_DATABASE=Amcrest Technologies + +@@ -73049,14 +91034,23 @@ OUI:9C8EDC* + OUI:9C934E* + ID_OUI_FROM_DATABASE=Xerox Corporation + ++OUI:9C93B0* ++ ID_OUI_FROM_DATABASE=Megatronix (Beijing) Technology Co., Ltd. ++ + OUI:9C93E4* + ID_OUI_FROM_DATABASE=Private + ++OUI:9C9567* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:9C95F8* + ID_OUI_FROM_DATABASE=SmartDoor Systems, LLC + + OUI:9C9726* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV ++ ++OUI:9C9789* ++ ID_OUI_FROM_DATABASE=1MORE + + OUI:9C9811* + ID_OUI_FROM_DATABASE=Guangzhou Sunrise Electronics Development Co., Ltd +@@ -73064,15 +91058,30 @@ OUI:9C9811* + OUI:9C99A0* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:9C99CD* ++ ID_OUI_FROM_DATABASE=Voippartners ++ ++OUI:9C9AC0* ++ ID_OUI_FROM_DATABASE=LEGO System A/S ++ + OUI:9C9C1D* + ID_OUI_FROM_DATABASE=Starkey Labs Inc. + ++OUI:9C9C1F* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:9C9C40* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:9C9D5D* + ID_OUI_FROM_DATABASE=Raden Inc + ++OUI:9C9D7E* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:9C9E71* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:9CA10A* + ID_OUI_FROM_DATABASE=SCLE SFE + +@@ -73085,6 +91094,15 @@ OUI:9CA3A9* + OUI:9CA3BA* + ID_OUI_FROM_DATABASE=SAKURA Internet Inc. + ++OUI:9CA513* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:9CA525* ++ ID_OUI_FROM_DATABASE=Shandong USR IOT Technology Limited ++ ++OUI:9CA570* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:9CA577* + ID_OUI_FROM_DATABASE=Osorno Enterprises Inc. + +@@ -73130,6 +91148,9 @@ OUI:9CB206* + OUI:9CB2B2* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:9CB2E8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:9CB654* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -73145,6 +91166,12 @@ OUI:9CB793* + OUI:9CBB98* + ID_OUI_FROM_DATABASE=Shen Zhen RND Electronic Co.,LTD + ++OUI:9CBCF0* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:9CBD6E* ++ ID_OUI_FROM_DATABASE=DERA Co., Ltd ++ + OUI:9CBD9D* + ID_OUI_FROM_DATABASE=SkyDisk, Inc. + +@@ -73169,9 +91196,15 @@ OUI:9CC7D1* + OUI:9CC8AE* + ID_OUI_FROM_DATABASE=Becton, Dickinson and Company + ++OUI:9CC8FC* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:9CC950* + ID_OUI_FROM_DATABASE=Baumer Holding + ++OUI:9CC9EB* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:9CCAD9* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -73199,6 +91232,9 @@ OUI:9CD36D* + OUI:9CD48B* + ID_OUI_FROM_DATABASE=Innolux Technology Europe BV + ++OUI:9CD57D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:9CD643* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -73211,6 +91247,12 @@ OUI:9CD9CB* + OUI:9CDA3E* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:9CDB07* ++ ID_OUI_FROM_DATABASE=Thum+Mahr GmbH ++ ++OUI:9CDBCB* ++ ID_OUI_FROM_DATABASE=Wuhan Funshion Online Technologies Co.,Ltd ++ + OUI:9CDC71* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -73229,6 +91271,9 @@ OUI:9CE063* + OUI:9CE10E* + ID_OUI_FROM_DATABASE=NCTech Ltd + ++OUI:9CE176* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:9CE1D6* + ID_OUI_FROM_DATABASE=Junger Audio-Studiotechnik GmbH + +@@ -73259,29 +91304,44 @@ OUI:9CE82B* + OUI:9CE895* + ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd + ++OUI:9CE91C* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:9CE951* + ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Ltd., Co. + ++OUI:9CEA97* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:9CEBE8* + ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd + ++OUI:9CEDFA* ++ ID_OUI_FROM_DATABASE=EVUlution AG ++ + OUI:9CEFD5* + ID_OUI_FROM_DATABASE=Panda Wireless, Inc. + ++OUI:9CF029* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:9CF387* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:9CF48E* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9CF531* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:9CF61A* +- ID_OUI_FROM_DATABASE=UTC Fire and Security ++ ID_OUI_FROM_DATABASE=Carrier Fire & Security + + OUI:9CF67D* + ID_OUI_FROM_DATABASE=Ricardo Prague, s.r.o. + + OUI:9CF6DD0* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:9CF6DD1* + ID_OUI_FROM_DATABASE=Ithor IT Co.,Ltd. +@@ -73340,15 +91400,66 @@ OUI:9CFBF1* + OUI:9CFC01* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:9CFC28* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:9CFCD1* + ID_OUI_FROM_DATABASE=Aetheris Technology (Shanghai) Co., Ltd. + ++OUI:9CFCE8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:9CFEA1* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + + OUI:9CFFBE* + ID_OUI_FROM_DATABASE=OTSL Inc. + ++OUI:9CFFC2* ++ ID_OUI_FROM_DATABASE=AVI Systems GmbH ++ ++OUI:A0024A0* ++ ID_OUI_FROM_DATABASE=Zhejiang Hechuan Technology Co.,Ltd ++ ++OUI:A0024A1* ++ ID_OUI_FROM_DATABASE=Vitec Imaging Solutions Spa ++ ++OUI:A0024A2* ++ ID_OUI_FROM_DATABASE=Danriver Technologies Corp. ++ ++OUI:A0024A3* ++ ID_OUI_FROM_DATABASE=SomaDetect Inc ++ ++OUI:A0024A4* ++ ID_OUI_FROM_DATABASE=Argos Solutions AS ++ ++OUI:A0024A5* ++ ID_OUI_FROM_DATABASE=Donguan Amsamotion Automation Technology Co., Ltd ++ ++OUI:A0024A6* ++ ID_OUI_FROM_DATABASE=Xiaojie Technology (Shenzhen) Co., Ltd ++ ++OUI:A0024A8* ++ ID_OUI_FROM_DATABASE=Beijing Lyratone Technology Co., Ltd ++ ++OUI:A0024A9* ++ ID_OUI_FROM_DATABASE=Kontakt Micro-Location Sp z o.o. ++ ++OUI:A0024AA* ++ ID_OUI_FROM_DATABASE=Guangdong Jinpeng Technology Co. LTD ++ ++OUI:A0024AB* ++ ID_OUI_FROM_DATABASE=Xi'an Yingsheng Electric Technology Co.,Ltd. ++ ++OUI:A0024AC* ++ ID_OUI_FROM_DATABASE=Encroute AB ++ ++OUI:A0024AD* ++ ID_OUI_FROM_DATABASE=bitbee Inc ++ ++OUI:A0024AE* ++ ID_OUI_FROM_DATABASE=IoTecha Corp ++ + OUI:A002DC* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -73412,6 +91523,9 @@ OUI:A0165C* + OUI:A01828* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A01842* ++ ID_OUI_FROM_DATABASE=Comtrend Corporation ++ + OUI:A01859* + ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd + +@@ -73469,6 +91583,9 @@ OUI:A01B29* + OUI:A01C05* + ID_OUI_FROM_DATABASE=NIMAX TELECOM CO.,LTD. + ++OUI:A01C8D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A01D48* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -73484,12 +91601,63 @@ OUI:A02195* + OUI:A021B7* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:A0224E0* ++ ID_OUI_FROM_DATABASE=Kyung In Electronics ++ ++OUI:A0224E1* ++ ID_OUI_FROM_DATABASE=rNET Controls ++ ++OUI:A0224E2* ++ ID_OUI_FROM_DATABASE=Closed Joint-Stock Company NORSI-TRANS ++ ++OUI:A0224E3* ++ ID_OUI_FROM_DATABASE=ProPhotonix ++ ++OUI:A0224E4* ++ ID_OUI_FROM_DATABASE=TMGcore LLC ++ ++OUI:A0224E5* ++ ID_OUI_FROM_DATABASE=Zhuhai Cheer Technology Co., LTD. ++ ++OUI:A0224E6* ++ ID_OUI_FROM_DATABASE=MESIT asd, s.r.o. ++ ++OUI:A0224E7* ++ ID_OUI_FROM_DATABASE=Applied Information, Inc. ++ ++OUI:A0224E8* ++ ID_OUI_FROM_DATABASE=EISST International Ltd ++ ++OUI:A0224E9* ++ ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc. ++ ++OUI:A0224EA* ++ ID_OUI_FROM_DATABASE=IST ElektronikgesmbH ++ ++OUI:A0224EB* ++ ID_OUI_FROM_DATABASE=All Inspire Health Inc. ++ ++OUI:A0224EC* ++ ID_OUI_FROM_DATABASE=Standartoptic, Limited Liability Company ++ ++OUI:A0224ED* ++ ID_OUI_FROM_DATABASE=Digifocus Technology Inc. ++ ++OUI:A0224EE* ++ ID_OUI_FROM_DATABASE=Hunan Youmei Science&Technology Development Co.,Ltd. ++ ++OUI:A022DE* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:A0231B* + ID_OUI_FROM_DATABASE=TeleComp R&D Corp. + + OUI:A0239F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A027B6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A028330* + ID_OUI_FROM_DATABASE=GERSYS GmbH + +@@ -73535,20 +91703,35 @@ OUI:A02833D* + OUI:A02833E* + ID_OUI_FROM_DATABASE=Precision Planting, LLC. + ++OUI:A028ED* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:A029BD* ++ ID_OUI_FROM_DATABASE=Team Group Inc ++ + OUI:A02BB8* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:A02C36* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + ++OUI:A02D13* ++ ID_OUI_FROM_DATABASE=AirTies Wireless Networks ++ + OUI:A02EF3* + ID_OUI_FROM_DATABASE=United Integrated Services Co., Led. + ++OUI:A031DB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A03299* + ID_OUI_FROM_DATABASE=Lenovo (Beijing) Co., Ltd. + + OUI:A0341B* +- ID_OUI_FROM_DATABASE=TrackR, Inc ++ ID_OUI_FROM_DATABASE=Adero Inc ++ ++OUI:A03679* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:A0369F* + ID_OUI_FROM_DATABASE=Intel Corporate +@@ -73571,12 +91754,21 @@ OUI:A039F7* + OUI:A03A75* + ID_OUI_FROM_DATABASE=PSS Belgium N.V. + ++OUI:A03B01* ++ ID_OUI_FROM_DATABASE=Kyung In Electronics ++ + OUI:A03B1B* + ID_OUI_FROM_DATABASE=Inspire Tech + + OUI:A03BE3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A03C31* ++ ID_OUI_FROM_DATABASE=Shenzhen Belon Technology CO.,LTD ++ ++OUI:A03D6E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A03D6F* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -73637,6 +91829,12 @@ OUI:A04041* + OUI:A040A0* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:A0412D* ++ ID_OUI_FROM_DATABASE=Lansen Systems AB ++ ++OUI:A04147* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A0415E* + ID_OUI_FROM_DATABASE=Opsens Solution Inc. + +@@ -73646,12 +91844,27 @@ OUI:A041A7* + OUI:A0423F* + ID_OUI_FROM_DATABASE=Tyan Computer Corp + ++OUI:A04246* ++ ID_OUI_FROM_DATABASE=IT Telecom Co., Ltd. ++ ++OUI:A043B0* ++ ID_OUI_FROM_DATABASE=Hangzhou BroadLink Technology Co.,Ltd ++ + OUI:A043DB* + ID_OUI_FROM_DATABASE=Sitael S.p.A. + ++OUI:A0445C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:A047D7* ++ ID_OUI_FROM_DATABASE=Best IT World (India) Pvt Ltd ++ + OUI:A0481C* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:A04A5E* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:A04C5B* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + +@@ -73667,9 +91880,18 @@ OUI:A04E04* + OUI:A04EA7* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A04ECF* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:A04F85* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:A04FD4* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + ++OUI:A0510B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A051C6* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -73709,6 +91931,12 @@ OUI:A05E6B* + OUI:A06090* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:A06260* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:A062FB* ++ ID_OUI_FROM_DATABASE=HISENSE VISUAL TECHNOLOGY CO.,LTD ++ + OUI:A06391* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -73724,6 +91952,15 @@ OUI:A06610* + OUI:A067BE* + ID_OUI_FROM_DATABASE=Sicon srl + ++OUI:A0681C* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:A0687E* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:A06974* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:A06986* + ID_OUI_FROM_DATABASE=Wellav Technologies Ltd + +@@ -73748,6 +91985,9 @@ OUI:A06FAA* + OUI:A07099* + ID_OUI_FROM_DATABASE=Beijing Huacan Electronics Co., Ltd + ++OUI:A070B7* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A071A9* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -73769,9 +92009,18 @@ OUI:A07591* + OUI:A075EA* + ID_OUI_FROM_DATABASE=BoxLock, Inc. + ++OUI:A0764E* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:A07751* ++ ID_OUI_FROM_DATABASE=ASMedia Technology Inc. ++ + OUI:A07771* + ID_OUI_FROM_DATABASE=Vialis BV + ++OUI:A07817* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A078BA* + ID_OUI_FROM_DATABASE=Pantech Co., Ltd. + +@@ -73787,6 +92036,9 @@ OUI:A082C7* + OUI:A084CB* + ID_OUI_FROM_DATABASE=SonicSensory,Inc. + ++OUI:A085FC* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:A0861D* + ID_OUI_FROM_DATABASE=Chengdu Fuhuaxin Technology co.,Ltd + +@@ -73832,6 +92084,9 @@ OUI:A090DE* + OUI:A09169* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:A091A2* ++ ID_OUI_FROM_DATABASE=OnePlus Electronics (Shenzhen) Co., Ltd. ++ + OUI:A091C8* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -73841,6 +92096,12 @@ OUI:A09347* + OUI:A09351* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A0941A* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:A0946A* ++ ID_OUI_FROM_DATABASE=Shenzhen XGTEC Technology Co,.Ltd. ++ + OUI:A0950C* + ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited + +@@ -73856,6 +92117,12 @@ OUI:A0999B* + OUI:A09A5A* + ID_OUI_FROM_DATABASE=Time Domain + ++OUI:A09B12* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ ++OUI:A09B17* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:A09BBD* + ID_OUI_FROM_DATABASE=Total Aviation Solutions Pty Ltd + +@@ -73871,6 +92138,15 @@ OUI:A09DC1* + OUI:A09E1A* + ID_OUI_FROM_DATABASE=Polar Electro Oy + ++OUI:A09F10* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ ++OUI:A09F7A* ++ ID_OUI_FROM_DATABASE=D-Link Middle East FZCO ++ ++OUI:A0A0DC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A0A130* + ID_OUI_FROM_DATABASE=DLI Taiwan Branch office + +@@ -73880,9 +92156,18 @@ OUI:A0A23C* + OUI:A0A33B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:A0A3B8* ++ ID_OUI_FROM_DATABASE=WISCLOUD ++ + OUI:A0A3E2* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + ++OUI:A0A3F0* ++ ID_OUI_FROM_DATABASE=D-Link International ++ ++OUI:A0A4C5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A0A65C* + ID_OUI_FROM_DATABASE=Supercomputing Systems AG + +@@ -73898,6 +92183,12 @@ OUI:A0AAFD* + OUI:A0AB1B* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:A0AB51* ++ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD ++ ++OUI:A0AC69* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A0ADA1* + ID_OUI_FROM_DATABASE=JMR Electronics, Inc + +@@ -73907,6 +92198,9 @@ OUI:A0AFBD* + OUI:A0B045* + ID_OUI_FROM_DATABASE=Halong Mining + ++OUI:A0B086* ++ ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH ++ + OUI:A0B100* + ID_OUI_FROM_DATABASE=ShenZhen Cando Electronics Co.,Ltd + +@@ -73916,9 +92210,15 @@ OUI:A0B3CC* + OUI:A0B437* + ID_OUI_FROM_DATABASE=GD Mission Systems + ++OUI:A0B439* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A0B4A5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:A0B549* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:A0B5DA* + ID_OUI_FROM_DATABASE=HongKong THTF Co., Ltd + +@@ -73982,6 +92282,9 @@ OUI:A0BB3EE* + OUI:A0BB3EF* + ID_OUI_FROM_DATABASE=Private + ++OUI:A0BD1D* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:A0BDCD* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +@@ -73998,7 +92301,7 @@ OUI:A0C3DE* + ID_OUI_FROM_DATABASE=Triton Electronic Systems Ltd. + + OUI:A0C4A5* +- ID_OUI_FROM_DATABASE=SYGN HOUSE CO.,LTD ++ ID_OUI_FROM_DATABASE=SYGN HOUSE INC. + + OUI:A0C562* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. +@@ -74022,7 +92325,7 @@ OUI:A0C5F24* + ID_OUI_FROM_DATABASE=AiCare Corp. + + OUI:A0C5F25* +- ID_OUI_FROM_DATABASE=Tango Wave ++ ID_OUI_FROM_DATABASE=Spacepath Communications Ltd + + OUI:A0C5F26* + ID_OUI_FROM_DATABASE=ShenZhen JuWangShi Tech +@@ -74057,6 +92360,9 @@ OUI:A0C6EC* + OUI:A0C9A0* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:A0CAA5* ++ ID_OUI_FROM_DATABASE=INTELLIGENCE TECHNOLOGY OF CEC CO., LTD ++ + OUI:A0CBFD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -74069,9 +92375,21 @@ OUI:A0CEC8* + OUI:A0CF5B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A0CFF5* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:A0D05B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:A0D0DC* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:A0D12A* + ID_OUI_FROM_DATABASE=AXPRO Technology Inc. + ++OUI:A0D2B1* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:A0D37A* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -74084,11 +92402,23 @@ OUI:A0D3C1* + OUI:A0D635* + ID_OUI_FROM_DATABASE=WBS Technology + ++OUI:A0D722* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A0D795* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A0D7A0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A0D807* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A0D83D* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:A0D86F* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=ARGO AI, LLC + + OUI:A0DA92* + ID_OUI_FROM_DATABASE=Nanjing Glarun Atten Technology Co. Ltd. +@@ -74105,6 +92435,12 @@ OUI:A0DDE5* + OUI:A0DE05* + ID_OUI_FROM_DATABASE=JSC Irbis-T + ++OUI:A0DE0F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A0DF15* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A0E0AF* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -74118,7 +92454,7 @@ OUI:A0E295* + ID_OUI_FROM_DATABASE=DAT System Co.,Ltd + + OUI:A0E453* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:A0E4CB* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation +@@ -74135,6 +92471,9 @@ OUI:A0E617* + OUI:A0E6F8* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:A0E70B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A0E9DB* + ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd + +@@ -74183,9 +92522,15 @@ OUI:A0F849* + OUI:A0F895* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + ++OUI:A0F9B7* ++ ID_OUI_FROM_DATABASE=Ademco Smart Homes Technology(Tianjin)Co.,Ltd. ++ + OUI:A0F9E0* + ID_OUI_FROM_DATABASE=VIVATEL COMPANY LIMITED + ++OUI:A0FBC5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A0FC6E* + ID_OUI_FROM_DATABASE=Telegrafia a.s. + +@@ -74195,6 +92540,15 @@ OUI:A0FE61* + OUI:A0FE91* + ID_OUI_FROM_DATABASE=AVAT Automation GmbH + ++OUI:A0FF22* ++ ID_OUI_FROM_DATABASE=SHENZHEN APICAL TECHNOLOGY CO., LTD ++ ++OUI:A0FF70* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:A400E2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A40130* + ID_OUI_FROM_DATABASE=ABIsystems Co., LTD + +@@ -74204,12 +92558,21 @@ OUI:A402B9* + OUI:A40450* + ID_OUI_FROM_DATABASE=nFore Technology Inc. + ++OUI:A4056E* ++ ID_OUI_FROM_DATABASE=Tiinlab Corporation ++ + OUI:A4059E* + ID_OUI_FROM_DATABASE=STA Infinity LLP + ++OUI:A406E9* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:A407B6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:A40801* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:A408EA* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +@@ -74222,6 +92585,9 @@ OUI:A409CB* + OUI:A40BED* + ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd + ++OUI:A40C66* ++ ID_OUI_FROM_DATABASE=Shenzhen Colorful Yugong Technology and Development Co., Ltd. ++ + OUI:A40CC3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -74234,6 +92600,9 @@ OUI:A40E2B* + OUI:A41115* + ID_OUI_FROM_DATABASE=Robert Bosch Engineering and Business Solutions pvt. Ltd. + ++OUI:A41162* ++ ID_OUI_FROM_DATABASE=Arlo Technology ++ + OUI:A411630* + ID_OUI_FROM_DATABASE=Adetel Equipment + +@@ -74279,6 +92648,12 @@ OUI:A41163D* + OUI:A41163E* + ID_OUI_FROM_DATABASE=tinylogics + ++OUI:A41194* ++ ID_OUI_FROM_DATABASE=Lenovo ++ ++OUI:A41232* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:A41242* + ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. + +@@ -74294,12 +92669,27 @@ OUI:A41566* + OUI:A41588* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:A416E7* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A41731* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:A4178B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:A41791* ++ ID_OUI_FROM_DATABASE=Shenzhen Decnta Technology Co.,LTD. ++ + OUI:A41875* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A41908* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:A41B34* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:A41BC0* + ID_OUI_FROM_DATABASE=Fastec Imaging Corporation + +@@ -74324,15 +92714,27 @@ OUI:A4251B* + OUI:A42618* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:A42655* ++ ID_OUI_FROM_DATABASE=LTI Motion (Shanghai) Co., Ltd. ++ ++OUI:A428B7* ++ ID_OUI_FROM_DATABASE=Yangtze Memory Technologies Co., Ltd. ++ + OUI:A42940* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + + OUI:A42983* + ID_OUI_FROM_DATABASE=Boeing Defence Australia + ++OUI:A42985* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:A429B7* + ID_OUI_FROM_DATABASE=bluesky + ++OUI:A42A71* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:A42B8C* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -74342,6 +92744,9 @@ OUI:A42BB0* + OUI:A42C08* + ID_OUI_FROM_DATABASE=Masterwork Automodules + ++OUI:A4307A* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A43111* + ID_OUI_FROM_DATABASE=ZIV + +@@ -74366,6 +92771,9 @@ OUI:A434F1* + OUI:A43523* + ID_OUI_FROM_DATABASE=Guangdong Donyan Network Technologies Co.,Ltd. + ++OUI:A4352D* ++ ID_OUI_FROM_DATABASE=TRIZ Networks corp. ++ + OUI:A43831* + ID_OUI_FROM_DATABASE=RF elements s.r.o. + +@@ -74375,9 +92783,15 @@ OUI:A438CC* + OUI:A438FC* + ID_OUI_FROM_DATABASE=Plastic Logic + ++OUI:A439B6* ++ ID_OUI_FROM_DATABASE=SHENZHEN PEIZHE MICROELECTRONICS CO .LTD ++ + OUI:A43A69* + ID_OUI_FROM_DATABASE=Vers Inc + ++OUI:A43B0E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A43BFA0* + ID_OUI_FROM_DATABASE=Chengdu Territory Technology Co.,Ltd + +@@ -74432,15 +92846,30 @@ OUI:A43D78* + OUI:A43E51* + ID_OUI_FROM_DATABASE=ANOV FRANCE + ++OUI:A43EA0* ++ ID_OUI_FROM_DATABASE=iComm HK LIMITED ++ + OUI:A44027* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:A4423B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A444D1* + ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited + ++OUI:A44519* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:A445CD* ++ ID_OUI_FROM_DATABASE=IoT Diagnostics ++ + OUI:A4466B* + ID_OUI_FROM_DATABASE=EOC Technology + ++OUI:A446B4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A446FA* + ID_OUI_FROM_DATABASE=AmTRAN Video Corporation + +@@ -74450,9 +92879,15 @@ OUI:A44AD3* + OUI:A44B15* + ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD + ++OUI:A44BD5* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:A44C11* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A44C62* ++ ID_OUI_FROM_DATABASE=Hangzhou Microimage Software Co., Ltd ++ + OUI:A44CC8* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -74510,18 +92945,72 @@ OUI:A44F29E* + OUI:A44F29F* + ID_OUI_FROM_DATABASE=Private + ++OUI:A45006* ++ ID_OUI_FROM_DATABASE=SHENZHEN HUACHUANG SHIDAI TECHNOLOGYCO.,LTD ++ ++OUI:A45046* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:A45055* + ID_OUI_FROM_DATABASE=BUSWARE.DE + ++OUI:A45129* ++ ID_OUI_FROM_DATABASE=XAG ++ + OUI:A4516F* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + + OUI:A4526F* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + ++OUI:A4530E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A45385* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + ++OUI:A453EE0* ++ ID_OUI_FROM_DATABASE=MAHLE ELECTRONICS, SLU ++ ++OUI:A453EE1* ++ ID_OUI_FROM_DATABASE=Stellamore ++ ++OUI:A453EE2* ++ ID_OUI_FROM_DATABASE=Ubisafe Smart Devices ++ ++OUI:A453EE3* ++ ID_OUI_FROM_DATABASE=Larva.io OÜ ++ ++OUI:A453EE4* ++ ID_OUI_FROM_DATABASE=Williamson Corporation ++ ++OUI:A453EE5* ++ ID_OUI_FROM_DATABASE=Foshan Yisihang Electrical Technology Co., Ltd. ++ ++OUI:A453EE6* ++ ID_OUI_FROM_DATABASE=Shenzhen Xunqi Interconnet Technology Co., Ltd ++ ++OUI:A453EE7* ++ ID_OUI_FROM_DATABASE=Beijing Lanke Science and Technology Co.,LTd. ++ ++OUI:A453EE8* ++ ID_OUI_FROM_DATABASE=T-Touching Co., Ltd. ++ ++OUI:A453EE9* ++ ID_OUI_FROM_DATABASE=Dongguan HuaFuu industrial co., LTD ++ ++OUI:A453EEB* ++ ID_OUI_FROM_DATABASE=Viper Design, LLC ++ ++OUI:A453EEC* ++ ID_OUI_FROM_DATABASE=SOS LAB Co., Ltd. ++ ++OUI:A453EED* ++ ID_OUI_FROM_DATABASE=SSK CORPORATION ++ ++OUI:A45590* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:A45602* + ID_OUI_FROM_DATABASE=fenglian Technology Co.,Ltd. + +@@ -74534,6 +93023,9 @@ OUI:A45630* + OUI:A456CC* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:A45802* ++ ID_OUI_FROM_DATABASE=SHIN-IL TECH ++ + OUI:A4580F0* + ID_OUI_FROM_DATABASE=INNOPRO + +@@ -74591,9 +93083,15 @@ OUI:A45D36* + OUI:A45DA1* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + ++OUI:A45E5A* ++ ID_OUI_FROM_DATABASE=ACTIVIO Inc. ++ + OUI:A45E60* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A45F9B* ++ ID_OUI_FROM_DATABASE=Nexell ++ + OUI:A46011* + ID_OUI_FROM_DATABASE=Verifone + +@@ -74606,11 +93104,17 @@ OUI:A46191* + OUI:A462DF* + ID_OUI_FROM_DATABASE=DS Global. Co., LTD + ++OUI:A463A1* ++ ID_OUI_FROM_DATABASE=Inventus Power Eletronica do Brasil LTDA ++ + OUI:A46706* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:A468BC* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Oakley Inc. ++ ++OUI:A46BB6* ++ ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:A46C2A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -74621,6 +93125,9 @@ OUI:A46CC1* + OUI:A46CF1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:A46DA4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A46E79* + ID_OUI_FROM_DATABASE=DFT System Co.Ltd + +@@ -74639,6 +93146,12 @@ OUI:A47758* + OUI:A47760* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:A477F3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:A47806* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A47886* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -74651,6 +93164,9 @@ OUI:A47AA4* + OUI:A47ACF* + ID_OUI_FROM_DATABASE=VIBICOM COMMUNICATIONS INC. + ++OUI:A47B1A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A47B2C* + ID_OUI_FROM_DATABASE=Nokia + +@@ -74666,15 +93182,30 @@ OUI:A47C14* + OUI:A47C1F* + ID_OUI_FROM_DATABASE=Cobham plc + ++OUI:A47CC9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:A47D9F* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ ++OUI:A47E36* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:A47E39* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:A4817A* ++ ID_OUI_FROM_DATABASE=CIG SHANGHAI CO LTD ++ + OUI:A481EE* + ID_OUI_FROM_DATABASE=Nokia Corporation + + OUI:A48269* + ID_OUI_FROM_DATABASE=Datrium, Inc. + ++OUI:A483E7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A48431* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -74682,11 +93213,17 @@ OUI:A4856B* + ID_OUI_FROM_DATABASE=Q Electronics Ltd + + OUI:A486AE* +- ID_OUI_FROM_DATABASE=Quectel Wireless Solutions ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ ++OUI:A48873* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:A4895B* + ID_OUI_FROM_DATABASE=ARK INFOSOLUTIONS PVT LTD + ++OUI:A48CC0* ++ ID_OUI_FROM_DATABASE=JLG Industries, Inc. ++ + OUI:A48CDB* + ID_OUI_FROM_DATABASE=Lenovo + +@@ -74700,7 +93237,7 @@ OUI:A49005* + ID_OUI_FROM_DATABASE=CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD + + OUI:A491B1* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:A492CB* + ID_OUI_FROM_DATABASE=Nokia +@@ -74708,12 +93245,30 @@ OUI:A492CB* + OUI:A4933F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:A49340* ++ ID_OUI_FROM_DATABASE=Beijing Supvan Information Technology Co.,Ltd. ++ + OUI:A4934C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:A49426* ++ ID_OUI_FROM_DATABASE=Elgama-Elektronika Ltd. ++ ++OUI:A49733* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ ++OUI:A4975C* ++ ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd. ++ ++OUI:A497B1* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:A497BB* + ID_OUI_FROM_DATABASE=Hitachi Industrial Equipment Systems Co.,Ltd + ++OUI:A49813* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:A49947* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -74729,6 +93284,9 @@ OUI:A49B13* + OUI:A49B4F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:A49BCD* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A49BF5* + ID_OUI_FROM_DATABASE=Hybridserver Tec GmbH + +@@ -74744,6 +93302,9 @@ OUI:A49F85* + OUI:A49F89* + ID_OUI_FROM_DATABASE=Shanghai Rui Rui Communication Technology Co.Ltd. + ++OUI:A4A179* ++ ID_OUI_FROM_DATABASE=Nanjing dianyan electric power automation co. LTD ++ + OUI:A4A1C2* + ID_OUI_FROM_DATABASE=Ericsson AB + +@@ -74753,6 +93314,9 @@ OUI:A4A1E4* + OUI:A4A24A* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:A4A46B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A4A4D3* + ID_OUI_FROM_DATABASE=Bluebank Communication Technology Co.Ltd + +@@ -74762,12 +93326,24 @@ OUI:A4A6A9* + OUI:A4A80F* + ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd. + ++OUI:A4AAFE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A4AC0F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A4AD00* + ID_OUI_FROM_DATABASE=Ragsdale Technology + + OUI:A4ADB8* + ID_OUI_FROM_DATABASE=Vitec Group, Camera Dynamics Ltd + ++OUI:A4AE11* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. ++ ++OUI:A4AE12* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. ++ + OUI:A4AE9A* + ID_OUI_FROM_DATABASE=Maestro Wireless Solutions ltd. + +@@ -74777,21 +93353,33 @@ OUI:A4B121* + OUI:A4B197* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A4B1C1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A4B1E9* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:A4B1EE* + ID_OUI_FROM_DATABASE=H. ZANDER GmbH & Co. KG + ++OUI:A4B239* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A4B2A7* + ID_OUI_FROM_DATABASE=Adaxys Solutions AG + + OUI:A4B36A* + ID_OUI_FROM_DATABASE=JSC SDO Chromatec + ++OUI:A4B439* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A4B52E* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:A4B61E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A4B805* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -74807,9 +93395,15 @@ OUI:A4BA76* + OUI:A4BADB* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:A4BB6D* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:A4BBAF* + ID_OUI_FROM_DATABASE=Lime Instruments + ++OUI:A4BDC4* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A4BE2B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -74834,23 +93428,50 @@ OUI:A4C2AB* + OUI:A4C361* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A4C3F0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A4C494* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:A4C54E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A4C64F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:A4C74B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A4C7DE* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:A4C939* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:A4CAA0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:A4CC32* + ID_OUI_FROM_DATABASE=Inficomm Co., Ltd + ++OUI:A4CCB9* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ ++OUI:A4CD23* ++ ID_OUI_FROM_DATABASE=Shenzhenshi Xinzhongxin Co., Ltd ++ ++OUI:A4CEDA* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ ++OUI:A4CF12* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:A4CFD2* ++ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited ++ + OUI:A4D094* +- ID_OUI_FROM_DATABASE=Erwin Peters Systemtechnik GmbH ++ ID_OUI_FROM_DATABASE=VIVAVIS AG + + OUI:A4D18C* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -74873,12 +93494,21 @@ OUI:A4D4B2* + OUI:A4D578* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:A4D73C* ++ ID_OUI_FROM_DATABASE=Seiko Epson Corporation ++ ++OUI:A4D795* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd ++ + OUI:A4D856* + ID_OUI_FROM_DATABASE=Gimbal, Inc + + OUI:A4D8CA* + ID_OUI_FROM_DATABASE=HONG KONG WATER WORLD TECHNOLOGY CO. LIMITED + ++OUI:A4D931* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A4D990* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -74916,7 +93546,7 @@ OUI:A4DA229* + ID_OUI_FROM_DATABASE=Malldon Technology Limited + + OUI:A4DA22A* +- ID_OUI_FROM_DATABASE=Abetechs GmbH ++ ID_OUI_FROM_DATABASE=Grundig + + OUI:A4DA22B* + ID_OUI_FROM_DATABASE=Klashwerks Inc. +@@ -74936,6 +93566,9 @@ OUI:A4DA32* + OUI:A4DA3F* + ID_OUI_FROM_DATABASE=Bionics Corp. + ++OUI:A4DAD4* ++ ID_OUI_FROM_DATABASE=Yamato Denki Co.,Ltd. ++ + OUI:A4DB2E* + ID_OUI_FROM_DATABASE=Kingspan Environmental Ltd + +@@ -74954,6 +93587,12 @@ OUI:A4DEC9* + OUI:A4E0E6* + ID_OUI_FROM_DATABASE=FILIZOLA S.A. PESAGEM E AUTOMACAO + ++OUI:A4E11A* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:A4E31B* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:A4E32E* + ID_OUI_FROM_DATABASE=Silicon & Software Systems Ltd. + +@@ -74963,6 +93602,9 @@ OUI:A4E391* + OUI:A4E4B8* + ID_OUI_FROM_DATABASE=BlackBerry RTS + ++OUI:A4E57C* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:A4E597* + ID_OUI_FROM_DATABASE=Gessler GmbH + +@@ -74999,6 +93641,12 @@ OUI:A4ED430* + OUI:A4ED431* + ID_OUI_FROM_DATABASE=INGELABS S.L. + ++OUI:A4ED432* ++ ID_OUI_FROM_DATABASE=Shanghai Mission Information Technologies (Group) Co.,Ltd ++ ++OUI:A4ED433* ++ ID_OUI_FROM_DATABASE=Dongguan Mingji Electronics technology Group Co., Ltd. ++ + OUI:A4ED434* + ID_OUI_FROM_DATABASE=NETAS TELEKOMUNIKASYON A.S. + +@@ -75008,6 +93656,9 @@ OUI:A4ED435* + OUI:A4ED436* + ID_OUI_FROM_DATABASE=Shanghai Facom Electronics Technology Co, ltd. + ++OUI:A4ED437* ++ ID_OUI_FROM_DATABASE=Wuxi Junction Infomation Technology Incorporated Company ++ + OUI:A4ED438* + ID_OUI_FROM_DATABASE=Linseis Messgeraete GmbH + +@@ -75017,9 +93668,18 @@ OUI:A4ED439* + OUI:A4ED43A* + ID_OUI_FROM_DATABASE=Guangzhou Maxfaith Communication Technology Co.,LTD. + ++OUI:A4ED43B* ++ ID_OUI_FROM_DATABASE=Paragon Business Solutions Ltd. ++ ++OUI:A4ED43C* ++ ID_OUI_FROM_DATABASE=leakSMART ++ + OUI:A4ED43D* + ID_OUI_FROM_DATABASE=Brand New Brand Nordic AB + ++OUI:A4ED43E* ++ ID_OUI_FROM_DATABASE=TOEC TECHNOLOGY CO.,LTD. ++ + OUI:A4ED4E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -75029,6 +93689,9 @@ OUI:A4EE57* + OUI:A4EF52* + ID_OUI_FROM_DATABASE=Telewave Co., Ltd. + ++OUI:A4F05E* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:A4F1E8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -75038,6 +93701,9 @@ OUI:A4F3C1* + OUI:A4F3E7* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:A4F465* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:A4F4C2* + ID_OUI_FROM_DATABASE=VNPT TECHNOLOGY + +@@ -75047,18 +93713,39 @@ OUI:A4F522* + OUI:A4F7D0* + ID_OUI_FROM_DATABASE=LAN Accessories Co., Ltd. + ++OUI:A4F9E4* ++ ID_OUI_FROM_DATABASE=AirVine Scientific, Inc. ++ ++OUI:A4FA76* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:A4FB8D* + ID_OUI_FROM_DATABASE=Hangzhou Dunchong Technology Co.Ltd + ++OUI:A4FC77* ++ ID_OUI_FROM_DATABASE=Mega Well Limited ++ + OUI:A4FCCE* + ID_OUI_FROM_DATABASE=Security Expert Ltd. + ++OUI:A4FF95* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:A8016D* + ID_OUI_FROM_DATABASE=Aiwa Corporation + + OUI:A80180* + ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH + ++OUI:A802DB* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:A8032A* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:A80577* ++ ID_OUI_FROM_DATABASE=Netlist, Inc. ++ + OUI:A80600* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -75114,7 +93801,7 @@ OUI:A81D16* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + + OUI:A81E84* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:A81FAF* + ID_OUI_FROM_DATABASE=KRYPTON POLSKA +@@ -75122,6 +93809,15 @@ OUI:A81FAF* + OUI:A82066* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A82316* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:A823FE* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ ++OUI:A824B8* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:A824EB* + ID_OUI_FROM_DATABASE=ZAO NPO Introtest + +@@ -75140,27 +93836,111 @@ OUI:A82BB5* + OUI:A82BB9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:A82BCD* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A82BD6* + ID_OUI_FROM_DATABASE=Shina System Co., Ltd + ++OUI:A8301C* ++ ID_OUI_FROM_DATABASE=Qingdao Intelligent&Precise Electronics Co.,Ltd. ++ + OUI:A830AD* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + ++OUI:A830BC* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A8329A* + ID_OUI_FROM_DATABASE=Digicom Futuristic Technologies Ltd. + ++OUI:A8346A* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:A83512* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A8367A* + ID_OUI_FROM_DATABASE=frogblue TECHNOLOGY GmbH + ++OUI:A83759* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A83944* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + ++OUI:A83B5C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:A83CCB* ++ ID_OUI_FROM_DATABASE=ROSSMA ++ + OUI:A83E0E* + ID_OUI_FROM_DATABASE=HMD Global Oy + ++OUI:A83FA10* ++ ID_OUI_FROM_DATABASE=Imecon Engineering SrL ++ ++OUI:A83FA11* ++ ID_OUI_FROM_DATABASE=GTDevice LLC ++ ++OUI:A83FA12* ++ ID_OUI_FROM_DATABASE=MEDCAPTAIN MEDICAL TECHNOLOGY CO., LTD. ++ ++OUI:A83FA13* ++ ID_OUI_FROM_DATABASE=Guangzhou Tupu Internet Technology Co., Ltd. ++ ++OUI:A83FA14* ++ ID_OUI_FROM_DATABASE=Zhejiang Wellsun Intelligent Technology Co.,Ltd. ++ ++OUI:A83FA15* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:A83FA16* ++ ID_OUI_FROM_DATABASE=BEGLEC ++ ++OUI:A83FA17* ++ ID_OUI_FROM_DATABASE=Plejd AB ++ ++OUI:A83FA18* ++ ID_OUI_FROM_DATABASE=Neos Ventures Limited ++ ++OUI:A83FA19* ++ ID_OUI_FROM_DATABASE=Shenzhen ITLONG Intelligent Technology Co.,Ltd ++ ++OUI:A83FA1A* ++ ID_OUI_FROM_DATABASE=Shanghai East China Computer Co., Ltd ++ ++OUI:A83FA1B* ++ ID_OUI_FROM_DATABASE=Exel s.r.l. unipersonale ++ ++OUI:A83FA1C* ++ ID_OUI_FROM_DATABASE=Laonz Co.,Ltd ++ ++OUI:A83FA1D* ++ ID_OUI_FROM_DATABASE=Shenzhen BIO I/E Co.,Ltd ++ ++OUI:A83FA1E* ++ ID_OUI_FROM_DATABASE=Guangzhou Navigateworx Technologies Co., Limited ++ ++OUI:A84025* ++ ID_OUI_FROM_DATABASE=Oxide Computer Company ++ + OUI:A84041* + ID_OUI_FROM_DATABASE=Dragino Technology Co., Limited + ++OUI:A8407D* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:A84122* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co.,Ltd. ++ ++OUI:A842A7* ++ ID_OUI_FROM_DATABASE=Jiangsu Huitong Group Co.,Ltd. ++ ++OUI:A84397* ++ ID_OUI_FROM_DATABASE=Innogrit Corporation ++ + OUI:A84481* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -75170,15 +93950,36 @@ OUI:A845CD* + OUI:A845E9* + ID_OUI_FROM_DATABASE=Firich Enterprises CO., LTD. + ++OUI:A8469D* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:A8474A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:A848FA* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:A8494D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A849A5* + ID_OUI_FROM_DATABASE=Lisantech Co., Ltd. + ++OUI:A84A28* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:A84A63* ++ ID_OUI_FROM_DATABASE=TPV Display Technology(Xiamen) Co.,Ltd. ++ ++OUI:A84D4A* ++ ID_OUI_FROM_DATABASE=Audiowise Technology Inc. ++ + OUI:A84E3F* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + ++OUI:A85081* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A8515B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -75186,7 +93987,7 @@ OUI:A854B2* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + + OUI:A8556A* +- ID_OUI_FROM_DATABASE=Pocketnet Technology Inc. ++ ID_OUI_FROM_DATABASE=3S System Technology Inc. + + OUI:A8574E* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. +@@ -75194,9 +93995,57 @@ OUI:A8574E* + OUI:A85840* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:A85AE0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A85AF3* + ID_OUI_FROM_DATABASE=Shanghai Siflower Communication Technology Co., Ltd + ++OUI:A85B360* ++ ID_OUI_FROM_DATABASE=Bluesoo Tech (HongKong) Co.,Limited ++ ++OUI:A85B361* ++ ID_OUI_FROM_DATABASE=PARMA LLC ++ ++OUI:A85B362* ++ ID_OUI_FROM_DATABASE=Loomanet Inc. ++ ++OUI:A85B363* ++ ID_OUI_FROM_DATABASE=Shenzhen Dandelion Intelligent Cloud Technology Development Co., LTD ++ ++OUI:A85B364* ++ ID_OUI_FROM_DATABASE=Luoxian (Guandong) Technology Co., Ltd ++ ++OUI:A85B365* ++ ID_OUI_FROM_DATABASE=JUGANU LTD ++ ++OUI:A85B366* ++ ID_OUI_FROM_DATABASE=DAP B.V. ++ ++OUI:A85B367* ++ ID_OUI_FROM_DATABASE=Louis Vuitton Malletier ++ ++OUI:A85B368* ++ ID_OUI_FROM_DATABASE=ShangHai SnowLake Technology Co.,LTD. ++ ++OUI:A85B369* ++ ID_OUI_FROM_DATABASE=Avista Edge ++ ++OUI:A85B36A* ++ ID_OUI_FROM_DATABASE=TAIDEN INDUSTRIAL CO.,LTD ++ ++OUI:A85B36B* ++ ID_OUI_FROM_DATABASE=Lampyris Plant LLC ++ ++OUI:A85B36C* ++ ID_OUI_FROM_DATABASE=ATER Technologies Co Ltd ++ ++OUI:A85B36D* ++ ID_OUI_FROM_DATABASE=Adam Hall GmbH ++ ++OUI:A85B36E* ++ ID_OUI_FROM_DATABASE=ORBITVU Sp. z o. o. ++ + OUI:A85B6C* + ID_OUI_FROM_DATABASE=Robert Bosch Gmbh, CM-CI2 + +@@ -75212,6 +94061,9 @@ OUI:A85BF3* + OUI:A85C2C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A85E45* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:A85EE4* + ID_OUI_FROM_DATABASE=12Sided Technology, LLC + +@@ -75227,6 +94079,9 @@ OUI:A861AA* + OUI:A862A2* + ID_OUI_FROM_DATABASE=JIWUMEDIA CO., LTD. + ++OUI:A8637D* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:A863DF* + ID_OUI_FROM_DATABASE=DISPLAIRE CORPORATION + +@@ -75236,15 +94091,27 @@ OUI:A863F2* + OUI:A86405* + ID_OUI_FROM_DATABASE=nimbus 9, Inc + ++OUI:A864F1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A865B2* + ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED + + OUI:A8667F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A8671E* ++ ID_OUI_FROM_DATABASE=RATP ++ ++OUI:A8698C* ++ ID_OUI_FROM_DATABASE=Oracle Corporation ++ + OUI:A86A6F* + ID_OUI_FROM_DATABASE=RIM + ++OUI:A86ABB* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:A86AC1* + ID_OUI_FROM_DATABASE=HanbitEDS Co., Ltd. + +@@ -75254,6 +94121,18 @@ OUI:A86B7C* + OUI:A86BAD* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:A86D5F* ++ ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD ++ ++OUI:A86DAA* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:A86E4E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A8705D* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:A870A5* + ID_OUI_FROM_DATABASE=UniComm Inc. + +@@ -75263,15 +94142,24 @@ OUI:A87285* + OUI:A8741D* + ID_OUI_FROM_DATABASE=PHOENIX CONTACT Electronics GmbH + ++OUI:A87484* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:A875D6* + ID_OUI_FROM_DATABASE=FreeTek International Co., Ltd. + + OUI:A875E2* + ID_OUI_FROM_DATABASE=Aventura Technologies, Inc. + ++OUI:A87650* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A8776F* + ID_OUI_FROM_DATABASE=Zonoff + ++OUI:A877E5* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ + OUI:A87B39* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -75284,9 +94172,15 @@ OUI:A87D12* + OUI:A87E33* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + ++OUI:A87EEA* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:A88038* + ID_OUI_FROM_DATABASE=ShenZhen MovingComm Technology Co., Limited + ++OUI:A8817E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A88195* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -75299,18 +94193,27 @@ OUI:A88200* + OUI:A8827F* + ID_OUI_FROM_DATABASE=CIBN Oriental Network(Beijing) CO.,Ltd + ++OUI:A885D7* ++ ID_OUI_FROM_DATABASE=Sangfor Technologies Inc. ++ + OUI:A886DD* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:A88792* + ID_OUI_FROM_DATABASE=Broadband Antenna Tracking Systems + ++OUI:A887B3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:A887ED* + ID_OUI_FROM_DATABASE=ARC Wireless LLC + + OUI:A88808* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A88940* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A88CEE* + ID_OUI_FROM_DATABASE=MicroMade Galka i Drozdz sp.j. + +@@ -75323,9 +94226,18 @@ OUI:A88E24* + OUI:A89008* + ID_OUI_FROM_DATABASE=Beijing Yuecheng Technology Co. Ltd. + ++OUI:A89042* ++ ID_OUI_FROM_DATABASE=Beijing Wanwei Intelligent Technology Co., Ltd. ++ ++OUI:A8913D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:A8922C* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:A8934A* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:A89352* + ID_OUI_FROM_DATABASE=SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD + +@@ -75341,6 +94253,9 @@ OUI:A89675* + OUI:A8968A* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A897CD* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:A897DC* + ID_OUI_FROM_DATABASE=IBM + +@@ -75353,12 +94268,24 @@ OUI:A8995C* + OUI:A89969* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:A899DC* ++ ID_OUI_FROM_DATABASE=i-TOP DESING TECHNOLOGY CO.,LTD ++ + OUI:A89A93* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:A89AD7* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:A89B10* + ID_OUI_FROM_DATABASE=inMotion Ltd. + ++OUI:A89CA4* ++ ID_OUI_FROM_DATABASE=Furrion Limited ++ ++OUI:A89CED* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:A89D21* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -75374,6 +94301,12 @@ OUI:A89FEC* + OUI:A8A089* + ID_OUI_FROM_DATABASE=Tactical Communications + ++OUI:A8A097* ++ ID_OUI_FROM_DATABASE=ScioTeq bvba ++ ++OUI:A8A159* ++ ID_OUI_FROM_DATABASE=ASRock Incorporation ++ + OUI:A8A198* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -75392,6 +94325,9 @@ OUI:A8A795* + OUI:A8AD3D* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + ++OUI:A8B088* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:A8B0AE* + ID_OUI_FROM_DATABASE=LEONI + +@@ -75401,6 +94337,9 @@ OUI:A8B1D4* + OUI:A8B2DA* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + ++OUI:A8B456* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:A8B86E* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -75413,6 +94352,9 @@ OUI:A8BB50* + OUI:A8BBCF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A8BC9C* ++ ID_OUI_FROM_DATABASE=Cloud Light Technology Limited ++ + OUI:A8BD1A* + ID_OUI_FROM_DATABASE=Honey Bee (Hong Kong) Limited + +@@ -75425,9 +94367,21 @@ OUI:A8BD3A* + OUI:A8BE27* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:A8BF3C* ++ ID_OUI_FROM_DATABASE=HDV Phoelectron Technology Limited ++ ++OUI:A8C092* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:A8C0EA* ++ ID_OUI_FROM_DATABASE=Pepwave Limited ++ + OUI:A8C222* + ID_OUI_FROM_DATABASE=TM-Research Inc. + ++OUI:A8C252* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A8C83A* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -75443,14 +94397,20 @@ OUI:A8CAB9* + OUI:A8CB95* + ID_OUI_FROM_DATABASE=EAST BEST CO., LTD. + ++OUI:A8CC6F* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:A8CCC5* + ID_OUI_FROM_DATABASE=Saab AB (publ) + + OUI:A8CE90* + ID_OUI_FROM_DATABASE=CVC + ++OUI:A8D081* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A8D0E3* +- ID_OUI_FROM_DATABASE=Systech Electronics Ltd. ++ ID_OUI_FROM_DATABASE=Systech Electronics Ltd + + OUI:A8D0E5* + ID_OUI_FROM_DATABASE=Juniper Networks +@@ -75482,24 +94442,48 @@ OUI:A8D88A* + OUI:A8DA01* + ID_OUI_FROM_DATABASE=Shenzhen NUOLIJIA Digital Technology Co.,Ltd + ++OUI:A8DA0C* ++ ID_OUI_FROM_DATABASE=SERVERCOM (INDIA) PRIVATE LIMITED ++ ++OUI:A8DB03* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ + OUI:A8E018* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:A8E2C1* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:A8E2C3* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:A8E3EE* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + + OUI:A8E539* + ID_OUI_FROM_DATABASE=Moimstone Co.,Ltd + ++OUI:A8E544* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:A8E552* + ID_OUI_FROM_DATABASE=JUWEL Aquarium AG & Co. KG + + OUI:A8E705* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:A8E77D* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:A8E81E* ++ ID_OUI_FROM_DATABASE=ATW TECHNOLOGY, INC. ++ + OUI:A8E824* + ID_OUI_FROM_DATABASE=INIM ELECTRONICS S.R.L. + ++OUI:A8E978* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A8EEC6* + ID_OUI_FROM_DATABASE=Muuselabs NV/SA + +@@ -75509,6 +94493,9 @@ OUI:A8EF26* + OUI:A8F038* + ID_OUI_FROM_DATABASE=SHEN ZHEN SHI JIN HUA TAI ELECTRONICS CO.,LTD + ++OUI:A8F266* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:A8F274* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -75518,6 +94505,12 @@ OUI:A8F470* + OUI:A8F5AC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:A8F5DD* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:A8F766* ++ ID_OUI_FROM_DATABASE=ITE Tech Inc ++ + OUI:A8F7E0* + ID_OUI_FROM_DATABASE=PLANET Technology Corporation + +@@ -75533,6 +94526,9 @@ OUI:A8FB70* + OUI:A8FCB7* + ID_OUI_FROM_DATABASE=Consolidated Resource Imaging + ++OUI:A8FFBA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:AA0000* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +@@ -75548,6 +94544,9 @@ OUI:AA0003* + OUI:AA0004* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + ++OUI:AC00D0* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:AC0142* + ID_OUI_FROM_DATABASE=Uriel Technologies SIA + +@@ -75578,6 +94577,9 @@ OUI:AC075F* + OUI:AC0A61* + ID_OUI_FROM_DATABASE=Labor S.r.L. + ++OUI:AC0BFB* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:AC0D1B* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -75587,12 +94589,27 @@ OUI:AC0DFE* + OUI:AC11D3* + ID_OUI_FROM_DATABASE=Suzhou HOTEK Video Technology Co. Ltd + ++OUI:AC1203* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:AC122F* ++ ID_OUI_FROM_DATABASE=Fantasia Trading LLC ++ ++OUI:AC139C* ++ ID_OUI_FROM_DATABASE=Adtran Inc ++ + OUI:AC1461* + ID_OUI_FROM_DATABASE=ATAW Co., Ltd. + + OUI:AC14D2* + ID_OUI_FROM_DATABASE=wi-daq, inc. + ++OUI:AC1585* ++ ID_OUI_FROM_DATABASE=silergy corp ++ ++OUI:AC15F4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:AC162D* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -75608,6 +94625,9 @@ OUI:AC1826* + OUI:AC199F* + ID_OUI_FROM_DATABASE=SUNGROW POWER SUPPLY CO.,LTD. + ++OUI:AC1D06* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:AC1DDF0* + ID_OUI_FROM_DATABASE=PiOctave Solutions Pvt Ltd + +@@ -75642,7 +94662,7 @@ OUI:AC1DDFA* + ID_OUI_FROM_DATABASE=WESCO INTEGRATED SUPPLY + + OUI:AC1DDFB* +- ID_OUI_FROM_DATABASE=Fine Inc. ++ ID_OUI_FROM_DATABASE=FINEpowerX INC + + OUI:AC1DDFC* + ID_OUI_FROM_DATABASE=Beijing Chunhong Technology Co., Ltd. +@@ -75653,6 +94673,18 @@ OUI:AC1DDFD* + OUI:AC1DDFE* + ID_OUI_FROM_DATABASE=Duravit AG + ++OUI:AC1E92* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD ++ ++OUI:AC1ED0* ++ ID_OUI_FROM_DATABASE=Temic Automotive Philippines Inc. ++ ++OUI:AC1F09* ++ ID_OUI_FROM_DATABASE=shenzhen RAKwireless technology Co.,Ltd ++ ++OUI:AC1F0F* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:AC1F6B* + ID_OUI_FROM_DATABASE=Super Micro Computer, Inc. + +@@ -75677,6 +94709,12 @@ OUI:AC2205* + OUI:AC220B* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:AC2316* ++ ID_OUI_FROM_DATABASE=Mist Systems, Inc. ++ ++OUI:AC2334* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ + OUI:AC233F* + ID_OUI_FROM_DATABASE=Shenzhen Minew Technologies Co., Ltd. + +@@ -75692,12 +94730,18 @@ OUI:AC2B6E* + OUI:AC2DA3* + ID_OUI_FROM_DATABASE=TXTR GmbH + ++OUI:AC2DA9* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:AC2FA8* + ID_OUI_FROM_DATABASE=Humannix Co.,Ltd. + + OUI:AC319D* + ID_OUI_FROM_DATABASE=Shenzhen TG-NET Botone Technology Co.,Ltd. + ++OUI:AC3328* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:AC34CB* + ID_OUI_FROM_DATABASE=Shanhai GBCOM Communication Technology Co. Ltd + +@@ -75707,12 +94751,24 @@ OUI:AC35EE* + OUI:AC3613* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:AC3651* ++ ID_OUI_FROM_DATABASE=Jiangsu Hengtong Terahertz Technology Co., Ltd. ++ ++OUI:AC3728* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:AC3743* + ID_OUI_FROM_DATABASE=HTC Corporation + ++OUI:AC37C9* ++ ID_OUI_FROM_DATABASE=RAID Incorporated ++ + OUI:AC3870* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + ++OUI:AC3A67* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:AC3A7A* + ID_OUI_FROM_DATABASE=Roku, Inc. + +@@ -75722,6 +94778,9 @@ OUI:AC3B77* + OUI:AC3C0B* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:AC3C8E* ++ ID_OUI_FROM_DATABASE=Flextronics Computing(Suzhou)Co.,Ltd. ++ + OUI:AC3CB4* + ID_OUI_FROM_DATABASE=Nilan A/S + +@@ -75740,18 +94799,39 @@ OUI:AC40EA* + OUI:AC4122* + ID_OUI_FROM_DATABASE=Eclipse Electronic Systems Inc. + ++OUI:AC4228* ++ ID_OUI_FROM_DATABASE=Parta Networks ++ ++OUI:AC4330* ++ ID_OUI_FROM_DATABASE=Versa Networks ++ + OUI:AC44F2* + ID_OUI_FROM_DATABASE=YAMAHA CORPORATION + ++OUI:AC471B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:AC4723* + ID_OUI_FROM_DATABASE=Genelec + + OUI:AC482D* + ID_OUI_FROM_DATABASE=Ralinwi Nanjing Electronic Technology Co., Ltd. + ++OUI:AC49DB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:AC4A56* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:AC4A67* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:AC4AFE* + ID_OUI_FROM_DATABASE=Hisense Broadband Multimedia Technology Co.,Ltd. + ++OUI:AC4B1E* ++ ID_OUI_FROM_DATABASE=Integri-Sys.Com LLC ++ + OUI:AC4BC8* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -75767,6 +94847,9 @@ OUI:AC4FFC* + OUI:AC5036* + ID_OUI_FROM_DATABASE=Pi-Coral Inc + ++OUI:AC5093* ++ ID_OUI_FROM_DATABASE=Magna Electronics Europe GmbH & Co. OHG ++ + OUI:AC512C* + ID_OUI_FROM_DATABASE=Infinix mobility limited + +@@ -75785,6 +94868,9 @@ OUI:AC54EC* + OUI:AC562C* + ID_OUI_FROM_DATABASE=LAVA INTERNATIONAL(H.K) LIMITED + ++OUI:AC5775* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:AC583B* + ID_OUI_FROM_DATABASE=Human Assembler, Inc. + +@@ -75794,15 +94880,30 @@ OUI:AC587B* + OUI:AC5A14* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:AC5AEE* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:AC5AFC* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:AC5D10* + ID_OUI_FROM_DATABASE=Pace Americas + ++OUI:AC5D5C* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:AC5E8C* + ID_OUI_FROM_DATABASE=Utillink + + OUI:AC5F3E* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:AC5FEA* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ ++OUI:AC6089* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:AC60B6* + ID_OUI_FROM_DATABASE=Ericsson AB + +@@ -75812,6 +94913,9 @@ OUI:AC6123* + OUI:AC6175* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:AC61B9* ++ ID_OUI_FROM_DATABASE=WAMA Technology Limited ++ + OUI:AC61EA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -75827,6 +94931,12 @@ OUI:AC6417* + OUI:AC6462* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:AC6490* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:AC64CF* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:AC64DD0* + ID_OUI_FROM_DATABASE=Jia-Teng + +@@ -75875,9 +94985,21 @@ OUI:AC64DDE* + OUI:AC6706* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:AC675D* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:AC676F* + ID_OUI_FROM_DATABASE=Electrocompaniet A.S. + ++OUI:AC6784* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:AC67B2* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:AC6AA3* ++ ID_OUI_FROM_DATABASE=Shenzhen Kertong Technology Co.,Ltd ++ + OUI:AC6B0F* + ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS INC + +@@ -75896,6 +95018,9 @@ OUI:AC6FBB* + OUI:AC6FD9* + ID_OUI_FROM_DATABASE=Valueplus Inc. + ++OUI:AC710C* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:AC7236* + ID_OUI_FROM_DATABASE=Lexking Technology Co., Ltd. + +@@ -75905,18 +95030,39 @@ OUI:AC7289* + OUI:AC7409* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:AC74B1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:AC74C4* ++ ID_OUI_FROM_DATABASE=Maytronics Ltd. ++ + OUI:AC751D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:AC764C* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:AC7713* ++ ID_OUI_FROM_DATABASE=Honeywell Safety Products (Shanghai) Co.,Ltd ++ ++OUI:AC78D1* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:AC7A42* + ID_OUI_FROM_DATABASE=iConnectivity + + OUI:AC7A4D* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ ++OUI:AC7A56* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:AC7BA1* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:AC7E01* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:AC7E8A* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -75932,9 +95078,15 @@ OUI:AC8112* + OUI:AC81F3* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:AC8247* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:AC8317* + ID_OUI_FROM_DATABASE=Shenzhen Furtunetel Communication Co., Ltd + ++OUI:AC83E9* ++ ID_OUI_FROM_DATABASE=Beijing Zile Technology Co., Ltd ++ + OUI:AC83F0* + ID_OUI_FROM_DATABASE=ImmediaTV Corporation + +@@ -75959,15 +95111,30 @@ OUI:AC867E* + OUI:AC87A3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:AC88FD* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:AC8995* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + + OUI:AC8ACD* + ID_OUI_FROM_DATABASE=ROGER D.Wensker, G.Wensker sp.j. + ++OUI:AC8B9C* ++ ID_OUI_FROM_DATABASE=Primera Technology, Inc. ++ + OUI:AC8D14* + ID_OUI_FROM_DATABASE=Smartrove Inc + ++OUI:AC8D34* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:AC8FF8* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:AC9085* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:AC9232* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -75977,11 +95144,20 @@ OUI:AC932F* + OUI:AC9403* + ID_OUI_FROM_DATABASE=Envision Peripherals Inc + ++OUI:AC9572* ++ ID_OUI_FROM_DATABASE=Jovision Technology Co., Ltd. ++ ++OUI:AC976C* ++ ID_OUI_FROM_DATABASE=Greenliant ++ ++OUI:AC9929* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:AC9A22* + ID_OUI_FROM_DATABASE=NXP Semiconductors + + OUI:AC9A96* +- ID_OUI_FROM_DATABASE=Lantiq Deutschland GmbH ++ ID_OUI_FROM_DATABASE=Maxlinear, Inc + + OUI:AC9B0A* + ID_OUI_FROM_DATABASE=Sony Corporation +@@ -76005,14 +95181,20 @@ OUI:ACA22C* + ID_OUI_FROM_DATABASE=Baycity Technologies Ltd + + OUI:ACA31E* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:ACA430* + ID_OUI_FROM_DATABASE=Peerless AV + ++OUI:ACA46E* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:ACA667* + ID_OUI_FROM_DATABASE=Electronic Systems Protection, Inc. + ++OUI:ACA88E* ++ ID_OUI_FROM_DATABASE=SHARP Corporation ++ + OUI:ACA919* + ID_OUI_FROM_DATABASE=TrekStor GmbH + +@@ -76028,12 +95210,21 @@ OUI:ACAB8D* + OUI:ACABBF* + ID_OUI_FROM_DATABASE=AthenTek Inc. + ++OUI:ACAE19* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:ACAFB9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:ACB1EE* ++ ID_OUI_FROM_DATABASE=SHENZHEN FENDA TECHNOLOGY CO., LTD ++ + OUI:ACB313* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:ACB3B5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:ACB57D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -76043,11 +95234,20 @@ OUI:ACB74F* + OUI:ACB859* + ID_OUI_FROM_DATABASE=Uniband Electronic Corp, + ++OUI:ACB92F* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ ++OUI:ACBB61* ++ ID_OUI_FROM_DATABASE=YSTen Technology Co.,Ltd ++ + OUI:ACBC32* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:ACBD0B* +- ID_OUI_FROM_DATABASE=IMAC CO.,LTD ++ ID_OUI_FROM_DATABASE=Leimac Ltd. ++ ++OUI:ACBD70* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. + + OUI:ACBE75* + ID_OUI_FROM_DATABASE=Ufine Technologies Co.,Ltd. +@@ -76058,12 +95258,18 @@ OUI:ACBEB6* + OUI:ACC1EE* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:ACC25D* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:ACC2EC* + ID_OUI_FROM_DATABASE=CLT INT'L IND. CORP. + + OUI:ACC33A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:ACC358* ++ ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o. ++ + OUI:ACC51B* + ID_OUI_FROM_DATABASE=Zhuhai Pantum Electronics Co., Ltd. + +@@ -76097,6 +95303,9 @@ OUI:ACCABA* + OUI:ACCB09* + ID_OUI_FROM_DATABASE=Hefcom Metering (Pty) Ltd + ++OUI:ACCB51* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:ACCC8E* + ID_OUI_FROM_DATABASE=Axis Communications AB + +@@ -76124,15 +95333,30 @@ OUI:ACD1B8* + OUI:ACD364* + ID_OUI_FROM_DATABASE=ABB SPA, ABB SACE DIV. + ++OUI:ACD564* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:ACD618* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ + OUI:ACD657* + ID_OUI_FROM_DATABASE=Shaanxi GuoLian Digital TV Technology Co.,Ltd. + ++OUI:ACD829* ++ ID_OUI_FROM_DATABASE=Bouffalo Lab (Nanjing) Co., Ltd. ++ + OUI:ACD9D6* + ID_OUI_FROM_DATABASE=tci GmbH + ++OUI:ACDB48* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:ACDBDA* + ID_OUI_FROM_DATABASE=Shenzhen Geniatech Inc, Ltd + ++OUI:ACDCCA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:ACDCE5* + ID_OUI_FROM_DATABASE=Procter & Gamble Company + +@@ -76145,12 +95369,18 @@ OUI:ACE010* + OUI:ACE069* + ID_OUI_FROM_DATABASE=ISAAC Instruments + ++OUI:ACE14F* ++ ID_OUI_FROM_DATABASE=Autonomic Controls, Inc. ++ + OUI:ACE215* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:ACE2D3* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:ACE342* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:ACE348* + ID_OUI_FROM_DATABASE=MadgeTech, Inc + +@@ -76167,7 +95397,7 @@ OUI:ACE64B* + ID_OUI_FROM_DATABASE=Shenzhen Baojia Battery Technology Co., Ltd. + + OUI:ACE77B* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:ACE87B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -76184,32 +95414,53 @@ OUI:ACE9AA* + OUI:ACEA6A* + ID_OUI_FROM_DATABASE=GENIX INFOCOMM CO., LTD. + ++OUI:ACEB51* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:ACEC80* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:ACEC85* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:ACED5C* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:ACEE3B* + ID_OUI_FROM_DATABASE=6harmonics Inc + ++OUI:ACEE70* ++ ID_OUI_FROM_DATABASE=Fontem Ventures BV ++ + OUI:ACEE9E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:ACF0B2* + ID_OUI_FROM_DATABASE=Becker Electronics Taiwan Ltd. + ++OUI:ACF108* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:ACF1DF* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:ACF2C5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:ACF5E6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:ACF6F7* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:ACF7F3* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:ACF85C* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Chengdu Higon Integrated Circuit Design Co,. Ltd. ++ ++OUI:ACF8CC* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:ACF970* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD +@@ -76217,6 +95468,9 @@ OUI:ACF970* + OUI:ACF97E* + ID_OUI_FROM_DATABASE=ELESYS INC. + ++OUI:ACFAA5* ++ ID_OUI_FROM_DATABASE=digitron ++ + OUI:ACFD93* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + +@@ -76226,15 +95480,27 @@ OUI:ACFDCE* + OUI:ACFDEC* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:ACFE05* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ ++OUI:B00073* ++ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation ++ + OUI:B000B4* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:B00247* ++ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. ++ + OUI:B0027E* + ID_OUI_FROM_DATABASE=MULLER SERVICES + + OUI:B00594* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + ++OUI:B00875* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B008BF* + ID_OUI_FROM_DATABASE=Vital Connect, Inc. + +@@ -76244,6 +95510,12 @@ OUI:B009D3* + OUI:B009DA* + ID_OUI_FROM_DATABASE=Ring Solutions + ++OUI:B00AD5* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:B00CD1* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:B01041* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -76256,6 +95528,9 @@ OUI:B01266* + OUI:B01408* + ID_OUI_FROM_DATABASE=LIGHTSPEED INTERNATIONAL CO. + ++OUI:B01656* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B01743* + ID_OUI_FROM_DATABASE=EDISON GLOBAL CIRCUITS LLC + +@@ -76325,6 +95600,12 @@ OUI:B01F81E* + OUI:B01F81F* + ID_OUI_FROM_DATABASE=Private + ++OUI:B0227A* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ ++OUI:B02491* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B024F3* + ID_OUI_FROM_DATABASE=Progeny Systems + +@@ -76337,9 +95618,24 @@ OUI:B02628* + OUI:B02680* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:B027CF* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:B02A1F* ++ ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited ++ + OUI:B02A43* + ID_OUI_FROM_DATABASE=Google, Inc. + ++OUI:B03055* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ ++OUI:B030C8* ++ ID_OUI_FROM_DATABASE=Teal Drones, Inc. ++ ++OUI:B033A6* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:B03495* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -76352,6 +95648,12 @@ OUI:B0358D* + OUI:B0359F* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:B035B5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:B03795* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:B03829* + ID_OUI_FROM_DATABASE=Siliconware Precision Industries Co., Ltd. + +@@ -76361,9 +95663,18 @@ OUI:B03850* + OUI:B03956* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:B03ACE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B03D96* + ID_OUI_FROM_DATABASE=Vision Valley FZ LLC + ++OUI:B03DC2* ++ ID_OUI_FROM_DATABASE=Wasp artificial intelligence(Shenzhen) Co.,ltd ++ ++OUI:B03E51* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:B03EB0* + ID_OUI_FROM_DATABASE=MICRODIA Ltd. + +@@ -76379,15 +95690,27 @@ OUI:B0416F* + OUI:B0435D* + ID_OUI_FROM_DATABASE=NuLEDs, Inc. + ++OUI:B04414* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:B04502* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B04515* + ID_OUI_FROM_DATABASE=mira fitness,LLC. + + OUI:B04519* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:B04530* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:B04545* + ID_OUI_FROM_DATABASE=YACOUB Automation GmbH + ++OUI:B04692* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:B046FC* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + +@@ -76403,6 +95726,9 @@ OUI:B0487A* + OUI:B0495F* + ID_OUI_FROM_DATABASE=OMRON HEALTHCARE Co., Ltd. + ++OUI:B04A39* ++ ID_OUI_FROM_DATABASE=Beijing Roborock Technology Co., Ltd. ++ + OUI:B04BBF* + ID_OUI_FROM_DATABASE=PT HAN SUNG ELECTORONICS INDONESIA + +@@ -76412,6 +95738,12 @@ OUI:B04C05* + OUI:B04E26* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:B04F13* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:B04FC3* ++ ID_OUI_FROM_DATABASE=Shenzhen NVC Cloud Technology Co., Ltd. ++ + OUI:B050BC* + ID_OUI_FROM_DATABASE=SHENZHEN BASICOM ELECTRONIC CO.,LTD. + +@@ -76445,9 +95777,18 @@ OUI:B05B1F* + OUI:B05B67* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B05CDA* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:B05CE5* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:B05DD4* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:B06088* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:B061C7* + ID_OUI_FROM_DATABASE=Ericsson-LG Enterprise + +@@ -76457,27 +95798,45 @@ OUI:B06563* + OUI:B065BD* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B065F1* ++ ID_OUI_FROM_DATABASE=WIO Manufacturing HK Limited ++ + OUI:B0672F* + ID_OUI_FROM_DATABASE=Bowers & Wilkins + + OUI:B068B6* + ID_OUI_FROM_DATABASE=Hangzhou OYE Technology Co. Ltd + ++OUI:B068E6* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:B06971* + ID_OUI_FROM_DATABASE=DEI Sales, Inc. + ++OUI:B06A41* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:B06CBF* + ID_OUI_FROM_DATABASE=3ality Digital Systems GmbH + + OUI:B06EBF* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:B06FE0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:B0700D* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:B0702D* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:B072BF* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + ++OUI:B0735D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B0750C* + ID_OUI_FROM_DATABASE=QA Cafe + +@@ -76487,6 +95846,9 @@ OUI:B0754D* + OUI:B075D5* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:B0761B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B077AC* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -76505,12 +95867,21 @@ OUI:B0793C* + OUI:B07994* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:B07B25* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:B07D47* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:B07D62* + ID_OUI_FROM_DATABASE=Dipl.-Ing. H. Horstmann GmbH + ++OUI:B07D64* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:B07E11* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:B07E70* + ID_OUI_FROM_DATABASE=Zadara Storage Ltd. + +@@ -76547,6 +95918,12 @@ OUI:B089C2* + OUI:B08BCF* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:B08BD0* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:B08C75* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B08E1A* + ID_OUI_FROM_DATABASE=URadio Systems Co., Ltd + +@@ -76571,6 +95948,9 @@ OUI:B09137* + OUI:B0935B* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:B09575* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:B0958E* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -76586,6 +95966,9 @@ OUI:B0982B* + OUI:B0989F* + ID_OUI_FROM_DATABASE=LG CNS + ++OUI:B098BC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B09928* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + +@@ -76607,12 +95990,27 @@ OUI:B0A2E7* + OUI:B0A37E* + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. + ++OUI:B0A454* ++ ID_OUI_FROM_DATABASE=Tripwire Inc. ++ ++OUI:B0A460* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:B0A651* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:B0A6F5* ++ ID_OUI_FROM_DATABASE=Xaptum, Inc. ++ + OUI:B0A72A* + ID_OUI_FROM_DATABASE=Ensemble Designs, Inc. + + OUI:B0A737* + ID_OUI_FROM_DATABASE=Roku, Inc. + ++OUI:B0A7B9* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:B0A86E* + ID_OUI_FROM_DATABASE=Juniper Networks + +@@ -76622,6 +96020,9 @@ OUI:B0AA36* + OUI:B0AA77* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:B0AAD2* ++ ID_OUI_FROM_DATABASE=Sichuan tianyi kanghe communications co., LTD ++ + OUI:B0ACD2* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -76631,6 +96032,15 @@ OUI:B0ACFA* + OUI:B0ADAA* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:B0AE25* ++ ID_OUI_FROM_DATABASE=Varikorea ++ ++OUI:B0B113* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:B0B194* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:B0B28F* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -76640,12 +96050,63 @@ OUI:B0B2DC* + OUI:B0B32B* + ID_OUI_FROM_DATABASE=Slican Sp. z o.o. + ++OUI:B0B3530* ++ ID_OUI_FROM_DATABASE=Blake UK ++ ++OUI:B0B3531* ++ ID_OUI_FROM_DATABASE=Sprocomm Technologies CO.,LTD. ++ ++OUI:B0B3532* ++ ID_OUI_FROM_DATABASE=Rizhao SUNWAM International Co., Ltd. ++ ++OUI:B0B3533* ++ ID_OUI_FROM_DATABASE=AD HOC DEVELOPMENTS S.L ++ ++OUI:B0B3534* ++ ID_OUI_FROM_DATABASE=Innotas Elektronik GmbH ++ ++OUI:B0B3535* ++ ID_OUI_FROM_DATABASE=Zenlayer ++ ++OUI:B0B3536* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikrobot Technology Co., Ltd. ++ ++OUI:B0B3537* ++ ID_OUI_FROM_DATABASE=WUUK LABS CORP. ++ ++OUI:B0B3538* ++ ID_OUI_FROM_DATABASE=VOXISCOM ++ ++OUI:B0B3539* ++ ID_OUI_FROM_DATABASE=HANMECIPS CO. ++ ++OUI:B0B353A* ++ ID_OUI_FROM_DATABASE=Ledger ++ ++OUI:B0B353B* ++ ID_OUI_FROM_DATABASE=Zoox ++ ++OUI:B0B353C* ++ ID_OUI_FROM_DATABASE=Beijing Geekplus Technology Co.,Ltd. ++ ++OUI:B0B353D* ++ ID_OUI_FROM_DATABASE=IPvideo Corporation ++ ++OUI:B0B353E* ++ ID_OUI_FROM_DATABASE=Nanjing Yining Intelligent Technology Co., Ltd. ++ + OUI:B0B3AD* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + + OUI:B0B448* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:B0B5C3* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:B0B5E8* ++ ID_OUI_FROM_DATABASE=Ruroc LTD ++ + OUI:B0B867* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -76655,6 +96116,15 @@ OUI:B0B8D5* + OUI:B0B98A* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:B0BB8B* ++ ID_OUI_FROM_DATABASE=WAVETEL TECHNOLOGY LIMITED ++ ++OUI:B0BBE5* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:B0BD1B* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co., Ltd. ++ + OUI:B0BD6D* + ID_OUI_FROM_DATABASE=Echostreams Innovative Solutions + +@@ -76664,6 +96134,9 @@ OUI:B0BDA1* + OUI:B0BE76* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:B0BE83* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B0BF99* + ID_OUI_FROM_DATABASE=WIZITDONGDO + +@@ -76682,12 +96155,18 @@ OUI:B0C205* + OUI:B0C287* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:B0C387* ++ ID_OUI_FROM_DATABASE=GOEFER, Inc. ++ + OUI:B0C46C* + ID_OUI_FROM_DATABASE=Senseit + + OUI:B0C4E7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:B0C53C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:B0C554* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -76754,12 +96233,18 @@ OUI:B0C83F* + OUI:B0C8AD* + ID_OUI_FROM_DATABASE=People Power Company + ++OUI:B0C952* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:B0C95B* + ID_OUI_FROM_DATABASE=Beijing Symtech CO.,LTD + + OUI:B0CA68* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B0CCFE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B0CE18* + ID_OUI_FROM_DATABASE=Zhejiang shenghui lighting co.,Ltd + +@@ -76772,6 +96257,9 @@ OUI:B0D09C* + OUI:B0D2F5* + ID_OUI_FROM_DATABASE=Vello Systems, Inc. + ++OUI:B0D568* ++ ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co., Ltd ++ + OUI:B0D59D* + ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd + +@@ -76784,6 +96272,9 @@ OUI:B0D7C5* + OUI:B0D7CC* + ID_OUI_FROM_DATABASE=Tridonic GmbH & Co KG + ++OUI:B0D888* ++ ID_OUI_FROM_DATABASE=Panasonic Corporation Automotive ++ + OUI:B0DA00* + ID_OUI_FROM_DATABASE=CERA ELECTRONIQUE + +@@ -76811,21 +96302,36 @@ OUI:B0E2E5* + OUI:B0E39D* + ID_OUI_FROM_DATABASE=CAT SYSTEM CO.,LTD. + ++OUI:B0E4D5* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:B0E50E* + ID_OUI_FROM_DATABASE=NRG SYSTEMS INC + + OUI:B0E5ED* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B0E5F9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:B0E71D* ++ ID_OUI_FROM_DATABASE=Shanghai Maigantech Co.,Ltd ++ + OUI:B0E754* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:B0E7DE* ++ ID_OUI_FROM_DATABASE=Homa Technologies JSC ++ + OUI:B0E892* + ID_OUI_FROM_DATABASE=Seiko Epson Corporation + + OUI:B0E97E* + ID_OUI_FROM_DATABASE=Advanced Micro Peripherals + ++OUI:B0E9FE* ++ ID_OUI_FROM_DATABASE=Woan Technology (Shenzhen) Co., Ltd. ++ + OUI:B0EABC* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +@@ -76838,6 +96344,9 @@ OUI:B0EC71* + OUI:B0EC8F* + ID_OUI_FROM_DATABASE=GMX SAS + ++OUI:B0ECDD* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B0ECE1* + ID_OUI_FROM_DATABASE=Private + +@@ -76856,6 +96365,9 @@ OUI:B0F1BC* + OUI:B0F1EC* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + ++OUI:B0F530* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:B0F893* + ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd. + +@@ -76871,9 +96383,57 @@ OUI:B0FC0D* + OUI:B0FC36* + ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. + ++OUI:B0FD0B0* ++ ID_OUI_FROM_DATABASE=TAE HYUNG Industrial Electronics Co., Ltd. ++ ++OUI:B0FD0B1* ++ ID_OUI_FROM_DATABASE=IDspire Corporation Ltd. ++ ++OUI:B0FD0B2* ++ ID_OUI_FROM_DATABASE=Vista Manufacturing ++ ++OUI:B0FD0B3* ++ ID_OUI_FROM_DATABASE=DMAC Security LLC ++ ++OUI:B0FD0B4* ++ ID_OUI_FROM_DATABASE=Fasii Information Technology (Shanghai) Ltd. ++ ++OUI:B0FD0B5* ++ ID_OUI_FROM_DATABASE=Taian Yuqi Communication Technology Co., Ltd ++ ++OUI:B0FD0B6* ++ ID_OUI_FROM_DATABASE=DNESO TEN Ltd. ++ ++OUI:B0FD0B7* ++ ID_OUI_FROM_DATABASE=Everynet Oy ++ ++OUI:B0FD0B8* ++ ID_OUI_FROM_DATABASE=eSenseLab Ltd. ++ ++OUI:B0FD0B9* ++ ID_OUI_FROM_DATABASE=Eagle Acoustics Manufacturing, LLC ++ ++OUI:B0FD0BA* ++ ID_OUI_FROM_DATABASE=TEMCO JAPAN CO., LTD. ++ ++OUI:B0FD0BB* ++ ID_OUI_FROM_DATABASE=MartinLogan, Ltd. ++ ++OUI:B0FD0BC* ++ ID_OUI_FROM_DATABASE=Haltian Products Oy ++ ++OUI:B0FD0BD* ++ ID_OUI_FROM_DATABASE=Habana Labs LTD ++ ++OUI:B0FD0BE* ++ ID_OUI_FROM_DATABASE=Shenzhen FEIBIT Electronic Technology Co.,LTD ++ + OUI:B0FEBD* + ID_OUI_FROM_DATABASE=Private + ++OUI:B0FEE5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B40016* + ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS + +@@ -76883,9 +96443,15 @@ OUI:B4009C* + OUI:B40142* + ID_OUI_FROM_DATABASE=GCI Science & Technology Co.,LTD + ++OUI:B40216* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:B40418* + ID_OUI_FROM_DATABASE=Smartchip Integrated Inc. + ++OUI:B4055D* ++ ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd. ++ + OUI:B40566* + ID_OUI_FROM_DATABASE=SP Best Corporation Co., LTD. + +@@ -76895,12 +96461,18 @@ OUI:B407F9* + OUI:B40832* + ID_OUI_FROM_DATABASE=TC Communications + ++OUI:B40931* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B40AC6* + ID_OUI_FROM_DATABASE=DEXON Systems Ltd. + + OUI:B40B44* + ID_OUI_FROM_DATABASE=Smartisan Technology Co., Ltd. + ++OUI:B40B78* ++ ID_OUI_FROM_DATABASE=Brusa Elektronik AG ++ + OUI:B40B7A* + ID_OUI_FROM_DATABASE=Brusa Elektronik AG + +@@ -76910,39 +96482,81 @@ OUI:B40C25* + OUI:B40E96* + ID_OUI_FROM_DATABASE=HERAN + ++OUI:B40ECF* ++ ID_OUI_FROM_DATABASE=Bouffalo Lab (Nanjing) Co., Ltd. ++ + OUI:B40EDC* + ID_OUI_FROM_DATABASE=LG-Ericsson Co.,Ltd. + ++OUI:B40EDE* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:B40F3B* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + ++OUI:B40FB3* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:B4107B* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:B41489* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:B414E6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B41513* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B4157E* ++ ID_OUI_FROM_DATABASE=Celona Inc. ++ + OUI:B41780* + ID_OUI_FROM_DATABASE=DTI Group Ltd + + OUI:B418D1* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B41A1D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:B41BB0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B41C30* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:B41CAB* ++ ID_OUI_FROM_DATABASE=ICR, inc. ++ ++OUI:B41D2B* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:B41DEF* + ID_OUI_FROM_DATABASE=Internet Laboratories, Inc. + ++OUI:B42046* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:B4211D* + ID_OUI_FROM_DATABASE=Beijing GuangXin Technology Co., Ltd + + OUI:B4218A* + ID_OUI_FROM_DATABASE=Dog Hunter LLC + ++OUI:B42200* ++ ID_OUI_FROM_DATABASE=Brother Industries, LTD. ++ ++OUI:B42330* ++ ID_OUI_FROM_DATABASE=Itron Inc ++ + OUI:B424E7* + ID_OUI_FROM_DATABASE=Codetek Technology Co.,Ltd + ++OUI:B4265D* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:B428F1* + ID_OUI_FROM_DATABASE=E-Prime Co., Ltd. + +@@ -76991,6 +96605,9 @@ OUI:B435F7* + OUI:B436A9* + ID_OUI_FROM_DATABASE=Fibocom Wireless Inc. + ++OUI:B436D1* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:B436E3* + ID_OUI_FROM_DATABASE=KBVISION GROUP + +@@ -77045,9 +96662,15 @@ OUI:B437D1E* + OUI:B437D1F* + ID_OUI_FROM_DATABASE=Private + ++OUI:B437D8* ++ ID_OUI_FROM_DATABASE=D-Link (Shanghai) Limited Corp. ++ + OUI:B43934* + ID_OUI_FROM_DATABASE=Pen Generations, Inc. + ++OUI:B43939* ++ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. ++ + OUI:B439D6* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +@@ -77060,6 +96683,9 @@ OUI:B43DB2* + OUI:B43E3B* + ID_OUI_FROM_DATABASE=Viableware, Inc + ++OUI:B440A4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B4417A* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + +@@ -77072,6 +96698,9 @@ OUI:B44326* + OUI:B4475E* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:B447F5* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:B44BD2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -77120,12 +96749,18 @@ OUI:B44BD6D* + OUI:B44BD6E* + ID_OUI_FROM_DATABASE=CHUNGHSIN INTERNATIONAL ELECTRONICS CO.,LTD. + ++OUI:B44C3B* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:B44CC2* + ID_OUI_FROM_DATABASE=NR ELECTRIC CO., LTD + + OUI:B44F96* + ID_OUI_FROM_DATABASE=Zhejiang Xinzailing Technology co., ltd + ++OUI:B45062* ++ ID_OUI_FROM_DATABASE=EmBestor Technology Inc. ++ + OUI:B451F9* + ID_OUI_FROM_DATABASE=NB Software + +@@ -77133,10 +96768,16 @@ OUI:B45253* + ID_OUI_FROM_DATABASE=Seagate Technology + + OUI:B4527D* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:B4527E* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:B452A9* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ ++OUI:B45459* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. + + OUI:B45570* + ID_OUI_FROM_DATABASE=Borea +@@ -77144,6 +96785,9 @@ OUI:B45570* + OUI:B456B9* + ID_OUI_FROM_DATABASE=Teraspek Technologies Co.,Ltd + ++OUI:B456E3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B45861* + ID_OUI_FROM_DATABASE=CRemote, LLC + +@@ -77151,7 +96795,16 @@ OUI:B45CA4* + ID_OUI_FROM_DATABASE=Thing-talk Wireless Communication Technologies Corporation Limited + + OUI:B45D50* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:B46077* ++ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. ++ ++OUI:B4608C* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:B460ED* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd + + OUI:B461FF* + ID_OUI_FROM_DATABASE=Lumigon A/S +@@ -77177,12 +96830,21 @@ OUI:B46921* + OUI:B46BFC* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:B46C47* ++ ID_OUI_FROM_DATABASE=Panasonic Appliances Company ++ + OUI:B46D35* + ID_OUI_FROM_DATABASE=Dalian Seasky Automation Co;Ltd + + OUI:B46D83* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:B46E08* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:B46F2D* ++ ID_OUI_FROM_DATABASE=Wahoo Fitness ++ + OUI:B47356* + ID_OUI_FROM_DATABASE=Hangzhou Treebear Networking Co., Ltd. + +@@ -77198,18 +96860,36 @@ OUI:B4749F* + OUI:B4750E* + ID_OUI_FROM_DATABASE=Belkin International Inc. + ++OUI:B47748* ++ ID_OUI_FROM_DATABASE=Shenzhen Neoway Technology Co.,Ltd. ++ ++OUI:B47947* ++ ID_OUI_FROM_DATABASE=Nutanix ++ + OUI:B479A7* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:B479C8* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ ++OUI:B47AF1* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:B47C29* + ID_OUI_FROM_DATABASE=Shenzhen Guzidi Technology Co.,Ltd + ++OUI:B47C59* ++ ID_OUI_FROM_DATABASE=Jiangsu Hengxin Technology Co.,Ltd. ++ + OUI:B47C9C* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + + OUI:B47F5E* + ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd + ++OUI:B48107* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ + OUI:B481BF* + ID_OUI_FROM_DATABASE=Meta-Networks, LLC + +@@ -77228,12 +96908,21 @@ OUI:B482FE* + OUI:B48547* + ID_OUI_FROM_DATABASE=Amptown System Company GmbH + ++OUI:B485E1* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B48655* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B48901* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B48910* + ID_OUI_FROM_DATABASE=Coster T.E. S.P.A. + ++OUI:B48A5F* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:B48B19* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -77252,21 +96941,81 @@ OUI:B4994C* + OUI:B499BA* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:B49A95* ++ ID_OUI_FROM_DATABASE=Shenzhen Boomtech Industrial Corporation ++ + OUI:B49CDF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B49D02* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:B49D0B* + ID_OUI_FROM_DATABASE=BQ + + OUI:B49DB4* + ID_OUI_FROM_DATABASE=Axion Technologies Inc. + ++OUI:B49E80* ++ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. ++ + OUI:B49EAC* + ID_OUI_FROM_DATABASE=Imagik Int'l Corp + + OUI:B49EE6* + ID_OUI_FROM_DATABASE=SHENZHEN TECHNOLOGY CO LTD + ++OUI:B4A25C* ++ ID_OUI_FROM_DATABASE=Cambium Networks Limited ++ ++OUI:B4A2EB0* ++ ID_OUI_FROM_DATABASE=QKM Technology(Dongguan)Co.,Ltd ++ ++OUI:B4A2EB1* ++ ID_OUI_FROM_DATABASE=DCI International, LLC. ++ ++OUI:B4A2EB2* ++ ID_OUI_FROM_DATABASE=Katerra Inc ++ ++OUI:B4A2EB3* ++ ID_OUI_FROM_DATABASE=Canaan Creative Co.,Ltd. ++ ++OUI:B4A2EB4* ++ ID_OUI_FROM_DATABASE=Softel SA de CV ++ ++OUI:B4A2EB5* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:B4A2EB6* ++ ID_OUI_FROM_DATABASE=ShenZhen Lark Acoustics Co., Ltd. ++ ++OUI:B4A2EB7* ++ ID_OUI_FROM_DATABASE=Kona I ++ ++OUI:B4A2EB8* ++ ID_OUI_FROM_DATABASE=SHENZHEN ZHUIFENGMA TECHNOLOGY CO., LTD ++ ++OUI:B4A2EB9* ++ ID_OUI_FROM_DATABASE=CURRENT WAYS, INC. ++ ++OUI:B4A2EBA* ++ ID_OUI_FROM_DATABASE=Hengkang(Hangzhou)Co.,Ltd ++ ++OUI:B4A2EBB* ++ ID_OUI_FROM_DATABASE=Quantitec GmbH ++ ++OUI:B4A2EBC* ++ ID_OUI_FROM_DATABASE=Shanghai Shenou Communication Equipment Co., Ltd. ++ ++OUI:B4A2EBD* ++ ID_OUI_FROM_DATABASE=SALZBRENNER media GmbH ++ ++OUI:B4A2EBE* ++ ID_OUI_FROM_DATABASE=Dongguan Finslink Communication Technology Co.,Ltd. ++ ++OUI:B4A305* ++ ID_OUI_FROM_DATABASE=XIAMEN YAXON NETWORK CO., LTD. ++ + OUI:B4A382* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + +@@ -77279,6 +97028,9 @@ OUI:B4A4E3* + OUI:B4A5A9* + ID_OUI_FROM_DATABASE=MODI GmbH + ++OUI:B4A5AC* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:B4A5EF* + ID_OUI_FROM_DATABASE=Sercomm Corporation. + +@@ -77288,6 +97040,9 @@ OUI:B4A828* + OUI:B4A82B* + ID_OUI_FROM_DATABASE=Histar Digital Electronics Co., Ltd. + ++OUI:B4A898* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B4A8B9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -77300,6 +97055,9 @@ OUI:B4A95A* + OUI:B4A984* + ID_OUI_FROM_DATABASE=Symantec Corporation + ++OUI:B4A9FC* ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. ++ + OUI:B4A9FE* + ID_OUI_FROM_DATABASE=GHIA Technology (Shenzhen) LTD + +@@ -77309,6 +97067,12 @@ OUI:B4AA4D* + OUI:B4AB2C* + ID_OUI_FROM_DATABASE=MtM Technology Corporation + ++OUI:B4AC8C* ++ ID_OUI_FROM_DATABASE=Berner Fachhochschule ++ ++OUI:B4ADA3* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ + OUI:B4AE2B* + ID_OUI_FROM_DATABASE=Microsoft + +@@ -77318,12 +97082,18 @@ OUI:B4AE6F* + OUI:B4B017* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:B4B055* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B4B15A* + ID_OUI_FROM_DATABASE=Siemens AG Energy Management Division + + OUI:B4B265* + ID_OUI_FROM_DATABASE=DAEHO I&T + ++OUI:B4B291* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ + OUI:B4B362* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -77339,6 +97109,9 @@ OUI:B4B542* + OUI:B4B5AF* + ID_OUI_FROM_DATABASE=Minsung Electronics + ++OUI:B4B5B6* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:B4B676* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -77351,6 +97124,12 @@ OUI:B4B859* + OUI:B4B88D* + ID_OUI_FROM_DATABASE=Thuh Company + ++OUI:B4BA12* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co.,Ltd. ++ ++OUI:B4BC7C* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:B4BFF6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -77360,9 +97139,21 @@ OUI:B4C0F5* + OUI:B4C170* + ID_OUI_FROM_DATABASE=Yi chip Microelectronics (Hangzhou) Co., Ltd + ++OUI:B4C26A* ++ ID_OUI_FROM_DATABASE=Garmin International ++ + OUI:B4C44E* + ID_OUI_FROM_DATABASE=VXL eTech Pvt Ltd + ++OUI:B4C476* ++ ID_OUI_FROM_DATABASE=Wuhan Maritime Communication Research Institute ++ ++OUI:B4C4FC* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:B4C62E* ++ ID_OUI_FROM_DATABASE=Molex CMS ++ + OUI:B4C6F8* + ID_OUI_FROM_DATABASE=Axilspot Communication + +@@ -77370,17 +97161,29 @@ OUI:B4C799* + ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:B4C810* +- ID_OUI_FROM_DATABASE=UMPI Elettronica ++ ID_OUI_FROM_DATABASE=Umpi srl ++ ++OUI:B4C9B9* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. + + OUI:B4CB57* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:B4CC04* ++ ID_OUI_FROM_DATABASE=Piranti ++ + OUI:B4CCE9* + ID_OUI_FROM_DATABASE=PROSYST + + OUI:B4CD27* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B4CDF5* ++ ID_OUI_FROM_DATABASE=CUB ELECPARTS INC. ++ ++OUI:B4CE40* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:B4CEF6* + ID_OUI_FROM_DATABASE=HTC Corporation + +@@ -77390,6 +97193,12 @@ OUI:B4CEFE* + OUI:B4CFDB* + ID_OUI_FROM_DATABASE=Shenzhen Jiuzhou Electric Co.,LTD + ++OUI:B4CFE0* ++ ID_OUI_FROM_DATABASE=Sichuan tianyi kanghe communications co., LTD ++ ++OUI:B4D0A9* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:B4D135* + ID_OUI_FROM_DATABASE=Cloudistics + +@@ -77405,6 +97214,9 @@ OUI:B4D8A9* + OUI:B4D8DE* + ID_OUI_FROM_DATABASE=iota Computing, Inc. + ++OUI:B4DC09* ++ ID_OUI_FROM_DATABASE=Guangzhou Dawei Communication Co.,Ltd ++ + OUI:B4DD15* + ID_OUI_FROM_DATABASE=ControlThings Oy Ab + +@@ -77438,6 +97250,12 @@ OUI:B4E1C4* + OUI:B4E1EB* + ID_OUI_FROM_DATABASE=Private + ++OUI:B4E3F9* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:B4E454* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:B4E62A* + ID_OUI_FROM_DATABASE=LG Innotek + +@@ -77447,14 +97265,26 @@ OUI:B4E62D* + OUI:B4E782* + ID_OUI_FROM_DATABASE=Vivalnk + ++OUI:B4E842* ++ ID_OUI_FROM_DATABASE=Hong Kong Bouffalo Lab Limited ++ ++OUI:B4E8C9* ++ ID_OUI_FROM_DATABASE=XADA Technologies ++ + OUI:B4E9A3* +- ID_OUI_FROM_DATABASE=port GmbH ++ ID_OUI_FROM_DATABASE=port industrial automation GmbH + + OUI:B4E9B0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:B4EC02* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ ++OUI:B4ECF2* ++ ID_OUI_FROM_DATABASE=Shanghai Listent Medical Tech Co., Ltd. ++ ++OUI:B4ECFF* ++ ID_OUI_FROM_DATABASE=Wuhan IPG Technologies Co., Ltd. + + OUI:B4ED19* + ID_OUI_FROM_DATABASE=Pie Digital, Inc. +@@ -77462,6 +97292,9 @@ OUI:B4ED19* + OUI:B4ED54* + ID_OUI_FROM_DATABASE=Wohler Technologies + ++OUI:B4EE25* ++ ID_OUI_FROM_DATABASE=Shenzhen Belon Technology CO.,LTD ++ + OUI:B4EEB4* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +@@ -77471,6 +97304,9 @@ OUI:B4EED4* + OUI:B4EF04* + ID_OUI_FROM_DATABASE=DAIHAN Scientific Co., Ltd. + ++OUI:B4EF1C* ++ ID_OUI_FROM_DATABASE=360 AI Technology Co.Ltd ++ + OUI:B4EF39* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -77480,6 +97316,9 @@ OUI:B4EFFA* + OUI:B4F0AB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B4F18C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B4F1DA* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -77489,6 +97328,9 @@ OUI:B4F2E8* + OUI:B4F323* + ID_OUI_FROM_DATABASE=PETATEL INC. + ++OUI:B4F58E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B4F61C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -77498,6 +97340,15 @@ OUI:B4F7A1* + OUI:B4F81E* + ID_OUI_FROM_DATABASE=Kinova + ++OUI:B4F949* ++ ID_OUI_FROM_DATABASE=optilink networks pvt ltd ++ ++OUI:B4FA48* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:B4FBE3* ++ ID_OUI_FROM_DATABASE=AltoBeam (China) Inc. ++ + OUI:B4FBE4* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + +@@ -77510,9 +97361,15 @@ OUI:B4FC75* + OUI:B4FE8C* + ID_OUI_FROM_DATABASE=Centro Sicurezza Italia SpA + ++OUI:B4FF98* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B80018* + ID_OUI_FROM_DATABASE=Htel + ++OUI:B802A4* ++ ID_OUI_FROM_DATABASE=Aeonsemi, Inc. ++ + OUI:B80305* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -77525,6 +97382,9 @@ OUI:B805AB* + OUI:B80716* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:B80756* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:B808CF* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -77537,12 +97397,27 @@ OUI:B8098A* + OUI:B80B9D* + ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH + ++OUI:B810D4* ++ ID_OUI_FROM_DATABASE=Masimo Corporation ++ ++OUI:B8114B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:B81332* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:B813E9* + ID_OUI_FROM_DATABASE=Trace Live Network + + OUI:B81413* + ID_OUI_FROM_DATABASE=Keen High Holding(HK) Ltd. + ++OUI:B8145C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:B814DB* ++ ID_OUI_FROM_DATABASE=OHSUNG ++ + OUI:B81619* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -77555,17 +97430,23 @@ OUI:B817C2* + OUI:B8186F* + ID_OUI_FROM_DATABASE=ORIENTAL MOTOR CO., LTD. + ++OUI:B81904* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:B81999* + ID_OUI_FROM_DATABASE=Nesys + + OUI:B81DAA* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:B81F5E* ++ ID_OUI_FROM_DATABASE=Apption Labs Limited ++ + OUI:B820E7* + ID_OUI_FROM_DATABASE=Guangzhou Horizontal Information & Network Integration Co. Ltd + + OUI:B8224F* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:B82410* + ID_OUI_FROM_DATABASE=Magneti Marelli Slovakia s.r.o. +@@ -77576,12 +97457,21 @@ OUI:B8241A* + OUI:B824F0* + ID_OUI_FROM_DATABASE=SOYO Technology Development Co., Ltd. + ++OUI:B8259A* ++ ID_OUI_FROM_DATABASE=Thalmic Labs ++ ++OUI:B825B5* ++ ID_OUI_FROM_DATABASE=Trakm8 Ltd ++ + OUI:B8266C* + ID_OUI_FROM_DATABASE=ANOV France + + OUI:B826D4* + ID_OUI_FROM_DATABASE=Furukawa Industrial S.A. Produtos Elétricos + ++OUI:B827C5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B827EB* + ID_OUI_FROM_DATABASE=Raspberry Pi Foundation + +@@ -77594,21 +97484,36 @@ OUI:B829F7* + OUI:B82A72* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:B82AA9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B82ADC* + ID_OUI_FROM_DATABASE=EFR Europäische Funk-Rundsteuerung GmbH + + OUI:B82CA0* +- ID_OUI_FROM_DATABASE=Honeywell HomMed ++ ID_OUI_FROM_DATABASE=Resideo ++ ++OUI:B82D28* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ ++OUI:B82FCB* ++ ID_OUI_FROM_DATABASE=CMS Electracom + + OUI:B830A8* + ID_OUI_FROM_DATABASE=Road-Track Telematics Development + ++OUI:B831B5* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:B83241* + ID_OUI_FROM_DATABASE=Wuhan Tianyu Information Industry Co., Ltd. + + OUI:B836D8* + ID_OUI_FROM_DATABASE=Videoswitch + ++OUI:B8374A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B83765* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + +@@ -77621,12 +97526,18 @@ OUI:B838CA* + OUI:B83A08* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + ++OUI:B83A5A* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:B83A7B* + ID_OUI_FROM_DATABASE=Worldplay (Canada) Inc. + + OUI:B83A9D* + ID_OUI_FROM_DATABASE=Alarm.com + ++OUI:B83BCC* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:B83D4E* + ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch + +@@ -77642,12 +97553,27 @@ OUI:B841A4* + OUI:B843E4* + ID_OUI_FROM_DATABASE=Vlatacom + ++OUI:B844AE* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:B844D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B8477A* ++ ID_OUI_FROM_DATABASE=Dasan Electron Co., Ltd. ++ + OUI:B847C6* + ID_OUI_FROM_DATABASE=SanJet Technology Corp. + ++OUI:B848AA* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ ++OUI:B84D43* ++ ID_OUI_FROM_DATABASE=HUNAN FN-LINK TECHNOLOGY LIMITED ++ ++OUI:B84DEE* ++ ID_OUI_FROM_DATABASE=Hisense broadband multimedia technology Co.,Ltd ++ + OUI:B84FD5* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +@@ -77660,15 +97586,27 @@ OUI:B853AC* + OUI:B85510* + ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. + ++OUI:B85600* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B856BD* + ID_OUI_FROM_DATABASE=ITT LLC + ++OUI:B85776* ++ ID_OUI_FROM_DATABASE=lignex1 ++ + OUI:B857D8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:B85810* + ID_OUI_FROM_DATABASE=NUMERA, INC. + ++OUI:B8599F* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ ++OUI:B859CE* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:B85A73* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -77678,12 +97616,24 @@ OUI:B85AF7* + OUI:B85AFE* + ID_OUI_FROM_DATABASE=Handaer Communication Technology (Beijing) Co., Ltd + ++OUI:B85D0A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B85E7B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:B85F98* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:B85FB0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B86091* + ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC + ++OUI:B86142* ++ ID_OUI_FROM_DATABASE=Beijing Tricolor Technology Co., Ltd ++ + OUI:B8616F* + ID_OUI_FROM_DATABASE=Accton Technology Corp + +@@ -77693,6 +97643,9 @@ OUI:B8621F* + OUI:B8634D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B86392* ++ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO., LTD. ++ + OUI:B863BC* + ID_OUI_FROM_DATABASE=ROBOTIS, Co, Ltd + +@@ -77702,6 +97655,9 @@ OUI:B86491* + OUI:B8653B* + ID_OUI_FROM_DATABASE=Bolymin, Inc. + ++OUI:B86685* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:B869C2* + ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd. + +@@ -77735,6 +97691,9 @@ OUI:B8763F* + OUI:B877C3* + ID_OUI_FROM_DATABASE=METER Group + ++OUI:B87826* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:B8782E* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -77747,18 +97706,33 @@ OUI:B8797E* + OUI:B87AC9* + ID_OUI_FROM_DATABASE=Siemens Ltd. + ++OUI:B87BC5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B87C6F* + ID_OUI_FROM_DATABASE=NXP (China) Management Ltd. + + OUI:B87CF2* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:B88035* ++ ID_OUI_FROM_DATABASE=Shenzhen Qihu Intelligent Technology Company Limited ++ ++OUI:B8804F* ++ ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:B88198* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:B881FA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B88303* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + ++OUI:B8857B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B88584* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -77768,9 +97742,15 @@ OUI:B88687* + OUI:B8871E* + ID_OUI_FROM_DATABASE=Good Mind Industries Co., Ltd. + ++OUI:B8876E* ++ ID_OUI_FROM_DATABASE=Yandex Services AG ++ + OUI:B887A8* + ID_OUI_FROM_DATABASE=Step Ahead Innovations Inc. + ++OUI:B887C6* ++ ID_OUI_FROM_DATABASE=Prudential Technology co.,LTD ++ + OUI:B888E3* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +@@ -77786,12 +97766,21 @@ OUI:B88A60* + OUI:B88AEC* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:B88C29* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ + OUI:B88D12* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:B88DF1* ++ ID_OUI_FROM_DATABASE=Nanjing BigFish Semiconductor Co., Ltd. ++ + OUI:B88E3A* + ID_OUI_FROM_DATABASE=Infinite Technologies JLT + ++OUI:B88E82* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B88EC6* + ID_OUI_FROM_DATABASE=Stateless Networks + +@@ -77801,6 +97790,15 @@ OUI:B88EDF* + OUI:B88F14* + ID_OUI_FROM_DATABASE=Analytica GmbH + ++OUI:B88FB4* ++ ID_OUI_FROM_DATABASE=JABIL CIRCUIT ITALIA S.R.L ++ ++OUI:B89047* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:B891C9* ++ ID_OUI_FROM_DATABASE=Handreamnet ++ + OUI:B8921D* + ID_OUI_FROM_DATABASE=BG T&A + +@@ -77825,9 +97823,18 @@ OUI:B898F7* + OUI:B89919* + ID_OUI_FROM_DATABASE=7signal Solutions, Inc + ++OUI:B899AE* ++ ID_OUI_FROM_DATABASE=Shenzhen MiaoMing Intelligent Technology Co.,Ltd ++ + OUI:B899B0* + ID_OUI_FROM_DATABASE=Cohere Technologies + ++OUI:B89A2A* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:B89A9A* ++ ID_OUI_FROM_DATABASE=Xin Shi Jia Technology (Beijing) Co.,Ltd ++ + OUI:B89ACD* + ID_OUI_FROM_DATABASE=ELITE OPTOELECTRONIC(ASIA)CO.,LTD + +@@ -77843,15 +97850,27 @@ OUI:B89BE4* + OUI:B89F09* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + ++OUI:B8A14A* ++ ID_OUI_FROM_DATABASE=Raisecom Technology CO.,LTD ++ + OUI:B8A175* + ID_OUI_FROM_DATABASE=Roku, Inc. + ++OUI:B8A377* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:B8A386* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:B8A3E0* + ID_OUI_FROM_DATABASE=BenRui Technology Co.,Ltd + ++OUI:B8A44F* ++ ID_OUI_FROM_DATABASE=Axis Communications AB ++ ++OUI:B8A58D* ++ ID_OUI_FROM_DATABASE=Axe Group Holdings Limited ++ + OUI:B8A8AF* + ID_OUI_FROM_DATABASE=Logic S.p.A. + +@@ -77861,6 +97880,12 @@ OUI:B8AC6F* + OUI:B8AD3E* + ID_OUI_FROM_DATABASE=BLUECOM + ++OUI:B8AE1C* ++ ID_OUI_FROM_DATABASE=Smart Cube., Ltd ++ ++OUI:B8AE1D* ++ ID_OUI_FROM_DATABASE=Guangzhou Xingyi Electronic Technology Co.,Ltd ++ + OUI:B8AE6E* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +@@ -77876,12 +97901,18 @@ OUI:B8B1C7* + OUI:B8B2EB* + ID_OUI_FROM_DATABASE=Googol Technology (HK) Limited + ++OUI:B8B2F8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B8B3DC* + ID_OUI_FROM_DATABASE=DEREK (SHAOGUAN) LIMITED + + OUI:B8B42E* + ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen + ++OUI:B8B77D* ++ ID_OUI_FROM_DATABASE=Guangdong Transtek Medical Electronics CO.,Ltd ++ + OUI:B8B7D7* + ID_OUI_FROM_DATABASE=2GIG Technologies + +@@ -77912,6 +97943,9 @@ OUI:B8BBAF* + OUI:B8BC1B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:B8BC5B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:B8BD79* + ID_OUI_FROM_DATABASE=TrendPoint Systems + +@@ -77930,6 +97964,15 @@ OUI:B8C111* + OUI:B8C1A2* + ID_OUI_FROM_DATABASE=Dragon Path Technologies Co., Limited + ++OUI:B8C227* ++ ID_OUI_FROM_DATABASE=PSTec ++ ++OUI:B8C253* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:B8C385* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B8C3BF* + ID_OUI_FROM_DATABASE=Henan Chengshi NetWork Technology Co.,Ltd + +@@ -77939,9 +97982,15 @@ OUI:B8C46F* + OUI:B8C68E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:B8C6AA* ++ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd ++ + OUI:B8C716* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:B8C74A* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:B8C75D* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -77951,27 +98000,54 @@ OUI:B8C855* + OUI:B8C8EB* + ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + ++OUI:B8C9B5* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:B8CA04* + ID_OUI_FROM_DATABASE=Holtek Semiconductor Inc. + + OUI:B8CA3A* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:B8CB29* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:B8CD93* + ID_OUI_FROM_DATABASE=Penetek, Inc + + OUI:B8CDA7* + ID_OUI_FROM_DATABASE=Maxeler Technologies Ltd. + ++OUI:B8CEF6* ++ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. ++ + OUI:B8D06F* + ID_OUI_FROM_DATABASE=GUANGZHOU HKUST FOK YING TUNG RESEARCH INSTITUTE + ++OUI:B8D309* ++ ID_OUI_FROM_DATABASE=Cox Communications, Inc ++ ++OUI:B8D43E* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:B8D49D* + ID_OUI_FROM_DATABASE=M Seven System Ltd. + ++OUI:B8D4E7* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:B8D50B* + ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd + ++OUI:B8D526* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ ++OUI:B8D56B* ++ ID_OUI_FROM_DATABASE=Mirka Ltd. ++ ++OUI:B8D6F6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:B8D7AF* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +@@ -78029,6 +98105,9 @@ OUI:B8D94D* + OUI:B8D9CE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:B8DAE8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:B8DAF1* + ID_OUI_FROM_DATABASE=Strahlenschutz- Entwicklungs- und Ausruestungsgesellschaft mbH + +@@ -78041,12 +98120,21 @@ OUI:B8DB1C* + OUI:B8DC87* + ID_OUI_FROM_DATABASE=IAI Corporation + ++OUI:B8DD71* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:B8DE5E* + ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED + + OUI:B8DF6B* + ID_OUI_FROM_DATABASE=SpotCam Co., Ltd. + ++OUI:B8E3B1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:B8E3EE* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:B8E589* + ID_OUI_FROM_DATABASE=Payter BV + +@@ -78077,9 +98165,18 @@ OUI:B8EE65* + OUI:B8EE79* + ID_OUI_FROM_DATABASE=YWire Technologies, Inc. + ++OUI:B8EF8B* ++ ID_OUI_FROM_DATABASE=SHENZHEN CANNICE TECHNOLOGY CO.,LTD ++ ++OUI:B8F009* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:B8F080* + ID_OUI_FROM_DATABASE=SPS, INC. + ++OUI:B8F12A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:B8F317* + ID_OUI_FROM_DATABASE=iSun Smasher Communications Private Limited + +@@ -78089,6 +98186,9 @@ OUI:B8F4D0* + OUI:B8F5E7* + ID_OUI_FROM_DATABASE=WayTools, LLC + ++OUI:B8F653* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ + OUI:B8F6B1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -78101,6 +98201,9 @@ OUI:B8F74A* + OUI:B8F828* + ID_OUI_FROM_DATABASE=Changshu Gaoshida Optoelectronic Technology Co. Ltd. + ++OUI:B8F853* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:B8F883* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -78108,7 +98211,7 @@ OUI:B8F8BE* + ID_OUI_FROM_DATABASE=BLUECOM + + OUI:B8F934* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:B8FC9A* + ID_OUI_FROM_DATABASE=Le Shi Zhi Xin Electronic Technology (Tianjin) Limited +@@ -78134,9 +98237,21 @@ OUI:BC0200* + OUI:BC024A* + ID_OUI_FROM_DATABASE=HMD Global Oy + ++OUI:BC03A7* ++ ID_OUI_FROM_DATABASE=MFP MICHELIN ++ + OUI:BC0543* + ID_OUI_FROM_DATABASE=AVM GmbH + ++OUI:BC062D* ++ ID_OUI_FROM_DATABASE=Wacom Co.,Ltd. ++ ++OUI:BC091B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:BC0963* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:BC0DA5* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -78146,12 +98261,18 @@ OUI:BC0F2B* + OUI:BC0F64* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:BC0F9A* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:BC0FA7* + ID_OUI_FROM_DATABASE=Ouster + + OUI:BC125E* + ID_OUI_FROM_DATABASE=Beijing WisVideo INC. + ++OUI:BC13A8* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:BC1401* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +@@ -78170,15 +98291,27 @@ OUI:BC15AC* + OUI:BC1665* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:BC1695* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:BC16F5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:BC17B8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:BC1A67* + ID_OUI_FROM_DATABASE=YF Technology Co., Ltd + ++OUI:BC1AE4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:BC1C81* + ID_OUI_FROM_DATABASE=Sichuan iLink Technology Co., Ltd. + ++OUI:BC1E85* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:BC20A4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -78188,6 +98321,9 @@ OUI:BC20BA* + OUI:BC22FB* + ID_OUI_FROM_DATABASE=RF Industries + ++OUI:BC2392* ++ ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd. ++ + OUI:BC25E0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -78200,6 +98336,12 @@ OUI:BC261D* + OUI:BC2643* + ID_OUI_FROM_DATABASE=Elprotronic Inc. + ++OUI:BC26A1* ++ ID_OUI_FROM_DATABASE=FACTORY FIVE Corporation ++ ++OUI:BC26C7* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:BC282C* + ID_OUI_FROM_DATABASE=e-Smart Systems Pvt. Ltd + +@@ -78221,9 +98363,15 @@ OUI:BC2C55* + OUI:BC2D98* + ID_OUI_FROM_DATABASE=ThinGlobal LLC + ++OUI:BC2DEF* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:BC2E48* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:BC2EF6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:BC2F3D* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +@@ -78242,6 +98390,12 @@ OUI:BC30D9* + OUI:BC325F* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. + ++OUI:BC3329* ++ ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. ++ ++OUI:BC33AC* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:BC34000* + ID_OUI_FROM_DATABASE=Redvision CCTV + +@@ -78293,6 +98447,9 @@ OUI:BC3400F* + OUI:BC35E5* + ID_OUI_FROM_DATABASE=Hydro Systems Company + ++OUI:BC3865* ++ ID_OUI_FROM_DATABASE=JWCNETWORKS ++ + OUI:BC38D2* + ID_OUI_FROM_DATABASE=Pandachip Limited + +@@ -78311,9 +98468,18 @@ OUI:BC3BAF* + OUI:BC3D85* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:BC3E07* ++ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc ++ + OUI:BC3E13* + ID_OUI_FROM_DATABASE=Accordance Systems Inc. + ++OUI:BC3ECB* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:BC3F4E* ++ ID_OUI_FROM_DATABASE=Teleepoch Ltd ++ + OUI:BC3F8F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -78323,6 +98489,9 @@ OUI:BC4100* + OUI:BC4101* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + ++OUI:BC428C* ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ + OUI:BC4377* + ID_OUI_FROM_DATABASE=Hang Zhou Huite Technology Co.,ltd. + +@@ -78344,6 +98513,9 @@ OUI:BC4699* + OUI:BC4760* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:BC4A56* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:BC4B79* + ID_OUI_FROM_DATABASE=SensingTek + +@@ -78368,6 +98540,9 @@ OUI:BC52B4* + OUI:BC52B7* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:BC542F* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:BC5436* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -78380,9 +98555,18 @@ OUI:BC54F9* + OUI:BC54FC* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + ++OUI:BC5A56* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:BC5BD5* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:BC5C4C* + ID_OUI_FROM_DATABASE=ELECOM CO.,LTD. + ++OUI:BC5EA1* ++ ID_OUI_FROM_DATABASE=PsiKick, Inc. ++ + OUI:BC5FF4* + ID_OUI_FROM_DATABASE=ASRock Incorporation + +@@ -78401,6 +98585,12 @@ OUI:BC620E* + OUI:BC629F* + ID_OUI_FROM_DATABASE=Telenet Systems P. Ltd. + ++OUI:BC62CE* ++ ID_OUI_FROM_DATABASE=SHENZHEN NETIS TECHNOLOGY CO.,LTD ++ ++OUI:BC62D2* ++ ID_OUI_FROM_DATABASE=Genexis International B.V. ++ + OUI:BC644B* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -78464,6 +98654,9 @@ OUI:BC6778* + OUI:BC6784* + ID_OUI_FROM_DATABASE=Environics Oy + ++OUI:BC69CB* ++ ID_OUI_FROM_DATABASE=Panasonic Life Solutions Networks Co., Ltd. ++ + OUI:BC6A16* + ID_OUI_FROM_DATABASE=tdvine + +@@ -78476,14 +98669,20 @@ OUI:BC6A2F* + OUI:BC6A44* + ID_OUI_FROM_DATABASE=Commend International GmbH + ++OUI:BC6AD1* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:BC6B4D* + ID_OUI_FROM_DATABASE=Nokia + + OUI:BC6C21* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:BC6D05* ++ ID_OUI_FROM_DATABASE=Dusun Electron Co.,Ltd. ++ + OUI:BC6E64* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:BC6E76* + ID_OUI_FROM_DATABASE=Green Energy Options Ltd +@@ -78497,9 +98696,15 @@ OUI:BC72B1* + OUI:BC74D7* + ID_OUI_FROM_DATABASE=HangZhou JuRu Technology CO.,LTD + ++OUI:BC7536* ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD ++ + OUI:BC7574* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:BC7596* ++ ID_OUI_FROM_DATABASE=Beijing Broadwit Technology Co., Ltd. ++ + OUI:BC764E* + ID_OUI_FROM_DATABASE=Rackspace US, Inc. + +@@ -78509,6 +98714,9 @@ OUI:BC765E* + OUI:BC7670* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:BC76C5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:BC7737* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -78518,9 +98726,21 @@ OUI:BC779F* + OUI:BC79AD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:BC7ABF* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:BC7DD1* + ID_OUI_FROM_DATABASE=Radio Data Comms + ++OUI:BC7E8B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:BC7F7B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:BC7FA4* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:BC811F* + ID_OUI_FROM_DATABASE=Ingate Systems + +@@ -78572,45 +98792,132 @@ OUI:BC91B5* + OUI:BC926B* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:BC9325* ++ ID_OUI_FROM_DATABASE=Ningbo Joyson Preh Car Connect Co.,Ltd. ++ + OUI:BC9680* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:BC97400* ++ ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd. ++ ++OUI:BC97401* ++ ID_OUI_FROM_DATABASE=comtac AG ++ ++OUI:BC97402* ++ ID_OUI_FROM_DATABASE=Lattec I/S ++ ++OUI:BC97403* ++ ID_OUI_FROM_DATABASE=Precision Galaxy Pvt. Ltd ++ ++OUI:BC97404* ++ ID_OUI_FROM_DATABASE=Wind Mobility Technology (Beijing) Co., Ltd ++ ++OUI:BC97405* ++ ID_OUI_FROM_DATABASE=Shanghai Laisi Information Technology Co.,Ltd ++ ++OUI:BC97406* ++ ID_OUI_FROM_DATABASE=Shenzhen Colorwin Optical Technology Co.,Ltd ++ ++OUI:BC97407* ++ ID_OUI_FROM_DATABASE=Airfi Oy AB ++ ++OUI:BC97408* ++ ID_OUI_FROM_DATABASE=Gaodi Rus ++ ++OUI:BC97409* ++ ID_OUI_FROM_DATABASE=Direct Communication Solutions ++ ++OUI:BC9740A* ++ ID_OUI_FROM_DATABASE=Amap Information Technology Co., Ltd ++ ++OUI:BC9740B* ++ ID_OUI_FROM_DATABASE=ForoTel ++ ++OUI:BC9740C* ++ ID_OUI_FROM_DATABASE=LISTEC GmbH ++ ++OUI:BC9740D* ++ ID_OUI_FROM_DATABASE=Rollock Oy ++ ++OUI:BC9740E* ++ ID_OUI_FROM_DATABASE=B4ComTechnologies LLC ++ ++OUI:BC9789* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:BC97E1* ++ ID_OUI_FROM_DATABASE=Broadcom Limited ++ + OUI:BC9889* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:BC98DF* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:BC9911* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + ++OUI:BC9930* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:BC99BC* + ID_OUI_FROM_DATABASE=FonSee Technology Inc. + ++OUI:BC9A53* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:BC9B68* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:BC9C31* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:BC9CC5* + ID_OUI_FROM_DATABASE=Beijing Huafei Technology Co., Ltd. + ++OUI:BC9D42* ++ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. ++ + OUI:BC9DA5* + ID_OUI_FROM_DATABASE=DASCOM Europe GmbH + ++OUI:BC9FE4* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:BC9FEF* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:BCA042* + ID_OUI_FROM_DATABASE=SHANGHAI FLYCO ELECTRICAL APPLIANCE CO.,LTD + ++OUI:BCA13A* ++ ID_OUI_FROM_DATABASE=SES-imagotag ++ ++OUI:BCA37F* ++ ID_OUI_FROM_DATABASE=Rail-Mil Sp. z o.o. Sp. K. ++ + OUI:BCA4E1* + ID_OUI_FROM_DATABASE=Nabto + ++OUI:BCA511* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ + OUI:BCA58B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:BCA5A9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:BCA8A6* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:BCA920* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:BCA993* ++ ID_OUI_FROM_DATABASE=Cambium Networks Limited ++ + OUI:BCA9D6* + ID_OUI_FROM_DATABASE=Cyber-Rain, Inc. + +@@ -78629,6 +98936,9 @@ OUI:BCAEC5* + OUI:BCAF91* + ID_OUI_FROM_DATABASE=TE Connectivity Sensor Solutions + ++OUI:BCB0E7* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:BCB181* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +@@ -78644,6 +98954,12 @@ OUI:BCB308* + OUI:BCB852* + ID_OUI_FROM_DATABASE=Cybera, Inc. + ++OUI:BCB863* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:BCBAC2* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:BCBAE1* + ID_OUI_FROM_DATABASE=AREC Inc. + +@@ -78653,6 +98969,9 @@ OUI:BCBBC9* + OUI:BCBC46* + ID_OUI_FROM_DATABASE=SKS Welding Systems GmbH + ++OUI:BCBD9E* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:BCC00F* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -78663,7 +98982,7 @@ OUI:BCC23A* + ID_OUI_FROM_DATABASE=Thomson Video Networks + + OUI:BCC31B* +- ID_OUI_FROM_DATABASE=Kygo Life AS ++ ID_OUI_FROM_DATABASE=Kygo Life A + + OUI:BCC342* + ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd. +@@ -78686,6 +99005,12 @@ OUI:BCCAB5* + OUI:BCCD45* + ID_OUI_FROM_DATABASE=VOISMART + ++OUI:BCCE25* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:BCCF4F* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:BCCFCC* + ID_OUI_FROM_DATABASE=HTC Corporation + +@@ -78701,12 +99026,27 @@ OUI:BCD177* + OUI:BCD1D3* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + ++OUI:BCD295* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:BCD5B6* + ID_OUI_FROM_DATABASE=d2d technologies + + OUI:BCD713* + ID_OUI_FROM_DATABASE=Owl Labs + ++OUI:BCD767* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:BCD7A5* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:BCD7CE* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ ++OUI:BCD7D4* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:BCD940* + ID_OUI_FROM_DATABASE=ASR Co,.Ltd. + +@@ -78728,9 +99068,21 @@ OUI:BCE59F* + OUI:BCE63F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:BCE67C* ++ ID_OUI_FROM_DATABASE=Cambium Networks Limited ++ ++OUI:BCE712* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:BCE767* + ID_OUI_FROM_DATABASE=Quanzhou TDX Electronics Co., Ltd + ++OUI:BCE796* ++ ID_OUI_FROM_DATABASE=Wireless CCTV Ltd ++ ++OUI:BCE92F* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:BCEA2B* + ID_OUI_FROM_DATABASE=CityCom GmbH + +@@ -78746,9 +99098,15 @@ OUI:BCEC23* + OUI:BCEC5D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:BCECA0* ++ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. ++ + OUI:BCEE7B* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:BCF171* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:BCF1F2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -78758,6 +99116,12 @@ OUI:BCF292* + OUI:BCF2AF* + ID_OUI_FROM_DATABASE=devolo AG + ++OUI:BCF310* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:BCF45F* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:BCF5AC* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -78770,9 +99134,24 @@ OUI:BCF685* + OUI:BCF811* + ID_OUI_FROM_DATABASE=Xiamen DNAKE Technology Co.,Ltd + ++OUI:BCF9F2* ++ ID_OUI_FROM_DATABASE=TEKO ++ ++OUI:BCFAB8* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ + OUI:BCFE8C* + ID_OUI_FROM_DATABASE=Altronic, LLC + ++OUI:BCFED9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:BCFF21* ++ ID_OUI_FROM_DATABASE=Smart Code(shenzhen)Technology Co.,Ltd ++ ++OUI:BCFF4D* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:BCFFAC* + ID_OUI_FROM_DATABASE=TOPCON CORPORATION + +@@ -78788,9 +99167,18 @@ OUI:C00380* + OUI:C005C2* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:C006C3* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ ++OUI:C0074A* ++ ID_OUI_FROM_DATABASE=Brita GmbH ++ + OUI:C00D7E* + ID_OUI_FROM_DATABASE=Additech, Inc. + ++OUI:C010B1* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:C01173* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -78800,18 +99188,39 @@ OUI:C011A6* + OUI:C01242* + ID_OUI_FROM_DATABASE=Alpha Security Products + ++OUI:C0132B* ++ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. ++ + OUI:C0143D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:C014B8* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:C014FE* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:C01692* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:C0174D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C01850* ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. ++ + OUI:C01885* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:C01ADA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C01B23* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:C01C30* ++ ID_OUI_FROM_DATABASE=Shenzhen WIFI-3L Technology Co.,Ltd ++ + OUI:C01E9B* + ID_OUI_FROM_DATABASE=Pixavi AS + +@@ -78819,11 +99228,17 @@ OUI:C0210D* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + + OUI:C02250* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Koss Corporation ++ ++OUI:C0238D* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:C02506* + ID_OUI_FROM_DATABASE=AVM GmbH + ++OUI:C0252F* ++ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. ++ + OUI:C0255C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -78833,12 +99248,18 @@ OUI:C02567* + OUI:C025A2* + ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. + ++OUI:C025A5* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:C025E9* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:C027B9* + ID_OUI_FROM_DATABASE=Beijing National Railway Research & Design Institute of Signal & Communication Co., Ltd. + ++OUI:C0280B* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:C0288D* + ID_OUI_FROM_DATABASE=Logitech, Inc + +@@ -78857,12 +99278,21 @@ OUI:C02C7A* + OUI:C02DEE* + ID_OUI_FROM_DATABASE=Cuff + ++OUI:C02E25* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:C02E26* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:C02FF1* + ID_OUI_FROM_DATABASE=Volta Networks + + OUI:C0335E* + ID_OUI_FROM_DATABASE=Microsoft + ++OUI:C033DA* ++ ID_OUI_FROM_DATABASE=Shenzhen JRUN Technologies CO., LTD ++ + OUI:C034B4* + ID_OUI_FROM_DATABASE=Gigastone Corporation + +@@ -78875,21 +99305,45 @@ OUI:C035BD* + OUI:C035C5* + ID_OUI_FROM_DATABASE=Prosoft Systems LTD + ++OUI:C03656* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:C03896* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:C038F9* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + ++OUI:C03937* ++ ID_OUI_FROM_DATABASE=GREE ELECTRIC APPLIANCES, INC. OF ZHUHAI ++ ++OUI:C0395A* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:C03B8F* + ID_OUI_FROM_DATABASE=Minicom Digital Signage + ++OUI:C03C04* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:C03C59* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:C03D03* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C03D46* + ID_OUI_FROM_DATABASE=Shanghai Sango Network Technology Co.,Ltd + ++OUI:C03DD9* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:C03E0F* + ID_OUI_FROM_DATABASE=BSkyB Ltd + ++OUI:C03EBA* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:C03F0E* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -78899,9 +99353,15 @@ OUI:C03F2A* + OUI:C03FD5* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd. + ++OUI:C03FDD* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C04004* + ID_OUI_FROM_DATABASE=Medicaroid Corporation + ++OUI:C04121* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ + OUI:C041F6* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + +@@ -78914,6 +99374,9 @@ OUI:C04301* + OUI:C044E3* + ID_OUI_FROM_DATABASE=Shenzhen Sinkna Electronics Co., LTD + ++OUI:C04754* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:C048E6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -78929,9 +99392,18 @@ OUI:C04A00* + OUI:C04A09* + ID_OUI_FROM_DATABASE=Zhejiang Everbright Communication Equip. Co,. Ltd + ++OUI:C04B13* ++ ID_OUI_FROM_DATABASE=WonderSound Technology Co., Ltd ++ + OUI:C04DF7* + ID_OUI_FROM_DATABASE=SERELEC + ++OUI:C0517E* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ ++OUI:C05336* ++ ID_OUI_FROM_DATABASE=Beijing National Railway Research & Design Institute of Signal & Communication Group Co..Ltd. ++ + OUI:C05627* + ID_OUI_FROM_DATABASE=Belkin International Inc. + +@@ -78953,15 +99425,66 @@ OUI:C05E79* + OUI:C06118* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:C0619A0* ++ ID_OUI_FROM_DATABASE=Paragon Robotics LLC ++ ++OUI:C0619A1* ++ ID_OUI_FROM_DATABASE=KidKraft ++ ++OUI:C0619A2* ++ ID_OUI_FROM_DATABASE=Grup Arge Enerji ve Kontrol Sistemleri ++ ++OUI:C0619A3* ++ ID_OUI_FROM_DATABASE=LYAND ACOUSTIC TECHNOLOGY CO.,LTD. ++ ++OUI:C0619A4* ++ ID_OUI_FROM_DATABASE=Stello ++ ++OUI:C0619A5* ++ ID_OUI_FROM_DATABASE=Nanjing Balance Network Technology Co., Ltd ++ ++OUI:C0619A6* ++ ID_OUI_FROM_DATABASE=IPG Automotive GmbH ++ ++OUI:C0619A7* ++ ID_OUI_FROM_DATABASE=MAD PIECE LLC. ++ ++OUI:C0619A8* ++ ID_OUI_FROM_DATABASE=Nanjing SinoVatio Technology Co., Ltd ++ ++OUI:C0619A9* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd. ++ ++OUI:C0619AA* ++ ID_OUI_FROM_DATABASE=Gronn Kontakt AS ++ ++OUI:C0619AB* ++ ID_OUI_FROM_DATABASE=Victron Energy B.V. ++ ++OUI:C0619AC* ++ ID_OUI_FROM_DATABASE=JAM-Labs Corp ++ ++OUI:C0619AD* ++ ID_OUI_FROM_DATABASE=Uhnder ++ ++OUI:C0619AE* ++ ID_OUI_FROM_DATABASE=Zhejiang Haikang Science And Technology Co.,Ltd ++ + OUI:C0626B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C06369* ++ ID_OUI_FROM_DATABASE=BINXIN TECHNOLOGY(ZHEJIANG) LTD. ++ + OUI:C06394* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:C064C6* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:C064E4* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:C06599* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -78983,6 +99506,15 @@ OUI:C07009* + OUI:C0742B* + ID_OUI_FROM_DATABASE=SHENZHEN XUNLONG SOFTWARE CO.,LIMITED + ++OUI:C074AD* ++ ID_OUI_FROM_DATABASE=Grandstream Networks, Inc. ++ ++OUI:C07831* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C07878* ++ ID_OUI_FROM_DATABASE=FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. ++ + OUI:C07BBC* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -79046,6 +99578,9 @@ OUI:C08359D* + OUI:C08359E* + ID_OUI_FROM_DATABASE=Cyber Sciences, Inc. + ++OUI:C083C9* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C0847A* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -79058,6 +99593,9 @@ OUI:C08488* + OUI:C0854C* + ID_OUI_FROM_DATABASE=Ragentek Technology Group + ++OUI:C086B3* ++ ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co., Ltd. ++ + OUI:C087EB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -79067,6 +99605,12 @@ OUI:C0885B* + OUI:C08997* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C089AB* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:C08ACD* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ + OUI:C08ADE* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -79076,12 +99620,30 @@ OUI:C08B6F* + OUI:C08C60* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C08C71* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:C08F20* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:C09132* + ID_OUI_FROM_DATABASE=Patriot Memory + + OUI:C09134* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + ++OUI:C09296* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:C09435* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:C094AD* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:C095DA* ++ ID_OUI_FROM_DATABASE=NXP India Private Limited ++ + OUI:C09727* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + +@@ -79097,6 +99659,54 @@ OUI:C098E5* + OUI:C09A71* + ID_OUI_FROM_DATABASE=XIAMEN MEITU MOBILE TECHNOLOGY CO.LTD + ++OUI:C09AD0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:C09BF40* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:C09BF41* ++ ID_OUI_FROM_DATABASE=Connected Space Management ++ ++OUI:C09BF42* ++ ID_OUI_FROM_DATABASE=Hitachi High-Tech Materials Corporation ++ ++OUI:C09BF43* ++ ID_OUI_FROM_DATABASE=Osprey Video, Inc ++ ++OUI:C09BF44* ++ ID_OUI_FROM_DATABASE=JSC NPK ATRONIK ++ ++OUI:C09BF45* ++ ID_OUI_FROM_DATABASE=Infiot Inc. ++ ++OUI:C09BF46* ++ ID_OUI_FROM_DATABASE=LTD Delovoy Office ++ ++OUI:C09BF47* ++ ID_OUI_FROM_DATABASE=Big Dutchman International GmbH ++ ++OUI:C09BF48* ++ ID_OUI_FROM_DATABASE=SHENZHEN WINS ELECTRONIC TECHNOLOGY CO., LTD ++ ++OUI:C09BF49* ++ ID_OUI_FROM_DATABASE=Alcatraz AI Inc. ++ ++OUI:C09BF4A* ++ ID_OUI_FROM_DATABASE=Inveo ++ ++OUI:C09BF4B* ++ ID_OUI_FROM_DATABASE=NUCTECH COMPANY LIMITED ++ ++OUI:C09BF4C* ++ ID_OUI_FROM_DATABASE=Pinpark Inc. ++ ++OUI:C09BF4D* ++ ID_OUI_FROM_DATABASE=The Professional Monitor Company Ltd ++ ++OUI:C09BF4E* ++ ID_OUI_FROM_DATABASE=Continental Automotive Component Malaysia Sdn.Bhd. ++ + OUI:C09C04* + ID_OUI_FROM_DATABASE=Shaanxi GuoLian Digital TV Technology Co.,Ltd. + +@@ -79112,6 +99722,9 @@ OUI:C09F05* + OUI:C09F42* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C09FE1* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:C0A00D* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -79136,6 +99749,9 @@ OUI:C0A26D* + OUI:C0A364* + ID_OUI_FROM_DATABASE=3D Systems Massachusetts + ++OUI:C0A36E* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ + OUI:C0A39E* + ID_OUI_FROM_DATABASE=EarthCam, Inc. + +@@ -79145,6 +99761,12 @@ OUI:C0A53E* + OUI:C0A5DD* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + ++OUI:C0A600* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:C0A66D* ++ ID_OUI_FROM_DATABASE=Inspur Group Co., Ltd. ++ + OUI:C0A8F0* + ID_OUI_FROM_DATABASE=Adamson Systems Engineering + +@@ -79154,12 +99776,27 @@ OUI:C0AA68* + OUI:C0AC54* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:C0AEFD* ++ ID_OUI_FROM_DATABASE=Shenzhen HC-WLAN Technology Co.,Ltd ++ ++OUI:C0B101* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:C0B339* + ID_OUI_FROM_DATABASE=Comigo Ltd. + + OUI:C0B357* + ID_OUI_FROM_DATABASE=Yoshiki Electronics Industry Ltd. + ++OUI:C0B47D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C0B5CD* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C0B5D7* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:C0B658* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -79169,18 +99806,33 @@ OUI:C0B6F9* + OUI:C0B713* + ID_OUI_FROM_DATABASE=Beijing Xiaoyuer Technology Co. Ltd. + ++OUI:C0B883* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C0B8B1* + ID_OUI_FROM_DATABASE=BitBox Ltd + ++OUI:C0B8E6* ++ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD ++ + OUI:C0BAE6* + ID_OUI_FROM_DATABASE=Application Solutions (Electronics and Vision) Ltd + ++OUI:C0BC9A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C0BD42* + ID_OUI_FROM_DATABASE=ZPA Smart Energy a.s. + ++OUI:C0BDC8* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C0BDD1* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:C0BFA7* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:C0BFC0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -79208,9 +99860,18 @@ OUI:C0C946* + OUI:C0C976* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + ++OUI:C0C9E3* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:C0CB38* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:C0CBF1* ++ ID_OUI_FROM_DATABASE=Mobiwire Mobiles (NingBo) Co., LTD ++ ++OUI:C0CC42* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:C0CCF8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -79223,12 +99884,24 @@ OUI:C0CFA3* + OUI:C0D012* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C0D026* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C0D044* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:C0D063* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:C0D0FF* + ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited + ++OUI:C0D193* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C0D2DD* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C0D2F3* + ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD + +@@ -79280,6 +99953,15 @@ OUI:C0D391E* + OUI:C0D3C0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C0D46B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C0D682* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ ++OUI:C0D834* ++ ID_OUI_FROM_DATABASE=xvtec ltd ++ + OUI:C0D962* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +@@ -79292,18 +99974,45 @@ OUI:C0DA74* + OUI:C0DC6A* + ID_OUI_FROM_DATABASE=Qingdao Eastsoft Communication Technology Co.,LTD + ++OUI:C0DCD7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C0DCDA* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C0DF77* + ID_OUI_FROM_DATABASE=Conrad Electronic SE + ++OUI:C0E018* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C0E1BE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C0E3A0* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ ++OUI:C0E3FB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C0E422* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:C0E42D* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:C0E434* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:C0E54E* + ID_OUI_FROM_DATABASE=ARIES Embedded GmbH + ++OUI:C0E7BF* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ ++OUI:C0E862* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C0EAE4* + ID_OUI_FROM_DATABASE=Sonicwall + +@@ -79325,12 +100034,24 @@ OUI:C0F2FB* + OUI:C0F4E6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C0F535* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:C0F636* + ID_OUI_FROM_DATABASE=Hangzhou Kuaiyue Technologies, Ltd. + ++OUI:C0F6C2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C0F6EC* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C0F79D* + ID_OUI_FROM_DATABASE=Powercode + ++OUI:C0F827* ++ ID_OUI_FROM_DATABASE=Rapidmax Technology Corporation ++ + OUI:C0F8DA* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -79340,6 +100061,60 @@ OUI:C0F945* + OUI:C0F991* + ID_OUI_FROM_DATABASE=GME Standard Communications P/L + ++OUI:C0F9B0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C0FBF90* ++ ID_OUI_FROM_DATABASE=Xerox Corporation ++ ++OUI:C0FBF91* ++ ID_OUI_FROM_DATABASE=LIXIL Corporation ++ ++OUI:C0FBF92* ++ ID_OUI_FROM_DATABASE=Dongguan Chuan OptoElectronics Limited ++ ++OUI:C0FBF93* ++ ID_OUI_FROM_DATABASE=SHENZHEN HEQIANG ELECTRONICS LIMITED ++ ++OUI:C0FBF94* ++ ID_OUI_FROM_DATABASE=Minato Advanced Technologies inc ++ ++OUI:C0FBF95* ++ ID_OUI_FROM_DATABASE=HAGUENET ++ ++OUI:C0FBF96* ++ ID_OUI_FROM_DATABASE=IVT corporation ++ ++OUI:C0FBF97* ++ ID_OUI_FROM_DATABASE=LongSung Technology (Shanghai) Co.,Ltd. ++ ++OUI:C0FBF98* ++ ID_OUI_FROM_DATABASE=Dongmengling ++ ++OUI:C0FBF99* ++ ID_OUI_FROM_DATABASE=zxsolution ++ ++OUI:C0FBF9A* ++ ID_OUI_FROM_DATABASE=Tiandi(Changzhou) Automation Co., Ltd. ++ ++OUI:C0FBF9B* ++ ID_OUI_FROM_DATABASE=SHENZHEN COMIX HST CLOUD COMPUTING CO., LTD. ++ ++OUI:C0FBF9C* ++ ID_OUI_FROM_DATABASE=SHENZHEN ELSKY TECHNOLOGY CO., LTD ++ ++OUI:C0FBF9D* ++ ID_OUI_FROM_DATABASE=Dropbeats Technology Co., Ltd. ++ ++OUI:C0FBF9E* ++ ID_OUI_FROM_DATABASE=Navitas Digital Safety Ltd ++ ++OUI:C0FD84* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:C0FFA8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C0FFD4* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -79364,6 +100139,9 @@ OUI:C401B1* + OUI:C401CE* + ID_OUI_FROM_DATABASE=PRESITION (2000) CO., LTD. + ++OUI:C402E1* ++ ID_OUI_FROM_DATABASE=Khwahish Technologies Private Limited ++ + OUI:C40415* + ID_OUI_FROM_DATABASE=NETGEAR + +@@ -79373,6 +100151,9 @@ OUI:C4047B* + OUI:C40528* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C40683* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C4072F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -79388,9 +100169,15 @@ OUI:C40938* + OUI:C40ACB* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C40B31* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C40BCB* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:C40D96* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C40E45* + ID_OUI_FROM_DATABASE=ACK Networks,Inc. + +@@ -79403,27 +100190,45 @@ OUI:C4108A* + OUI:C411E0* + ID_OUI_FROM_DATABASE=Bull Group Co., Ltd + ++OUI:C41234* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C412F5* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:C413E2* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:C41411* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:C4143C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C41688* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C416FA* + ID_OUI_FROM_DATABASE=Prysm Inc + + OUI:C417FE* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:C418E9* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C4198B* + ID_OUI_FROM_DATABASE=Dominion Voting Systems Corporation + ++OUI:C419D1* ++ ID_OUI_FROM_DATABASE=Telink Semiconductor (Shanghai) Co., Ltd. ++ + OUI:C419EC* + ID_OUI_FROM_DATABASE=Qualisys AB + ++OUI:C41C9C* ++ ID_OUI_FROM_DATABASE=JiQiDao ++ + OUI:C41CFF* + ID_OUI_FROM_DATABASE=Vizio, Inc + +@@ -79433,6 +100238,9 @@ OUI:C41ECE* + OUI:C421C8* + ID_OUI_FROM_DATABASE=KYOCERA CORPORATION + ++OUI:C42360* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C4237A* + ID_OUI_FROM_DATABASE=WhizNets Inc. + +@@ -79448,6 +100256,9 @@ OUI:C42456* + OUI:C42628* + ID_OUI_FROM_DATABASE=Airo Wireless + ++OUI:C4278C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C42795* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + +@@ -79457,6 +100268,15 @@ OUI:C4282D* + OUI:C4291D* + ID_OUI_FROM_DATABASE=KLEMSAN ELEKTRIK ELEKTRONIK SAN.VE TIC.AS. + ++OUI:C42996* ++ ID_OUI_FROM_DATABASE=Signify B.V. ++ ++OUI:C42AD0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:C42B44* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C42C03* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -79469,6 +100289,12 @@ OUI:C42F90* + OUI:C43018* + ID_OUI_FROM_DATABASE=MCS Logic Inc. + ++OUI:C430CA* ++ ID_OUI_FROM_DATABASE=SD Biosensor ++ ++OUI:C432D1* ++ ID_OUI_FROM_DATABASE=Farlink Technology Limited ++ + OUI:C43306* + ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. + +@@ -79484,33 +100310,60 @@ OUI:C4366C* + OUI:C436DA* + ID_OUI_FROM_DATABASE=Rusteletech Ltd. + ++OUI:C43772* ++ ID_OUI_FROM_DATABASE=Virtuozzo International GmbH ++ + OUI:C438D3* + ID_OUI_FROM_DATABASE=TAGATEC CO.,LTD + + OUI:C4393A* + ID_OUI_FROM_DATABASE=SMC Networks Inc + ++OUI:C43960* ++ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd. ++ ++OUI:C43A35* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:C43A9F* + ID_OUI_FROM_DATABASE=Siconix Inc. + + OUI:C43ABE* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:C43C3C* + ID_OUI_FROM_DATABASE=CYBELEC SA + ++OUI:C43CEA* ++ ID_OUI_FROM_DATABASE=BUFFALO.INC ++ + OUI:C43DC7* + ID_OUI_FROM_DATABASE=NETGEAR + + OUI:C44044* + ID_OUI_FROM_DATABASE=RackTop Systems Inc. + ++OUI:C440F6* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:C4411E* ++ ID_OUI_FROM_DATABASE=Belkin International Inc. ++ ++OUI:C44137* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. ++ + OUI:C44202* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C44268* ++ ID_OUI_FROM_DATABASE=CRESTRON ELECTRONICS, INC. ++ + OUI:C4438F* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:C4447D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C444A0* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -79541,6 +100394,9 @@ OUI:C44B44* + OUI:C44BD1* + ID_OUI_FROM_DATABASE=Wallys Communications Teachnologies Co.,Ltd. + ++OUI:C44D84* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:C44E1F* + ID_OUI_FROM_DATABASE=BlueN + +@@ -79557,7 +100413,7 @@ OUI:C4518D* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + + OUI:C45444* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:C455A6* + ID_OUI_FROM_DATABASE=Cadac Holdings Ltd +@@ -79583,9 +100439,24 @@ OUI:C458C2* + OUI:C45976* + ID_OUI_FROM_DATABASE=Fugoo Coorporation + ++OUI:C45A86* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C45BBE* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:C45BF7* ++ ID_OUI_FROM_DATABASE=ants ++ ++OUI:C45D83* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C45DD8* + ID_OUI_FROM_DATABASE=HDMI Forum + ++OUI:C45E5C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C46044* + ID_OUI_FROM_DATABASE=Everex Electronics Limited + +@@ -79601,24 +100472,39 @@ OUI:C462EA* + OUI:C46354* + ID_OUI_FROM_DATABASE=U-Raku, Inc. + ++OUI:C463FB* ++ ID_OUI_FROM_DATABASE=Neatframe AS ++ + OUI:C46413* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C464B7* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:C464E3* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:C46516* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:C46699* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:C467B5* + ID_OUI_FROM_DATABASE=Libratone A/S + ++OUI:C467D1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C468D0* + ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd. + + OUI:C4693E* + ID_OUI_FROM_DATABASE=Turbulence Design Inc. + ++OUI:C469F0* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C46AB7* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -79631,12 +100517,18 @@ OUI:C46DF1* + OUI:C46E1F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:C46E33* ++ ID_OUI_FROM_DATABASE=Zhong Ge Smart Technology Co., Ltd. ++ + OUI:C46E7B* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + + OUI:C4700B* + ID_OUI_FROM_DATABASE=GUANGZHOU CHIP TECHNOLOGIES CO.,LTD + ++OUI:C470AB* ++ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD ++ + OUI:C47130* + ID_OUI_FROM_DATABASE=Fon Technology S.L. + +@@ -79652,12 +100544,24 @@ OUI:C47295* + OUI:C4731E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C4741E* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:C47469* ++ ID_OUI_FROM_DATABASE=BT9 ++ ++OUI:C474F8* ++ ID_OUI_FROM_DATABASE=Hot Pepper, Inc. ++ + OUI:C477AB* + ID_OUI_FROM_DATABASE=Beijing ASU Tech Co.,Ltd + + OUI:C477AF* + ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA + ++OUI:C478A2* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C47B2F* + ID_OUI_FROM_DATABASE=Beijing JoinHope Image Technology Ltd. + +@@ -79724,6 +100628,12 @@ OUI:C47DFE* + OUI:C47F51* + ID_OUI_FROM_DATABASE=Inventek Systems + ++OUI:C48025* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C4808A* ++ ID_OUI_FROM_DATABASE=Cloud Diagnostics Canada ULC ++ + OUI:C4823F* + ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd. + +@@ -79745,15 +100655,30 @@ OUI:C486E9* + OUI:C488E5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C489ED* ++ ID_OUI_FROM_DATABASE=Solid Optics EU N.V. ++ ++OUI:C48A5A* ++ ID_OUI_FROM_DATABASE=JFCONTROL ++ + OUI:C48E8F* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:C48F07* + ID_OUI_FROM_DATABASE=Shenzhen Yihao Hulian Science and Technology Co., Ltd. + ++OUI:C48FC1* ++ ID_OUI_FROM_DATABASE=DEEPTRACK S.L.U. ++ ++OUI:C4910C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C4913A* + ID_OUI_FROM_DATABASE=Shenzhen Sanland Electronic Co., ltd. + ++OUI:C491CF* ++ ID_OUI_FROM_DATABASE=Luxul ++ + OUI:C4924C* + ID_OUI_FROM_DATABASE=KEISOKUKI CENTER CO.,LTD. + +@@ -79772,6 +100697,51 @@ OUI:C493D9* + OUI:C49500* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:C4954D0* ++ ID_OUI_FROM_DATABASE=BA International Electronics Co. Ltd. ++ ++OUI:C4954D1* ++ ID_OUI_FROM_DATABASE=Teletronik AG ++ ++OUI:C4954D2* ++ ID_OUI_FROM_DATABASE=Shen Zhen Euse Technology Co.,Ltd ++ ++OUI:C4954D3* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ ++OUI:C4954D4* ++ ID_OUI_FROM_DATABASE=GL Solutions Inc. ++ ++OUI:C4954D5* ++ ID_OUI_FROM_DATABASE=Marble Automation ++ ++OUI:C4954D6* ++ ID_OUI_FROM_DATABASE=AKKA Germany GmbH ++ ++OUI:C4954D7* ++ ID_OUI_FROM_DATABASE=LLC TechnoEnergo ++ ++OUI:C4954D8* ++ ID_OUI_FROM_DATABASE=Xinjiang Golden Calf Energy IOT Technology Co., Ltd ++ ++OUI:C4954D9* ++ ID_OUI_FROM_DATABASE=Shenzhen Xtooltech Co., Ltd ++ ++OUI:C4954DA* ++ ID_OUI_FROM_DATABASE=KAT Mekatronik Urunleri AS ++ ++OUI:C4954DB* ++ ID_OUI_FROM_DATABASE=Multicom, Inc ++ ++OUI:C4954DC* ++ ID_OUI_FROM_DATABASE=SolidGear Corporation ++ ++OUI:C4954DD* ++ ID_OUI_FROM_DATABASE=Newland Era Edu Hi-Tech(BeiJing)Co.,Ltd ++ ++OUI:C4954DE* ++ ID_OUI_FROM_DATABASE=Canare Electric Co., Ltd. ++ + OUI:C495A2* + ID_OUI_FROM_DATABASE=SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD + +@@ -79781,9 +100751,15 @@ OUI:C49805* + OUI:C4985C* + ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD + ++OUI:C49878* ++ ID_OUI_FROM_DATABASE=SHANGHAI MOAAN INTELLIGENT TECHNOLOGY CO.,LTD ++ + OUI:C49880* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C49886* ++ ID_OUI_FROM_DATABASE=Qorvo International Pte. Ltd. ++ + OUI:C49A02* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -79799,9 +100775,18 @@ OUI:C49F4C* + OUI:C49FF3* + ID_OUI_FROM_DATABASE=Mciao Technologies, Inc. + ++OUI:C4A151* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:C4A366* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:C4A402* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C4A72B* ++ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD ++ + OUI:C4A81D* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -79811,18 +100796,30 @@ OUI:C4AAA1* + OUI:C4ABB2* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:C4AC59* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:C4AD21* + ID_OUI_FROM_DATABASE=MEDIAEDGE Corporation + ++OUI:C4AD34* ++ ID_OUI_FROM_DATABASE=Routerboard.com ++ + OUI:C4ADF1* + ID_OUI_FROM_DATABASE=GOPEACE Inc. + + OUI:C4AE12* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C4B239* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:C4B301* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C4B36A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:C4B512* + ID_OUI_FROM_DATABASE=General Electric Digital Energy + +@@ -79844,6 +100841,9 @@ OUI:C4BB4C* + OUI:C4BBEA* + ID_OUI_FROM_DATABASE=Pakedge Device and Software Inc + ++OUI:C4BCD7* ++ ID_OUI_FROM_DATABASE=New Ryatek ++ + OUI:C4BD6A* + ID_OUI_FROM_DATABASE=SKF GmbH + +@@ -79853,15 +100853,27 @@ OUI:C4BE84* + OUI:C4BED4* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:C4BF60* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:C4C0AE* + ID_OUI_FROM_DATABASE=MIDORI ELECTRONIC CO., LTD. + ++OUI:C4C138* ++ ID_OUI_FROM_DATABASE=OWLink Technology Inc ++ + OUI:C4C19F* + ID_OUI_FROM_DATABASE=National Oilwell Varco Instrumentation, Monitoring, and Optimization (NOV IMO) + ++OUI:C4C36B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C4C563* + ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + ++OUI:C4C603* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:C4C755* + ID_OUI_FROM_DATABASE=Beijing HuaqinWorld Technology Co.,Ltd + +@@ -79874,6 +100886,9 @@ OUI:C4C9EC* + OUI:C4CAD9* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:C4CB54* ++ ID_OUI_FROM_DATABASE=Fibocom Auto Inc. ++ + OUI:C4CB6B* + ID_OUI_FROM_DATABASE=Airista Flow, Inc. + +@@ -79883,15 +100898,27 @@ OUI:C4CD45* + OUI:C4CD82* + ID_OUI_FROM_DATABASE=Hangzhou Lowan Information Technology Co., Ltd. + ++OUI:C4D0E3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C4D197* + ID_OUI_FROM_DATABASE=Ventia Utility Services + ++OUI:C4D438* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C4D489* + ID_OUI_FROM_DATABASE=JiangSu Joyque Information Industry Co.,Ltd + + OUI:C4D655* + ID_OUI_FROM_DATABASE=Tercel technology co.,ltd + ++OUI:C4D738* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C4D8F3* ++ ID_OUI_FROM_DATABASE=iZotope ++ + OUI:C4D987* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -79901,18 +100928,42 @@ OUI:C4DA26* + OUI:C4DA7D* + ID_OUI_FROM_DATABASE=Ivium Technologies B.V. + ++OUI:C4DD57* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:C4DE7B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C4E032* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + ++OUI:C4E0DE* ++ ID_OUI_FROM_DATABASE=Zhengzhou XindaJiean Information Technology Co.,Ltd. ++ + OUI:C4E17C* + ID_OUI_FROM_DATABASE=U2S co. + ++OUI:C4E1A1* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:C4E287* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C4E39F* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ ++OUI:C4E506* ++ ID_OUI_FROM_DATABASE=Piper Networks, Inc. ++ + OUI:C4E510* + ID_OUI_FROM_DATABASE=Mechatro, Inc. + + OUI:C4E7BE* + ID_OUI_FROM_DATABASE=SCSpro Co.,Ltd + ++OUI:C4E90A* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:C4E92F* + ID_OUI_FROM_DATABASE=AB Sciex + +@@ -79920,7 +100971,7 @@ OUI:C4E984* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:C4EA1D* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:C4EBE3* + ID_OUI_FROM_DATABASE=RRCN SAS +@@ -79940,6 +100991,12 @@ OUI:C4EF70* + OUI:C4F081* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C4F0EC* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:C4F174* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:C4F1D1* + ID_OUI_FROM_DATABASE=BEIJING SOGOU TECHNOLOGY DEVELOPMENT CO., LTD. + +@@ -79950,20 +101007,38 @@ OUI:C4F464* + ID_OUI_FROM_DATABASE=Spica international + + OUI:C4F57C* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:C4F5A5* + ID_OUI_FROM_DATABASE=Kumalift Co., Ltd. + ++OUI:C4F7D5* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:C4F839* ++ ID_OUI_FROM_DATABASE=Actia Automotive ++ ++OUI:C4FBAA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C4FCE4* + ID_OUI_FROM_DATABASE=DishTV NZ Ltd + ++OUI:C4FDE6* ++ ID_OUI_FROM_DATABASE=DRTECH ++ ++OUI:C4FE5B* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:C4FEE2* + ID_OUI_FROM_DATABASE=AMICCOM Electronics Corporation + + OUI:C4FF1F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C4FF22* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C4FFBC0* + ID_OUI_FROM_DATABASE=Danego BV + +@@ -80024,18 +101099,36 @@ OUI:C8028F* + OUI:C802A6* + ID_OUI_FROM_DATABASE=Beijing Newmine Technology + ++OUI:C803F5* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ ++OUI:C8059E* ++ ID_OUI_FROM_DATABASE=Hefei Symboltek Co.,Ltd ++ + OUI:C80718* + ID_OUI_FROM_DATABASE=TDSi + ++OUI:C80739* ++ ID_OUI_FROM_DATABASE=NAKAYO Inc ++ ++OUI:C80873* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:C808E9* + ID_OUI_FROM_DATABASE=LG Electronics + ++OUI:C809A8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C80AA9* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:C80CC8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C80D32* ++ ID_OUI_FROM_DATABASE=Holoplot GmbH ++ + OUI:C80E14* + ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH + +@@ -80048,6 +101141,9 @@ OUI:C80E95* + OUI:C81073* + ID_OUI_FROM_DATABASE=CENTURY OPTICOMM CO.,LTD + ++OUI:C8138B* ++ ID_OUI_FROM_DATABASE=Shenzhen Skyworth Digital Technology CO., Ltd ++ + OUI:C81451* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -80060,6 +101156,12 @@ OUI:C816A5* + OUI:C816BD* + ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd. + ++OUI:C816DA* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ ++OUI:C81739* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:C819F7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -80072,6 +101174,9 @@ OUI:C81B5C* + OUI:C81B6B* + ID_OUI_FROM_DATABASE=Innova Security + ++OUI:C81CFE* ++ ID_OUI_FROM_DATABASE=Zebra Technologies Inc. ++ + OUI:C81E8E* + ID_OUI_FROM_DATABASE=ADV Security (S) Pte Ltd + +@@ -80093,15 +101198,72 @@ OUI:C8208E* + OUI:C82158* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:C821DA* ++ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd ++ + OUI:C825E1* + ID_OUI_FROM_DATABASE=Lemobile Information Technology (Beijing) Co., Ltd + ++OUI:C82832* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ + OUI:C8292A* + ID_OUI_FROM_DATABASE=Barun Electronics + + OUI:C82A14* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C82B96* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:C82C2B0* ++ ID_OUI_FROM_DATABASE=Fungible, Inc. ++ ++OUI:C82C2B1* ++ ID_OUI_FROM_DATABASE=Galgus ++ ++OUI:C82C2B2* ++ ID_OUI_FROM_DATABASE=Repp Health ++ ++OUI:C82C2B3* ++ ID_OUI_FROM_DATABASE=RF Engineering and Energy Resource ++ ++OUI:C82C2B4* ++ ID_OUI_FROM_DATABASE=iWave Systems Tech Pvt Ltd ++ ++OUI:C82C2B5* ++ ID_OUI_FROM_DATABASE=DALCO AG ++ ++OUI:C82C2B6* ++ ID_OUI_FROM_DATABASE=Grav I.T. ++ ++OUI:C82C2B7* ++ ID_OUI_FROM_DATABASE=Merpa Bilgi Islem Ltd.Sti ++ ++OUI:C82C2B8* ++ ID_OUI_FROM_DATABASE=Verifone Systems (China),lnc. ++ ++OUI:C82C2B9* ++ ID_OUI_FROM_DATABASE=BIOT Sp. z o.o. ++ ++OUI:C82C2BA* ++ ID_OUI_FROM_DATABASE=Shiftall Inc. ++ ++OUI:C82C2BB* ++ ID_OUI_FROM_DATABASE=Kunshan SVL Electric Co.,Ltd ++ ++OUI:C82C2BC* ++ ID_OUI_FROM_DATABASE=Smart Wires Inc ++ ++OUI:C82C2BD* ++ ID_OUI_FROM_DATABASE=UBITRON Co.,LTD ++ ++OUI:C82C2BE* ++ ID_OUI_FROM_DATABASE=Fränkische Rohrwerke Gebr. Kirchner GmbH & Co. KG ++ ++OUI:C82E47* ++ ID_OUI_FROM_DATABASE=Suzhou SmartChip Semiconductor Co., LTD ++ + OUI:C82E94* + ID_OUI_FROM_DATABASE=Halfa Enterprise Co., Ltd. + +@@ -80114,6 +101276,9 @@ OUI:C83232* + OUI:C8334B* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C833E5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C8348E* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -80141,8 +101306,11 @@ OUI:C83D97* + OUI:C83DD4* + ID_OUI_FROM_DATABASE=CyberTAN Technology Inc. + ++OUI:C83DDC* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:C83DFC* +- ID_OUI_FROM_DATABASE=Pioneer DJ Corporation ++ ID_OUI_FROM_DATABASE=AlphaTheta Corporation + + OUI:C83E99* + ID_OUI_FROM_DATABASE=Texas Instruments +@@ -80168,6 +101336,9 @@ OUI:C84544* + OUI:C8458F* + ID_OUI_FROM_DATABASE=Wyler AG + ++OUI:C84782* ++ ID_OUI_FROM_DATABASE=Areson Technology Corp. ++ + OUI:C8478C* + ID_OUI_FROM_DATABASE=Beken Corporation + +@@ -80177,12 +101348,36 @@ OUI:C848F5* + OUI:C84C75* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C84D34* ++ ID_OUI_FROM_DATABASE=LIONS Taiwan Technology Inc. ++ ++OUI:C84D44* ++ ID_OUI_FROM_DATABASE=Shenzhen Jiapeng Huaxiang Technology Co.,Ltd ++ ++OUI:C84F0E* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ ++OUI:C84F86* ++ ID_OUI_FROM_DATABASE=Sophos Ltd ++ ++OUI:C850CE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C850E9* + ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD + ++OUI:C85142* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C85195* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:C85261* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:C853E1* ++ ID_OUI_FROM_DATABASE=Beijing Bytedance Network Technology Co., Ltd ++ + OUI:C8544B* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + +@@ -80192,15 +101387,75 @@ OUI:C85645* + OUI:C85663* + ID_OUI_FROM_DATABASE=Sunflex Europe GmbH + ++OUI:C858C0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:C85A9F* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:C85B76* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd + ++OUI:C85BA0* ++ ID_OUI_FROM_DATABASE=Shenzhen Qihu Intelligent Technology Company Limited ++ ++OUI:C85D38* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ + OUI:C86000* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:C863140* ++ ID_OUI_FROM_DATABASE=Western Reserve Controls, Inc. ++ ++OUI:C863141* ++ ID_OUI_FROM_DATABASE=Autonics Co., Ltd. ++ ++OUI:C863142* ++ ID_OUI_FROM_DATABASE=Tymphany Acoustic Technology (Huizhou) Co., Ltd. ++ ++OUI:C863143* ++ ID_OUI_FROM_DATABASE=TrackMan ++ ++OUI:C863144* ++ ID_OUI_FROM_DATABASE=Shenzhen Zero Zero Infinity Technology Co.,Ltd. ++ ++OUI:C863145* ++ ID_OUI_FROM_DATABASE=Meyer Electronics Limited ++ ++OUI:C863146* ++ ID_OUI_FROM_DATABASE=GRINBI PARTNERS ++ ++OUI:C863147* ++ ID_OUI_FROM_DATABASE=Shenzhen Wesion Technology Co., Ltd ++ ++OUI:C863148* ++ ID_OUI_FROM_DATABASE=Thinci, Inc. ++ ++OUI:C863149* ++ ID_OUI_FROM_DATABASE=Maxcom S.A. ++ ++OUI:C86314A* ++ ID_OUI_FROM_DATABASE=Optictimes Co.,Ltd ++ ++OUI:C86314B* ++ ID_OUI_FROM_DATABASE=Shenzhen Lihewei Electronics Co.,Ltd.Hunan Branch ++ ++OUI:C86314C* ++ ID_OUI_FROM_DATABASE=Freeus LLC ++ ++OUI:C86314D* ++ ID_OUI_FROM_DATABASE=Telematix AG ++ ++OUI:C86314E* ++ ID_OUI_FROM_DATABASE=Taylor Dynamometer ++ + OUI:C863F1* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + ++OUI:C863FC* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:C864C7* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -80208,10 +101463,13 @@ OUI:C8662C* + ID_OUI_FROM_DATABASE=Beijing Haitai Fangyuan High Technology Co,.Ltd. + + OUI:C8665D* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:C8675E* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:C868DE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. + + OUI:C869CD* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -80219,6 +101477,9 @@ OUI:C869CD* + OUI:C86C1E* + ID_OUI_FROM_DATABASE=Display Systems Ltd + ++OUI:C86C3D* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:C86C87* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + +@@ -80228,6 +101489,9 @@ OUI:C86CB6* + OUI:C86F1D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C87125* ++ ID_OUI_FROM_DATABASE=Johnson Outdoors Marine Electronics d/b/a Minnkota ++ + OUI:C87248* + ID_OUI_FROM_DATABASE=Aplicom Oy + +@@ -80243,6 +101507,9 @@ OUI:C87765* + OUI:C8778B* + ID_OUI_FROM_DATABASE=Mercury Systems – Trusted Mission Solutions, Inc. + ++OUI:C87B23* ++ ID_OUI_FROM_DATABASE=Bose Corporation ++ + OUI:C87B5B* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -80255,12 +101522,24 @@ OUI:C87D77* + OUI:C87E75* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C87EA1* ++ ID_OUI_FROM_DATABASE=TCL MOKA International Limited ++ ++OUI:C88314* ++ ID_OUI_FROM_DATABASE=Tempo Communications ++ + OUI:C88439* + ID_OUI_FROM_DATABASE=Sunrise Technologies + + OUI:C88447* + ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd + ++OUI:C884A1* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:C884CF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C88550* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -80279,6 +101558,9 @@ OUI:C88A83* + OUI:C88B47* + ID_OUI_FROM_DATABASE=Nolangroup S.P.A con Socio Unico + ++OUI:C88BE8* ++ ID_OUI_FROM_DATABASE=Masimo Corporation ++ + OUI:C88D83* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -80345,21 +101627,42 @@ OUI:C89346* + OUI:C89383* + ID_OUI_FROM_DATABASE=Embedded Automation, Inc. + ++OUI:C89402* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:C894BB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:C894D2* + ID_OUI_FROM_DATABASE=Jiangsu Datang Electronic Products Co., Ltd + ++OUI:C89665* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:C8979F* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:C89BAD* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ ++OUI:C89C13* ++ ID_OUI_FROM_DATABASE=Inspiremobile ++ + OUI:C89C1D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:C89CDC* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd. + ++OUI:C89D18* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:C89E43* ++ ID_OUI_FROM_DATABASE=NETGEAR ++ ++OUI:C89F1A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C89F1D* + ID_OUI_FROM_DATABASE=SHENZHEN COMMUNICATION TECHNOLOGIES CO.,LTD + +@@ -80378,6 +101681,9 @@ OUI:C8A1BA* + OUI:C8A2CE* + ID_OUI_FROM_DATABASE=Oasis Media Systems LLC + ++OUI:C8A40D* ++ ID_OUI_FROM_DATABASE=Cooler Master Technology Inc ++ + OUI:C8A620* + ID_OUI_FROM_DATABASE=Nebula, Inc + +@@ -80387,6 +101693,9 @@ OUI:C8A70A* + OUI:C8A729* + ID_OUI_FROM_DATABASE=SYStronics Co., Ltd. + ++OUI:C8A776* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C8A823* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -80411,36 +101720,63 @@ OUI:C8AF40* + OUI:C8AFE3* + ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd + ++OUI:C8B1CD* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:C8B1EE* + ID_OUI_FROM_DATABASE=Qorvo + + OUI:C8B21E* + ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. + ++OUI:C8B29B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C8B373* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + ++OUI:C8B422* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ + OUI:C8B5AD* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + + OUI:C8B5B7* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C8B6D3* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C8BA94* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + + OUI:C8BAE9* + ID_OUI_FROM_DATABASE=QDIS + ++OUI:C8BB81* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C8BBD3* + ID_OUI_FROM_DATABASE=Embrane + ++OUI:C8BC9C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C8BCC8* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:C8BCE5* ++ ID_OUI_FROM_DATABASE=Sense Things Japan INC. ++ ++OUI:C8BD69* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:C8BE19* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:C8BFFE* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C8C126* + ID_OUI_FROM_DATABASE=ZPM Industria e Comercio Ltda + +@@ -80453,12 +101789,30 @@ OUI:C8C2C6* + OUI:C8C2F5* + ID_OUI_FROM_DATABASE=FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. + ++OUI:C8C2FA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:C8C465* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C8C50E* + ID_OUI_FROM_DATABASE=Shenzhen Primestone Network Technologies.Co., Ltd. + ++OUI:C8C64A* ++ ID_OUI_FROM_DATABASE=Flextronics Tech.(Ind) Pvt Ltd ++ ++OUI:C8C750* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:C8C791* + ID_OUI_FROM_DATABASE=Zero1.tv GmbH + ++OUI:C8C9A3* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:C8CA63* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:C8CBB8* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -80501,15 +101855,24 @@ OUI:C8D590* + OUI:C8D5FE* + ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd + ++OUI:C8D69D* ++ ID_OUI_FROM_DATABASE=Arab International Optronics ++ + OUI:C8D719* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + ++OUI:C8D778* ++ ID_OUI_FROM_DATABASE=BSH Hausgeraete GmbH ++ + OUI:C8D779* + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. + + OUI:C8D7B0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:C8D884* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:C8D9D2* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -80540,9 +101903,15 @@ OUI:C8E130* + OUI:C8E1A7* + ID_OUI_FROM_DATABASE=Vertu Corporation Limited + ++OUI:C8E265* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:C8E42F* + ID_OUI_FROM_DATABASE=Technical Research Design and Development + ++OUI:C8E600* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:C8E776* + ID_OUI_FROM_DATABASE=PTCOM Technology + +@@ -80552,6 +101921,9 @@ OUI:C8E7D8* + OUI:C8E7F0* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:C8EAF8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:C8EE08* + ID_OUI_FROM_DATABASE=TANGTOP TECHNOLOGY CO.,LTD + +@@ -80567,6 +101939,9 @@ OUI:C8EF2E* + OUI:C8F230* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:C8F319* ++ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) ++ + OUI:C8F36B* + ID_OUI_FROM_DATABASE=Yamato Scale Co.,Ltd. + +@@ -80576,18 +101951,72 @@ OUI:C8F386* + OUI:C8F406* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:C8F5D60* ++ ID_OUI_FROM_DATABASE=MEIRYO TECHNICA CORPORATION ++ ++OUI:C8F5D61* ++ ID_OUI_FROM_DATABASE=Valeo Interior Controls (Shenzhen) Co.,Ltd ++ ++OUI:C8F5D62* ++ ID_OUI_FROM_DATABASE=Qbic Technology Co., Ltd ++ ++OUI:C8F5D63* ++ ID_OUI_FROM_DATABASE=BBPOS International Limited ++ ++OUI:C8F5D64* ++ ID_OUI_FROM_DATABASE=EVOTOR LLC ++ ++OUI:C8F5D65* ++ ID_OUI_FROM_DATABASE=Pinmicro K K ++ ++OUI:C8F5D66* ++ ID_OUI_FROM_DATABASE=Jabil ++ ++OUI:C8F5D67* ++ ID_OUI_FROM_DATABASE=Oscars Pro ++ ++OUI:C8F5D68* ++ ID_OUI_FROM_DATABASE=Yarward Electronics Co., Ltd. ++ ++OUI:C8F5D69* ++ ID_OUI_FROM_DATABASE=Shanghai Mo xiang Network Technology CO.,Ltd ++ ++OUI:C8F5D6A* ++ ID_OUI_FROM_DATABASE=HENAN FOXSTAR DIGITAL DISPLAY Co.,Ltd. ++ ++OUI:C8F5D6B* ++ ID_OUI_FROM_DATABASE=United Barcode Systems ++ ++OUI:C8F5D6C* ++ ID_OUI_FROM_DATABASE=Eltako GmbH ++ ++OUI:C8F5D6D* ++ ID_OUI_FROM_DATABASE=Volansys technologies pvt ltd ++ ++OUI:C8F5D6E* ++ ID_OUI_FROM_DATABASE=HEITEC AG ++ + OUI:C8F650* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:C8F68D* + ID_OUI_FROM_DATABASE=S.E.TECHNOLOGIES LIMITED + ++OUI:C8F6C8* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:C8F704* + ID_OUI_FROM_DATABASE=Building Block Video + + OUI:C8F733* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:C8F742* ++ ID_OUI_FROM_DATABASE=HangZhou Gubei Electronics Technology Co.,Ltd ++ ++OUI:C8F750* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:C8F86D* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +@@ -80603,6 +102032,9 @@ OUI:C8F9C8* + OUI:C8F9F9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:C8FA84* ++ ID_OUI_FROM_DATABASE=Trusonus corp. ++ + OUI:C8FAE1* + ID_OUI_FROM_DATABASE=ARQ Digital LLC + +@@ -80615,6 +102047,9 @@ OUI:C8FD19* + OUI:C8FE30* + ID_OUI_FROM_DATABASE=Bejing DAYO Mobile Communication Technology Ltd. + ++OUI:C8FE6A* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:C8FF28* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -80639,6 +102074,9 @@ OUI:CC04B4* + OUI:CC051B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:CC0577* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CC0677* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -80663,15 +102101,24 @@ OUI:CC09C8* + OUI:CC0CDA* + ID_OUI_FROM_DATABASE=Miljovakt AS + ++OUI:CC0DE7* ++ ID_OUI_FROM_DATABASE=B METERS S.R.L. ++ + OUI:CC0DEC* + ID_OUI_FROM_DATABASE=Cisco SPVTG + ++OUI:CC0DF2* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:CC10A3* + ID_OUI_FROM_DATABASE=Beijing Nan Bao Technology Co., Ltd. + + OUI:CC14A6* + ID_OUI_FROM_DATABASE=Yichun MyEnergy Domain, Inc + ++OUI:CC1531* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:CC167E* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -80738,6 +102185,9 @@ OUI:CC1EFF* + OUI:CC1FC4* + ID_OUI_FROM_DATABASE=InVue + ++OUI:CC208C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CC20E8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -80792,6 +102242,9 @@ OUI:CC2237D* + OUI:CC2237E* + ID_OUI_FROM_DATABASE=MANUFACTURAS Y TRANSFORMADOS AB, S.L. + ++OUI:CC242E* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:CC25EF* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -80804,6 +102257,12 @@ OUI:CC29F5* + OUI:CC2A80* + ID_OUI_FROM_DATABASE=Micro-Biz intelligence solutions Co.,Ltd + ++OUI:CC2C83* ++ ID_OUI_FROM_DATABASE=DarkMatter L.L.C ++ ++OUI:CC2D1B* ++ ID_OUI_FROM_DATABASE=SFR ++ + OUI:CC2D21* + ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch + +@@ -80825,6 +102284,18 @@ OUI:CC2F71* + OUI:CC3080* + ID_OUI_FROM_DATABASE=VAIO Corporation + ++OUI:CC312A* ++ ID_OUI_FROM_DATABASE=HUIZHOU TCL COMMUNICATION ELECTRON CO.,LTD ++ ++OUI:CC3296* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:CC32E5* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:CC3331* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:CC33BB* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -80837,8 +102308,11 @@ OUI:CC34D7* + OUI:CC3540* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:CC355A* ++ ID_OUI_FROM_DATABASE=SecuGen Corporation ++ + OUI:CC37AB* +- ID_OUI_FROM_DATABASE=Edgecore Networks Corportation ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation + + OUI:CC398C* + ID_OUI_FROM_DATABASE=Shiningtek +@@ -80847,7 +102321,10 @@ OUI:CC3A61* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + + OUI:CC3ADF* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Neptune Technology Group Inc. ++ ++OUI:CC3B27* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + + OUI:CC3B3E* + ID_OUI_FROM_DATABASE=Lester Electrical +@@ -80867,9 +102344,18 @@ OUI:CC3E5F* + OUI:CC3F1D* + ID_OUI_FROM_DATABASE=Intesis Software SL + ++OUI:CC3F8A* ++ ID_OUI_FROM_DATABASE=KOMATSU LTD. ++ ++OUI:CC3FEA* ++ ID_OUI_FROM_DATABASE=BAE Systems, Inc ++ + OUI:CC40D0* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:CC418E* ++ ID_OUI_FROM_DATABASE=MSA Innovation ++ + OUI:CC43E3* + ID_OUI_FROM_DATABASE=Trump s.a. + +@@ -80879,12 +102365,21 @@ OUI:CC4463* + OUI:CC4639* + ID_OUI_FROM_DATABASE=WAAV, Inc. + ++OUI:CC464E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:CC46D6* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:CC4703* + ID_OUI_FROM_DATABASE=Intercon Systems Co., Ltd. + ++OUI:CC47BD* ++ ID_OUI_FROM_DATABASE=Rhombus Systems ++ ++OUI:CC483A* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:CC4AE1* + ID_OUI_FROM_DATABASE=fourtec -Fourier Technologies + +@@ -80898,11 +102393,53 @@ OUI:CC4D38* + ID_OUI_FROM_DATABASE=Carnegie Technologies + + OUI:CC4E24* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:CC4EEC* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:CC4F5C1* ++ ID_OUI_FROM_DATABASE=lesswire GmbH ++ ++OUI:CC4F5C2* ++ ID_OUI_FROM_DATABASE=MatchX GmbH ++ ++OUI:CC4F5C3* ++ ID_OUI_FROM_DATABASE=Shanghai Zenchant Electornics Co.,LTD ++ ++OUI:CC4F5C4* ++ ID_OUI_FROM_DATABASE=Spark Biomedical ++ ++OUI:CC4F5C5* ++ ID_OUI_FROM_DATABASE=Kymati GmbH ++ ++OUI:CC4F5C6* ++ ID_OUI_FROM_DATABASE=Watertech S.p.A. ++ ++OUI:CC4F5C7* ++ ID_OUI_FROM_DATABASE=Smiths US Innovation LLC ++ ++OUI:CC4F5C8* ++ ID_OUI_FROM_DATABASE=Feelmore Labs ++ ++OUI:CC4F5C9* ++ ID_OUI_FROM_DATABASE=Dtrovision ++ ++OUI:CC4F5CA* ++ ID_OUI_FROM_DATABASE=AZ-TECHNOLOGY SDN BHD ++ ++OUI:CC4F5CB* ++ ID_OUI_FROM_DATABASE=Ontex BV ++ ++OUI:CC4F5CC* ++ ID_OUI_FROM_DATABASE=Beijing Cotytech Technology Co.,LTD. ++ ++OUI:CC4F5CD* ++ ID_OUI_FROM_DATABASE=Beijing Neutron Technology CO.,LTD. ++ ++OUI:CC4F5CE* ++ ID_OUI_FROM_DATABASE=Buttons (Beijing) Technology Limited ++ + OUI:CC500A* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -80918,6 +102455,9 @@ OUI:CC50E3* + OUI:CC51B4* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:CC5289* ++ ID_OUI_FROM_DATABASE=SHENZHEN OPTFOCUS TECHNOLOGY.,LTD ++ + OUI:CC52AF* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +@@ -80931,7 +102471,7 @@ OUI:CC55AD* + ID_OUI_FROM_DATABASE=RIM + + OUI:CC593E* +- ID_OUI_FROM_DATABASE=TOUMAZ LTD ++ ID_OUI_FROM_DATABASE=Sensium Healthcare Limited + + OUI:CC5A53* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -80939,12 +102479,18 @@ OUI:CC5A53* + OUI:CC5C75* + ID_OUI_FROM_DATABASE=Weightech Com. Imp. Exp. Equip. Pesagem Ltda + ++OUI:CC5CDE* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:CC5D4E* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + + OUI:CC5D57* + ID_OUI_FROM_DATABASE=Information System Research Institute,Inc. + ++OUI:CC5D78* ++ ID_OUI_FROM_DATABASE=JTD Consulting ++ + OUI:CC5FBF* + ID_OUI_FROM_DATABASE=Topwise 3G Communication Co., Ltd. + +@@ -80954,15 +102500,33 @@ OUI:CC60BB* + OUI:CC61E5* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:CC64A6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CC65AD* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:CC660A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:CC66B2* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:CC68B6* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ + OUI:CC69B0* + ID_OUI_FROM_DATABASE=Global Traffic Technologies, LLC + ++OUI:CC69FA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:CC6A10* ++ ID_OUI_FROM_DATABASE=The Chamberlain Group, Inc ++ ++OUI:CC6B1E* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:CC6B98* + ID_OUI_FROM_DATABASE=Minetec Wireless Technologies + +@@ -80978,15 +102542,24 @@ OUI:CC6DEF* + OUI:CC6EA4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:CC70ED* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:CC720F* + ID_OUI_FROM_DATABASE=Viscount Systems Inc. + ++OUI:CC7286* ++ ID_OUI_FROM_DATABASE=Xi'an Fengyu Information Technology Co., Ltd. ++ + OUI:CC7314* + ID_OUI_FROM_DATABASE=HONG KONG WHEATEK TECHNOLOGY LIMITED + + OUI:CC7498* + ID_OUI_FROM_DATABASE=Filmetrics Inc. + ++OUI:CC75E2* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:CC7669* + ID_OUI_FROM_DATABASE=SEETECH + +@@ -81017,6 +102590,15 @@ OUI:CC7D37* + OUI:CC7EE7* + ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company + ++OUI:CC7F75* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:CC7F76* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:CC812A* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:CC81DA* + ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd. + +@@ -81026,6 +102608,24 @@ OUI:CC82EB* + OUI:CC856C* + ID_OUI_FROM_DATABASE=SHENZHEN MDK DIGITAL TECHNOLOGY CO.,LTD + ++OUI:CC86EC* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:CC874A* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:CC8826* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ ++OUI:CC88C7* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:CC895E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:CC896C* ++ ID_OUI_FROM_DATABASE=GN Hearing A/S ++ + OUI:CC89FD* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -81038,6 +102638,9 @@ OUI:CC8CE3* + OUI:CC8E71* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:CC9070* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:CC9093* + ID_OUI_FROM_DATABASE=Hansong Tehnologies + +@@ -81065,15 +102668,30 @@ OUI:CC9635* + OUI:CC96A0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:CC988B* ++ ID_OUI_FROM_DATABASE=SONY Visual Products Inc. ++ + OUI:CC9891* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:CC9916* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:CC9C3E* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ ++OUI:CC9DA2* ++ ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd. ++ + OUI:CC9E00* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:CC9EA2* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:CC9ECA* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:CC9F35* + ID_OUI_FROM_DATABASE=Transbit Sp. z o.o. + +@@ -81083,6 +102701,9 @@ OUI:CC9F7A* + OUI:CCA0E5* + ID_OUI_FROM_DATABASE=DZG Metering GmbH + ++OUI:CCA12B* ++ ID_OUI_FROM_DATABASE=TCL King Electrical Appliances (Huizhou) Co., Ltd ++ + OUI:CCA219* + ID_OUI_FROM_DATABASE=SHENZHEN ALONG INVESTMENT CO.,LTD + +@@ -81090,7 +102711,7 @@ OUI:CCA223* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:CCA260* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:CCA374* + ID_OUI_FROM_DATABASE=Guangdong Guanglian Electronic Technology Co.Ltd +@@ -81104,15 +102725,27 @@ OUI:CCA4AF* + OUI:CCA614* + ID_OUI_FROM_DATABASE=AIFA TECHNOLOGY CORP. + ++OUI:CCA7C1* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:CCAB2C* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ + OUI:CCAF78* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:CCB0A8* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:CCB0DA* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + + OUI:CCB11A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:CCB182* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CCB255* + ID_OUI_FROM_DATABASE=D-Link International + +@@ -81125,6 +102758,9 @@ OUI:CCB3F8* + OUI:CCB55A* + ID_OUI_FROM_DATABASE=Fraunhofer ITWM + ++OUI:CCB5D1* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:CCB691* + ID_OUI_FROM_DATABASE=NECMagnusCommunications + +@@ -81137,6 +102773,12 @@ OUI:CCB8A8* + OUI:CCB8F1* + ID_OUI_FROM_DATABASE=EAGLE KINGDOM TECHNOLOGIES LIMITED + ++OUI:CCBBFE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:CCBCE3* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CCBD35* + ID_OUI_FROM_DATABASE=Steinel GmbH + +@@ -81155,6 +102797,48 @@ OUI:CCC079* + OUI:CCC104* + ID_OUI_FROM_DATABASE=Applied Technical Systems + ++OUI:CCC2610* ++ ID_OUI_FROM_DATABASE=Ebiologic Technology Co., Ltd. ++ ++OUI:CCC2611* ++ ID_OUI_FROM_DATABASE=NWL Inc. ++ ++OUI:CCC2612* ++ ID_OUI_FROM_DATABASE=Tecnoideal Srl ++ ++OUI:CCC2613* ++ ID_OUI_FROM_DATABASE=NETRADYNE, INC. ++ ++OUI:CCC2614* ++ ID_OUI_FROM_DATABASE=EDAG Engineering GmbH ++ ++OUI:CCC2615* ++ ID_OUI_FROM_DATABASE=Viper Design, LLC ++ ++OUI:CCC2616* ++ ID_OUI_FROM_DATABASE=Guardiar USA ++ ++OUI:CCC2617* ++ ID_OUI_FROM_DATABASE=Ability Enterprise Co., Ltd ++ ++OUI:CCC2619* ++ ID_OUI_FROM_DATABASE=BYTERG LLC ++ ++OUI:CCC261A* ++ ID_OUI_FROM_DATABASE=Shenzhen Uyesee Technology Co.,Ltd ++ ++OUI:CCC261B* ++ ID_OUI_FROM_DATABASE=Winterthur Gas & Diesel Ltd. ++ ++OUI:CCC261C* ++ ID_OUI_FROM_DATABASE=Nortek Security & Control ++ ++OUI:CCC261D* ++ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc. ++ ++OUI:CCC261E* ++ ID_OUI_FROM_DATABASE=Toong In Electronic Corp. ++ + OUI:CCC2E0* + ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD + +@@ -81182,12 +102866,18 @@ OUI:CCC8D7* + OUI:CCC92C* + ID_OUI_FROM_DATABASE=Schindler - PORT Technology + ++OUI:CCC95D* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:CCCC4E* + ID_OUI_FROM_DATABASE=Sun Fountainhead USA. Corp + + OUI:CCCC81* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:CCCCCC* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ + OUI:CCCD64* + ID_OUI_FROM_DATABASE=SM-Electronic GmbH + +@@ -81197,6 +102887,12 @@ OUI:CCCE1E* + OUI:CCCE40* + ID_OUI_FROM_DATABASE=Janteq Corp + ++OUI:CCD083* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:CCD281* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:CCD29B* + ID_OUI_FROM_DATABASE=Shenzhen Bopengfa Elec&Technology CO.,Ltd + +@@ -81245,30 +102941,111 @@ OUI:CCD31ED* + OUI:CCD31EE* + ID_OUI_FROM_DATABASE=ShenZhenBoryNet Co.,LTD. + ++OUI:CCD39D0* ++ ID_OUI_FROM_DATABASE=INX CO.,LTD. ++ ++OUI:CCD39D1* ++ ID_OUI_FROM_DATABASE=Evoko Unlimited AB ++ ++OUI:CCD39D2* ++ ID_OUI_FROM_DATABASE=Continental Control Systems ++ ++OUI:CCD39D3* ++ ID_OUI_FROM_DATABASE=MagTarget LLC ++ ++OUI:CCD39D4* ++ ID_OUI_FROM_DATABASE=Shenzhen Chenggu Technology Co., Ltd ++ ++OUI:CCD39D5* ++ ID_OUI_FROM_DATABASE=SHENZHEN ROYOLE TECHNOLOGIES CO., LTD. ++ ++OUI:CCD39D6* ++ ID_OUI_FROM_DATABASE=Krontech ++ ++OUI:CCD39D7* ++ ID_OUI_FROM_DATABASE=Glenair ++ ++OUI:CCD39D8* ++ ID_OUI_FROM_DATABASE=Obelisk Inc. ++ ++OUI:CCD39D9* ++ ID_OUI_FROM_DATABASE=Bejing Nexsec Inc. ++ ++OUI:CCD39DA* ++ ID_OUI_FROM_DATABASE=Lubelskie Fabryki Wag FAWAG S.A. ++ ++OUI:CCD39DB* ++ ID_OUI_FROM_DATABASE=Q-Branch Labs, Inc. ++ ++OUI:CCD39DC* ++ ID_OUI_FROM_DATABASE=Hangzhou Scooper Technology Co.,Ltd. ++ ++OUI:CCD39DD* ++ ID_OUI_FROM_DATABASE=Ethernity Networks ++ ++OUI:CCD39DE* ++ ID_OUI_FROM_DATABASE=Shanghai tongli information technology co. LTD ++ ++OUI:CCD3C1* ++ ID_OUI_FROM_DATABASE=Vestel Elektronik San ve Tic. A.Ş. ++ + OUI:CCD3E2* + ID_OUI_FROM_DATABASE=Jiangsu Yinhe Electronics Co.,Ltd. + ++OUI:CCD42E* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ ++OUI:CCD4A1* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:CCD539* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:CCD73C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:CCD811* + ID_OUI_FROM_DATABASE=Aiconn Technology Corporation + ++OUI:CCD81F* ++ ID_OUI_FROM_DATABASE=Maipu Communication Technology Co.,Ltd. ++ + OUI:CCD8C1* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:CCD9AC* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:CCD9E9* + ID_OUI_FROM_DATABASE=SCR Engineers Ltd. + ++OUI:CCDB04* ++ ID_OUI_FROM_DATABASE=DataRemote Inc. ++ ++OUI:CCDB93* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:CCDC55* ++ ID_OUI_FROM_DATABASE=Dragonchip Limited ++ + OUI:CCE0C3* +- ID_OUI_FROM_DATABASE=Mangstor, Inc. ++ ID_OUI_FROM_DATABASE=EXTEN Technologies, Inc. ++ ++OUI:CCE0DA* ++ ID_OUI_FROM_DATABASE=Baidu Online Network Technology (Beijing) Co., Ltd + + OUI:CCE17F* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:CCE194* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:CCE1D5* + ID_OUI_FROM_DATABASE=BUFFALO.INC + ++OUI:CCE236* ++ ID_OUI_FROM_DATABASE=Hangzhou Yaguan Technology Co. LTD ++ + OUI:CCE798* + ID_OUI_FROM_DATABASE=My Social Stuff + +@@ -81281,9 +103058,18 @@ OUI:CCE8AC* + OUI:CCEA1C* + ID_OUI_FROM_DATABASE=DCONWORKS Co., Ltd + ++OUI:CCED21* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ ++OUI:CCEDDC* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:CCEED9* + ID_OUI_FROM_DATABASE=VAHLE Automation GmbH + ++OUI:CCEF03* ++ ID_OUI_FROM_DATABASE=Hunan Keyshare Communication Technology Co., Ltd. ++ + OUI:CCEF48* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -81296,12 +103082,21 @@ OUI:CCF3A5* + OUI:CCF407* + ID_OUI_FROM_DATABASE=EUKREA ELECTROMATIQUE SARL + ++OUI:CCF411* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:CCF538* + ID_OUI_FROM_DATABASE=3isysnetworks + ++OUI:CCF55F* ++ ID_OUI_FROM_DATABASE=E FOCUS INSTRUMENTS INDIA PRIVATE LIMITED ++ + OUI:CCF67A* + ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD + ++OUI:CCF735* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:CCF841* + ID_OUI_FROM_DATABASE=Lumewave + +@@ -81314,12 +103109,18 @@ OUI:CCF954* + OUI:CCF957* + ID_OUI_FROM_DATABASE=u-blox AG + ++OUI:CCF9E4* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:CCF9E8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:CCFA00* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:CCFA66* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:CCFB65* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +@@ -81335,12 +103136,18 @@ OUI:CCFD17* + OUI:CCFE3C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:CCFF90* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D0034B* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:D003DF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D003EB* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:D00401* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -81350,6 +103157,9 @@ OUI:D00492* + OUI:D0052A* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + ++OUI:D005E4* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D00790* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -81359,6 +103169,9 @@ OUI:D007CA* + OUI:D00AAB* + ID_OUI_FROM_DATABASE=Yokogawa Digital Computer Corporation + ++OUI:D00DF7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D00EA4* + ID_OUI_FROM_DATABASE=Porsche Cars North America + +@@ -81371,30 +103184,99 @@ OUI:D00F6D* + OUI:D01242* + ID_OUI_FROM_DATABASE=BIOS Corporation + ++OUI:D012CB* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:D0131E* + ID_OUI_FROM_DATABASE=Sunrex Technology Corp + + OUI:D013FD* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + ++OUI:D014110* ++ ID_OUI_FROM_DATABASE=EkkoSense Ltd ++ ++OUI:D014111* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:D014112* ++ ID_OUI_FROM_DATABASE=Evoco Labs CO., LTD ++ ++OUI:D014113* ++ ID_OUI_FROM_DATABASE=iLOQ Oy ++ ++OUI:D014114* ++ ID_OUI_FROM_DATABASE=powerall ++ ++OUI:D014116* ++ ID_OUI_FROM_DATABASE=Ahnnet ++ ++OUI:D014117* ++ ID_OUI_FROM_DATABASE=Realwave Inc. ++ ++OUI:D014118* ++ ID_OUI_FROM_DATABASE=Video Security, Inc. ++ ++OUI:D014119* ++ ID_OUI_FROM_DATABASE=Airthings ++ ++OUI:D01411A* ++ ID_OUI_FROM_DATABASE=ABB EVI SPA ++ ++OUI:D01411B* ++ ID_OUI_FROM_DATABASE=CYLTek Limited ++ ++OUI:D01411C* ++ ID_OUI_FROM_DATABASE=Shen Zhen HaiHe Hi-Tech Co., Ltd ++ ++OUI:D01411D* ++ ID_OUI_FROM_DATABASE=Guangdong Shiqi Manufacture Co., Ltd. ++ ++OUI:D01411E* ++ ID_OUI_FROM_DATABASE=Tecnosoft srl ++ + OUI:D0154A* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:D015A6* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:D0167C* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:D016B4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:D01769* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:D0176A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:D017C2* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:D0196A* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ + OUI:D01AA7* + ID_OUI_FROM_DATABASE=UniPrint + ++OUI:D01C3C* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:D01CBB* + ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd. + ++OUI:D01E1D* ++ ID_OUI_FROM_DATABASE=SaiNXT Technologies LLP ++ ++OUI:D021AC* ++ ID_OUI_FROM_DATABASE=Yo Labs LLC ++ ++OUI:D021F9* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ + OUI:D022120* + ID_OUI_FROM_DATABASE=Spirit IT B.V. + +@@ -81458,6 +103340,9 @@ OUI:D02598* + OUI:D02788* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:D028BA* ++ ID_OUI_FROM_DATABASE=Realme Chongqing MobileTelecommunications Corp Ltd ++ + OUI:D02B20* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -81467,6 +103352,9 @@ OUI:D02C45* + OUI:D02DB3* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:D02EAB* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:D03110* + ID_OUI_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd + +@@ -81476,9 +103364,15 @@ OUI:D03169* + OUI:D03311* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D035E5* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:D03742* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd + ++OUI:D03745* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:D03761* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -81488,21 +103382,51 @@ OUI:D03972* + OUI:D039B3* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:D039EA* ++ ID_OUI_FROM_DATABASE=NetApp ++ ++OUI:D03C1F* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D03D52* ++ ID_OUI_FROM_DATABASE=Ava Security Limited ++ + OUI:D03DC3* + ID_OUI_FROM_DATABASE=AQ Corporation + + OUI:D03E5C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:D03E7D* ++ ID_OUI_FROM_DATABASE=CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. ++ ++OUI:D03F27* ++ ID_OUI_FROM_DATABASE=Wyze Labs Inc ++ ++OUI:D03FAA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:D040EF* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ ++OUI:D041C9* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:D0431E* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:D046DC* + ID_OUI_FROM_DATABASE=Southwest Research Institute + ++OUI:D047C1* ++ ID_OUI_FROM_DATABASE=Elma Electronic AG ++ + OUI:D048F3* + ID_OUI_FROM_DATABASE=DATTUS Inc + ++OUI:D0497C* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ + OUI:D0498B* + ID_OUI_FROM_DATABASE=ZOOM SERVER + +@@ -81512,14 +103436,23 @@ OUI:D04CC1* + OUI:D04D2C* + ID_OUI_FROM_DATABASE=Roku, Inc. + ++OUI:D04DC6* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:D04E50* ++ ID_OUI_FROM_DATABASE=Mobiwire Mobiles (NingBo) Co., LTD ++ + OUI:D04F7E* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:D05099* + ID_OUI_FROM_DATABASE=ASRock Incorporation + ++OUI:D05157* ++ ID_OUI_FROM_DATABASE=LEAX Arkivator Telecom ++ + OUI:D05162* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:D052A8* + ID_OUI_FROM_DATABASE=Physical Graph Corporation +@@ -81530,9 +103463,18 @@ OUI:D05349* + OUI:D0542D* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:D05475* ++ ID_OUI_FROM_DATABASE=SAVI Controls ++ ++OUI:D05509* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:D055B2* + ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. + ++OUI:D056BF* ++ ID_OUI_FROM_DATABASE=AMOSENSE ++ + OUI:D0574C* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -81542,6 +103484,9 @@ OUI:D0577B* + OUI:D05785* + ID_OUI_FROM_DATABASE=Pantech Co., Ltd. + ++OUI:D05794* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:D057A1* + ID_OUI_FROM_DATABASE=Werma Signaltechnik GmbH & Co. KG + +@@ -81551,9 +103496,15 @@ OUI:D05875* + OUI:D058A8* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:D058C0* ++ ID_OUI_FROM_DATABASE=Qingdao Haier Multimedia Limited. ++ + OUI:D058FC* + ID_OUI_FROM_DATABASE=BSkyB Ltd + ++OUI:D05919* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:D05995* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -81572,12 +103523,60 @@ OUI:D05A0F* + OUI:D05AF1* + ID_OUI_FROM_DATABASE=Shenzhen Pulier Tech CO.,Ltd + ++OUI:D05AFD* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:D05BA8* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:D05C7A* + ID_OUI_FROM_DATABASE=Sartura d.o.o. + ++OUI:D05F640* ++ ID_OUI_FROM_DATABASE=Decathlon SA ++ ++OUI:D05F641* ++ ID_OUI_FROM_DATABASE=Hangzhou ToupTek Photonics Co., Ltd. ++ ++OUI:D05F642* ++ ID_OUI_FROM_DATABASE=SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD ++ ++OUI:D05F643* ++ ID_OUI_FROM_DATABASE=HUAQIN TELECOM HONG KONG LTD ++ ++OUI:D05F644* ++ ID_OUI_FROM_DATABASE=wallbe GmbH ++ ++OUI:D05F645* ++ ID_OUI_FROM_DATABASE=Atoll Solutions Private Limited ++ ++OUI:D05F646* ++ ID_OUI_FROM_DATABASE=Cyrus Technology GmbH ++ ++OUI:D05F647* ++ ID_OUI_FROM_DATABASE=Beijing Core Shield Group Co., Ltd. ++ ++OUI:D05F648* ++ ID_OUI_FROM_DATABASE=TytoCare LTD. ++ ++OUI:D05F649* ++ ID_OUI_FROM_DATABASE=Shanghai Luying International Trade Co.,Ltd ++ ++OUI:D05F64A* ++ ID_OUI_FROM_DATABASE=PartnerNET LTD ++ ++OUI:D05F64B* ++ ID_OUI_FROM_DATABASE=North American Blue Tiger Company, LLC ++ ++OUI:D05F64C* ++ ID_OUI_FROM_DATABASE=Nanjing Huamai Technology Co.,Ltd ++ ++OUI:D05F64D* ++ ID_OUI_FROM_DATABASE=Shenzhen Canzone Technology Co.,Ltd. ++ ++OUI:D05F64E* ++ ID_OUI_FROM_DATABASE=Montblanc-Simplo GmbH ++ + OUI:D05FB8* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -81596,6 +103595,9 @@ OUI:D0634D* + OUI:D063B4* + ID_OUI_FROM_DATABASE=SolidRun Ltd. + ++OUI:D06544* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:D065CA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -81620,6 +103622,9 @@ OUI:D069D0* + OUI:D06A1F* + ID_OUI_FROM_DATABASE=BSE CO.,LTD. + ++OUI:D06EDE* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:D06F4A* + ID_OUI_FROM_DATABASE=TOPWELL INTERNATIONAL HOLDINGS LIMITED + +@@ -81692,6 +103697,9 @@ OUI:D07650E* + OUI:D07650F* + ID_OUI_FROM_DATABASE=Private + ++OUI:D0768F* ++ ID_OUI_FROM_DATABASE=Calix Inc. ++ + OUI:D076E7* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -81704,6 +103712,9 @@ OUI:D07AB5* + OUI:D07C2D* + ID_OUI_FROM_DATABASE=Leie IOT technology Co., Ltd + ++OUI:D07D33* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D07DE5* + ID_OUI_FROM_DATABASE=Forward Pay Systems, Inc. + +@@ -81749,9 +103760,15 @@ OUI:D08CB5* + OUI:D08CFF* + ID_OUI_FROM_DATABASE=UPWIS AB + ++OUI:D08E79* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:D0929E* + ID_OUI_FROM_DATABASE=Microsoft Corporation + ++OUI:D092FA* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:D09380* + ID_OUI_FROM_DATABASE=Ducere Technologies Pvt. Ltd. + +@@ -81767,6 +103784,9 @@ OUI:D095C7* + OUI:D096FB* + ID_OUI_FROM_DATABASE=DASAN Network Solutions + ++OUI:D097FE* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:D099D5* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +@@ -81776,12 +103796,63 @@ OUI:D09B05* + OUI:D09C30* + ID_OUI_FROM_DATABASE=Foster Electric Company, Limited + ++OUI:D09C7A* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:D09CAE* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:D09D0A* + ID_OUI_FROM_DATABASE=LINKCOM + + OUI:D09DAB* + ID_OUI_FROM_DATABASE=TCT mobile ltd + ++OUI:D09FD90* ++ ID_OUI_FROM_DATABASE=Lemei Intelligent IOT (Shenzhen) Co., Ltd ++ ++OUI:D09FD91* ++ ID_OUI_FROM_DATABASE=elecgator bvba ++ ++OUI:D09FD92* ++ ID_OUI_FROM_DATABASE=Westar Display Technologies ++ ++OUI:D09FD93* ++ ID_OUI_FROM_DATABASE=GS Yuasa Infrastructure Systems Co.,Ltd. ++ ++OUI:D09FD94* ++ ID_OUI_FROM_DATABASE=Poten (Shanghai) Technology Co.,Ltd. ++ ++OUI:D09FD95* ++ ID_OUI_FROM_DATABASE=Carbon Mobile GmbH ++ ++OUI:D09FD96* ++ ID_OUI_FROM_DATABASE=Elevoc Technology Co., Ltd. ++ ++OUI:D09FD97* ++ ID_OUI_FROM_DATABASE=Raymax Technology Ltd. ++ ++OUI:D09FD98* ++ ID_OUI_FROM_DATABASE=Queclink Wireless Solutions Co., Ltd. ++ ++OUI:D09FD99* ++ ID_OUI_FROM_DATABASE=ENTTEC Pty Ltd. ++ ++OUI:D09FD9A* ++ ID_OUI_FROM_DATABASE=Eurolan Ltd ++ ++OUI:D09FD9B* ++ ID_OUI_FROM_DATABASE=Cablewireless Laboratory Co., Ltd ++ ++OUI:D09FD9C* ++ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd. ++ ++OUI:D09FD9D* ++ ID_OUI_FROM_DATABASE=Shenzhen eloT Technology Co.,Ltd ++ ++OUI:D09FD9E* ++ ID_OUI_FROM_DATABASE=Minibems Ltd ++ + OUI:D0A0D6* + ID_OUI_FROM_DATABASE=Chengdu TD Tech Ltd. + +@@ -81797,6 +103868,9 @@ OUI:D0A5A6* + OUI:D0A637* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D0ABD5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:D0AEEC* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + +@@ -81818,6 +103892,9 @@ OUI:D0B2C4* + OUI:D0B33F* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + ++OUI:D0B45D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D0B498* + ID_OUI_FROM_DATABASE=Robert Bosch LLC Automotive Electronics + +@@ -81830,12 +103907,21 @@ OUI:D0B53D* + OUI:D0B5C2* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:D0B60A* ++ ID_OUI_FROM_DATABASE=Xingluo Technology Company Limited ++ ++OUI:D0B66F* ++ ID_OUI_FROM_DATABASE=SERNET (SUZHOU) TECHNOLOGIES CORPORATION ++ + OUI:D0BAE4* + ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd. + + OUI:D0BB80* + ID_OUI_FROM_DATABASE=SHL Telemedicine International Ltd. + ++OUI:D0BCC1* ++ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD ++ + OUI:D0BD01* + ID_OUI_FROM_DATABASE=DS International + +@@ -81854,9 +103940,15 @@ OUI:D0C193* + OUI:D0C1B1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D0C24E* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:D0C282* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:D0C31E* ++ ID_OUI_FROM_DATABASE=JUNGJIN Electronics Co.,Ltd ++ + OUI:D0C42F* + ID_OUI_FROM_DATABASE=Tamagawa Seiki Co.,Ltd. + +@@ -81869,18 +103961,75 @@ OUI:D0C5D8* + OUI:D0C5F3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D0C637* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D0C65B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D0C789* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:D0C7C0* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:D0C8570* ++ ID_OUI_FROM_DATABASE=YUAN High-Tech Development Co., Ltd. ++ ++OUI:D0C8571* ++ ID_OUI_FROM_DATABASE=DALI A/S ++ ++OUI:D0C8572* ++ ID_OUI_FROM_DATABASE=FORGAMERS INC. ++ ++OUI:D0C8573* ++ ID_OUI_FROM_DATABASE=Mobicon ++ ++OUI:D0C8574* ++ ID_OUI_FROM_DATABASE=Imin Technology Pte Ltd ++ ++OUI:D0C8575* ++ ID_OUI_FROM_DATABASE=Beijing Inspiry Technology Co., Ltd. ++ ++OUI:D0C8576* ++ ID_OUI_FROM_DATABASE=Innovative Industrial(HK)Co., Limited ++ ++OUI:D0C8577* ++ ID_OUI_FROM_DATABASE=Eco Mobile ++ ++OUI:D0C8578* ++ ID_OUI_FROM_DATABASE=Nanjing Magewell Electronics Co.,Ltd ++ ++OUI:D0C8579* ++ ID_OUI_FROM_DATABASE=Shenzhen xiaosha Intelligence Technology Co. Ltd ++ ++OUI:D0C857A* ++ ID_OUI_FROM_DATABASE=shenzhen cnsun ++ ++OUI:D0C857B* ++ ID_OUI_FROM_DATABASE=CHUNGHSIN INTERNATIONAL ELECTRONICS CO.,LTD. ++ ++OUI:D0C857C* ++ ID_OUI_FROM_DATABASE=Dante Security Inc. ++ ++OUI:D0C857D* ++ ID_OUI_FROM_DATABASE=IFLYTEK CO.,LTD. ++ ++OUI:D0C857E* ++ ID_OUI_FROM_DATABASE=E-T-A Elektrotechnische Apparate GmbH ++ + OUI:D0CDE1* + ID_OUI_FROM_DATABASE=Scientech Electronics + + OUI:D0CF5E* + ID_OUI_FROM_DATABASE=Energy Micro AS + ++OUI:D0CFD8* ++ ID_OUI_FROM_DATABASE=Huizhou Boshijie Technology Co.,Ltd ++ ++OUI:D0D003* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD ++ + OUI:D0D04B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -81890,12 +104039,18 @@ OUI:D0D0FD* + OUI:D0D212* + ID_OUI_FROM_DATABASE=K2NET Co.,Ltd. + ++OUI:D0D23C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:D0D286* + ID_OUI_FROM_DATABASE=Beckman Coulter K.K. + + OUI:D0D2B0* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D0D3E0* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:D0D3FC* + ID_OUI_FROM_DATABASE=Mios, Ltd. + +@@ -81933,7 +104088,7 @@ OUI:D0D94F6* + ID_OUI_FROM_DATABASE=Hyundai Autohow + + OUI:D0D94F7* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Mitsubishi Electric US, Inc. + + OUI:D0D94F8* + ID_OUI_FROM_DATABASE=Apption Labs Limited +@@ -81959,6 +104114,12 @@ OUI:D0D94FE* + OUI:D0DB32* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:D0DBB7* ++ ID_OUI_FROM_DATABASE=Casa Systems ++ ++OUI:D0DD49* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:D0DF9A* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +@@ -81968,6 +104129,9 @@ OUI:D0DFB2* + OUI:D0DFC7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D0E042* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D0E140* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -81992,18 +104156,30 @@ OUI:D0EB03* + OUI:D0EB9E* + ID_OUI_FROM_DATABASE=Seowoo Inc. + ++OUI:D0EC35* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D0EFC1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:D0F0DB* + ID_OUI_FROM_DATABASE=Ericsson + ++OUI:D0F121* ++ ID_OUI_FROM_DATABASE=Xi'an LINKSCI Technology Co., Ltd ++ + OUI:D0F27F* + ID_OUI_FROM_DATABASE=SteadyServ Technoligies, LLC + ++OUI:D0F3F5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D0F73B* + ID_OUI_FROM_DATABASE=Helmut Mauell GmbH Werk Weida + ++OUI:D0F865* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:D0F88C* + ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. + +@@ -82043,6 +104219,9 @@ OUI:D404FF* + OUI:D40598* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:D40868* ++ ID_OUI_FROM_DATABASE=Beijing Lanxum Computer Technology CO.,LTD. ++ + OUI:D40AA9* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -82061,9 +104240,15 @@ OUI:D41090* + OUI:D410CF* + ID_OUI_FROM_DATABASE=Huanshun Network Science and Technology Co., Ltd. + ++OUI:D411A3* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:D411D6* + ID_OUI_FROM_DATABASE=ShotSpotter, Inc. + ++OUI:D41243* ++ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. ++ + OUI:D41296* + ID_OUI_FROM_DATABASE=Anobit Technologies Ltd. + +@@ -82076,6 +104261,12 @@ OUI:D4136F* + OUI:D41A3F* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:D41AC8* ++ ID_OUI_FROM_DATABASE=Nippon Printer Engineering ++ ++OUI:D41B81* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:D41C1C* + ID_OUI_FROM_DATABASE=RCF S.P.A. + +@@ -82086,11 +104277,14 @@ OUI:D41E35* + ID_OUI_FROM_DATABASE=TOHO Electronics INC. + + OUI:D41F0C* +- ID_OUI_FROM_DATABASE=JAI Oy ++ ID_OUI_FROM_DATABASE=JAI Manufacturing + + OUI:D4206D* + ID_OUI_FROM_DATABASE=HTC Corporation + ++OUI:D420B0* ++ ID_OUI_FROM_DATABASE=Mist Systems, Inc. ++ + OUI:D42122* + ID_OUI_FROM_DATABASE=Sercomm Corporation. + +@@ -82100,9 +104294,60 @@ OUI:D4223F* + OUI:D4224E* + ID_OUI_FROM_DATABASE=Alcatel Lucent + ++OUI:D422CD* ++ ID_OUI_FROM_DATABASE=Xsens Technologies B.V. ++ ++OUI:D42493* ++ ID_OUI_FROM_DATABASE=GW Technologies Co.,Ltd ++ + OUI:D4258B* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:D425CC0* ++ ID_OUI_FROM_DATABASE=NORDI TELEKOMMUNIKATSIOONI OÜ ++ ++OUI:D425CC1* ++ ID_OUI_FROM_DATABASE=Eware Information Technology com.,Ltd ++ ++OUI:D425CC2* ++ ID_OUI_FROM_DATABASE=MusicLens Inc. ++ ++OUI:D425CC3* ++ ID_OUI_FROM_DATABASE=EISST Ltd ++ ++OUI:D425CC4* ++ ID_OUI_FROM_DATABASE=Barobo, Inc. ++ ++OUI:D425CC5* ++ ID_OUI_FROM_DATABASE=bvk technology ++ ++OUI:D425CC6* ++ ID_OUI_FROM_DATABASE=Nanjing LES Information Technology Co., Ltd ++ ++OUI:D425CC7* ++ ID_OUI_FROM_DATABASE=BlueCats US, LLC ++ ++OUI:D425CC8* ++ ID_OUI_FROM_DATABASE=DOLBY LABORATORIES, INC. ++ ++OUI:D425CC9* ++ ID_OUI_FROM_DATABASE=TAKUMI JAPAN LTD ++ ++OUI:D425CCA* ++ ID_OUI_FROM_DATABASE=E-MetroTel ++ ++OUI:D425CCB* ++ ID_OUI_FROM_DATABASE=Veea ++ ++OUI:D425CCC* ++ ID_OUI_FROM_DATABASE=POSNET Polska S.A. ++ ++OUI:D425CCD* ++ ID_OUI_FROM_DATABASE=Combined Energy Technologies Pty Ltd ++ ++OUI:D425CCE* ++ ID_OUI_FROM_DATABASE=Coperion ++ + OUI:D42751* + ID_OUI_FROM_DATABASE=Infopia Co., Ltd + +@@ -82124,15 +104369,24 @@ OUI:D42C3D* + OUI:D42C44* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:D42DC5* ++ ID_OUI_FROM_DATABASE=Panasonic i-PRO Sensing Solutions Co., Ltd. ++ + OUI:D42F23* + ID_OUI_FROM_DATABASE=Akenori PTE Ltd + + OUI:D4319D* + ID_OUI_FROM_DATABASE=Sinwatec + ++OUI:D43260* ++ ID_OUI_FROM_DATABASE=GoPro ++ + OUI:D43266* + ID_OUI_FROM_DATABASE=Fike Corporation + ++OUI:D4351D* ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV ++ + OUI:D43639* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -82143,7 +104397,13 @@ OUI:D437D7* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:D4389C* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation ++ ++OUI:D439B8* ++ ID_OUI_FROM_DATABASE=Ciena Corporation ++ ++OUI:D43A2E* ++ ID_OUI_FROM_DATABASE=SHENZHEN MTC CO LTD + + OUI:D43A65* + ID_OUI_FROM_DATABASE=IGRS Engineering Lab Ltd. +@@ -82151,17 +104411,32 @@ OUI:D43A65* + OUI:D43AE9* + ID_OUI_FROM_DATABASE=DONGGUAN ipt INDUSTRIAL CO., LTD + ++OUI:D43B04* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D43D39* ++ ID_OUI_FROM_DATABASE=Dialog Semiconductor ++ + OUI:D43D67* + ID_OUI_FROM_DATABASE=Carma Industries Inc. + + OUI:D43D7E* + ID_OUI_FROM_DATABASE=Micro-Star Int'l Co, Ltd + ++OUI:D43DF3* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ ++OUI:D43FCB* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:D440D0* ++ ID_OUI_FROM_DATABASE=OCOSMOS Co., LTD ++ + OUI:D440F0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:D44165* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:D443A8* + ID_OUI_FROM_DATABASE=Changzhou Haojie Electric Co., Ltd. +@@ -82169,9 +104444,24 @@ OUI:D443A8* + OUI:D445E8* + ID_OUI_FROM_DATABASE=Jiangxi Hongpai Technology Co., Ltd. + ++OUI:D44649* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:D446E1* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:D4475A* ++ ID_OUI_FROM_DATABASE=ScreenBeam, Inc. ++ ++OUI:D4482D* ++ ID_OUI_FROM_DATABASE=Shenzhen Deejoy Lighting Technology Co.,Ltd. ++ + OUI:D44B5E* + ID_OUI_FROM_DATABASE=TAIYO YUDEN CO., LTD. + ++OUI:D44BB6* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:D44C24* + ID_OUI_FROM_DATABASE=Vuppalamritha Magnetic Components LTD + +@@ -82181,6 +104471,15 @@ OUI:D44C9C* + OUI:D44CA7* + ID_OUI_FROM_DATABASE=Informtekhnika & Communication, LLC + ++OUI:D44DA4* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ ++OUI:D44F67* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:D44F68* ++ ID_OUI_FROM_DATABASE=Eidetic Communications Inc ++ + OUI:D44F80* + ID_OUI_FROM_DATABASE=Kemper Digital GmbH + +@@ -82199,15 +104498,27 @@ OUI:D45251* + OUI:D45297* + ID_OUI_FROM_DATABASE=nSTREAMS Technologies, Inc. + ++OUI:D452EE* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:D45383* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ + OUI:D453AF* + ID_OUI_FROM_DATABASE=VIGO System S.A. + ++OUI:D4548B* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:D45556* + ID_OUI_FROM_DATABASE=Fiber Mountain Inc. + + OUI:D455BE* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD + ++OUI:D45800* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:D45AB2* + ID_OUI_FROM_DATABASE=Galleon Systems + +@@ -82217,12 +104528,21 @@ OUI:D45C70* + OUI:D45D42* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:D45D64* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:D45DDF* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + ++OUI:D45EEC* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ + OUI:D45F25* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + ++OUI:D46075* ++ ID_OUI_FROM_DATABASE=Baidu Online Network Technology (Beijing) Co., Ltd ++ + OUI:D460E3* + ID_OUI_FROM_DATABASE=Sercomm Corporation. + +@@ -82241,6 +104561,9 @@ OUI:D461DA* + OUI:D461FE* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + ++OUI:D462EA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D463C6* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -82254,7 +104577,10 @@ OUI:D466A8* + ID_OUI_FROM_DATABASE=Riedo Networks Ltd + + OUI:D46761* +- ID_OUI_FROM_DATABASE=United Gulf Gate Co. ++ ID_OUI_FROM_DATABASE=XonTel Technology Co. ++ ++OUI:D467D3* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + + OUI:D467E7* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD +@@ -82271,15 +104597,21 @@ OUI:D468BA* + OUI:D469A5* + ID_OUI_FROM_DATABASE=Miura Systems Ltd. + ++OUI:D46A35* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D46A6A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:D46A91* +- ID_OUI_FROM_DATABASE=Snap AV ++ ID_OUI_FROM_DATABASE=SnapAV + + OUI:D46AA8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:D46BA6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D46CBF* + ID_OUI_FROM_DATABASE=Goodrich ISR + +@@ -82307,15 +104639,36 @@ OUI:D47208* + OUI:D47226* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:D47350* ++ ID_OUI_FROM_DATABASE=DBG Commnunications Technology Co., Ltd. ++ ++OUI:D47415* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D4741B* + ID_OUI_FROM_DATABASE=Beijing HuaDa ZhiBao Electronic System Co.,Ltd. + ++OUI:D476A0* ++ ID_OUI_FROM_DATABASE=Fortinet, Inc. ++ + OUI:D476EA* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:D4772B* ++ ID_OUI_FROM_DATABASE=Nanjing Ztlink Network Technology Co.,Ltd ++ ++OUI:D47798* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:D477B2* ++ ID_OUI_FROM_DATABASE=Netix Global B.V. ++ + OUI:D47856* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:D4789B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D479C3* + ID_OUI_FROM_DATABASE=Cameronet GmbH & Co. KG + +@@ -82379,6 +104732,9 @@ OUI:D47C44E* + OUI:D47DFC* + ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED + ++OUI:D47EE4* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ + OUI:D481CA* + ID_OUI_FROM_DATABASE=iDevices, LLC + +@@ -82394,6 +104750,9 @@ OUI:D48304* + OUI:D48564* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:D48660* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:D487D8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82403,6 +104762,9 @@ OUI:D4883F* + OUI:D48890* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D48A39* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:D48CB5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -82421,9 +104783,18 @@ OUI:D4909C* + OUI:D490E0* + ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG + ++OUI:D4910F* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:D491AF* + ID_OUI_FROM_DATABASE=Electroacustica General Iberica, S.A. + ++OUI:D49234* ++ ID_OUI_FROM_DATABASE=NEC Corporation ++ ++OUI:D49390* ++ ID_OUI_FROM_DATABASE=CLEVO CO. ++ + OUI:D49398* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -82439,6 +104810,9 @@ OUI:D494A1* + OUI:D494E8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:D494FB* ++ ID_OUI_FROM_DATABASE=Continental Automotive Systems Inc. ++ + OUI:D49524* + ID_OUI_FROM_DATABASE=Clover Network, Inc. + +@@ -82451,6 +104825,9 @@ OUI:D4970B* + OUI:D49A20* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D49AA0* ++ ID_OUI_FROM_DATABASE=VNPT TECHNOLOGY ++ + OUI:D49B5C* + ID_OUI_FROM_DATABASE=Chongqing Miedu Technology Co., Ltd. + +@@ -82460,12 +104837,21 @@ OUI:D49C28* + OUI:D49C8E* + ID_OUI_FROM_DATABASE=University of FUKUI + ++OUI:D49CDD* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:D49CF4* + ID_OUI_FROM_DATABASE=Palo Alto Networks + ++OUI:D49DC0* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:D49E05* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:D49E3B* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ + OUI:D49E6D* + ID_OUI_FROM_DATABASE=Wuhan Zhongyuan Huadian Science & Technology Co., + +@@ -82484,6 +104870,9 @@ OUI:D4A425* + OUI:D4A499* + ID_OUI_FROM_DATABASE=InView Technology Corporation + ++OUI:D4A651* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:D4A928* + ID_OUI_FROM_DATABASE=GreenWave Reality Inc + +@@ -82493,18 +104882,30 @@ OUI:D4AAFF* + OUI:D4AB82* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:D4ABCD* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:D4AC4E* + ID_OUI_FROM_DATABASE=BODi rS, LLC + + OUI:D4AD2D* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:D4AD71* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:D4ADBD* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D4AE05* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:D4AE52* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:D4AFF7* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ + OUI:D4B110* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -82517,9 +104918,27 @@ OUI:D4B27A* + OUI:D4B43E* + ID_OUI_FROM_DATABASE=Messcomp Datentechnik GmbH + ++OUI:D4B709* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:D4B761* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:D4B8FF* + ID_OUI_FROM_DATABASE=Home Control Singapore Pte Ltd + ++OUI:D4B92F* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:D4BBC8* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:D4BBE6* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:D4BD1E* ++ ID_OUI_FROM_DATABASE=5VT Technologies,Taiwan LTd. ++ + OUI:D4BED9* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -82544,6 +104963,12 @@ OUI:D4C766* + OUI:D4C8B0* + ID_OUI_FROM_DATABASE=Prime Electronics & Satellitics Inc. + ++OUI:D4C93C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:D4C94B* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:D4C9B2* + ID_OUI_FROM_DATABASE=Quanergy Systems Inc + +@@ -82566,7 +104991,7 @@ OUI:D4CF37* + ID_OUI_FROM_DATABASE=Symbolic IO + + OUI:D4CFF9* +- ID_OUI_FROM_DATABASE=Shenzhen Sen5 Technology Co., Ltd. ++ ID_OUI_FROM_DATABASE=Shenzhen SEI Robotics Co.,Ltd + + OUI:D4D184* + ID_OUI_FROM_DATABASE=ADB Broadband Italia +@@ -82574,12 +104999,21 @@ OUI:D4D184* + OUI:D4D249* + ID_OUI_FROM_DATABASE=Power Ethernet + ++OUI:D4D252* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D4D2D6* ++ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED ++ + OUI:D4D2E5* + ID_OUI_FROM_DATABASE=BKAV Corporation + + OUI:D4D50D* + ID_OUI_FROM_DATABASE=Southwest Microwave, Inc + ++OUI:D4D51B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D4D748* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -82592,6 +105026,12 @@ OUI:D4D898* + OUI:D4D919* + ID_OUI_FROM_DATABASE=GoPro + ++OUI:D4DACD* ++ ID_OUI_FROM_DATABASE=BSkyB Ltd ++ ++OUI:D4DC09* ++ ID_OUI_FROM_DATABASE=Mist Systems, Inc. ++ + OUI:D4DCCD* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -82610,6 +105050,12 @@ OUI:D4E33F* + OUI:D4E6B7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D4E853* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ ++OUI:D4E880* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D4E8B2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82619,17 +105065,26 @@ OUI:D4E90B* + OUI:D4EA0E* + ID_OUI_FROM_DATABASE=Avaya Inc + ++OUI:D4EB68* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:D4EC0C* + ID_OUI_FROM_DATABASE=Harley-Davidson Motor Company + + OUI:D4EC86* + ID_OUI_FROM_DATABASE=LinkedHope Intelligent Technologies Co., Ltd + ++OUI:D4ECAB* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:D4EE07* + ID_OUI_FROM_DATABASE=HIWIFI Co., Ltd. + + OUI:D4F027* +- ID_OUI_FROM_DATABASE=Navetas Energy Management ++ ID_OUI_FROM_DATABASE=Trust Power Ltd. ++ ++OUI:D4F057* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + + OUI:D4F0B4* + ID_OUI_FROM_DATABASE=Napco Security Technologies +@@ -82640,6 +105095,9 @@ OUI:D4F143* + OUI:D4F207* + ID_OUI_FROM_DATABASE=DIAODIAO(Beijing)Technology CO.,Ltd + ++OUI:D4F337* ++ ID_OUI_FROM_DATABASE=Xunison Ltd. ++ + OUI:D4F46F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -82649,12 +105107,27 @@ OUI:D4F4BE* + OUI:D4F513* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:D4F527* ++ ID_OUI_FROM_DATABASE=SIEMENS AG ++ ++OUI:D4F547* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:D4F5EF* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:D4F63F* + ID_OUI_FROM_DATABASE=IEA S.R.L. + ++OUI:D4F756* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:D4F786* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:D4F829* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:D4F9A1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -82664,12 +105137,18 @@ OUI:D4FC13* + OUI:D8004D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D80093* ++ ID_OUI_FROM_DATABASE=Aurender Inc. ++ + OUI:D8052E* + ID_OUI_FROM_DATABASE=Skyviia Corporation + + OUI:D806D1* + ID_OUI_FROM_DATABASE=Honeywell Fire System (Shanghai) Co,. Ltd. + ++OUI:D807B6* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:D80831* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82679,6 +105158,15 @@ OUI:D808F5* + OUI:D809C3* + ID_OUI_FROM_DATABASE=Cercacor Labs + ++OUI:D809D6* ++ ID_OUI_FROM_DATABASE=ZEXELON CO., LTD. ++ ++OUI:D80B9A* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:D80BCB* ++ ID_OUI_FROM_DATABASE=Telink Semiconductor (Shanghai) Co., Ltd. ++ + OUI:D80CCF* + ID_OUI_FROM_DATABASE=C.G.V. S.A.S. + +@@ -82691,9 +105179,24 @@ OUI:D80DE3* + OUI:D80F99* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:D8109F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:D810CB* ++ ID_OUI_FROM_DATABASE=Andrea Informatique ++ ++OUI:D81265* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ ++OUI:D81399* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:D814D6* + ID_OUI_FROM_DATABASE=SURE SYSTEM Co Ltd + ++OUI:D814DF* ++ ID_OUI_FROM_DATABASE=TCL King Electrical Appliances (Huizhou) Co., Ltd ++ + OUI:D8150D* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -82721,14 +105224,23 @@ OUI:D81BFE* + OUI:D81C14* + ID_OUI_FROM_DATABASE=Compacta International, Ltd. + ++OUI:D81C79* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:D81D72* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D81EDD* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:D81EDE* + ID_OUI_FROM_DATABASE=B&W Group Ltd + ++OUI:D81F12* ++ ID_OUI_FROM_DATABASE=Tuya Smart Inc. ++ + OUI:D81FCC* +- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. ++ ID_OUI_FROM_DATABASE=Brocade Communications Systems LLC + + OUI:D8209F* + ID_OUI_FROM_DATABASE=Cubro Acronet GesmbH +@@ -82760,6 +105272,9 @@ OUI:D828C9* + OUI:D82916* + ID_OUI_FROM_DATABASE=Ascent Communication Technology + ++OUI:D82918* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D82986* + ID_OUI_FROM_DATABASE=Best Wish Technology LTD + +@@ -82775,9 +105290,15 @@ OUI:D82D9B* + OUI:D82DE1* + ID_OUI_FROM_DATABASE=Tricascade Inc. + ++OUI:D82FE6* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:D83062* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D83134* ++ ID_OUI_FROM_DATABASE=Roku, Inc ++ + OUI:D831CF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82793,6 +105314,12 @@ OUI:D832E3* + OUI:D8337F* + ID_OUI_FROM_DATABASE=Office FA.com Co.,Ltd. + ++OUI:D834EE* ++ ID_OUI_FROM_DATABASE=Stem Audio ++ ++OUI:D8373B* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ + OUI:D837BE* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + +@@ -82802,6 +105329,12 @@ OUI:D8380D* + OUI:D838FC* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:D83AF5* ++ ID_OUI_FROM_DATABASE=Wideband Labs LLC ++ ++OUI:D83BBF* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:D83C69* + ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. + +@@ -82826,6 +105359,12 @@ OUI:D84606* + OUI:D84710* + ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. + ++OUI:D84732* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ ++OUI:D847BB* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D848EE* + ID_OUI_FROM_DATABASE=Hangzhou Xueji Technology Co., Ltd. + +@@ -82841,6 +105380,15 @@ OUI:D84A87* + OUI:D84B2A* + ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc. + ++OUI:D84C90* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:D84DB9* ++ ID_OUI_FROM_DATABASE=Wu Qi Technologies,Inc. ++ ++OUI:D84F37* ++ ID_OUI_FROM_DATABASE=Proxis, spol. s r.o. ++ + OUI:D84FB8* + ID_OUI_FROM_DATABASE=LG ELECTRONICS + +@@ -82851,7 +105399,10 @@ OUI:D8543A* + ID_OUI_FROM_DATABASE=Texas Instruments + + OUI:D854A2* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:D85575* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:D855A3* + ID_OUI_FROM_DATABASE=zte corporation +@@ -82862,6 +105413,9 @@ OUI:D857EF* + OUI:D858D7* + ID_OUI_FROM_DATABASE=CZ.NIC, z.s.p.o. + ++OUI:D85982* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D85B2A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82880,6 +105434,12 @@ OUI:D85DEF* + OUI:D85DFB* + ID_OUI_FROM_DATABASE=Private + ++OUI:D85ED3* ++ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. ++ ++OUI:D85F77* ++ ID_OUI_FROM_DATABASE=Telink Semiconductor (Shanghai) Co., Ltd. ++ + OUI:D860B0* + ID_OUI_FROM_DATABASE=bioMérieux Italia S.p.A. + +@@ -82907,9 +105467,15 @@ OUI:D866C6* + OUI:D866EE* + ID_OUI_FROM_DATABASE=BOXIN COMMUNICATION CO.,LTD. + ++OUI:D867D3* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D867D9* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:D86852* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D868C3* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -82928,6 +105494,12 @@ OUI:D86C63* + OUI:D86CE9* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:D86D17* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:D8714D* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:D87157* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +@@ -82940,6 +105512,15 @@ OUI:D87533* + OUI:D8760A* + ID_OUI_FROM_DATABASE=Escort, Inc. + ++OUI:D876AE* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:D8778B* ++ ID_OUI_FROM_DATABASE=Intelbras ++ ++OUI:D8787F* ++ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited ++ + OUI:D878E5* + ID_OUI_FROM_DATABASE=KUHN SA + +@@ -82952,6 +105533,9 @@ OUI:D87CDD* + OUI:D87D7F* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:D87E76* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:D87EB1* + ID_OUI_FROM_DATABASE=x.o.ware, inc. + +@@ -82961,12 +105545,60 @@ OUI:D88039* + OUI:D8803C* + ID_OUI_FROM_DATABASE=Anhui Huami Information Technology Company Limited + ++OUI:D88083* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:D881CE* + ID_OUI_FROM_DATABASE=AHN INC. + + OUI:D88466* + ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + ++OUI:D8860B0* ++ ID_OUI_FROM_DATABASE=Inspur Group Co., Ltd. ++ ++OUI:D8860B1* ++ ID_OUI_FROM_DATABASE=Krspace ++ ++OUI:D8860B2* ++ ID_OUI_FROM_DATABASE=Get SAT ++ ++OUI:D8860B3* ++ ID_OUI_FROM_DATABASE=Auvidea GmbH ++ ++OUI:D8860B4* ++ ID_OUI_FROM_DATABASE=Teplovodokhran Ltd. ++ ++OUI:D8860B5* ++ ID_OUI_FROM_DATABASE=CAMTRACE ++ ++OUI:D8860B6* ++ ID_OUI_FROM_DATABASE=SCANMATIK ++ ++OUI:D8860B7* ++ ID_OUI_FROM_DATABASE=Grünbeck Wasseraufbereitung GmbH ++ ++OUI:D8860B8* ++ ID_OUI_FROM_DATABASE=VRINDA NANO TECHNOLOGIES PVT LTD ++ ++OUI:D8860B9* ++ ID_OUI_FROM_DATABASE=DIGITAL CONCEPTS ++ ++OUI:D8860BA* ++ ID_OUI_FROM_DATABASE=GLO Science ++ ++OUI:D8860BB* ++ ID_OUI_FROM_DATABASE=Library Ideas ++ ++OUI:D8860BC* ++ ID_OUI_FROM_DATABASE=YUSAN INDUSTRIES LIMITED ++ ++OUI:D8860BD* ++ ID_OUI_FROM_DATABASE=ComNav Technology Ltd. ++ ++OUI:D8860BE* ++ ID_OUI_FROM_DATABASE=Shenzhen Yidong Technology Co.,Ltd ++ + OUI:D887D5* + ID_OUI_FROM_DATABASE=Leadcore Technology CO.,LTD + +@@ -82976,12 +105608,24 @@ OUI:D888CE* + OUI:D88A3B* + ID_OUI_FROM_DATABASE=UNIT-EM + ++OUI:D88ADC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D88B4C* + ID_OUI_FROM_DATABASE=KingTing Tech. + ++OUI:D88C73* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:D88C79* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:D88D5C* + ID_OUI_FROM_DATABASE=Elentec + ++OUI:D88DC8* ++ ID_OUI_FROM_DATABASE=Atil Technology Co., LTD ++ + OUI:D88F76* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -82991,6 +105635,9 @@ OUI:D890E8* + OUI:D8912A* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + ++OUI:D89136* ++ ID_OUI_FROM_DATABASE=Dover Fueling Solutions ++ + OUI:D89341* + ID_OUI_FROM_DATABASE=General Electric Global Research + +@@ -83018,12 +105665,21 @@ OUI:D89760* + OUI:D8977C* + ID_OUI_FROM_DATABASE=Grey Innovation + ++OUI:D89790* ++ ID_OUI_FROM_DATABASE=Commonwealth Scientific and Industrial Research Organisation ++ + OUI:D897BA* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + + OUI:D89A34* + ID_OUI_FROM_DATABASE=Beijing SHENQI Technology Co., Ltd. + ++OUI:D89AC1* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:D89B3B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:D89C67* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -83036,9 +105692,18 @@ OUI:D89DB9* + OUI:D89E3F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D89E61* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:D89ED4* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:D89EF3* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:D8A011* ++ ID_OUI_FROM_DATABASE=WiZ ++ + OUI:D8A01D* + ID_OUI_FROM_DATABASE=Espressif Inc. + +@@ -83048,18 +105713,48 @@ OUI:D8A105* + OUI:D8A25E* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D8A315* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:D8A35C* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:D8A491* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D8A534* + ID_OUI_FROM_DATABASE=Spectronix Corporation + ++OUI:D8A6F0* ++ ID_OUI_FROM_DATABASE=Wu Qi Technologies,Inc. ++ ++OUI:D8A6FD* ++ ID_OUI_FROM_DATABASE=Ghost Locomotion ++ ++OUI:D8A756* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:D8A8C8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:D8A98B* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:D8ADDD* + ID_OUI_FROM_DATABASE=Sonavation, Inc. + + OUI:D8AE90* + ID_OUI_FROM_DATABASE=Itibia Technologies + ++OUI:D8AED0* ++ ID_OUI_FROM_DATABASE=Shanghai Engineering Science & Technology Co.,LTD CGNPC ++ + OUI:D8AF3B* + ID_OUI_FROM_DATABASE=Hangzhou Bigbright Integrated communications system Co.,Ltd + ++OUI:D8AF81* ++ ID_OUI_FROM_DATABASE=ZAO NPK Rotek ++ + OUI:D8AFF1* + ID_OUI_FROM_DATABASE=Panasonic Appliances Company + +@@ -83099,15 +105794,33 @@ OUI:D8B90E* + OUI:D8BB2C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D8BBC1* ++ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. ++ ++OUI:D8BC59* ++ ID_OUI_FROM_DATABASE=Shenzhen DAPU Microelectronics Co., Ltd ++ ++OUI:D8BE1F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:D8BE65* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:D8BF4C* + ID_OUI_FROM_DATABASE=Victory Concept Electronics Limited + ++OUI:D8BFC0* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:D8C068* + ID_OUI_FROM_DATABASE=Netgenetech.co.,ltd. + + OUI:D8C06A* + ID_OUI_FROM_DATABASE=Hunantv.com Interactive Entertainment Media Co.,Ltd. + ++OUI:D8C0A6* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:D8C3FB* + ID_OUI_FROM_DATABASE=DETRACOM + +@@ -83120,6 +105833,12 @@ OUI:D8C497* + OUI:D8C4E9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:D8C561* ++ ID_OUI_FROM_DATABASE=CommFront Communications Pte Ltd ++ ++OUI:D8C678* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:D8C691* + ID_OUI_FROM_DATABASE=Hichan Technology Corp. + +@@ -83127,7 +105846,7 @@ OUI:D8C771* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:D8C7C8* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company + + OUI:D8C8E9* + ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd. +@@ -83135,12 +105854,30 @@ OUI:D8C8E9* + OUI:D8C99D* + ID_OUI_FROM_DATABASE=EA DISPLAY LIMITED + ++OUI:D8CA06* ++ ID_OUI_FROM_DATABASE=Titan DataCenters France ++ + OUI:D8CB8A* + ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD. + ++OUI:D8CC98* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:D8CD2C* ++ ID_OUI_FROM_DATABASE=WUXI NEIHUA NETWORK TECHNOLOGY CO., LTD ++ ++OUI:D8CE3A* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:D8CF89* ++ ID_OUI_FROM_DATABASE=Beijing DoSee Science and Technology Co., Ltd. ++ + OUI:D8CF9C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:D8D090* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:D8D1CB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -83153,12 +105890,18 @@ OUI:D8D385* + OUI:D8D43C* + ID_OUI_FROM_DATABASE=Sony Corporation + ++OUI:D8D4E6* ++ ID_OUI_FROM_DATABASE=Hytec Inter Co., Ltd. ++ + OUI:D8D5B9* + ID_OUI_FROM_DATABASE=Rainforest Automation, Inc. + + OUI:D8D67E* + ID_OUI_FROM_DATABASE=GSK CNC EQUIPMENT CO.,LTD + ++OUI:D8D6F3* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:D8D723* + ID_OUI_FROM_DATABASE=IDS, Inc + +@@ -83171,6 +105914,9 @@ OUI:D8D866* + OUI:D8DA52* + ID_OUI_FROM_DATABASE=APATOR S.A. + ++OUI:D8DC40* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:D8DCE9* + ID_OUI_FROM_DATABASE=Kunshan Erlab ductless filtration system Co.,Ltd + +@@ -83180,6 +105926,9 @@ OUI:D8DD5F* + OUI:D8DDFD* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:D8DE3A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:D8DECE* + ID_OUI_FROM_DATABASE=ISUNG CO.,LTD + +@@ -83205,7 +105954,7 @@ OUI:D8E56D* + ID_OUI_FROM_DATABASE=TCT mobile ltd + + OUI:D8E72B* +- ID_OUI_FROM_DATABASE=NetScout Systems, Inc. ++ ID_OUI_FROM_DATABASE=NETSCOUT SYSTEMS INC + + OUI:D8E743* + ID_OUI_FROM_DATABASE=Wush, Inc +@@ -83213,30 +105962,57 @@ OUI:D8E743* + OUI:D8E952* + ID_OUI_FROM_DATABASE=KEOPSYS + ++OUI:D8EB46* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:D8EB97* + ID_OUI_FROM_DATABASE=TRENDnet, Inc. + ++OUI:D8EC5E* ++ ID_OUI_FROM_DATABASE=Belkin International Inc. ++ ++OUI:D8ECE5* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:D8ED1C* + ID_OUI_FROM_DATABASE=Magna Technology SL + + OUI:D8EE78* + ID_OUI_FROM_DATABASE=Moog Protokraft + ++OUI:D8EF42* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:D8EFCD* +- ID_OUI_FROM_DATABASE=Nokia ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG + + OUI:D8F0F2* + ID_OUI_FROM_DATABASE=Zeebo Inc + ++OUI:D8F15B* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:D8F1F0* + ID_OUI_FROM_DATABASE=Pepxim International Limited + ++OUI:D8F2CA* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D8F3BC* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:D8F3DB* + ID_OUI_FROM_DATABASE=Post CH AG + + OUI:D8F710* + ID_OUI_FROM_DATABASE=Libre Wireless Technologies Inc. + ++OUI:D8F883* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:D8F8AF* ++ ID_OUI_FROM_DATABASE=DAONTEC ++ + OUI:D8FB11* + ID_OUI_FROM_DATABASE=AXACORE + +@@ -83261,12 +106037,18 @@ OUI:D8FEE3* + OUI:DC0077* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:DC00B0* ++ ID_OUI_FROM_DATABASE=FREEBOX SAS ++ + OUI:DC0265* + ID_OUI_FROM_DATABASE=Meditech Kft + + OUI:DC028E* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:DC0398* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ + OUI:DC052F* + ID_OUI_FROM_DATABASE=National Products Inc. + +@@ -83279,6 +106061,9 @@ OUI:DC05ED* + OUI:DC07C1* + ID_OUI_FROM_DATABASE=HangZhou QiYang Technology Co.,Ltd. + ++OUI:DC080F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:DC0856* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise + +@@ -83306,6 +106091,9 @@ OUI:DC0D30* + OUI:DC0EA1* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:DC15C8* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:DC15DB* + ID_OUI_FROM_DATABASE=Ge Ruili Intelligent Technology ( Beijing ) Co., Ltd. + +@@ -83327,6 +106115,9 @@ OUI:DC1A01* + OUI:DC1AC5* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:DC1BA1* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:DC1D9F* + ID_OUI_FROM_DATABASE=U & B tech + +@@ -83339,6 +106130,21 @@ OUI:DC1EA3* + OUI:DC2008* + ID_OUI_FROM_DATABASE=ASD Electronics Ltd + ++OUI:DC2148* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:DC215C* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:DC21B9* ++ ID_OUI_FROM_DATABASE=Sentec Co.Ltd ++ ++OUI:DC21E2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:DC2727* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DC2834* + ID_OUI_FROM_DATABASE=HAKKO Corporation + +@@ -83351,6 +106157,9 @@ OUI:DC293A* + OUI:DC2A14* + ID_OUI_FROM_DATABASE=Shanghai Longjing Technology Co. + ++OUI:DC2AA1* ++ ID_OUI_FROM_DATABASE=MedHab LLC ++ + OUI:DC2B2A* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -83366,6 +106175,9 @@ OUI:DC2BCA* + OUI:DC2C26* + ID_OUI_FROM_DATABASE=Iton Technology Limited + ++OUI:DC2D3C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DC2DCB* + ID_OUI_FROM_DATABASE=Beijing Unis HengYue Technology Co., Ltd. + +@@ -83378,14 +106190,20 @@ OUI:DC2F03* + OUI:DC309C* + ID_OUI_FROM_DATABASE=Heyrex Limited + ++OUI:DC31D1* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:DC330D* + ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD. + ++OUI:DC333D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DC3350* + ID_OUI_FROM_DATABASE=TechSAT GmbH + + OUI:DC35F1* +- ID_OUI_FROM_DATABASE=Positivo Informática SA. ++ ID_OUI_FROM_DATABASE=Positivo Tecnologia S.A. + + OUI:DC3714* + ID_OUI_FROM_DATABASE=Apple, Inc. +@@ -83402,6 +106220,9 @@ OUI:DC37D2* + OUI:DC38E1* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:DC396F* ++ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH ++ + OUI:DC3979* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -83426,6 +106247,9 @@ OUI:DC3EF8* + OUI:DC415F* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:DC41A9* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:DC41E5* + ID_OUI_FROM_DATABASE=Shenzhen Zhixin Data Service Co., Ltd. + +@@ -83433,7 +106257,7 @@ OUI:DC44270* + ID_OUI_FROM_DATABASE=Suritel + + OUI:DC44271* +- ID_OUI_FROM_DATABASE=Tesla Motors, Inc ++ ID_OUI_FROM_DATABASE=Tesla,Inc. + + OUI:DC44272* + ID_OUI_FROM_DATABASE=Skywave Technology Co,.Ltd. +@@ -83495,6 +106319,57 @@ OUI:DC49C9* + OUI:DC4A3E* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:DC4A9E0* ++ ID_OUI_FROM_DATABASE=Dongguan Huili electroacoustic Industrial Co.,ltd ++ ++OUI:DC4A9E1* ++ ID_OUI_FROM_DATABASE=Advanced Electronics Ltd ++ ++OUI:DC4A9E2* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:DC4A9E3* ++ ID_OUI_FROM_DATABASE=LEACH INTERNATIONAL EUROPE ++ ++OUI:DC4A9E4* ++ ID_OUI_FROM_DATABASE=ADIAL ++ ++OUI:DC4A9E5* ++ ID_OUI_FROM_DATABASE=Nuove Tecnologie srl ++ ++OUI:DC4A9E6* ++ ID_OUI_FROM_DATABASE=TATTILE SRL ++ ++OUI:DC4A9E7* ++ ID_OUI_FROM_DATABASE=Astrogate Inc. ++ ++OUI:DC4A9E8* ++ ID_OUI_FROM_DATABASE=Methodex Systems Pvt. Ltd. ++ ++OUI:DC4A9E9* ++ ID_OUI_FROM_DATABASE=AiSight GmbH ++ ++OUI:DC4A9EA* ++ ID_OUI_FROM_DATABASE=LongSung Technology (Shanghai) Co.,Ltd. ++ ++OUI:DC4A9EB* ++ ID_OUI_FROM_DATABASE=Maxvision Technology Corp. ++ ++OUI:DC4A9EC* ++ ID_OUI_FROM_DATABASE=HEFEI DATANG STORAGE TECHNOLOGY CO.,LTD ++ ++OUI:DC4A9ED* ++ ID_OUI_FROM_DATABASE=HAPPIEST BABY INC. ++ ++OUI:DC4A9EE* ++ ID_OUI_FROM_DATABASE=SES-imagotag Deutschland GmbH ++ ++OUI:DC4BDD* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ ++OUI:DC4BFE* ++ ID_OUI_FROM_DATABASE=Shenzhen Belon Technology CO.,LTD ++ + OUI:DC4D23* + ID_OUI_FROM_DATABASE=MRV Comunications + +@@ -83507,12 +106382,24 @@ OUI:DC4EF4* + OUI:DC4F22* + ID_OUI_FROM_DATABASE=Espressif Inc. + ++OUI:DC503A* ++ ID_OUI_FROM_DATABASE=Nanjing Ticom Tech Co., Ltd. ++ ++OUI:DC5285* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:DC5360* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:DC537C* + ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc. + ++OUI:DC543D* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ ++OUI:DC54D7* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:DC5583* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + +@@ -83525,12 +106412,18 @@ OUI:DC56E7* + OUI:DC5726* + ID_OUI_FROM_DATABASE=Power-One + ++OUI:DC58BC* ++ ID_OUI_FROM_DATABASE=Thomas-Krenn.AG ++ + OUI:DC5E36* + ID_OUI_FROM_DATABASE=Paterson Technology + + OUI:DC60A1* + ID_OUI_FROM_DATABASE=Teledyne DALSA Professional Imaging + ++OUI:DC6373* ++ ID_OUI_FROM_DATABASE=OBARA KOREA ++ + OUI:DC647C* + ID_OUI_FROM_DATABASE=C.R.S. iiMotion GmbH + +@@ -83543,12 +106436,21 @@ OUI:DC663A* + OUI:DC6672* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:DC6723* ++ ID_OUI_FROM_DATABASE=barox Kommunikation GmbH ++ ++OUI:DC680C* ++ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise ++ + OUI:DC68EB* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + + OUI:DC6AEA* + ID_OUI_FROM_DATABASE=Infinix mobility limited + ++OUI:DC6B12* ++ ID_OUI_FROM_DATABASE=worldcns inc. ++ + OUI:DC6DCD* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + +@@ -83561,15 +106463,30 @@ OUI:DC6F08* + OUI:DC7014* + ID_OUI_FROM_DATABASE=Private + ++OUI:DC7137* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:DC7144* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + ++OUI:DC7196* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:DC7223* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ + OUI:DC729B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:DC7385* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DC74A8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:DC774C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:DC7834* + ID_OUI_FROM_DATABASE=LOGICOM SA + +@@ -83591,12 +106508,39 @@ OUI:DC85DE* + OUI:DC86D8* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:DC87CB* ++ ID_OUI_FROM_DATABASE=Beijing Perfectek Technologies Co., Ltd. ++ ++OUI:DC8983* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:DC8B28* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:DC8C1B* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:DC8C37* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:DC8D8A* ++ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks GmbH & Co. KG ++ ++OUI:DC9020* ++ ID_OUI_FROM_DATABASE=RURU TEK PRIVATE LIMITED ++ + OUI:DC9088* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:DC91BF* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:DC962C* ++ ID_OUI_FROM_DATABASE=NST Audio Ltd ++ ++OUI:DC9840* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:DC9914* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -83609,6 +106553,9 @@ OUI:DC9B1E* + OUI:DC9B9C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:DC9BD6* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:DC9C52* + ID_OUI_FROM_DATABASE=Sapphire Technology Limited. + +@@ -83621,12 +106568,18 @@ OUI:DC9FA4* + OUI:DC9FDB* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + ++OUI:DCA120* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:DCA266* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + + OUI:DCA333* + ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd + ++OUI:DCA3A2* ++ ID_OUI_FROM_DATABASE=Feng mi(Beijing)technology co., LTD ++ + OUI:DCA3AC* + ID_OUI_FROM_DATABASE=RBcloudtech + +@@ -83636,6 +106589,9 @@ OUI:DCA4CA* + OUI:DCA5F4* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:DCA632* ++ ID_OUI_FROM_DATABASE=Raspberry Pi Trading Ltd ++ + OUI:DCA6BD* + ID_OUI_FROM_DATABASE=Beijing Lanbo Technology Co., Ltd. + +@@ -83660,12 +106616,21 @@ OUI:DCAD9E* + OUI:DCAE04* + ID_OUI_FROM_DATABASE=CELOXICA Ltd + ++OUI:DCAEEB* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:DCAF68* + ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD + + OUI:DCB058* + ID_OUI_FROM_DATABASE=Bürkert Werke GmbH + ++OUI:DCB082* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:DCB131* ++ ID_OUI_FROM_DATABASE=SHENZHEN HUARUIAN TECHNOLOGY CO.,LTD ++ + OUI:DCB3B4* + ID_OUI_FROM_DATABASE=Honeywell Environmental & Combustion Controls (Tianjin) Co., Ltd. + +@@ -83675,6 +106640,24 @@ OUI:DCB4AC* + OUI:DCB4C4* + ID_OUI_FROM_DATABASE=Microsoft XCG + ++OUI:DCB54F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:DCB72E* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:DCB7FC* ++ ID_OUI_FROM_DATABASE=Alps Electric (Ireland) Ltd ++ ++OUI:DCB808* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:DCBB96* ++ ID_OUI_FROM_DATABASE=Full Solution Telecom ++ ++OUI:DCBD7A* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ + OUI:DCBE7A* + ID_OUI_FROM_DATABASE=Zhejiang Nurotron Biotechnology Co. + +@@ -83711,6 +106694,15 @@ OUI:DCC8F5* + OUI:DCCBA8* + ID_OUI_FROM_DATABASE=Explora Technologies Inc + ++OUI:DCCC8D* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ ++OUI:DCCD2F* ++ ID_OUI_FROM_DATABASE=Seiko Epson Corporation ++ ++OUI:DCCD74* ++ ID_OUI_FROM_DATABASE=Japan E.M.Solutions Co., Ltd. ++ + OUI:DCCE41* + ID_OUI_FROM_DATABASE=FE GLOBAL HONG KONG LIMITED + +@@ -83741,9 +106733,15 @@ OUI:DCD321* + OUI:DCD3A2* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:DCD444* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DCD52A* + ID_OUI_FROM_DATABASE=Sunny Heart Limited + ++OUI:DCD7A0* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:DCD87C* + ID_OUI_FROM_DATABASE=Beijing Jingdong Century Trading Co., LTD. + +@@ -83753,15 +106751,24 @@ OUI:DCD87F* + OUI:DCD916* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:DCD9AE* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:DCDA4F* + ID_OUI_FROM_DATABASE=GETCK TECHNOLOGY, INC + ++OUI:DCDA80* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:DCDB70* + ID_OUI_FROM_DATABASE=Tonfunk Systementwicklung und Service GmbH + + OUI:DCDC07* + ID_OUI_FROM_DATABASE=TRP Systems BV + ++OUI:DCDCE2* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:DCDD24* + ID_OUI_FROM_DATABASE=Energica Motor Company SpA + +@@ -83771,6 +106778,9 @@ OUI:DCDE4F* + OUI:DCDECA* + ID_OUI_FROM_DATABASE=Akyllor + ++OUI:DCDFD6* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:DCE026* + ID_OUI_FROM_DATABASE=Patrol Tag, Inc + +@@ -83817,7 +106827,7 @@ OUI:DCE5339* + ID_OUI_FROM_DATABASE=Tiertime Corporation + + OUI:DCE533A* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Amazinglayer Network Co., Ltd. + + OUI:DCE533B* + ID_OUI_FROM_DATABASE=Tintel Hongkong Co.Ltd +@@ -83840,21 +106850,36 @@ OUI:DCE71C* + OUI:DCE838* + ID_OUI_FROM_DATABASE=CK Telecom (Shenzhen) Limited + ++OUI:DCE994* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:DCEB53* + ID_OUI_FROM_DATABASE=Wuhan QianXiao Elecronic Technology CO.,LTD + ++OUI:DCEB69* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:DCEB94* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:DCEC06* + ID_OUI_FROM_DATABASE=Heimi Network Technology Co., Ltd. + ++OUI:DCED83* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ ++OUI:DCED84* ++ ID_OUI_FROM_DATABASE=Haverford Systems Inc ++ + OUI:DCEE06* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:DCEF09* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:DCEF80* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:DCEFCA* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +@@ -83867,30 +106892,54 @@ OUI:DCF090* + OUI:DCF110* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:DCF401* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:DCF4CA* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:DCF505* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:DCF56E* ++ ID_OUI_FROM_DATABASE=Wellysis Corp. ++ + OUI:DCF719* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:DCF755* + ID_OUI_FROM_DATABASE=SITRONIK + ++OUI:DCF756* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:DCF858* + ID_OUI_FROM_DATABASE=Lorent Networks, Inc. + ++OUI:DCF8B9* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:DCFAD5* + ID_OUI_FROM_DATABASE=STRONG Ges.m.b.H. + + OUI:DCFB02* + ID_OUI_FROM_DATABASE=BUFFALO.INC + ++OUI:DCFB48* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:DCFE07* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + + OUI:DCFE18* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:E00084* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E002A5* ++ ID_OUI_FROM_DATABASE=ABB Robotics ++ + OUI:E00370* + ID_OUI_FROM_DATABASE=ShenZhen Continental Wireless Technology Co., Ltd. + +@@ -83903,12 +106952,21 @@ OUI:E006E6* + OUI:E0071B* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + ++OUI:E009BF* ++ ID_OUI_FROM_DATABASE=SHENZHEN TONG BO WEI TECHNOLOGY Co.,LTD ++ ++OUI:E00AF6* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:E00B28* + ID_OUI_FROM_DATABASE=Inovonics + + OUI:E00C7F* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:E00CE5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E00DB9* + ID_OUI_FROM_DATABASE=Cree, Inc. + +@@ -83918,21 +106976,36 @@ OUI:E00EDA* + OUI:E00EE1* + ID_OUI_FROM_DATABASE=We Corporation Inc. + ++OUI:E00EE4* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ + OUI:E0107F* + ID_OUI_FROM_DATABASE=Ruckus Wireless + + OUI:E01283* + ID_OUI_FROM_DATABASE=Shenzhen Fanzhuo Communication Technology Co., Lt + ++OUI:E013B5* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:E0143E* + ID_OUI_FROM_DATABASE=Modoosis Inc. + + OUI:E01877* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + ++OUI:E0189F* ++ ID_OUI_FROM_DATABASE=EM Microelectronic ++ + OUI:E0191D* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E01954* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:E01995* ++ ID_OUI_FROM_DATABASE=Nutanix ++ + OUI:E019D8* + ID_OUI_FROM_DATABASE=BH TECHNOLOGIES + +@@ -83940,11 +107013,14 @@ OUI:E01AEA* + ID_OUI_FROM_DATABASE=Allied Telesis, Inc. + + OUI:E01C41* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:E01CEE* + ID_OUI_FROM_DATABASE=Bravo Tech, Inc. + ++OUI:E01CFC* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:E01D38* + ID_OUI_FROM_DATABASE=Beijing HuaqinWorld Technology Co.,Ltd + +@@ -83957,12 +107033,27 @@ OUI:E01E07* + OUI:E01F0A* + ID_OUI_FROM_DATABASE=Xslent Energy Technologies. LLC + ++OUI:E01F88* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:E01FED* ++ ID_OUI_FROM_DATABASE=Nokia Shanghai Bell Co., Ltd. ++ + OUI:E02202* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E023D7* ++ ID_OUI_FROM_DATABASE=Sleep Number ++ ++OUI:E023FF* ++ ID_OUI_FROM_DATABASE=Fortinet, Inc. ++ + OUI:E0247F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E02481* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E02538* + ID_OUI_FROM_DATABASE=Titan Pet Products + +@@ -83981,21 +107072,39 @@ OUI:E02861* + OUI:E0286D* + ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH + ++OUI:E02967* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ + OUI:E02A82* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:E02AE6* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:E02B96* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E02BE9* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:E02CB2* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication (Wuhan) Company Limited + + OUI:E02CF3* + ID_OUI_FROM_DATABASE=MRS Electronic GmbH + ++OUI:E02E3F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E02F6D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:E03005* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + ++OUI:E030F9* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:E0319E* + ID_OUI_FROM_DATABASE=Valve Corporation + +@@ -84017,6 +107126,9 @@ OUI:E03676* + OUI:E036E3* + ID_OUI_FROM_DATABASE=Stage One International Co., Ltd. + ++OUI:E03717* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:E037BF* + ID_OUI_FROM_DATABASE=Wistron Neweb Corporation + +@@ -84041,15 +107153,24 @@ OUI:E03E7D* + OUI:E03F49* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:E04007* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E04136* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + + OUI:E043DB* + ID_OUI_FROM_DATABASE=Shenzhen ViewAt Technology Co.,Ltd. + ++OUI:E0456D* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:E0469A* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:E046E5* ++ ID_OUI_FROM_DATABASE=Gosuncn Technology Group Co., Ltd. ++ + OUI:E048AF* + ID_OUI_FROM_DATABASE=Premietech Limited + +@@ -84062,11 +107183,14 @@ OUI:E049ED* + OUI:E04B45* + ID_OUI_FROM_DATABASE=Hi-P Electronics Pte Ltd + ++OUI:E04BA6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E04F43* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + + OUI:E04FBD* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:E0508B* + ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. +@@ -84089,9 +107213,57 @@ OUI:E056F4* + OUI:E0589E* + ID_OUI_FROM_DATABASE=Laerdal Medical + ++OUI:E05A9F0* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:E05A9F1* ++ ID_OUI_FROM_DATABASE=AITEC SYSTEM CO., LTD. ++ ++OUI:E05A9F2* ++ ID_OUI_FROM_DATABASE=Chengdu Song Yuan Electronic Technology Co.,Ltd ++ ++OUI:E05A9F3* ++ ID_OUI_FROM_DATABASE=Link of Things Co., Ltd. ++ ++OUI:E05A9F4* ++ ID_OUI_FROM_DATABASE=Hale Products ++ ++OUI:E05A9F5* ++ ID_OUI_FROM_DATABASE=TRYEN ++ ++OUI:E05A9F6* ++ ID_OUI_FROM_DATABASE=Fibrain ++ ++OUI:E05A9F7* ++ ID_OUI_FROM_DATABASE=OMB Guitars LLC ++ ++OUI:E05A9F8* ++ ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd. ++ ++OUI:E05A9F9* ++ ID_OUI_FROM_DATABASE=Gemalto Document Readers ++ ++OUI:E05A9FA* ++ ID_OUI_FROM_DATABASE=Contemporary Amperex Technology Co., Limited ++ ++OUI:E05A9FB* ++ ID_OUI_FROM_DATABASE=Shenzhen Rongan Networks Technology Co.,Ltd ++ ++OUI:E05A9FC* ++ ID_OUI_FROM_DATABASE=ShenZhen Mornsun Smartlinker Limited Co., LTD ++ ++OUI:E05A9FD* ++ ID_OUI_FROM_DATABASE=Mountz, Inc. ++ ++OUI:E05A9FE* ++ ID_OUI_FROM_DATABASE=ShenZhen Arts Changhua Intelligent Technology Co., Ltd ++ + OUI:E05B70* + ID_OUI_FROM_DATABASE=Innovid, Co., Ltd. + ++OUI:E05D5C* ++ ID_OUI_FROM_DATABASE=Oy Everon Ab ++ + OUI:E05DA6* + ID_OUI_FROM_DATABASE=Detlef Fink Elektronik & Softwareentwicklung + +@@ -84110,6 +107282,9 @@ OUI:E06089* + OUI:E061B2* + ID_OUI_FROM_DATABASE=HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD + ++OUI:E06234* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:E06267* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -84120,7 +107295,7 @@ OUI:E063DA* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + + OUI:E063E5* +- ID_OUI_FROM_DATABASE=Sony Mobile Communications Inc ++ ID_OUI_FROM_DATABASE=Sony Corporation + + OUI:E064BB* + ID_OUI_FROM_DATABASE=DigiView S.r.l. +@@ -84128,30 +107303,60 @@ OUI:E064BB* + OUI:E06678* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:E06781* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co., Ltd. ++ + OUI:E067B3* +- ID_OUI_FROM_DATABASE=C-Data Technology Co., Ltd ++ ID_OUI_FROM_DATABASE=Shenzhen C-Data Technology Co., Ltd + + OUI:E0686D* + ID_OUI_FROM_DATABASE=Raybased AB + ++OUI:E0693A* ++ ID_OUI_FROM_DATABASE=Innophase Inc. ++ + OUI:E06995* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + ++OUI:E069BA* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:E06C4E* ++ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp. ++ ++OUI:E06CA6* ++ ID_OUI_FROM_DATABASE=Creotech Instruments S.A. ++ ++OUI:E06D17* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E0735F* + ID_OUI_FROM_DATABASE=NUCOM + + OUI:E0750A* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:E0757D* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:E075AA* ++ ID_OUI_FROM_DATABASE=Beijing Jingling Information System Technology Co., Ltd. ++ + OUI:E076D0* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + ++OUI:E07726* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E078A3* + ID_OUI_FROM_DATABASE=Shanghai Winner Information Technology Co.,Inc + ++OUI:E0795E* ++ ID_OUI_FROM_DATABASE=Wuxi Xiaohu Technology Co.,Ltd. ++ ++OUI:E079C4* ++ ID_OUI_FROM_DATABASE=iRay Technology Company Limited ++ + OUI:E07C13* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -84173,12 +107378,18 @@ OUI:E08177* + OUI:E084F3* + ID_OUI_FROM_DATABASE=High Grade Controls Corporation + ++OUI:E0859A* ++ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. ++ + OUI:E087B1* + ID_OUI_FROM_DATABASE=Nata-Info Ltd. + + OUI:E0885D* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:E0897E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E0899D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -84191,12 +107402,21 @@ OUI:E08E3C* + OUI:E08FEC* + ID_OUI_FROM_DATABASE=REPOTEC CO., LTD. + ++OUI:E0913C* ++ ID_OUI_FROM_DATABASE=Kyeungin CNS Co., Ltd. ++ + OUI:E09153* + ID_OUI_FROM_DATABASE=XAVi Technologies Corp. + + OUI:E091F5* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:E0925C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E092A7* ++ ID_OUI_FROM_DATABASE=Feitian Technologies Co., Ltd ++ + OUI:E09467* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -84209,6 +107429,9 @@ OUI:E09796* + OUI:E097F2* + ID_OUI_FROM_DATABASE=Atomax Inc. + ++OUI:E09806* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:E09861* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -84224,18 +107447,27 @@ OUI:E09DB8* + OUI:E09DFA* + ID_OUI_FROM_DATABASE=Wanan Hongsheng Electronic Co.Ltd + ++OUI:E09F2A* ++ ID_OUI_FROM_DATABASE=Iton Technology Corp. ++ + OUI:E0A198* + ID_OUI_FROM_DATABASE=NOJA Power Switchgear Pty Ltd + + OUI:E0A1D7* + ID_OUI_FROM_DATABASE=SFR + ++OUI:E0A258* ++ ID_OUI_FROM_DATABASE=Wanbang Digital Energy Co.,Ltd ++ + OUI:E0A30F* + ID_OUI_FROM_DATABASE=Pevco + + OUI:E0A3AC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E0A509* ++ ID_OUI_FROM_DATABASE=Bitmain Technologies Inc ++ + OUI:E0A670* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -84249,7 +107481,7 @@ OUI:E0AA96* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:E0AAB0* +- ID_OUI_FROM_DATABASE=GENERAL VISION ELECTRONICS CO. LTD. ++ ID_OUI_FROM_DATABASE=SUNTAILI ENTERPRISE CO. LTD, + + OUI:E0AADB* + ID_OUI_FROM_DATABASE=Nanjing PANENG Technology Development Co.,Ltd +@@ -84264,7 +107496,7 @@ OUI:E0ACF1* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:E0AE5E* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:E0AEB2* + ID_OUI_FROM_DATABASE=Bender GmbH & Co.KG +@@ -84278,12 +107510,21 @@ OUI:E0AF4B* + OUI:E0AF4F* + ID_OUI_FROM_DATABASE=Deutsche Telekom AG + ++OUI:E0B260* ++ ID_OUI_FROM_DATABASE=TENO NETWORK TECHNOLOGIES COMPANY LIMITED ++ + OUI:E0B2F1* + ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED + + OUI:E0B52D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:E0B55F* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E0B655* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ + OUI:E0B6F50* + ID_OUI_FROM_DATABASE=BeSTAR Corporation + +@@ -84332,6 +107573,9 @@ OUI:E0B6F5E* + OUI:E0B70A* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E0B72E* ++ ID_OUI_FROM_DATABASE=ShenZhen Qualmesh Technology Co.,Ltd. ++ + OUI:E0B7B1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -84345,14 +107589,20 @@ OUI:E0B9BA* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:E0B9E5* +- ID_OUI_FROM_DATABASE=Technicolor ++ ID_OUI_FROM_DATABASE=Technicolor Delivery Technologies Belgium NV + + OUI:E0BAB4* + ID_OUI_FROM_DATABASE=Arrcus, Inc + ++OUI:E0BB9E* ++ ID_OUI_FROM_DATABASE=Seiko Epson Corporation ++ + OUI:E0BC43* + ID_OUI_FROM_DATABASE=C2 Microsystems, Inc. + ++OUI:E0BE03* ++ ID_OUI_FROM_DATABASE=Lite-On Network Communication (Dongguan) Limited ++ + OUI:E0C0D1* + ID_OUI_FROM_DATABASE=CK Telecom (Shenzhen) Limited + +@@ -84362,9 +107612,18 @@ OUI:E0C286* + OUI:E0C2B7* + ID_OUI_FROM_DATABASE=Masimo Corporation + ++OUI:E0C377* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:E0C3F3* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:E0C58F* ++ ID_OUI_FROM_DATABASE=China Mobile IOT Company Limited ++ ++OUI:E0C63C* ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ + OUI:E0C6B3* + ID_OUI_FROM_DATABASE=MilDef AB + +@@ -84395,12 +107654,21 @@ OUI:E0CB1D* + OUI:E0CB4E* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:E0CB56* ++ ID_OUI_FROM_DATABASE=Shenzhen iComm Semiconductor CO.,LTD ++ + OUI:E0CBBC* + ID_OUI_FROM_DATABASE=Cisco Meraki + + OUI:E0CBEE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E0CC7A* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E0CCF8* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:E0CDFD* + ID_OUI_FROM_DATABASE=Beijing E3Control Technology Co, LTD + +@@ -84410,6 +107678,9 @@ OUI:E0CEC3* + OUI:E0CF2D* + ID_OUI_FROM_DATABASE=Gemintek Corporation + ++OUI:E0D083* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:E0D10A* + ID_OUI_FROM_DATABASE=Katoudenkikougyousyo co ltd + +@@ -84422,6 +107693,15 @@ OUI:E0D1E6* + OUI:E0D31A* + ID_OUI_FROM_DATABASE=EQUES Technology Co., Limited + ++OUI:E0D462* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E0D464* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:E0D4E8* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:E0D55E* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +@@ -84437,6 +107717,9 @@ OUI:E0D9A2* + OUI:E0D9E3* + ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd. + ++OUI:E0DA90* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E0DADC* + ID_OUI_FROM_DATABASE=JVC KENWOOD Corporation + +@@ -84449,12 +107732,33 @@ OUI:E0DB55* + OUI:E0DB88* + ID_OUI_FROM_DATABASE=Open Standard Digital-IF Interface for SATCOM Systems + ++OUI:E0DBD1* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:E0DCA0* + ID_OUI_FROM_DATABASE=Siemens Industrial Automation Products Ltd Chengdu + ++OUI:E0DCFF* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:E0DDC0* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:E0E0C2* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ ++OUI:E0E0FC* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E0E1A9* ++ ID_OUI_FROM_DATABASE=Shenzhen Four Seas Global Link Network Technology Co., Ltd. ++ ++OUI:E0E2E6* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:E0E37C* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E0E5CF* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -84464,15 +107768,30 @@ OUI:E0E62E* + OUI:E0E631* + ID_OUI_FROM_DATABASE=SNB TECHNOLOGIES LIMITED + ++OUI:E0E656* ++ ID_OUI_FROM_DATABASE=Nethesis srl ++ + OUI:E0E751* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + + OUI:E0E7BB* + ID_OUI_FROM_DATABASE=Nureva, Inc. + ++OUI:E0E8BB* ++ ID_OUI_FROM_DATABASE=Unicom Vsens Telecommunications Co., Ltd. ++ ++OUI:E0E8E6* ++ ID_OUI_FROM_DATABASE=Shenzhen C-Data Technology Co., Ltd. ++ + OUI:E0E8E8* + ID_OUI_FROM_DATABASE=Olive Telecommunication Pvt. Ltd + ++OUI:E0EB40* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E0EB62* ++ ID_OUI_FROM_DATABASE=Shanghai Hulu Devices Co., Ltd ++ + OUI:E0ED1A* + ID_OUI_FROM_DATABASE=vastriver Technology Co., Ltd + +@@ -84491,12 +107810,18 @@ OUI:E0F211* + OUI:E0F379* + ID_OUI_FROM_DATABASE=Vaddio + ++OUI:E0F442* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E0F5C6* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:E0F5CA* + ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD. + ++OUI:E0F6B5* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:E0F847* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -84515,6 +107840,18 @@ OUI:E4029B* + OUI:E40439* + ID_OUI_FROM_DATABASE=TomTom Software Ltd + ++OUI:E405F8* ++ ID_OUI_FROM_DATABASE=Bytedance ++ ++OUI:E4072B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E408E7* ++ ID_OUI_FROM_DATABASE=Quectel Wireless Solutions Co.,Ltd. ++ ++OUI:E40CFD* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:E40EEE* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -84530,12 +107867,18 @@ OUI:E4121D* + OUI:E41289* + ID_OUI_FROM_DATABASE=topsystem Systemhaus GmbH + ++OUI:E415F6* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:E417D8* + ID_OUI_FROM_DATABASE=8BITDO TECHNOLOGY HK LIMITED + + OUI:E4186B* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + ++OUI:E419C1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E41A2C* + ID_OUI_FROM_DATABASE=ZPE Systems, Inc. + +@@ -84545,9 +107888,57 @@ OUI:E41C4B* + OUI:E41D2D* + ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. + ++OUI:E41E0A0* ++ ID_OUI_FROM_DATABASE=Zavod № 423 ++ ++OUI:E41E0A1* ++ ID_OUI_FROM_DATABASE=Connected Cars A/S ++ ++OUI:E41E0A2* ++ ID_OUI_FROM_DATABASE=IDvaco Private Limited ++ ++OUI:E41E0A3* ++ ID_OUI_FROM_DATABASE=Avast Software s.r.o. ++ ++OUI:E41E0A4* ++ ID_OUI_FROM_DATABASE=XPR Group ++ ++OUI:E41E0A5* ++ ID_OUI_FROM_DATABASE=Aeroel srl ++ ++OUI:E41E0A6* ++ ID_OUI_FROM_DATABASE=SFC Energy AG ++ ++OUI:E41E0A7* ++ ID_OUI_FROM_DATABASE=Tritium Pty Ltd ++ ++OUI:E41E0A8* ++ ID_OUI_FROM_DATABASE=SAGE Glass ++ ++OUI:E41E0A9* ++ ID_OUI_FROM_DATABASE=B METERS S.R.L. ++ ++OUI:E41E0AA* ++ ID_OUI_FROM_DATABASE=FireAngel Safety Technology Ltd ++ ++OUI:E41E0AB* ++ ID_OUI_FROM_DATABASE=Safety Vision, LLC ++ ++OUI:E41E0AC* ++ ID_OUI_FROM_DATABASE=TELETASK BELGIUM ++ ++OUI:E41E0AD* ++ ID_OUI_FROM_DATABASE=ROMO Wind A/S ++ ++OUI:E41E0AE* ++ ID_OUI_FROM_DATABASE=Shanghai LeXiang Technology Co., Ltd ++ + OUI:E41F13* + ID_OUI_FROM_DATABASE=IBM Corp + ++OUI:E41F7B* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:E41FE9* + ID_OUI_FROM_DATABASE=Dunkermotoren GmbH + +@@ -84557,15 +107948,36 @@ OUI:E422A5* + OUI:E42354* + ID_OUI_FROM_DATABASE=SHENZHEN FUZHI SOFTWARE TECHNOLOGY CO.,LTD + ++OUI:E4246C* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ + OUI:E425E7* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:E425E9* + ID_OUI_FROM_DATABASE=Color-Chip + ++OUI:E42686* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ ++OUI:E4268B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E42761* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:E42771* + ID_OUI_FROM_DATABASE=Smartlabs + ++OUI:E42805* ++ ID_OUI_FROM_DATABASE=Pivotal Optics ++ ++OUI:E428A4* ++ ID_OUI_FROM_DATABASE=Prama India Private Limited ++ ++OUI:E42AAC* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ + OUI:E42AD3* + ID_OUI_FROM_DATABASE=Magneti Marelli S.p.A. Powertrain + +@@ -84596,6 +108008,9 @@ OUI:E43022* + OUI:E432CB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E433AE* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:E43493* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -84611,12 +108026,30 @@ OUI:E435FB* + OUI:E437D7* + ID_OUI_FROM_DATABASE=HENRI DEPAEPE S.A.S. + ++OUI:E4388C* ++ ID_OUI_FROM_DATABASE=Digital Products Limited ++ + OUI:E438F2* + ID_OUI_FROM_DATABASE=Advantage Controls + ++OUI:E43A65* ++ ID_OUI_FROM_DATABASE=MofiNetwork Inc ++ + OUI:E43A6E* + ID_OUI_FROM_DATABASE=Shenzhen Zeroone Technology CO.,LTD + ++OUI:E43BC9* ++ ID_OUI_FROM_DATABASE=HISENSE VISUAL TECHNOLOGY CO.,LTD ++ ++OUI:E43C80* ++ ID_OUI_FROM_DATABASE=University of Oklahoma ++ ++OUI:E43D1A* ++ ID_OUI_FROM_DATABASE=Broadcom Limited ++ ++OUI:E43EC6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E43ED7* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + +@@ -84626,6 +108059,12 @@ OUI:E43FA2* + OUI:E440E2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E44122* ++ ID_OUI_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd ++ ++OUI:E44164* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:E441E6* + ID_OUI_FROM_DATABASE=Ottec Technology GmbH + +@@ -84635,6 +108074,9 @@ OUI:E442A6* + OUI:E4434B* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:E446B0* ++ ID_OUI_FROM_DATABASE=Fujitsu Client Computing Limited ++ + OUI:E446BD* + ID_OUI_FROM_DATABASE=C&C TECHNIC TAIWAN CO., LTD. + +@@ -84644,15 +108086,69 @@ OUI:E446DA* + OUI:E44790* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:E44791* ++ ID_OUI_FROM_DATABASE=Iris ID Systems, Inc. ++ ++OUI:E447B3* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:E448C7* + ID_OUI_FROM_DATABASE=Cisco SPVTG + + OUI:E44C6C* + ID_OUI_FROM_DATABASE=Shenzhen Guo Wei Electronic Co,. Ltd. + ++OUI:E44CC70* ++ ID_OUI_FROM_DATABASE=Alert Alarm AB ++ ++OUI:E44CC71* ++ ID_OUI_FROM_DATABASE=ACS-Solutions GmbH ++ ++OUI:E44CC72* ++ ID_OUI_FROM_DATABASE=Doowon Electronics & Telecom Co.,Ltd ++ ++OUI:E44CC73* ++ ID_OUI_FROM_DATABASE=JSC Svyaz Inginiring M ++ ++OUI:E44CC74* ++ ID_OUI_FROM_DATABASE=Beijing Zhongchuangwei Nanjing Quantum Communication Technology Co., Ltd. ++ ++OUI:E44CC75* ++ ID_OUI_FROM_DATABASE=CE LABS, LLC ++ ++OUI:E44CC76* ++ ID_OUI_FROM_DATABASE=HANGZHOU OLE-SYSTEMS CO., LTD ++ ++OUI:E44CC77* ++ ID_OUI_FROM_DATABASE=Channel Enterprises (HK) Ltd. ++ ++OUI:E44CC78* ++ ID_OUI_FROM_DATABASE=IAG GROUP LTD ++ ++OUI:E44CC79* ++ ID_OUI_FROM_DATABASE=Ottomate International Pvt. Ltd. ++ ++OUI:E44CC7A* ++ ID_OUI_FROM_DATABASE=Muzik Inc ++ ++OUI:E44CC7B* ++ ID_OUI_FROM_DATABASE=SmallHD ++ ++OUI:E44CC7C* ++ ID_OUI_FROM_DATABASE=EPS Bio ++ ++OUI:E44CC7D* ++ ID_OUI_FROM_DATABASE=Telo Systems Limitd ++ ++OUI:E44CC7E* ++ ID_OUI_FROM_DATABASE=FLK information security technology Co,. Ltd ++ + OUI:E44E18* + ID_OUI_FROM_DATABASE=Gardasoft VisionLimited + ++OUI:E44E2D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:E44E76* + ID_OUI_FROM_DATABASE=CHAMPIONTECH ENTERPRISE (SHENZHEN) INC + +@@ -84665,6 +108161,15 @@ OUI:E44F5F* + OUI:E4509A* + ID_OUI_FROM_DATABASE=HW Communications Ltd + ++OUI:E450EB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E454E8* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ ++OUI:E455A8* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:E455EA* + ID_OUI_FROM_DATABASE=Dedicated Computing + +@@ -84686,6 +108191,12 @@ OUI:E458E7* + OUI:E45AA2* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:E45AD4* ++ ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd. ++ ++OUI:E45D37* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:E45D51* + ID_OUI_FROM_DATABASE=SFR + +@@ -84695,6 +108206,15 @@ OUI:E45D52* + OUI:E45D75* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E45E1B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:E45E37* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:E45F01* ++ ID_OUI_FROM_DATABASE=Raspberry Pi Trading Ltd ++ + OUI:E46059* + ID_OUI_FROM_DATABASE=Pingtek Co., Ltd. + +@@ -84704,6 +108224,9 @@ OUI:E46251* + OUI:E46449* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E4671E* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN NUO XIN CHENG TECHNOLOGY co., Ltd. ++ + OUI:E467BA* + ID_OUI_FROM_DATABASE=Danish Interpretation Systems A/S + +@@ -84731,9 +108254,18 @@ OUI:E472E2* + OUI:E4751E* + ID_OUI_FROM_DATABASE=Getinge Sterilization AB + ++OUI:E475DC* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ ++OUI:E47684* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E47723* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:E47727* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E4776B* + ID_OUI_FROM_DATABASE=AARTESYS AG + +@@ -84743,6 +108275,9 @@ OUI:E477D4* + OUI:E47B3F* + ID_OUI_FROM_DATABASE=BEIJING CO-CLOUD TECHNOLOGY LTD. + ++OUI:E47C65* ++ ID_OUI_FROM_DATABASE=Sunstar Communication Technology Co., Ltd ++ + OUI:E47CF9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -84758,6 +108293,9 @@ OUI:E47DEB* + OUI:E47E66* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E47E9A* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:E47FB2* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + +@@ -84770,9 +108308,15 @@ OUI:E481B3* + OUI:E482CC* + ID_OUI_FROM_DATABASE=Jumptronic GmbH + ++OUI:E48326* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E48399* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E4842B* ++ ID_OUI_FROM_DATABASE=HANGZHOU SOFTEL OPTIC CO., LTD ++ + OUI:E48501* + ID_OUI_FROM_DATABASE=Geberit International AG + +@@ -84788,6 +108332,9 @@ OUI:E48C0F* + OUI:E48D8C* + ID_OUI_FROM_DATABASE=Routerboard.com + ++OUI:E48F1D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E48F34* + ID_OUI_FROM_DATABASE=Vodafone Italia S.p.A. + +@@ -84800,12 +108347,21 @@ OUI:E49069* + OUI:E4907E* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:E490FD* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:E4922A* ++ ID_OUI_FROM_DATABASE=DBG HOLDINGS LIMITED ++ + OUI:E492E7* + ID_OUI_FROM_DATABASE=Gridlink Tech. Co.,Ltd. + + OUI:E492FB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E4936A* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:E4956E0* + ID_OUI_FROM_DATABASE=SMC Networks, Inc + +@@ -84860,6 +108416,9 @@ OUI:E496AE* + OUI:E497F0* + ID_OUI_FROM_DATABASE=Shanghai VLC Technologies Ltd. Co. + ++OUI:E498BB* ++ ID_OUI_FROM_DATABASE=Phyplus Microelectronics Limited ++ + OUI:E498D1* + ID_OUI_FROM_DATABASE=Microsoft Mobile Oy + +@@ -84875,6 +108434,9 @@ OUI:E49ADC* + OUI:E49E12* + ID_OUI_FROM_DATABASE=FREEBOX SAS + ++OUI:E49F1E* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:E4A1E6* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +@@ -84905,12 +108467,24 @@ OUI:E4A7FD* + OUI:E4A8B6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E4A8DF* ++ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. ++ + OUI:E4AA5D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:E4AAEA* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ ++OUI:E4AAEC* ++ ID_OUI_FROM_DATABASE=Tianjin Hualai Technology Co., Ltd ++ + OUI:E4AB46* + ID_OUI_FROM_DATABASE=UAB Selteka + ++OUI:E4AB89* ++ ID_OUI_FROM_DATABASE=MitraStar Technology Corp. ++ + OUI:E4AD7D* + ID_OUI_FROM_DATABASE=SCL Elements + +@@ -84923,9 +108497,18 @@ OUI:E4B005* + OUI:E4B021* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E4B2FB* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E4B318* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:E4B503* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ ++OUI:E4B97A* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:E4BAD9* + ID_OUI_FROM_DATABASE=360 Fly Inc. + +@@ -84935,6 +108518,12 @@ OUI:E4BD4B* + OUI:E4BEED* + ID_OUI_FROM_DATABASE=Netcore Technology Inc. + ++OUI:E4BFFA* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:E4C0CC* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:E4C146* + ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A + +@@ -84944,6 +108533,9 @@ OUI:E4C1F1* + OUI:E4C2D1* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E4C32A* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:E4C483* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + +@@ -84965,12 +108557,18 @@ OUI:E4C801* + OUI:E4C806* + ID_OUI_FROM_DATABASE=Ceiec Electric Technology Inc. + ++OUI:E4C90B* ++ ID_OUI_FROM_DATABASE=Radwin ++ + OUI:E4CA12* + ID_OUI_FROM_DATABASE=zte corporation + + OUI:E4CB59* + ID_OUI_FROM_DATABASE=Beijing Loveair Science and Technology Co. Ltd. + ++OUI:E4CC9D* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:E4CE02* + ID_OUI_FROM_DATABASE=WyreStorm Technologies Ltd + +@@ -84986,6 +108584,12 @@ OUI:E4D124* + OUI:E4D332* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:E4D373* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E4D3AA* ++ ID_OUI_FROM_DATABASE=FUJITSU CONNECTED TECHNOLOGIES LIMITED ++ + OUI:E4D3F1* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -84998,6 +108602,12 @@ OUI:E4D71D* + OUI:E4DB6D* + ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. + ++OUI:E4DC43* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E4DC5F* ++ ID_OUI_FROM_DATABASE=Cofractal, Inc. ++ + OUI:E4DD79* + ID_OUI_FROM_DATABASE=En-Vision America, Inc. + +@@ -85007,6 +108617,9 @@ OUI:E4E0A6* + OUI:E4E0C5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E4E112* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:E4E130* + ID_OUI_FROM_DATABASE=TCT mobile ltd + +@@ -85016,6 +108629,9 @@ OUI:E4E409* + OUI:E4E4AB* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:E4E749* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:E4EA83* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + +@@ -85034,18 +108650,33 @@ OUI:E4F042* + OUI:E4F14C* + ID_OUI_FROM_DATABASE=Private + ++OUI:E4F1D4* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:E4F327* ++ ID_OUI_FROM_DATABASE=ATOL LLC ++ + OUI:E4F365* + ID_OUI_FROM_DATABASE=Time-O-Matic, Inc. + ++OUI:E4F3C4* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:E4F3E3* + ID_OUI_FROM_DATABASE=Shanghai iComhome Co.,Ltd. + ++OUI:E4F3E8* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:E4F3F5* + ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + + OUI:E4F4C6* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:E4F75B* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:E4F7A1* + ID_OUI_FROM_DATABASE=Datafox GmbH + +@@ -85076,6 +108707,12 @@ OUI:E4FB8F* + OUI:E4FC82* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:E4FD45* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:E4FDA1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E4FED9* + ID_OUI_FROM_DATABASE=EDMI Europe Ltd + +@@ -85085,6 +108722,9 @@ OUI:E4FFDD* + OUI:E80036* + ID_OUI_FROM_DATABASE=Befs co,. ltd + ++OUI:E8018D* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:E8039A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -85103,6 +108743,9 @@ OUI:E804F3* + OUI:E8056D* + ID_OUI_FROM_DATABASE=Nortel Networks + ++OUI:E805DC* ++ ID_OUI_FROM_DATABASE=Verifone Inc. ++ + OUI:E80688* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -85121,6 +108764,9 @@ OUI:E80945* + OUI:E80959* + ID_OUI_FROM_DATABASE=Guoguang Electric Co.,Ltd + ++OUI:E80AEC* ++ ID_OUI_FROM_DATABASE=Jiangsu Hengtong Optic-Electric Co., LTD ++ + OUI:E80B13* + ID_OUI_FROM_DATABASE=Akib Systems Taiwan, INC + +@@ -85130,6 +108776,9 @@ OUI:E80C38* + OUI:E80C75* + ID_OUI_FROM_DATABASE=Syncbak, Inc. + ++OUI:E80FC8* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ + OUI:E8102E* + ID_OUI_FROM_DATABASE=Really Simple Software, Inc + +@@ -85148,6 +108797,9 @@ OUI:E81363* + OUI:E81367* + ID_OUI_FROM_DATABASE=AIRSOUND Inc. + ++OUI:E8136E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E8150E* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -85202,21 +108854,45 @@ OUI:E81863E* + OUI:E81863F* + ID_OUI_FROM_DATABASE=Private + ++OUI:E81A58* ++ ID_OUI_FROM_DATABASE=TECHNOLOGIC SYSTEMS ++ + OUI:E81AAC* + ID_OUI_FROM_DATABASE=ORFEO SOUNDWORKS Inc. + ++OUI:E81B4B* ++ ID_OUI_FROM_DATABASE=amnimo Inc. ++ ++OUI:E81B69* ++ ID_OUI_FROM_DATABASE=Sercomm Corporation. ++ + OUI:E81CBA* + ID_OUI_FROM_DATABASE=Fortinet, Inc. + ++OUI:E81CD8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E81DA8* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:E81E92* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E820E2* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + ++OUI:E82689* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:E826B6* ++ ID_OUI_FROM_DATABASE=Inside Biometrics International Limited ++ + OUI:E82877* + ID_OUI_FROM_DATABASE=TMY Co., Ltd. + ++OUI:E828C1* ++ ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd. ++ + OUI:E828D5* + ID_OUI_FROM_DATABASE=Cots Technology + +@@ -85226,6 +108902,12 @@ OUI:E82A44* + OUI:E82AEA* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:E82C6D* ++ ID_OUI_FROM_DATABASE=SmartRG, Inc. ++ ++OUI:E82E0C* ++ ID_OUI_FROM_DATABASE=NETINT Technologies Inc. ++ + OUI:E82E24* + ID_OUI_FROM_DATABASE=Out of the Fog Research LLC + +@@ -85238,6 +108920,9 @@ OUI:E83381* + OUI:E8343E* + ID_OUI_FROM_DATABASE=Beijing Infosec Technologies Co., LTD. + ++OUI:E83617* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E8361D* + ID_OUI_FROM_DATABASE=Sense Labs, Inc. + +@@ -85265,6 +108950,9 @@ OUI:E83EFB* + OUI:E83EFC* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E83F67* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E84040* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -85280,6 +108968,18 @@ OUI:E8447E* + OUI:E8481F* + ID_OUI_FROM_DATABASE=Advanced Automotive Antennas + ++OUI:E848B8* ++ ID_OUI_FROM_DATABASE=TP-Link Corporation Limited ++ ++OUI:E84943* ++ ID_OUI_FROM_DATABASE=YUGE Information technology Co. Ltd ++ ++OUI:E84C56* ++ ID_OUI_FROM_DATABASE=INTERCEPT SERVICES LIMITED ++ ++OUI:E84D74* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E84DD0* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -85292,6 +108992,15 @@ OUI:E84E84* + OUI:E84ECE* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + ++OUI:E84F25* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ ++OUI:E84F4B* ++ ID_OUI_FROM_DATABASE=Shenzhen Delos Electronic Co., Ltd ++ ++OUI:E84FA7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E8508B* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + +@@ -85313,15 +109022,27 @@ OUI:E85659* + OUI:E856D6* + ID_OUI_FROM_DATABASE=NCTech Ltd + ++OUI:E85A8B* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:E85AA7* + ID_OUI_FROM_DATABASE=LLC Emzior + ++OUI:E85AD1* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:E85B5B* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + ++OUI:E85BB7* ++ ID_OUI_FROM_DATABASE=Ample Systems Inc. ++ + OUI:E85BF0* + ID_OUI_FROM_DATABASE=Imaging Diagnostics + ++OUI:E85C0A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:E85D6B* + ID_OUI_FROM_DATABASE=Luminate Wireless + +@@ -85355,9 +109076,57 @@ OUI:E866C4* + OUI:E86819* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:E868E7* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:E86A64* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd + ++OUI:E86CC70* ++ ID_OUI_FROM_DATABASE=Trapeze Switzerland GmbH ++ ++OUI:E86CC71* ++ ID_OUI_FROM_DATABASE=ASSA ABLOY(GuangZhou) Smart Technology Co., Ltd ++ ++OUI:E86CC72* ++ ID_OUI_FROM_DATABASE=Xirgo Technologies LLC ++ ++OUI:E86CC73* ++ ID_OUI_FROM_DATABASE=Shenzhen Yibaifen Industrial Co.,Ltd. ++ ++OUI:E86CC74* ++ ID_OUI_FROM_DATABASE=Koal Software Co., Ltd ++ ++OUI:E86CC75* ++ ID_OUI_FROM_DATABASE=Shenzhen Rongda Computer Co.,Ltd ++ ++OUI:E86CC76* ++ ID_OUI_FROM_DATABASE=KLAB ++ ++OUI:E86CC77* ++ ID_OUI_FROM_DATABASE=Huaqin Technology Co.,Ltd ++ ++OUI:E86CC78* ++ ID_OUI_FROM_DATABASE=Lighthouse EIP ++ ++OUI:E86CC79* ++ ID_OUI_FROM_DATABASE=Hangzhou Lanxum Security Technology Co., Ltd ++ ++OUI:E86CC7A* ++ ID_OUI_FROM_DATABASE=CoxSpace ++ ++OUI:E86CC7B* ++ ID_OUI_FROM_DATABASE=MORNSUN Guangzhou Science & Technology Co., Ltd. ++ ++OUI:E86CC7C* ++ ID_OUI_FROM_DATABASE=Limited Liability Company M.S.Korp ++ ++OUI:E86CC7D* ++ ID_OUI_FROM_DATABASE=z-max mediasolution ++ ++OUI:E86CC7E* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ + OUI:E86CDA* + ID_OUI_FROM_DATABASE=Supercomputers and Neurocomputers Research Center + +@@ -85373,33 +109142,114 @@ OUI:E86D65* + OUI:E86D6E* + ID_OUI_FROM_DATABASE=voestalpine SIGNALING Fareham Ltd. + ++OUI:E86DCB* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:E86DE9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E86E44* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:E86F38* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:E86FF2* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + + OUI:E8718D* + ID_OUI_FROM_DATABASE=Elsys Equipamentos Eletronicos Ltda + ++OUI:E874C7* ++ ID_OUI_FROM_DATABASE=Sentinhealth ++ + OUI:E874E6* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + + OUI:E8757F* + ID_OUI_FROM_DATABASE=FIRS Technologies(Shenzhen) Co., Ltd + ++OUI:E878290* ++ ID_OUI_FROM_DATABASE=Tanz Security Technology Ltd. ++ ++OUI:E878291* ++ ID_OUI_FROM_DATABASE=Shenzhen Jointelli Technologies Co.,Ltd ++ ++OUI:E878292* ++ ID_OUI_FROM_DATABASE=Galcon ++ ++OUI:E878293* ++ ID_OUI_FROM_DATABASE=Electronic Controlled Systems, Inc. ++ ++OUI:E878294* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:E878295* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN SKYSI WISDOM TECHNOLOGY CO.,LTD. ++ ++OUI:E878296* ++ ID_OUI_FROM_DATABASE=AXING AG ++ ++OUI:E878297* ++ ID_OUI_FROM_DATABASE=FAIOT Co., LTD ++ ++OUI:E878298* ++ ID_OUI_FROM_DATABASE=JVISMall CO.,LTD ++ ++OUI:E878299* ++ ID_OUI_FROM_DATABASE=Ryu Tech. LTD ++ ++OUI:E87829A* ++ ID_OUI_FROM_DATABASE=METZ CONNECT GmbH ++ ++OUI:E87829B* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:E87829C* ++ ID_OUI_FROM_DATABASE=FairPhone B.V. ++ ++OUI:E87829D* ++ ID_OUI_FROM_DATABASE=Bernd Walter Computer Technology ++ ++OUI:E87829E* ++ ID_OUI_FROM_DATABASE=Solos Technology Limited ++ ++OUI:E87865* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E878A1* + ID_OUI_FROM_DATABASE=BEOVIEW INTERCOM DOO + + OUI:E87AF3* + ID_OUI_FROM_DATABASE=S5 Tech S.r.l. + ++OUI:E87F6B* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:E87F95* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E8802E* + ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:E880D8* + ID_OUI_FROM_DATABASE=GNTEK Electronics Co.,Ltd. + ++OUI:E88152* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E8825B* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E884A5* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:E884C6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E8854B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E887A3* + ID_OUI_FROM_DATABASE=Loxley Public Company Limited + +@@ -85418,6 +109268,9 @@ OUI:E88DF5* + OUI:E88E60* + ID_OUI_FROM_DATABASE=NSD Corporation + ++OUI:E8910F* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:E89120* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -85430,18 +109283,27 @@ OUI:E892A4* + OUI:E89309* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:E89363* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:E8944C* + ID_OUI_FROM_DATABASE=Cogent Healthcare Systems Ltd + + OUI:E894F6* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:E89526* ++ ID_OUI_FROM_DATABASE=Luxshare Precision Industry CO., LTD. ++ + OUI:E89606* + ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd. + + OUI:E8986D* + ID_OUI_FROM_DATABASE=Palo Alto Networks + ++OUI:E898C2* ++ ID_OUI_FROM_DATABASE=ZETLAB Company ++ + OUI:E8995A* + ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB + +@@ -85449,7 +109311,7 @@ OUI:E899C4* + ID_OUI_FROM_DATABASE=HTC Corporation + + OUI:E89A8F* +- ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. ++ ID_OUI_FROM_DATABASE=Quanta Computer Inc. + + OUI:E89AFF* + ID_OUI_FROM_DATABASE=Fujian LANDI Commercial Equipment Co.,Ltd +@@ -85458,19 +109320,43 @@ OUI:E89D87* + ID_OUI_FROM_DATABASE=Toshiba + + OUI:E89E0C* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=MAX8USA DISTRIBUTORS INC. + + OUI:E89EB4* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:E89F39* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:E89F80* ++ ID_OUI_FROM_DATABASE=Belkin International Inc. ++ + OUI:E89FEC* + ID_OUI_FROM_DATABASE=CHENGDU KT ELECTRONIC HI-TECH CO.,LTD + ++OUI:E8A0CD* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ ++OUI:E8A1F8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:E8A245* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:E8A364* + ID_OUI_FROM_DATABASE=Signal Path International / Peachtree Audio + + OUI:E8A4C1* +- ID_OUI_FROM_DATABASE=Deep Sea Electronics PLC ++ ID_OUI_FROM_DATABASE=Deep Sea Electronics Ltd ++ ++OUI:E8A660* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:E8A6CA* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:E8A730* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:E8A788* + ID_OUI_FROM_DATABASE=XIAMEN LEELEN TECHNOLOGY CO., LTD +@@ -85484,12 +109370,66 @@ OUI:E8ABF3* + OUI:E8ABFA* + ID_OUI_FROM_DATABASE=Shenzhen Reecam Tech.Ltd. + ++OUI:E8ACAD* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:E8ADA6* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:E8B1FC* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:E8B2AC* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:E8B2FE* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ ++OUI:E8B4700* ++ ID_OUI_FROM_DATABASE=DongGuan Ramaxel Memory Technology ++ ++OUI:E8B4701* ++ ID_OUI_FROM_DATABASE=Autocom Diagnostic Partner AB ++ ++OUI:E8B4702* ++ ID_OUI_FROM_DATABASE=internet domain name system beijing engineering research center ltd ++ ++OUI:E8B4703* ++ ID_OUI_FROM_DATABASE=Webfleet Solutions B.V. ++ ++OUI:E8B4704* ++ ID_OUI_FROM_DATABASE=YAWATA ELECTRIC INDUSTRIAL CO.,LTD. ++ ++OUI:E8B4705* ++ ID_OUI_FROM_DATABASE=Alperia Fiber srl ++ ++OUI:E8B4706* ++ ID_OUI_FROM_DATABASE=Elcoma ++ ++OUI:E8B4707* ++ ID_OUI_FROM_DATABASE=Tibit Communications ++ ++OUI:E8B4708* ++ ID_OUI_FROM_DATABASE=DEHN SE + Co KG ++ ++OUI:E8B4709* ++ ID_OUI_FROM_DATABASE=Miltek Industries Pte Ltd ++ ++OUI:E8B470A* ++ ID_OUI_FROM_DATABASE=plc2 Design GmbH ++ ++OUI:E8B470B* ++ ID_OUI_FROM_DATABASE=Digifocus Technology Inc. ++ ++OUI:E8B470C* ++ ID_OUI_FROM_DATABASE=Anduril Industries ++ ++OUI:E8B470D* ++ ID_OUI_FROM_DATABASE=Medica Corporation ++ ++OUI:E8B470E* ++ ID_OUI_FROM_DATABASE=UNICACCES GROUPE ++ + OUI:E8B4AE* + ID_OUI_FROM_DATABASE=Shenzhen C&D Electronics Co.,Ltd + +@@ -85526,11 +109466,20 @@ OUI:E8C1B8* + OUI:E8C1D7* + ID_OUI_FROM_DATABASE=Philips + ++OUI:E8C1E8* ++ ID_OUI_FROM_DATABASE=Shenzhen Xiao Bi En Culture Education Technology Co.,Ltd. ++ + OUI:E8C229* + ID_OUI_FROM_DATABASE=H-Displays (MSC) Bhd + ++OUI:E8C2DD* ++ ID_OUI_FROM_DATABASE=Infinix mobility limited ++ + OUI:E8C320* +- ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd ++ ID_OUI_FROM_DATABASE=Austco Marketing & Service (USA) ltd. ++ ++OUI:E8C417* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + + OUI:E8C57A* + ID_OUI_FROM_DATABASE=Ufispace Co., LTD. +@@ -85553,30 +109502,57 @@ OUI:E8CD2D* + OUI:E8CE06* + ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC. + ++OUI:E8D03C* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ + OUI:E8D099* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:E8D0B9* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:E8D0FA* + ID_OUI_FROM_DATABASE=MKS Instruments Deutschland GmbH + ++OUI:E8D0FC* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:E8D11B* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + ++OUI:E8D2FF* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:E8D483* + ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH + + OUI:E8D4E0* + ID_OUI_FROM_DATABASE=Beijing BenyWave Technology Co., Ltd. + ++OUI:E8D765* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E8D819* + ID_OUI_FROM_DATABASE=AzureWave Technology Inc. + ++OUI:E8D8D1* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ ++OUI:E8DA00* ++ ID_OUI_FROM_DATABASE=Kivo Technology, Inc. ++ ++OUI:E8DA20* ++ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd ++ + OUI:E8DA96* + ID_OUI_FROM_DATABASE=Zhuhai Tianrui Electrical Power Tech. Co., Ltd. + + OUI:E8DAAA* + ID_OUI_FROM_DATABASE=VideoHome Technology Corp. + ++OUI:E8DB84* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:E8DE00* + ID_OUI_FROM_DATABASE=ChongQing GuanFang Technology Co.,LTD + +@@ -85625,6 +109601,15 @@ OUI:E8E776* + OUI:E8E875* + ID_OUI_FROM_DATABASE=iS5 Communications Inc. + ++OUI:E8E8B7* ++ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. ++ ++OUI:E8E98E* ++ ID_OUI_FROM_DATABASE=SOLAR controls s.r.o. ++ ++OUI:E8EA4D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E8EA6A* + ID_OUI_FROM_DATABASE=StarTech.com + +@@ -85634,9 +109619,21 @@ OUI:E8EADA* + OUI:E8EB11* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:E8EB1B* ++ ID_OUI_FROM_DATABASE=Microchip Technology Inc. ++ ++OUI:E8EB34* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:E8ECA3* ++ ID_OUI_FROM_DATABASE=Dongguan Liesheng Electronic Co.Ltd ++ + OUI:E8ED05* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:E8EDD6* ++ ID_OUI_FROM_DATABASE=Fortinet, Inc. ++ + OUI:E8EDF3* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -85655,6 +109652,12 @@ OUI:E8F2E2* + OUI:E8F2E3* + ID_OUI_FROM_DATABASE=Starcor Beijing Co.,Limited + ++OUI:E8F408* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:E8F654* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:E8F724* + ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise + +@@ -85664,12 +109667,18 @@ OUI:E8F928* + OUI:E8FAF7* + ID_OUI_FROM_DATABASE=Guangdong Uniteddata Holding Group Co., Ltd. + ++OUI:E8FBE9* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:E8FC60* + ID_OUI_FROM_DATABASE=ELCOM Innovations Private Limited + + OUI:E8FCAF* + ID_OUI_FROM_DATABASE=NETGEAR + ++OUI:E8FD35* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:E8FD72* + ID_OUI_FROM_DATABASE=SHANGHAI LINGUO TECHNOLOGY CO., LTD. + +@@ -85688,15 +109697,27 @@ OUI:EC01E2* + OUI:EC01EE* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD + ++OUI:EC0273* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:EC0441* + ID_OUI_FROM_DATABASE=ShenZhen TIGO Semiconductor Co., Ltd. + + OUI:EC086B* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:EC08E5* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ ++OUI:EC0BAE* ++ ID_OUI_FROM_DATABASE=Hangzhou BroadLink Technology Co.,Ltd ++ + OUI:EC0D9A* + ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. + ++OUI:EC0DE4* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:EC0EC4* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -85721,6 +109742,9 @@ OUI:EC13DB* + OUI:EC14F6* + ID_OUI_FROM_DATABASE=BioControl AS + ++OUI:EC153D* ++ ID_OUI_FROM_DATABASE=Beijing Yaxunhongda Technology Co., Ltd. ++ + OUI:EC172F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -85730,6 +109754,12 @@ OUI:EC1766* + OUI:EC1A59* + ID_OUI_FROM_DATABASE=Belkin International Inc. + ++OUI:EC1BBD* ++ ID_OUI_FROM_DATABASE=Silicon Laboratories ++ ++OUI:EC1C5D* ++ ID_OUI_FROM_DATABASE=Siemens AG ++ + OUI:EC1D7F* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -85763,6 +109793,9 @@ OUI:EC237B* + OUI:EC24B8* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:EC2651* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:EC26CA* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +@@ -85775,12 +109808,24 @@ OUI:EC2AF0* + OUI:EC2C49* + ID_OUI_FROM_DATABASE=University of Tokyo + ++OUI:EC2CE2* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:EC2E4E* + ID_OUI_FROM_DATABASE=HITACHI-LG DATA STORAGE INC + ++OUI:EC2E98* ++ ID_OUI_FROM_DATABASE=AzureWave Technology Inc. ++ + OUI:EC3091* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:EC316D* ++ ID_OUI_FROM_DATABASE=Hansgrohe ++ ++OUI:EC354D* ++ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd ++ + OUI:EC3586* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -85802,18 +109847,27 @@ OUI:EC3C5A* + OUI:EC3C88* + ID_OUI_FROM_DATABASE=MCNEX Co.,Ltd. + ++OUI:EC3CBB* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:EC3DFD* + ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD + + OUI:EC3E09* + ID_OUI_FROM_DATABASE=PERFORMANCE DESIGNED PRODUCTS, LLC + ++OUI:EC3EB3* ++ ID_OUI_FROM_DATABASE=Zyxel Communications Corporation ++ + OUI:EC3EF7* + ID_OUI_FROM_DATABASE=Juniper Networks + + OUI:EC3F05* + ID_OUI_FROM_DATABASE=Institute 706, The Second Academy China Aerospace Science & Industry Corp + ++OUI:EC4118* ++ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD ++ + OUI:EC42B4* + ID_OUI_FROM_DATABASE=ADC Corporation + +@@ -85847,6 +109901,9 @@ OUI:EC4993* + OUI:EC4C4D* + ID_OUI_FROM_DATABASE=ZAO NPK RoTeK + ++OUI:EC4D3E* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Mobile Software Co., Ltd ++ + OUI:EC4D47* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -85865,6 +109922,12 @@ OUI:EC542E* + OUI:EC55F9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:EC5623* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:EC570D* ++ ID_OUI_FROM_DATABASE=AFE Inc. ++ + OUI:EC58EA* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +@@ -85874,6 +109937,12 @@ OUI:EC59E7* + OUI:EC5A86* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd + ++OUI:EC5B73* ++ ID_OUI_FROM_DATABASE=Advanced & Wise Technology Corp. ++ ++OUI:EC5C68* ++ ID_OUI_FROM_DATABASE=CHONGQING FUGUI ELECTRONICS CO.,LTD. ++ + OUI:EC5C69* + ID_OUI_FROM_DATABASE=MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD. + +@@ -85886,9 +109955,18 @@ OUI:EC60E0* + OUI:EC6264* + ID_OUI_FROM_DATABASE=Global411 Internet Services, LLC + ++OUI:EC63D7* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:EC63E5* + ID_OUI_FROM_DATABASE=ePBoard Design LLC + ++OUI:EC63ED* ++ ID_OUI_FROM_DATABASE=Hyundai Autoever Corp. ++ ++OUI:EC6488* ++ ID_OUI_FROM_DATABASE=Honor Device Co., Ltd. ++ + OUI:EC64E7* + ID_OUI_FROM_DATABASE=MOCACARE Corporation + +@@ -85901,9 +109979,15 @@ OUI:EC66D1* + OUI:EC6881* + ID_OUI_FROM_DATABASE=Palo Alto Networks + ++OUI:EC6C9A* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:EC6C9F* + ID_OUI_FROM_DATABASE=Chengdu Volans Technology CO.,LTD + ++OUI:EC6CB5* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:EC6F0B* + ID_OUI_FROM_DATABASE=FADU, Inc. + +@@ -85916,17 +110000,35 @@ OUI:EC71DB* + OUI:EC74BA* + ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH + ++OUI:EC753E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:EC75ED* ++ ID_OUI_FROM_DATABASE=Citrix Systems, Inc. ++ ++OUI:EC7949* ++ ID_OUI_FROM_DATABASE=FUJITSU LIMITED ++ + OUI:EC79F2* + ID_OUI_FROM_DATABASE=Startel + ++OUI:EC7C2C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:EC7C74* + ID_OUI_FROM_DATABASE=Justone Technologies Co., Ltd. + ++OUI:EC7CB6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:EC7D11* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:EC7D9D* +- ID_OUI_FROM_DATABASE=MEI ++ ID_OUI_FROM_DATABASE=CPI ++ ++OUI:EC7E91* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + + OUI:EC7FC6* + ID_OUI_FROM_DATABASE=ECCEL CORPORATION SAS +@@ -85937,6 +110039,9 @@ OUI:EC8009* + OUI:EC8193* + ID_OUI_FROM_DATABASE=Logitech, Inc + ++OUI:EC8263* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:EC8350* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +@@ -85967,6 +110072,9 @@ OUI:EC89F5* + OUI:EC8A4C* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:EC8AC4* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:EC8AC7* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +@@ -85994,12 +110102,30 @@ OUI:EC9327* + OUI:EC9365* + ID_OUI_FROM_DATABASE=Mapper.ai, Inc. + ++OUI:EC937D* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:EC93ED* + ID_OUI_FROM_DATABASE=DDoS-Guard LTD + ++OUI:EC9468* ++ ID_OUI_FROM_DATABASE=META SYSTEM SPA ++ ++OUI:EC94CB* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ ++OUI:EC94D5* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:EC9681* + ID_OUI_FROM_DATABASE=2276427 Ontario Inc + ++OUI:EC97B2* ++ ID_OUI_FROM_DATABASE=SUMEC Machinery & Electric Co.,Ltd. ++ ++OUI:EC97E0* ++ ID_OUI_FROM_DATABASE=Hangzhou Ezviz Software Co.,Ltd. ++ + OUI:EC986C* + ID_OUI_FROM_DATABASE=Lufft Mess- und Regeltechnik GmbH + +@@ -86018,6 +110144,9 @@ OUI:EC9B8B* + OUI:EC9BF3* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + ++OUI:EC9C32* ++ ID_OUI_FROM_DATABASE=Sichuan AI-Link Technology Co., Ltd. ++ + OUI:EC9ECD* + ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies + +@@ -86066,14 +110195,29 @@ OUI:EC9F0DD* + OUI:EC9F0DE* + ID_OUI_FROM_DATABASE=MAX Technologies + ++OUI:ECA1D1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:ECA29B* + ID_OUI_FROM_DATABASE=Kemppi Oy + ++OUI:ECA5DE* ++ ID_OUI_FROM_DATABASE=ONYX WIFI Inc ++ ++OUI:ECA81F* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:ECA86B* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co.,Ltd. + ++OUI:ECA940* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:ECA9FA* +- ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO.,LTD. ++ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO., LTD. ++ ++OUI:ECAA25* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:ECAAA0* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION +@@ -86081,6 +110225,9 @@ OUI:ECAAA0* + OUI:ECADB8* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:ECADE0* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:ECAF97* + ID_OUI_FROM_DATABASE=GIT + +@@ -86096,6 +110243,9 @@ OUI:ECB1D7* + OUI:ECB313* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:ECB4E8* ++ ID_OUI_FROM_DATABASE=Wistron Mexico SA de CV ++ + OUI:ECB541* + ID_OUI_FROM_DATABASE=SHINANO E and E Co.Ltd. + +@@ -86108,6 +110258,9 @@ OUI:ECB870* + OUI:ECB907* + ID_OUI_FROM_DATABASE=CloudGenix Inc + ++OUI:ECB970* ++ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD ++ + OUI:ECBAFE* + ID_OUI_FROM_DATABASE=GIROPTIC + +@@ -86120,24 +110273,54 @@ OUI:ECBD09* + OUI:ECBD1D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:ECBE5F* ++ ID_OUI_FROM_DATABASE=Vestel Elektronik San ve Tic. A.Ş. ++ ++OUI:ECBEDD* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ ++OUI:ECC01B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:ECC06A* + ID_OUI_FROM_DATABASE=PowerChord Group Limited + ++OUI:ECC1AB* ++ ID_OUI_FROM_DATABASE=Guangzhou Shiyuan Electronic Technology Company Limited ++ ++OUI:ECC302* ++ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. ++ + OUI:ECC38A* + ID_OUI_FROM_DATABASE=Accuenergy (CANADA) Inc + + OUI:ECC40D* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd + ++OUI:ECC57F* ++ ID_OUI_FROM_DATABASE=Suzhou Pairlink Network Technology ++ ++OUI:ECC5D2* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:ECC882* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:ECC89C* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ + OUI:ECCB30* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:ECCD6D* + ID_OUI_FROM_DATABASE=Allied Telesis, Inc. + ++OUI:ECCE13* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:ECCED7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:ECD00E* + ID_OUI_FROM_DATABASE=MiraeRecognition Co., Ltd. + +@@ -86162,6 +110345,9 @@ OUI:ECD950* + OUI:ECD9D1* + ID_OUI_FROM_DATABASE=Shenzhen TG-NET Botone Technology Co.,Ltd. + ++OUI:ECDB86* ++ ID_OUI_FROM_DATABASE=API-K ++ + OUI:ECDE3D* + ID_OUI_FROM_DATABASE=Lamprey Networks, Inc. + +@@ -86210,6 +110396,12 @@ OUI:ECEED8* + OUI:ECF00E* + ID_OUI_FROM_DATABASE=AboCom + ++OUI:ECF0FE* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:ECF22B* ++ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED ++ + OUI:ECF236* + ID_OUI_FROM_DATABASE=NEOMONTANA ELECTRONICS + +@@ -86219,21 +110411,30 @@ OUI:ECF342* + OUI:ECF35B* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:ECF40C* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:ECF451* + ID_OUI_FROM_DATABASE=Arcadyan Corporation + + OUI:ECF4BB* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:ECF6BD* ++ ID_OUI_FROM_DATABASE=SNCF MOBILITÉS ++ + OUI:ECF72B* + ID_OUI_FROM_DATABASE=HD DIGITAL TECH CO., LTD. + + OUI:ECF8EB* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:ECFA03* + ID_OUI_FROM_DATABASE=FCA + ++OUI:ECFA5C* ++ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronics Co., Ltd. ++ + OUI:ECFAAA* + ID_OUI_FROM_DATABASE=The IMS Company + +@@ -86252,6 +110453,9 @@ OUI:ECFE7E* + OUI:F0007F* + ID_OUI_FROM_DATABASE=Janz - Contadores de Energia, SA + ++OUI:F0016E* ++ ID_OUI_FROM_DATABASE=Tianyi Telecom Terminals Company Limited ++ + OUI:F0022B* + ID_OUI_FROM_DATABASE=Chrontel + +@@ -86264,18 +110468,36 @@ OUI:F0038C* + OUI:F00786* + ID_OUI_FROM_DATABASE=Shandong Bittel Electronics Co., Ltd + ++OUI:F008D1* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:F008F1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:F00D5C* + ID_OUI_FROM_DATABASE=JinQianMao Technology Co.,Ltd. + ++OUI:F00DF5* ++ ID_OUI_FROM_DATABASE=ACOMA Medical Industry Co,. Ltd. ++ + OUI:F00E1D* + ID_OUI_FROM_DATABASE=Megafone Limited + ++OUI:F00EBF* ++ ID_OUI_FROM_DATABASE=ZettaHash Inc. ++ + OUI:F00FEC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F01090* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ ++OUI:F010AB* ++ ID_OUI_FROM_DATABASE=China Mobile (Hangzhou) Information Technology Co., Ltd. ++ ++OUI:F013C1* ++ ID_OUI_FROM_DATABASE=Hannto Technology Co., Ltd ++ + OUI:F013C3* + ID_OUI_FROM_DATABASE=SHENZHEN FENDA TECHNOLOGY CO., LTD + +@@ -86285,6 +110507,9 @@ OUI:F015A0* + OUI:F015B9* + ID_OUI_FROM_DATABASE=PlayFusion Limited + ++OUI:F01628* ++ ID_OUI_FROM_DATABASE=Technicolor (China) Technology Co., Ltd. ++ + OUI:F0182B* + ID_OUI_FROM_DATABASE=LG Chem + +@@ -86300,6 +110525,9 @@ OUI:F01C13* + OUI:F01C2D* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:F01D2D* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:F01DBC* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +@@ -86312,12 +110540,18 @@ OUI:F01FAF* + OUI:F0219D* + ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd. + ++OUI:F021E0* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:F0224E* + ID_OUI_FROM_DATABASE=Esan electronic co. + + OUI:F02329* + ID_OUI_FROM_DATABASE=SHOWA DENKI CO.,LTD. + ++OUI:F023AE* ++ ID_OUI_FROM_DATABASE=AMPAK Technology,Inc. ++ + OUI:F023B90* + ID_OUI_FROM_DATABASE=Aquametro AG + +@@ -86349,7 +110583,7 @@ OUI:F023B99* + ID_OUI_FROM_DATABASE=Emu Technology + + OUI:F023B9A* +- ID_OUI_FROM_DATABASE=annapurnalabs ++ ID_OUI_FROM_DATABASE=Annapurna labs + + OUI:F023B9B* + ID_OUI_FROM_DATABASE=Q Core Medical Ltd +@@ -86358,7 +110592,7 @@ OUI:F023B9C* + ID_OUI_FROM_DATABASE=Shenzhen Lachesis Mhealth Co., Ltd. + + OUI:F023B9D* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Shenyang Ali Technology Company Limited + + OUI:F023B9E* + ID_OUI_FROM_DATABASE=Domotz Ltd +@@ -86375,6 +110609,9 @@ OUI:F02475* + OUI:F02572* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F0258E* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F025B7* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) + +@@ -86382,7 +110619,7 @@ OUI:F02624* + ID_OUI_FROM_DATABASE=WAFA TECHNOLOGIES CO., LTD. + + OUI:F0264C* +- ID_OUI_FROM_DATABASE=Dr. Sigrist AG ++ ID_OUI_FROM_DATABASE=Sigrist-Photometer AG + + OUI:F0272D* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. +@@ -86399,9 +110636,63 @@ OUI:F02929* + OUI:F02A23* + ID_OUI_FROM_DATABASE=Creative Next Design + ++OUI:F02A2B0* ++ ID_OUI_FROM_DATABASE=Merlin Security Inc. ++ ++OUI:F02A2B1* ++ ID_OUI_FROM_DATABASE=Tobi Tribe Inc. ++ ++OUI:F02A2B2* ++ ID_OUI_FROM_DATABASE=Shanghai Armour Technology Co., Ltd. ++ ++OUI:F02A2B3* ++ ID_OUI_FROM_DATABASE=Frigotel SRL ++ ++OUI:F02A2B4* ++ ID_OUI_FROM_DATABASE=Onclave Networks ++ ++OUI:F02A2B5* ++ ID_OUI_FROM_DATABASE=Agile Sports Technologies, dba Hudl ++ ++OUI:F02A2B6* ++ ID_OUI_FROM_DATABASE=Shenzhen ORVIBO Technology Co., Ltd. ++ ++OUI:F02A2B7* ++ ID_OUI_FROM_DATABASE=Protronix s.r.o. ++ ++OUI:F02A2B8* ++ ID_OUI_FROM_DATABASE=Tenways Engineering Service Ltd ++ ++OUI:F02A2B9* ++ ID_OUI_FROM_DATABASE=ZiGong Pengcheng Technology Co.,Ltd ++ ++OUI:F02A2BA* ++ ID_OUI_FROM_DATABASE=Navigil Ltd ++ ++OUI:F02A2BB* ++ ID_OUI_FROM_DATABASE=EL.MO. spa ++ ++OUI:F02A2BC* ++ ID_OUI_FROM_DATABASE=Comexio GmbH ++ ++OUI:F02A2BD* ++ ID_OUI_FROM_DATABASE=Definitely Win Corp.,Ltd. ++ ++OUI:F02A2BE* ++ ID_OUI_FROM_DATABASE=Shenzhen CUCO Technology Co., Ltd ++ + OUI:F02A61* + ID_OUI_FROM_DATABASE=Waldo Networks, Inc. + ++OUI:F02E51* ++ ID_OUI_FROM_DATABASE=Casa Systems ++ ++OUI:F02F4B* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F02F74* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:F02FA7* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -86411,12 +110702,18 @@ OUI:F02FD8* + OUI:F0321A* + ID_OUI_FROM_DATABASE=Mita-Teknik A/S + ++OUI:F033E5* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F03404* + ID_OUI_FROM_DATABASE=TCT mobile ltd + + OUI:F037A1* + ID_OUI_FROM_DATABASE=Huike Electronics (SHENZHEN) CO., LTD. + ++OUI:F03965* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F03A4B* + ID_OUI_FROM_DATABASE=Bloombase, Inc. + +@@ -86435,12 +110732,18 @@ OUI:F03E90* + OUI:F03EBF* + ID_OUI_FROM_DATABASE=GOGORO TAIWAN LIMITED + ++OUI:F03F95* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F03FF8* + ID_OUI_FROM_DATABASE=R L Drake + + OUI:F0407B* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:F041C6* ++ ID_OUI_FROM_DATABASE=Heat Tech Company, Ltd. ++ + OUI:F041C80* + ID_OUI_FROM_DATABASE=LINPA ACOUSTIC TECHNOLOGY CO.,LTD + +@@ -86489,6 +110792,9 @@ OUI:F041C8E* + OUI:F0421C* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:F042F5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F04335* + ID_OUI_FROM_DATABASE=DVN(Shanghai)Ltd. + +@@ -86498,6 +110804,12 @@ OUI:F04347* + OUI:F045DA* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:F0463B* ++ ID_OUI_FROM_DATABASE=Comcast Cable Corporation ++ ++OUI:F04A02* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:F04A2B* + ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH + +@@ -86517,7 +110829,22 @@ OUI:F04DA2* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:F04F7C* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:F05136* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ ++OUI:F051EA* ++ ID_OUI_FROM_DATABASE=Fitbit, Inc. ++ ++OUI:F05494* ++ ID_OUI_FROM_DATABASE=Honeywell Connected Building ++ ++OUI:F05501* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F057A6* ++ ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:F05849* + ID_OUI_FROM_DATABASE=CareView Communications +@@ -86529,7 +110856,13 @@ OUI:F05B7B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:F05C19* +- ID_OUI_FROM_DATABASE=Aruba Networks ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:F05C77* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ ++OUI:F05CD5* ++ ID_OUI_FROM_DATABASE=Apple, Inc. + + OUI:F05D89* + ID_OUI_FROM_DATABASE=Dycon Limited +@@ -86537,6 +110870,9 @@ OUI:F05D89* + OUI:F05DC8* + ID_OUI_FROM_DATABASE=Duracell Powermat + ++OUI:F05ECD* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:F05F5A* + ID_OUI_FROM_DATABASE=Getriebebau NORD GmbH and Co. KG + +@@ -86546,18 +110882,33 @@ OUI:F06130* + OUI:F0620D* + ID_OUI_FROM_DATABASE=Shenzhen Egreat Tech Corp.,Ltd + ++OUI:F0625A* ++ ID_OUI_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp.,Ltd. ++ + OUI:F06281* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + ++OUI:F063F9* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:F06426* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ + OUI:F065C2* + ID_OUI_FROM_DATABASE=Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd. + + OUI:F065DD* + ID_OUI_FROM_DATABASE=Primax Electronics Ltd. + ++OUI:F06728* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:F06853* + ID_OUI_FROM_DATABASE=Integrated Corporation + ++OUI:F06865* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:F06BCA* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -86570,9 +110921,15 @@ OUI:F06E0B* + OUI:F06E32* + ID_OUI_FROM_DATABASE=MICROTEL INNOVATION S.R.L. + ++OUI:F06F46* ++ ID_OUI_FROM_DATABASE=Ubiik ++ + OUI:F0728C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F072EA* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:F073AE* + ID_OUI_FROM_DATABASE=PEAK-System Technik + +@@ -86591,9 +110948,15 @@ OUI:F0766F* + OUI:F07765* + ID_OUI_FROM_DATABASE=Sourcefire, Inc + ++OUI:F077C3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F077D0* + ID_OUI_FROM_DATABASE=Xcellen + ++OUI:F07807* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F07816* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -86609,6 +110972,9 @@ OUI:F079E8* + OUI:F07BCB* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:F07CC7* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:F07D68* + ID_OUI_FROM_DATABASE=D-Link Corporation + +@@ -86621,6 +110987,9 @@ OUI:F07F0C* + OUI:F08173* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:F08175* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:F081AF* + ID_OUI_FROM_DATABASE=IRZ AUTOMATION TECHNOLOGIES LTD + +@@ -86636,9 +111005,15 @@ OUI:F084C9* + OUI:F085C1* + ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. + ++OUI:F08620* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:F08A28* + ID_OUI_FROM_DATABASE=JIANGSU HENGSION ELECTRONIC S and T CO.,LTD + ++OUI:F08A76* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F08BFE* + ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD + +@@ -86652,7 +111027,7 @@ OUI:F0921C* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:F092B4* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD + + OUI:F0933A* + ID_OUI_FROM_DATABASE=NxtConect +@@ -86660,6 +111035,9 @@ OUI:F0933A* + OUI:F093C5* + ID_OUI_FROM_DATABASE=Garland Technology + ++OUI:F095F1* ++ ID_OUI_FROM_DATABASE=Carl Zeiss AG ++ + OUI:F097E5* + ID_OUI_FROM_DATABASE=TAMIO, INC + +@@ -86669,6 +111047,9 @@ OUI:F09838* + OUI:F0989D* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F09919* ++ ID_OUI_FROM_DATABASE=Garmin International ++ + OUI:F099B6* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -86678,6 +111059,9 @@ OUI:F099BF* + OUI:F09A51* + ID_OUI_FROM_DATABASE=Shanghai Viroyal Electronic Technology Company Limited + ++OUI:F09BB8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F09CBB* + ID_OUI_FROM_DATABASE=RaonThink Inc. + +@@ -86685,7 +111069,10 @@ OUI:F09CD7* + ID_OUI_FROM_DATABASE=Guangzhou Blue Cheetah Intelligent Technology Co., Ltd. + + OUI:F09CE9* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:F09E4A* ++ ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:F09E63* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc +@@ -86697,11 +111084,26 @@ OUI:F09FFC* + ID_OUI_FROM_DATABASE=SHARP Corporation + + OUI:F0A225* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:F0A35A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F0A3B2* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD + + OUI:F0A764* + ID_OUI_FROM_DATABASE=GST Co., Ltd. + ++OUI:F0A7B2* ++ ID_OUI_FROM_DATABASE=FUTABA CORPORATION ++ ++OUI:F0A968* ++ ID_OUI_FROM_DATABASE=Antailiye Technology Co.,Ltd ++ ++OUI:F0AA0B* ++ ID_OUI_FROM_DATABASE=Arra Networks/ Spectramesh ++ + OUI:F0AB54* + ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD. + +@@ -86762,33 +111164,63 @@ OUI:F0AE51* + OUI:F0AF50* + ID_OUI_FROM_DATABASE=Phantom Intelligence + ++OUI:F0AF85* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:F0B014* + ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH + ++OUI:F0B022* ++ ID_OUI_FROM_DATABASE=TOHO Electronics INC. ++ + OUI:F0B052* + ID_OUI_FROM_DATABASE=Ruckus Wireless + + OUI:F0B0E7* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F0B107* ++ ID_OUI_FROM_DATABASE=Ericsson AB ++ ++OUI:F0B11D* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:F0B13F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F0B2E5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F0B31E* ++ ID_OUI_FROM_DATABASE=Universal Electronics, Inc. ++ ++OUI:F0B3EC* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F0B429* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:F0B479* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F0B4D2* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:F0B5B7* + ID_OUI_FROM_DATABASE=Disruptive Technologies Research AS + + OUI:F0B5D1* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:F0B61E* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F0B6EB* + ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd. + ++OUI:F0B968* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:F0BCC8* + ID_OUI_FROM_DATABASE=MaxID (Pty) Ltd + +@@ -86813,9 +111245,21 @@ OUI:F0C24C* + OUI:F0C27C* + ID_OUI_FROM_DATABASE=Mianyang Netop Telecom Equipment Co.,Ltd. + ++OUI:F0C371* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F0C42F* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F0C478* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F0C77F* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:F0C814* ++ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD ++ + OUI:F0C850* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -86828,6 +111272,9 @@ OUI:F0C9D1* + OUI:F0CBA1* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F0D08C* ++ ID_OUI_FROM_DATABASE=TCT mobile ltd ++ + OUI:F0D14F* + ID_OUI_FROM_DATABASE=LINEAR LLC + +@@ -86846,9 +111293,15 @@ OUI:F0D3A7* + OUI:F0D3E7* + ID_OUI_FROM_DATABASE=Sensometrix SA + ++OUI:F0D4E2* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:F0D4F6* + ID_OUI_FROM_DATABASE=Lars Thrane A/S + ++OUI:F0D4F7* ++ ID_OUI_FROM_DATABASE=varram system ++ + OUI:F0D5BF* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -86861,6 +111314,51 @@ OUI:F0D767* + OUI:F0D7AA* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:F0D7AF0* ++ ID_OUI_FROM_DATABASE=ID Tech Japan Co.,Ltd. ++ ++OUI:F0D7AF1* ++ ID_OUI_FROM_DATABASE=Beijing Serviatech lnformation Tech Co.,Ltd ++ ++OUI:F0D7AF2* ++ ID_OUI_FROM_DATABASE=Blacknight Internet Solutions Limited ++ ++OUI:F0D7AF3* ++ ID_OUI_FROM_DATABASE=720?bei jing?Health iTech Co.,Ltd ++ ++OUI:F0D7AF4* ++ ID_OUI_FROM_DATABASE=ADAM Audio GmbH ++ ++OUI:F0D7AF5* ++ ID_OUI_FROM_DATABASE=Dongguan Huili electroacoustic Industrial Co.,ltd ++ ++OUI:F0D7AF6* ++ ID_OUI_FROM_DATABASE=Anord Mardix (USA) Inc. ++ ++OUI:F0D7AF7* ++ ID_OUI_FROM_DATABASE=Rievtech Electronic Co.,Ltd ++ ++OUI:F0D7AF8* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN MICHIP TECHNOLOGIES CO.,LTD. ++ ++OUI:F0D7AF9* ++ ID_OUI_FROM_DATABASE=New IT Project LLC ++ ++OUI:F0D7AFA* ++ ID_OUI_FROM_DATABASE=MSTAR TECHNOLOGIES,INC ++ ++OUI:F0D7AFB* ++ ID_OUI_FROM_DATABASE=EVCO SPA ++ ++OUI:F0D7AFC* ++ ID_OUI_FROM_DATABASE=Shenzhen Virtual Clusters Information Technology Co.,Ltd. ++ ++OUI:F0D7AFD* ++ ID_OUI_FROM_DATABASE=Dongguan Gedi Electrons Techeology Co.,LTD ++ ++OUI:F0D7AFE* ++ ID_OUI_FROM_DATABASE=Wren Associates, LTD ++ + OUI:F0D7DC* + ID_OUI_FROM_DATABASE=Wesine (Wuhan) Technology Co., Ltd. + +@@ -86894,6 +111392,9 @@ OUI:F0DEF1* + OUI:F0E3DC* + ID_OUI_FROM_DATABASE=Tecon MT, LLC + ++OUI:F0E4A2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F0E5C3* + ID_OUI_FROM_DATABASE=Drägerwerk AG & Co. KG aA + +@@ -86918,6 +111419,9 @@ OUI:F0EE58* + OUI:F0EEBB* + ID_OUI_FROM_DATABASE=VIPAR GmbH + ++OUI:F0EF86* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:F0EFD2* + ID_OUI_FROM_DATABASE=TF PAYMENT SERVICE CO., LTD + +@@ -86927,6 +111431,9 @@ OUI:F0F002* + OUI:F0F08F* + ID_OUI_FROM_DATABASE=Nextek Solutions Pte Ltd + ++OUI:F0F0A4* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:F0F249* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +@@ -86936,6 +111443,9 @@ OUI:F0F260* + OUI:F0F336* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:F0F564* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F0F5AE* + ID_OUI_FROM_DATABASE=Adaptrum Inc. + +@@ -86948,12 +111458,18 @@ OUI:F0F644* + OUI:F0F669* + ID_OUI_FROM_DATABASE=Motion Analysis Corporation + ++OUI:F0F6C1* ++ ID_OUI_FROM_DATABASE=Sonos, Inc. ++ + OUI:F0F755* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:F0F7B3* + ID_OUI_FROM_DATABASE=Phorm + ++OUI:F0F7E7* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F0F842* + ID_OUI_FROM_DATABASE=KEEBOX, Inc. + +@@ -86963,6 +111479,9 @@ OUI:F0F8F2* + OUI:F0F9F7* + ID_OUI_FROM_DATABASE=IES GmbH & Co. KG + ++OUI:F0FAC7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F0FCC8* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -86972,12 +111491,27 @@ OUI:F0FDA0* + OUI:F0FE6B* + ID_OUI_FROM_DATABASE=Shanghai High-Flying Electronics Technology Co., Ltd + ++OUI:F0FEE7* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F40223* ++ ID_OUI_FROM_DATABASE=PAX Computer Technology(Shenzhen) Ltd. ++ ++OUI:F40228* ++ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND) ++ ++OUI:F40270* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:F40304* + ID_OUI_FROM_DATABASE=Google, Inc. + + OUI:F40321* + ID_OUI_FROM_DATABASE=BeNeXt B.V. + ++OUI:F4032A* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:F4032F* + ID_OUI_FROM_DATABASE=Reduxio Systems + +@@ -86987,6 +111521,9 @@ OUI:F40343* + OUI:F4044C* + ID_OUI_FROM_DATABASE=ValenceTech Limited + ++OUI:F40616* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F40669* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -87005,6 +111542,12 @@ OUI:F40A4A* + OUI:F40B93* + ID_OUI_FROM_DATABASE=BlackBerry RTS + ++OUI:F40B9F* ++ ID_OUI_FROM_DATABASE=CIG SHANGHAI CO LTD ++ ++OUI:F40E01* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F40E110* + ID_OUI_FROM_DATABASE=realphone technology co.,ltd + +@@ -87080,9 +111623,18 @@ OUI:F415FD* + OUI:F417B8* + ID_OUI_FROM_DATABASE=AirTies Wireless Networks + ++OUI:F419E2* ++ ID_OUI_FROM_DATABASE=Volterra ++ + OUI:F41BA1* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F41C95* ++ ID_OUI_FROM_DATABASE=BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD ++ ++OUI:F41D6B* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F41E26* + ID_OUI_FROM_DATABASE=Simon-Kaloi Engineering + +@@ -87101,6 +111653,12 @@ OUI:F41FC2* + OUI:F42012* + ID_OUI_FROM_DATABASE=Cuciniale GmbH + ++OUI:F4239C* ++ ID_OUI_FROM_DATABASE=SERNET (SUZHOU) TECHNOLOGIES CORPORATION ++ ++OUI:F42679* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F42833* + ID_OUI_FROM_DATABASE=MMPC Inc. + +@@ -87113,18 +111671,36 @@ OUI:F42896* + OUI:F42981* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:F42A7D* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:F42B48* + ID_OUI_FROM_DATABASE=Ubiqam + + OUI:F42C56* + ID_OUI_FROM_DATABASE=SENOR TECH CO LTD + ++OUI:F42E7F* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ ++OUI:F4308B* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:F430B9* + ID_OUI_FROM_DATABASE=Hewlett Packard + + OUI:F431C3* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F4323D* ++ ID_OUI_FROM_DATABASE=Sichuan tianyi kanghe communications co., LTD ++ ++OUI:F43328* ++ ID_OUI_FROM_DATABASE=CIMCON Lighting Inc. ++ ++OUI:F434F0* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F436E1* + ID_OUI_FROM_DATABASE=Abilis Systems SARL + +@@ -87134,18 +111710,27 @@ OUI:F437B7* + OUI:F43814* + ID_OUI_FROM_DATABASE=Shanghai Howell Electronic Co.,Ltd + ++OUI:F43909* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:F43D80* + ID_OUI_FROM_DATABASE=FAG Industrial Services GmbH + + OUI:F43E61* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:F43E66* ++ ID_OUI_FROM_DATABASE=Bee Computing (HK) Limited ++ + OUI:F43E9D* + ID_OUI_FROM_DATABASE=Benu Networks, Inc. + + OUI:F44156* + ID_OUI_FROM_DATABASE=Arrikto Inc. + ++OUI:F4419E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F44227* + ID_OUI_FROM_DATABASE=S & S Research Inc. + +@@ -87155,9 +111740,15 @@ OUI:F4428F* + OUI:F44450* + ID_OUI_FROM_DATABASE=BND Co., Ltd. + ++OUI:F44588* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F445ED* + ID_OUI_FROM_DATABASE=Portable Innovation Technology Ltd. + ++OUI:F44637* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F44713* + ID_OUI_FROM_DATABASE=Leading Public Performance Co., Ltd. + +@@ -87167,6 +111758,9 @@ OUI:F4472A* + OUI:F44848* + ID_OUI_FROM_DATABASE=Amscreen Group Ltd + ++OUI:F44955* ++ ID_OUI_FROM_DATABASE=MIMO TECH Co., Ltd. ++ + OUI:F449EF* + ID_OUI_FROM_DATABASE=EMSTONE + +@@ -87188,15 +111782,27 @@ OUI:F44D30* + OUI:F44E05* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F44E38* ++ ID_OUI_FROM_DATABASE=Olibra LLC ++ ++OUI:F44EE3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F44EFD* + ID_OUI_FROM_DATABASE=Actions Semiconductor Co.,Ltd.(Cayman Islands) + ++OUI:F44FD3* ++ ID_OUI_FROM_DATABASE=shenzhen hemuwei technology co.,ltd ++ + OUI:F450EB* + ID_OUI_FROM_DATABASE=Telechips Inc + + OUI:F45214* + ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. + ++OUI:F45420* ++ ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO ++ + OUI:F45433* + ID_OUI_FROM_DATABASE=Rockwell Automation + +@@ -87236,6 +111842,9 @@ OUI:F45FF7* + OUI:F4600D* + ID_OUI_FROM_DATABASE=Panoptic Technology, Inc + ++OUI:F46077* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:F460E2* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + +@@ -87248,18 +111857,75 @@ OUI:F4631F* + OUI:F46349* + ID_OUI_FROM_DATABASE=Diffon Corporation + ++OUI:F463E7* ++ ID_OUI_FROM_DATABASE=Nanjing Maxon O.E. Tech. Co., LTD ++ + OUI:F4645D* + ID_OUI_FROM_DATABASE=Toshiba + ++OUI:F465A6* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F4672D* + ID_OUI_FROM_DATABASE=ShenZhen Topstar Technology Company + ++OUI:F46942* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ ++OUI:F469D50* ++ ID_OUI_FROM_DATABASE=Mossman Limited ++ ++OUI:F469D51* ++ ID_OUI_FROM_DATABASE=Junchuang (Xiamen) Automation Technology Co.,Ltd ++ ++OUI:F469D52* ++ ID_OUI_FROM_DATABASE=Pulsar Engineering srl ++ ++OUI:F469D53* ++ ID_OUI_FROM_DATABASE=ITS Co., Ltd. ++ ++OUI:F469D54* ++ ID_OUI_FROM_DATABASE=Stype CS d.o.o. ++ ++OUI:F469D55* ++ ID_OUI_FROM_DATABASE=Hefei STAROT Technology Co.,Ltd ++ ++OUI:F469D56* ++ ID_OUI_FROM_DATABASE=TianJin KCHT Information Technology Co., Ltd. ++ ++OUI:F469D57* ++ ID_OUI_FROM_DATABASE=Rosco, Inc ++ ++OUI:F469D59* ++ ID_OUI_FROM_DATABASE=Terminus (Shanghai) Technology Co.,Ltd. ++ ++OUI:F469D5A* ++ ID_OUI_FROM_DATABASE=ShenZhenShi EVADA technology Co.,Ltd ++ ++OUI:F469D5B* ++ ID_OUI_FROM_DATABASE=Konntek Inc ++ ++OUI:F469D5C* ++ ID_OUI_FROM_DATABASE=Huaqin Telecom Technology Co.,Ltd. ++ ++OUI:F469D5D* ++ ID_OUI_FROM_DATABASE=Nantong ZYDZ Electronic.,Co.Ltd ++ ++OUI:F469D5E* ++ ID_OUI_FROM_DATABASE=ORtek Technology, Inc. ++ + OUI:F46A92* + ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD + + OUI:F46ABC* + ID_OUI_FROM_DATABASE=Adonit Corp. Ltd. + ++OUI:F46AD7* ++ ID_OUI_FROM_DATABASE=Microsoft Corporation ++ ++OUI:F46B8C* ++ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. ++ + OUI:F46BEF* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + +@@ -87272,27 +111938,54 @@ OUI:F46DE2* + OUI:F46E24* + ID_OUI_FROM_DATABASE=NEC Personal Computers, Ltd. + ++OUI:F46E95* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:F46F4E* ++ ID_OUI_FROM_DATABASE=Echowell ++ ++OUI:F46FA4* ++ ID_OUI_FROM_DATABASE=Physik Instrumente GmbH & Co. KG ++ ++OUI:F46FED* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:F470AB* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + + OUI:F47190* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F47335* ++ ID_OUI_FROM_DATABASE=Logitech Far East ++ + OUI:F473CA* + ID_OUI_FROM_DATABASE=Conversion Sound Inc. + ++OUI:F47488* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:F47626* + ID_OUI_FROM_DATABASE=Viltechmeda UAB + ++OUI:F47960* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F47A4E* + ID_OUI_FROM_DATABASE=Woojeon&Handan + + OUI:F47ACC* + ID_OUI_FROM_DATABASE=SolidFire, Inc. + ++OUI:F47B09* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F47B5E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F47DEF* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F47F35* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -87314,12 +112007,18 @@ OUI:F485C6* + OUI:F48771* + ID_OUI_FROM_DATABASE=Infoblox + ++OUI:F487C5* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F48B32* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + + OUI:F48C50* + ID_OUI_FROM_DATABASE=Intel Corporate + ++OUI:F48CEB* ++ ID_OUI_FROM_DATABASE=D-Link International ++ + OUI:F48E09* + ID_OUI_FROM_DATABASE=Nokia Corporation + +@@ -87332,12 +112031,60 @@ OUI:F48E92* + OUI:F490CA* + ID_OUI_FROM_DATABASE=Tensorcom + ++OUI:F490CB0* ++ ID_OUI_FROM_DATABASE=Epitel, Inc. ++ ++OUI:F490CB1* ++ ID_OUI_FROM_DATABASE=DELEM BV ++ ++OUI:F490CB2* ++ ID_OUI_FROM_DATABASE=ICE Gateway GmbH ++ ++OUI:F490CB3* ++ ID_OUI_FROM_DATABASE=Ricker Lyman Robotic ++ ++OUI:F490CB4* ++ ID_OUI_FROM_DATABASE=OmniNet ++ ++OUI:F490CB5* ++ ID_OUI_FROM_DATABASE=Avilution ++ ++OUI:F490CB6* ++ ID_OUI_FROM_DATABASE=Airbeam Wireless Technologies Inc. ++ ++OUI:F490CB7* ++ ID_OUI_FROM_DATABASE=TEQ SA ++ ++OUI:F490CB8* ++ ID_OUI_FROM_DATABASE=Beijing Penslink Co., Ltd. ++ ++OUI:F490CB9* ++ ID_OUI_FROM_DATABASE=Fractyl Labs ++ ++OUI:F490CBA* ++ ID_OUI_FROM_DATABASE=Private ++ ++OUI:F490CBB* ++ ID_OUI_FROM_DATABASE=A-dec Inc. ++ ++OUI:F490CBC* ++ ID_OUI_FROM_DATABASE=Cheetah Medical ++ ++OUI:F490CBD* ++ ID_OUI_FROM_DATABASE=Simavita (Aust) Pty Ltd ++ ++OUI:F490CBE* ++ ID_OUI_FROM_DATABASE=RSAE Labs Inc ++ + OUI:F490EA* + ID_OUI_FROM_DATABASE=Deciso B.V. + + OUI:F4911E* + ID_OUI_FROM_DATABASE=ZHUHAI EWPE INFORMATION TECHNOLOGY INC + ++OUI:F492BF* ++ ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. ++ + OUI:F4939F* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +@@ -87347,15 +112094,24 @@ OUI:F49461* + OUI:F49466* + ID_OUI_FROM_DATABASE=CountMax, ltd + ++OUI:F4951B* ++ ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd ++ + OUI:F49634* + ID_OUI_FROM_DATABASE=Intel Corporate + + OUI:F49651* + ID_OUI_FROM_DATABASE=NAKAYO Inc + ++OUI:F497C2* ++ ID_OUI_FROM_DATABASE=Nebulon Inc ++ + OUI:F499AC* + ID_OUI_FROM_DATABASE=WEBER Schraubautomaten GmbH + ++OUI:F49C12* ++ ID_OUI_FROM_DATABASE=Structab AB ++ + OUI:F49EEF* + ID_OUI_FROM_DATABASE=Taicang T&W Electronics + +@@ -87368,21 +112124,45 @@ OUI:F49FF3* + OUI:F4A294* + ID_OUI_FROM_DATABASE=EAGLE WORLD DEVELOPMENT CO., LIMITED + ++OUI:F4A475* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ ++OUI:F4A4D6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4A52A* + ID_OUI_FROM_DATABASE=Hawa Technologies Inc + ++OUI:F4A59D* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F4A739* + ID_OUI_FROM_DATABASE=Juniper Networks + ++OUI:F4A80D* ++ ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. ++ + OUI:F4A997* + ID_OUI_FROM_DATABASE=CANON INC. + + OUI:F4ACC1* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F4AFE7* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F4B164* + ID_OUI_FROM_DATABASE=Lightning Telecommunications Technology Co. Ltd + ++OUI:F4B19C* ++ ID_OUI_FROM_DATABASE=AltoBeam (China) Inc. ++ ++OUI:F4B1C2* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ ++OUI:F4B301* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F4B381* + ID_OUI_FROM_DATABASE=WindowMaster A/S + +@@ -87395,12 +112175,24 @@ OUI:F4B52F* + OUI:F4B549* + ID_OUI_FROM_DATABASE=Xiamen Yeastar Information Technology Co., Ltd. + ++OUI:F4B5AA* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:F4B5BB* ++ ID_OUI_FROM_DATABASE=CERAGON NETWORKS ++ ++OUI:F4B688* ++ ID_OUI_FROM_DATABASE=PLANTRONICS, INC. ++ + OUI:F4B6E5* + ID_OUI_FROM_DATABASE=TerraSem Co.,Ltd + + OUI:F4B72A* + ID_OUI_FROM_DATABASE=TIME INTERCONNECT LTD + ++OUI:F4B78D* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4B7B3* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +@@ -87416,12 +112208,30 @@ OUI:F4B8A7* + OUI:F4BC97* + ID_OUI_FROM_DATABASE=Shenzhen Crave Communication Co., LTD + ++OUI:F4BCDA* ++ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd ++ + OUI:F4BD7C* + ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD + ++OUI:F4BD9E* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:F4BEEC* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F4BF80* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F4BFA8* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ ++OUI:F4C02F* ++ ID_OUI_FROM_DATABASE=BlueBite ++ ++OUI:F4C114* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ + OUI:F4C248* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -87441,7 +112251,13 @@ OUI:F4C714* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + + OUI:F4C795* +- ID_OUI_FROM_DATABASE=WEY Elektronik AG ++ ID_OUI_FROM_DATABASE=WEY Technology AG ++ ++OUI:F4C7AA* ++ ID_OUI_FROM_DATABASE=Marvell Semiconductors ++ ++OUI:F4C7C8* ++ ID_OUI_FROM_DATABASE=Kelvin Inc. + + OUI:F4CA24* + ID_OUI_FROM_DATABASE=FreeBit Co., Ltd. +@@ -87458,24 +112274,51 @@ OUI:F4CC55* + OUI:F4CD90* + ID_OUI_FROM_DATABASE=Vispiron Rotec GmbH + ++OUI:F4CE36* ++ ID_OUI_FROM_DATABASE=Nordic Semiconductor ASA ++ + OUI:F4CE46* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:F4CE48* ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. ++ ++OUI:F4CFA2* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:F4CFE2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:F4D032* + ID_OUI_FROM_DATABASE=Yunnan Ideal Information&Technology.,Ltd + ++OUI:F4D108* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F4D261* + ID_OUI_FROM_DATABASE=SEMOCON Co., Ltd + ++OUI:F4D488* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F4D620* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:F4D7B2* + ID_OUI_FROM_DATABASE=LGS Innovations, LLC + ++OUI:F4D9C6* ++ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD ++ + OUI:F4D9FB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F4DBE3* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F4DBE6* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:F4DC41* + ID_OUI_FROM_DATABASE=YOUNGZONE CULTURE (SHANGHAI) CORP + +@@ -87497,6 +112340,9 @@ OUI:F4DD9E* + OUI:F4DE0C* + ID_OUI_FROM_DATABASE=ESPOD Ltd. + ++OUI:F4DEAF* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4E11E* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -87509,9 +112355,18 @@ OUI:F4E204* + OUI:F4E3FB* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F4E451* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4E4AD* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:F4E578* ++ ID_OUI_FROM_DATABASE=LLC Proizvodstvennaya Kompania TransService ++ ++OUI:F4E5F2* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4E6D7* + ID_OUI_FROM_DATABASE=Solar Power Technologies, Inc. + +@@ -87525,17 +112380,23 @@ OUI:F4EA67* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + + OUI:F4EAB5* +- ID_OUI_FROM_DATABASE=Aerohive Networks Inc. ++ ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + + OUI:F4EB38* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:F4EB9F* ++ ID_OUI_FROM_DATABASE=Ellu Company 2019 SL ++ + OUI:F4EC38* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + + OUI:F4ED5F* + ID_OUI_FROM_DATABASE=SHENZHEN KTC TECHNOLOGY GROUP + ++OUI:F4EE08* ++ ID_OUI_FROM_DATABASE=Dell Inc. ++ + OUI:F4EE14* + ID_OUI_FROM_DATABASE=MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. + +@@ -87578,6 +112439,9 @@ OUI:F4F646* + OUI:F4F951* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F4FBB8* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F4FC32* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -87587,6 +112451,12 @@ OUI:F4FCB1* + OUI:F4FD2B* + ID_OUI_FROM_DATABASE=ZOYI Company + ++OUI:F4FEFB* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:F800A1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F80113* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -87650,6 +112520,9 @@ OUI:F8042E* + OUI:F8051C* + ID_OUI_FROM_DATABASE=DRS Imaging and Targeting Solutions + ++OUI:F8084F* ++ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS ++ + OUI:F80BBE* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +@@ -87659,6 +112532,9 @@ OUI:F80BCB* + OUI:F80BD0* + ID_OUI_FROM_DATABASE=Datang Telecom communication terminal (Tianjin) Co., Ltd. + ++OUI:F80C58* ++ ID_OUI_FROM_DATABASE=Taicang T&W Electronics ++ + OUI:F80CF3* + ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications) + +@@ -87668,18 +112544,39 @@ OUI:F80D43* + OUI:F80D60* + ID_OUI_FROM_DATABASE=CANON INC. + ++OUI:F80DAC* ++ ID_OUI_FROM_DATABASE=HP Inc. ++ + OUI:F80DEA* + ID_OUI_FROM_DATABASE=ZyCast Technology Inc. + ++OUI:F80DF0* ++ ID_OUI_FROM_DATABASE=zte corporation ++ ++OUI:F80DF1* ++ ID_OUI_FROM_DATABASE=Sontex SA ++ + OUI:F80F41* + ID_OUI_FROM_DATABASE=Wistron Infocomm (Zhongshan) Corporation + ++OUI:F80F6F* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:F80F84* + ID_OUI_FROM_DATABASE=Natural Security SAS + ++OUI:F80FF9* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:F81037* + ID_OUI_FROM_DATABASE=Atopia Systems, LP + ++OUI:F81093* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F81308* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:F81547* + ID_OUI_FROM_DATABASE=Avaya Inc + +@@ -87689,9 +112586,15 @@ OUI:F81654* + OUI:F81897* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:F81A2B* ++ ID_OUI_FROM_DATABASE=Google, Inc. ++ + OUI:F81A67* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + ++OUI:F81B04* ++ ID_OUI_FROM_DATABASE=Zhong Shan City Richsound Electronic Industrial Ltd ++ + OUI:F81CE5* + ID_OUI_FROM_DATABASE=Telefonbau Behnke GmbH + +@@ -87749,15 +112652,24 @@ OUI:F81D90* + OUI:F81D93* + ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd + ++OUI:F81E6F* ++ ID_OUI_FROM_DATABASE=EBG compleo GmbH ++ + OUI:F81EDF* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F81F32* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:F82055* + ID_OUI_FROM_DATABASE=Green Information System + + OUI:F82285* + ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD. + ++OUI:F82387* ++ ID_OUI_FROM_DATABASE=Shenzhen Horn Audio Co.,Ltd. ++ + OUI:F823B2* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -87779,21 +112691,39 @@ OUI:F82BC8* + OUI:F82C18* + ID_OUI_FROM_DATABASE=2Wire Inc + ++OUI:F82D7C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F82DC0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:F82E3F* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:F82E8E* ++ ID_OUI_FROM_DATABASE=Nanjing Kechen Electric Co., Ltd. ++ + OUI:F82EDB* + ID_OUI_FROM_DATABASE=RTW GmbH & Co. KG + + OUI:F82F08* +- ID_OUI_FROM_DATABASE=Molex ++ ID_OUI_FROM_DATABASE=Molex CMS + + OUI:F82F5B* + ID_OUI_FROM_DATABASE=eGauge Systems LLC + ++OUI:F82F65* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F82F6A* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED ++ + OUI:F82FA8* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + ++OUI:F83002* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:F83094* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Telecom Limited + +@@ -87803,6 +112733,9 @@ OUI:F8313E* + OUI:F832E4* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + ++OUI:F83331* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:F83376* + ID_OUI_FROM_DATABASE=Good Mind Innovation Co., Ltd. + +@@ -87818,12 +112751,30 @@ OUI:F835DD* + OUI:F8369B* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:F83869* ++ ID_OUI_FROM_DATABASE=LG Electronics ++ ++OUI:F83880* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F83B1D* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:F83B7E* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F83CBF* ++ ID_OUI_FROM_DATABASE=BOTATO ELECTRONICS SDN BHD ++ + OUI:F83D4E* + ID_OUI_FROM_DATABASE=Softlink Automation System Co., Ltd + + OUI:F83DFF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F83E95* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F83F51* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -87836,6 +112787,9 @@ OUI:F844E3* + OUI:F845AD* + ID_OUI_FROM_DATABASE=Konka Group Co., Ltd. + ++OUI:F845C4* ++ ID_OUI_FROM_DATABASE=Shenzhen Netforward Micro-Electronic Co., Ltd. ++ + OUI:F8461C* + ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc. + +@@ -87848,6 +112802,9 @@ OUI:F8472D* + OUI:F84897* + ID_OUI_FROM_DATABASE=Hitachi, Ltd. + ++OUI:F848FD* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:F84A73* + ID_OUI_FROM_DATABASE=EUMTECH CO., LTD + +@@ -87857,21 +112814,54 @@ OUI:F84A7F* + OUI:F84ABF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F84CDA* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:F84D33* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ ++OUI:F84DFC* ++ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. ++ ++OUI:F84E73* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F84F57* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F84FAD* ++ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD ++ ++OUI:F8501C* ++ ID_OUI_FROM_DATABASE=Tianjin Geneuo Technology Co.,Ltd ++ + OUI:F85063* + ID_OUI_FROM_DATABASE=Verathon + ++OUI:F85128* ++ ID_OUI_FROM_DATABASE=SimpliSafe ++ + OUI:F8516D* + ID_OUI_FROM_DATABASE=Denwa Technology Corp. + + OUI:F852DF* + ID_OUI_FROM_DATABASE=VNL Europe AB + ++OUI:F85329* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F854AF* + ID_OUI_FROM_DATABASE=ECI Telecom Ltd. + ++OUI:F854B8* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ ++OUI:F855CD* ++ ID_OUI_FROM_DATABASE=Visteon Corporation ++ ++OUI:F856C3* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:F8572E* + ID_OUI_FROM_DATABASE=Core Brands, LLC + +@@ -87881,6 +112871,9 @@ OUI:F85971* + OUI:F85A00* + ID_OUI_FROM_DATABASE=Sanford LP + ++OUI:F85B3B* ++ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP ++ + OUI:F85B9C* + ID_OUI_FROM_DATABASE=SB SYSTEMS Co.,Ltd + +@@ -87893,12 +112886,24 @@ OUI:F85C45* + OUI:F85C4D* + ID_OUI_FROM_DATABASE=Nokia + ++OUI:F85C7D* ++ ID_OUI_FROM_DATABASE=Shenzhen Honesty Electronics Co.,Ltd. ++ + OUI:F85E3C* + ID_OUI_FROM_DATABASE=SHENZHEN ZHIBOTONG ELECTRONICS CO.,LTD + ++OUI:F85E42* ++ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. ++ ++OUI:F85EA0* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F85F2A* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:F860F0* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:F86214* + ID_OUI_FROM_DATABASE=Apple, Inc. + +@@ -87911,9 +112916,15 @@ OUI:F8633F* + OUI:F86465* + ID_OUI_FROM_DATABASE=Anova Applied Electronics, Inc. + ++OUI:F864B8* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:F86601* + ID_OUI_FROM_DATABASE=Suzhou Chi-tek information technology Co., Ltd + ++OUI:F8665A* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F866D1* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +@@ -87923,9 +112934,18 @@ OUI:F866F2* + OUI:F86971* + ID_OUI_FROM_DATABASE=Seibu Electric Co., + ++OUI:F86BD9* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:F86C03* ++ ID_OUI_FROM_DATABASE=Shenzhen Teleone Technology Co., Ltd ++ + OUI:F86CE1* + ID_OUI_FROM_DATABASE=Taicang T&W Electronics + ++OUI:F86D73* ++ ID_OUI_FROM_DATABASE=Zengge Co., Limited ++ + OUI:F86ECF* + ID_OUI_FROM_DATABASE=Arcx Inc + +@@ -87935,6 +112955,9 @@ OUI:F86EEE* + OUI:F86FC1* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F86FDE* ++ ID_OUI_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. ++ + OUI:F871FE* + ID_OUI_FROM_DATABASE=The Goldman Sachs Group, Inc. + +@@ -87950,12 +112973,21 @@ OUI:F873A2* + OUI:F87588* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F875A4* ++ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd ++ + OUI:F8769B* + ID_OUI_FROM_DATABASE=Neopis Co., Ltd. + + OUI:F877B8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F8790A* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ ++OUI:F87A41* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ + OUI:F87AEF* + ID_OUI_FROM_DATABASE=Rosonix Technology, Inc. + +@@ -87971,18 +113003,36 @@ OUI:F87B7A* + OUI:F87B8C* + ID_OUI_FROM_DATABASE=Amped Wireless + ++OUI:F87FA5* ++ ID_OUI_FROM_DATABASE=GREATEK ++ + OUI:F88096* + ID_OUI_FROM_DATABASE=Elsys Equipamentos Eletrônicos Ltda + + OUI:F8811A* + ID_OUI_FROM_DATABASE=OVERKIZ + ++OUI:F88200* ++ ID_OUI_FROM_DATABASE=CaptionCall ++ + OUI:F88479* + ID_OUI_FROM_DATABASE=Yaojin Technology(Shenzhen)Co.,Ltd + + OUI:F884F2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:F885F9* ++ ID_OUI_FROM_DATABASE=Calix Inc. ++ ++OUI:F887F1* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ ++OUI:F8893C* ++ ID_OUI_FROM_DATABASE=Inventec Appliances Corp. ++ ++OUI:F889D2* ++ ID_OUI_FROM_DATABASE=CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD. ++ + OUI:F88A3C0* + ID_OUI_FROM_DATABASE=ART SPA + +@@ -88028,18 +113078,30 @@ OUI:F88A3CD* + OUI:F88A3CE* + ID_OUI_FROM_DATABASE=Avateq Corp. + ++OUI:F88A5E* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:F88B37* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + + OUI:F88C1C* + ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING + ++OUI:F88C21* ++ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. ++ + OUI:F88DEF* + ID_OUI_FROM_DATABASE=Tenebraex + + OUI:F88E85* + ID_OUI_FROM_DATABASE=Comtrend Corporation + ++OUI:F88EA1* ++ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation ++ ++OUI:F88F07* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F88FCA* + ID_OUI_FROM_DATABASE=Google, Inc. + +@@ -88049,6 +113111,9 @@ OUI:F89066* + OUI:F8912A* + ID_OUI_FROM_DATABASE=GLP German Light Products GmbH + ++OUI:F89173* ++ ID_OUI_FROM_DATABASE=AEDLE SAS ++ + OUI:F893F3* + ID_OUI_FROM_DATABASE=VOLANS + +@@ -88064,6 +113129,9 @@ OUI:F895C7* + OUI:F895EA* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:F89753* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:F897CF* + ID_OUI_FROM_DATABASE=DAESHIN-INFORMATION TECHNOLOGY CO., LTD. + +@@ -88082,12 +113150,18 @@ OUI:F89910* + OUI:F89955* + ID_OUI_FROM_DATABASE=Fortress Technology Inc + ++OUI:F89A78* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:F89D0D* + ID_OUI_FROM_DATABASE=Control Technology Inc. + + OUI:F89DBB* + ID_OUI_FROM_DATABASE=Tintri + ++OUI:F89E28* ++ ID_OUI_FROM_DATABASE=Cisco Meraki ++ + OUI:F89FB8* + ID_OUI_FROM_DATABASE=YAZAKI Energy System Corporation + +@@ -88100,9 +113174,15 @@ OUI:F8A097* + OUI:F8A188* + ID_OUI_FROM_DATABASE=LED Roadway Lighting + ++OUI:F8A26D* ++ ID_OUI_FROM_DATABASE=CANON INC. ++ + OUI:F8A2B4* + ID_OUI_FROM_DATABASE=RHEWA-WAAGENFABRIK August Freudewald GmbH &Co. KG + ++OUI:F8A2D6* ++ ID_OUI_FROM_DATABASE=Liteon Technology Corporation ++ + OUI:F8A34F* + ID_OUI_FROM_DATABASE=zte corporation + +@@ -88112,6 +113192,12 @@ OUI:F8A45F* + OUI:F8A5C5* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F8A73A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:F8A763* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:F8A963* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +@@ -88121,21 +113207,48 @@ OUI:F8A9D0* + OUI:F8A9DE* + ID_OUI_FROM_DATABASE=PUISSANCE PLUS + ++OUI:F8AA3F* ++ ID_OUI_FROM_DATABASE=DWnet Technologies(Suzhou) Corporation ++ + OUI:F8AA8A* + ID_OUI_FROM_DATABASE=Axview Technology (Shenzhen) Co.,Ltd + + OUI:F8AB05* + ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS + ++OUI:F8ABE5* ++ ID_OUI_FROM_DATABASE=shenzhen worldelite electronics co., LTD ++ ++OUI:F8AC65* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F8AC6D* + ID_OUI_FROM_DATABASE=Deltenna Ltd + ++OUI:F8ADCB* ++ ID_OUI_FROM_DATABASE=HMD Global Oy ++ ++OUI:F8AE27* ++ ID_OUI_FROM_DATABASE=John Deere Electronic Solutions ++ ++OUI:F8AF05* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:F8AFDB* ++ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD ++ + OUI:F8B156* + ID_OUI_FROM_DATABASE=Dell Inc. + ++OUI:F8B1DD* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F8B2F3* + ID_OUI_FROM_DATABASE=GUANGZHOU BOSMA TECHNOLOGY CO.,LTD + ++OUI:F8B46A* ++ ID_OUI_FROM_DATABASE=Hewlett Packard ++ + OUI:F8B5680* + ID_OUI_FROM_DATABASE=LifePrint Products, Inc. + +@@ -88184,12 +113297,24 @@ OUI:F8B568E* + OUI:F8B599* + ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd + ++OUI:F8B797* ++ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd. ++ + OUI:F8B7E2* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:F8B95A* ++ ID_OUI_FROM_DATABASE=LG Innotek ++ ++OUI:F8BAE6* ++ ID_OUI_FROM_DATABASE=Nokia ++ + OUI:F8BBBF* + ID_OUI_FROM_DATABASE=eero inc. + ++OUI:F8BC0E* ++ ID_OUI_FROM_DATABASE=eero inc. ++ + OUI:F8BC12* + ID_OUI_FROM_DATABASE=Dell Inc. + +@@ -88211,6 +113336,9 @@ OUI:F8C091* + OUI:F8C120* + ID_OUI_FROM_DATABASE=Xi'an Link-Science Technology Co.,Ltd + ++OUI:F8C249* ++ ID_OUI_FROM_DATABASE=Private ++ + OUI:F8C288* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -88223,18 +113351,30 @@ OUI:F8C397* + OUI:F8C39E* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F8C4F3* ++ ID_OUI_FROM_DATABASE=Shanghai Infinity Wireless Technologies Co.,Ltd. ++ + OUI:F8C678* + ID_OUI_FROM_DATABASE=Carefusion + + OUI:F8C96C* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:F8CA59* ++ ID_OUI_FROM_DATABASE=NetComm Wireless ++ ++OUI:F8CA85* ++ ID_OUI_FROM_DATABASE=NEC Corporation ++ + OUI:F8CAB8* + ID_OUI_FROM_DATABASE=Dell Inc. + + OUI:F8CC6E* + ID_OUI_FROM_DATABASE=DEPO Electronics Ltd + ++OUI:F8CE72* ++ ID_OUI_FROM_DATABASE=Wistron Corporation ++ + OUI:F8CFC5* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + +@@ -88256,6 +113396,9 @@ OUI:F8D3A9* + OUI:F8D462* + ID_OUI_FROM_DATABASE=Pumatronix Equipamentos Eletronicos Ltda. + ++OUI:F8D478* ++ ID_OUI_FROM_DATABASE=Flextronics Tech.(Ind) Pvt Ltd ++ + OUI:F8D756* + ID_OUI_FROM_DATABASE=Simm Tronic Limited + +@@ -88272,7 +113415,7 @@ OUI:F8DADF* + ID_OUI_FROM_DATABASE=EcoTech, Inc. + + OUI:F8DAE2* +- ID_OUI_FROM_DATABASE=Beta LaserMike ++ ID_OUI_FROM_DATABASE=NDC Technologies + + OUI:F8DAF4* + ID_OUI_FROM_DATABASE=Taishan Online Technology Co., Ltd. +@@ -88295,30 +113438,51 @@ OUI:F8DF15* + OUI:F8DFA8* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:F8DFE1* ++ ID_OUI_FROM_DATABASE=MyLight Systems ++ + OUI:F8E079* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:F8E43B* ++ ID_OUI_FROM_DATABASE=ASIX Electronics Corporation ++ + OUI:F8E44E* + ID_OUI_FROM_DATABASE=MCOT INC. + ++OUI:F8E4E3* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:F8E4FB* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + ++OUI:F8E5CF* ++ ID_OUI_FROM_DATABASE=CGI IT UK LIMITED ++ + OUI:F8E61A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + + OUI:F8E71E* + ID_OUI_FROM_DATABASE=Ruckus Wireless + ++OUI:F8E7A0* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:F8E7B5* + ID_OUI_FROM_DATABASE=µTech Tecnologia LTDA + + OUI:F8E811* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:F8E877* ++ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH ++ + OUI:F8E903* + ID_OUI_FROM_DATABASE=D-Link International + ++OUI:F8E94E* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:F8E968* + ID_OUI_FROM_DATABASE=Egker Kft. + +@@ -88335,11 +113499,14 @@ OUI:F8F014* + ID_OUI_FROM_DATABASE=RackWare Inc. + + OUI:F8F082* +- ID_OUI_FROM_DATABASE=NAG LLC ++ ID_OUI_FROM_DATABASE=NAGTECH LLC + + OUI:F8F1B6* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company + ++OUI:F8F1E6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ + OUI:F8F21E* + ID_OUI_FROM_DATABASE=Intel Corporate + +@@ -88373,6 +113540,9 @@ OUI:F8FF0B* + OUI:F8FF5F* + ID_OUI_FROM_DATABASE=Shenzhen Communication Technology Co.,Ltd + ++OUI:F8FFC2* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FC0012* + ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation + +@@ -88388,6 +113558,9 @@ OUI:FC01CD* + OUI:FC039F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:FC041C* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:FC0647* + ID_OUI_FROM_DATABASE=Cortland Research, LLC + +@@ -88412,6 +113585,9 @@ OUI:FC09F6* + OUI:FC0A81* + ID_OUI_FROM_DATABASE=Extreme Networks, Inc. + ++OUI:FC0C45* ++ ID_OUI_FROM_DATABASE=Shenzhen SuperElectron Technology Co.,Ltd. ++ + OUI:FC0F4B* + ID_OUI_FROM_DATABASE=Texas Instruments + +@@ -88427,9 +113603,18 @@ OUI:FC10C6* + OUI:FC1186* + ID_OUI_FROM_DATABASE=Logic3 plc + ++OUI:FC122C* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FC1349* + ID_OUI_FROM_DATABASE=Global Apps Corp. + ++OUI:FC13F0* ++ ID_OUI_FROM_DATABASE=Bouffalo Lab (Nanjing) Co., Ltd. ++ ++OUI:FC1499* ++ ID_OUI_FROM_DATABASE=Aimore Acoustics Incorporation ++ + OUI:FC15B4* + ID_OUI_FROM_DATABASE=Hewlett Packard + +@@ -88439,18 +113624,39 @@ OUI:FC1607* + OUI:FC1794* + ID_OUI_FROM_DATABASE=InterCreative Co., Ltd + ++OUI:FC183C* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FC1910* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:FC1928* ++ ID_OUI_FROM_DATABASE=Actions Microelectronics Co., Ltd ++ ++OUI:FC1999* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ + OUI:FC19D0* + ID_OUI_FROM_DATABASE=Cloud Vision Networks Technology Co.,Ltd. + + OUI:FC1A11* + ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + ++OUI:FC1BD1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FC1BFF* + ID_OUI_FROM_DATABASE=V-ZUG AG + ++OUI:FC1CA1* ++ ID_OUI_FROM_DATABASE=Nokia ++ ++OUI:FC1D2A* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++OUI:FC1D43* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FC1D59* + ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd + +@@ -88478,15 +113684,24 @@ OUI:FC253F* + OUI:FC27A2* + ID_OUI_FROM_DATABASE=TRANS ELECTRIC CO., LTD. + ++OUI:FC29F3* ++ ID_OUI_FROM_DATABASE=McPay Co.,LTD. ++ + OUI:FC2A54* + ID_OUI_FROM_DATABASE=Connected Data, Inc. + + OUI:FC2A9C* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:FC2BB2* ++ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc ++ + OUI:FC2D5E* + ID_OUI_FROM_DATABASE=zte corporation + ++OUI:FC2E19* ++ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd. ++ + OUI:FC2E2D* + ID_OUI_FROM_DATABASE=Lorom Industrial Co.LTD. + +@@ -88505,9 +113720,15 @@ OUI:FC2FEF* + OUI:FC3288* + ID_OUI_FROM_DATABASE=CELOT Wireless Co., Ltd + ++OUI:FC3342* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:FC335F* + ID_OUI_FROM_DATABASE=Polyera + ++OUI:FC3497* ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ++ + OUI:FC3598* + ID_OUI_FROM_DATABASE=Favite Inc. + +@@ -88515,7 +113736,10 @@ OUI:FC35E6* + ID_OUI_FROM_DATABASE=Visteon corp + + OUI:FC372B* +- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD ++ ID_OUI_FROM_DATABASE=Sichuan Tianyi Comheart Telecom Co.,LTD ++ ++OUI:FC3964* ++ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED + + OUI:FC3CE9* + ID_OUI_FROM_DATABASE=Tsingtong Technologies Co, Ltd. +@@ -88523,6 +113747,9 @@ OUI:FC3CE9* + OUI:FC3D93* + ID_OUI_FROM_DATABASE=LONGCHEER TELECOMMUNICATION LIMITED + ++OUI:FC3DA5* ++ ID_OUI_FROM_DATABASE=Arcadyan Corporation ++ + OUI:FC3F7C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +@@ -88532,39 +113759,66 @@ OUI:FC3FAB* + OUI:FC3FDB* + ID_OUI_FROM_DATABASE=Hewlett Packard + ++OUI:FC4009* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:FC4203* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:FC4265* ++ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd. ++ + OUI:FC4463* + ID_OUI_FROM_DATABASE=Universal Audio, Inc + ++OUI:FC4482* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:FC4499* + ID_OUI_FROM_DATABASE=Swarco LEA d.o.o. + ++OUI:FC449F* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:FC455F* + ID_OUI_FROM_DATABASE=JIANGXI SHANSHUI OPTOELECTRONIC TECHNOLOGY CO.,LTD + + OUI:FC4596* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + ++OUI:FC45C3* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:FC48EF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + ++OUI:FC492D* ++ ID_OUI_FROM_DATABASE=Amazon Technologies Inc. ++ + OUI:FC4AE9* + ID_OUI_FROM_DATABASE=Castlenet Technology Inc. + + OUI:FC4B1C* + ID_OUI_FROM_DATABASE=INTERSENSOR S.R.L. + ++OUI:FC4B57* ++ ID_OUI_FROM_DATABASE=Peerless Instrument Division of Curtiss-Wright ++ + OUI:FC4BBC* + ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd. + + OUI:FC4D8C* + ID_OUI_FROM_DATABASE=SHENZHEN PANTE ELECTRONICS TECHNOLOGY CO., LTD + ++OUI:FC4DA6* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FC4DD4* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + ++OUI:FC4EA4* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FC5090* + ID_OUI_FROM_DATABASE=SIMEX Sp. z o.o. + +@@ -88583,6 +113837,15 @@ OUI:FC539E* + OUI:FC55DC* + ID_OUI_FROM_DATABASE=Baltic Latvian Universal Electronics LLC + ++OUI:FC584A* ++ ID_OUI_FROM_DATABASE=xiamenshi c-chip technology co., ltd ++ ++OUI:FC589A* ++ ID_OUI_FROM_DATABASE=Cisco Systems, Inc ++ ++OUI:FC58DF* ++ ID_OUI_FROM_DATABASE=Interphone Service ++ + OUI:FC58FA* + ID_OUI_FROM_DATABASE=Shen Zhen Shi Xin Zhong Xin Technology Co.,Ltd. + +@@ -88598,9 +113861,15 @@ OUI:FC5B26* + OUI:FC5B39* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + ++OUI:FC5C45* ++ ID_OUI_FROM_DATABASE=Ruckus Wireless ++ + OUI:FC6018* + ID_OUI_FROM_DATABASE=Zhejiang Kangtai Electric Co., Ltd. + ++OUI:FC609B* ++ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd ++ + OUI:FC6198* + ID_OUI_FROM_DATABASE=NEC Personal Products, Ltd + +@@ -88611,7 +113880,7 @@ OUI:FC626E* + ID_OUI_FROM_DATABASE=Beijing MDC Telecom + + OUI:FC62B9* +- ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. ++ ID_OUI_FROM_DATABASE=ALPSALPINE CO,.LTD + + OUI:FC643A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd +@@ -88619,15 +113888,24 @@ OUI:FC643A* + OUI:FC64BA* + ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd + ++OUI:FC65B3* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:FC65DE* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + ++OUI:FC66CF* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FC683E* + ID_OUI_FROM_DATABASE=Directed Perception, Inc + + OUI:FC6947* + ID_OUI_FROM_DATABASE=Texas Instruments + ++OUI:FC698C* ++ ID_OUI_FROM_DATABASE=ANDREAS STIHL AG & Co. KG ++ + OUI:FC6BF0* + ID_OUI_FROM_DATABASE=TOPWELL INTERNATIONAL HOLDINDS LIMITED + +@@ -88637,15 +113915,27 @@ OUI:FC6C31* + OUI:FC6DC0* + ID_OUI_FROM_DATABASE=BME CORPORATION + ++OUI:FC6DD1* ++ ID_OUI_FROM_DATABASE=APRESIA Systems, Ltd. ++ + OUI:FC6FB7* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:FC71FA* ++ ID_OUI_FROM_DATABASE=Trane Technologies ++ ++OUI:FC73FB* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FC7516* + ID_OUI_FROM_DATABASE=D-Link International + + OUI:FC75E6* + ID_OUI_FROM_DATABASE=Handreamnet + ++OUI:FC7774* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:FC790B* + ID_OUI_FROM_DATABASE=Hitachi High Technologies America, Inc. + +@@ -88655,9 +113945,15 @@ OUI:FC7C02* + OUI:FC7CE7* + ID_OUI_FROM_DATABASE=FCI USA LLC + ++OUI:FC7D6C* ++ ID_OUI_FROM_DATABASE=HYESUNG TECHWIN Co., Ltd ++ + OUI:FC7F56* + ID_OUI_FROM_DATABASE=CoSyst Control Systems GmbH + ++OUI:FC7FF1* ++ ID_OUI_FROM_DATABASE=Aruba, a Hewlett Packard Enterprise Company ++ + OUI:FC8329* + ID_OUI_FROM_DATABASE=Trei technics + +@@ -88667,12 +113963,36 @@ OUI:FC8399* + OUI:FC83C6* + ID_OUI_FROM_DATABASE=N-Radio Technologies Co., Ltd. + ++OUI:FC8596* ++ ID_OUI_FROM_DATABASE=Axonne Inc. ++ ++OUI:FC862A* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ ++OUI:FC8743* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:FC8A3D* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:FC8B97* + ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT + ++OUI:FC8D3D* ++ ID_OUI_FROM_DATABASE=Leapfive Tech. Ltd. ++ ++OUI:FC8E5B* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ ++OUI:FC8E6E* ++ ID_OUI_FROM_DATABASE=StreamCCTV, LLC ++ + OUI:FC8E7E* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + ++OUI:FC8F7D* ++ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT ++ + OUI:FC8F90* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +@@ -88688,12 +114008,27 @@ OUI:FC9114* + OUI:FC923B* + ID_OUI_FROM_DATABASE=Nokia Corporation + ++OUI:FC9257* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ ++OUI:FC9435* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FC946C* + ID_OUI_FROM_DATABASE=UBIVELOX + ++OUI:FC94CE* ++ ID_OUI_FROM_DATABASE=zte corporation ++ + OUI:FC94E3* + ID_OUI_FROM_DATABASE=Technicolor CH USA Inc. + ++OUI:FC956A* ++ ID_OUI_FROM_DATABASE=OCTAGON SYSTEMS CORP. ++ ++OUI:FC9643* ++ ID_OUI_FROM_DATABASE=Juniper Networks ++ + OUI:FC9947* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc + +@@ -88703,6 +114038,9 @@ OUI:FC9AFA* + OUI:FC9BC6* + ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd + ++OUI:FC9C98* ++ ID_OUI_FROM_DATABASE=Arlo Technology ++ + OUI:FC9DD8* + ID_OUI_FROM_DATABASE=Beijing TongTongYiLian Science and Technology Ltd. + +@@ -88724,9 +114062,60 @@ OUI:FCA22A* + OUI:FCA386* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD + ++OUI:FCA47A0* ++ ID_OUI_FROM_DATABASE=Broadcom Inc. ++ ++OUI:FCA47A1* ++ ID_OUI_FROM_DATABASE=Shenzhen VMAX New Energy Co., Ltd. ++ ++OUI:FCA47A2* ++ ID_OUI_FROM_DATABASE=Ant Financial(Hang Zhou)Network Technology Co.,Ltd. ++ ++OUI:FCA47A3* ++ ID_OUI_FROM_DATABASE=Cliptech Industria e Comercio Ltda ++ ++OUI:FCA47A4* ++ ID_OUI_FROM_DATABASE=HOOC AG ++ ++OUI:FCA47A5* ++ ID_OUI_FROM_DATABASE=Syfer ++ ++OUI:FCA47A6* ++ ID_OUI_FROM_DATABASE=Token ++ ++OUI:FCA47A7* ++ ID_OUI_FROM_DATABASE=Innovative Advantage ++ ++OUI:FCA47A8* ++ ID_OUI_FROM_DATABASE=KARRY COMMUNICATION LIMITED ++ ++OUI:FCA47A9* ++ ID_OUI_FROM_DATABASE=Oberix Group Pty Ltd ++ ++OUI:FCA47AA* ++ ID_OUI_FROM_DATABASE=Shenzhen Elebao Technology Co., Ltd ++ ++OUI:FCA47AB* ++ ID_OUI_FROM_DATABASE=Shenzhen Nokelock Technology Co, Ltd. ++ ++OUI:FCA47AC* ++ ID_OUI_FROM_DATABASE=Shenzhen ALFEYE Technology CO.,Ltd ++ ++OUI:FCA47AD* ++ ID_OUI_FROM_DATABASE=SHENZHEN KUKU TECHNOLOGY CO.,LTD ++ ++OUI:FCA47AE* ++ ID_OUI_FROM_DATABASE=Hefei Feier Smart Science&Technology Co. Ltd ++ ++OUI:FCA5D0* ++ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ++ + OUI:FCA621* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + ++OUI:FCA64C* ++ ID_OUI_FROM_DATABASE=Alibaba cloud computing Co., Ltd ++ + OUI:FCA667* + ID_OUI_FROM_DATABASE=Amazon Technologies Inc. + +@@ -88739,15 +114128,30 @@ OUI:FCA841* + OUI:FCA89A* + ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd + ++OUI:FCA89B* ++ ID_OUI_FROM_DATABASE=Texas Instruments ++ + OUI:FCA9B0* + ID_OUI_FROM_DATABASE=MIARTECH (SHANGHAI),INC. + ++OUI:FCA9DC* ++ ID_OUI_FROM_DATABASE=Renesas Electronics (Penang) Sdn. Bhd. ++ + OUI:FCAA14* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + ++OUI:FCAAB6* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:FCAB90* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ + OUI:FCAD0F* + ID_OUI_FROM_DATABASE=QTS NETWORKS + ++OUI:FCAE34* ++ ID_OUI_FROM_DATABASE=ARRIS Group, Inc. ++ + OUI:FCAF6A* + ID_OUI_FROM_DATABASE=Qulsar Inc + +@@ -88760,26 +114164,50 @@ OUI:FCB0C4* + OUI:FCB10D* + ID_OUI_FROM_DATABASE=Shenzhen Tian Kun Technology Co.,LTD. + ++OUI:FCB3BC* ++ ID_OUI_FROM_DATABASE=Intel Corporate ++ + OUI:FCB4E6* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + + OUI:FCB58A* + ID_OUI_FROM_DATABASE=Wapice Ltd. + ++OUI:FCB662* ++ ID_OUI_FROM_DATABASE=IC Holdings LLC ++ + OUI:FCB698* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + ++OUI:FCB69D* ++ ID_OUI_FROM_DATABASE=Zhejiang Dahua Technology Co., Ltd. ++ ++OUI:FCB6D8* ++ ID_OUI_FROM_DATABASE=Apple, Inc. ++ + OUI:FCB7F0* + ID_OUI_FROM_DATABASE=Idaho National Laboratory + + OUI:FCBBA1* + ID_OUI_FROM_DATABASE=Shenzhen Minicreate Technology Co.,Ltd + ++OUI:FCBC0E* ++ ID_OUI_FROM_DATABASE=Zhejiang Cainiao Supply Chain Management Co., Ltd ++ + OUI:FCBC9C* + ID_OUI_FROM_DATABASE=Vimar Spa + ++OUI:FCBCD1* ++ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD ++ ++OUI:FCBD67* ++ ID_OUI_FROM_DATABASE=Arista Networks ++ ++OUI:FCBE7B* ++ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ + OUI:FCC233* +- ID_OUI_FROM_DATABASE=Private ++ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + + OUI:FCC23D* + ID_OUI_FROM_DATABASE=Atmel Corporation +@@ -88799,12 +114227,105 @@ OUI:FCCAC4* + OUI:FCCCE4* + ID_OUI_FROM_DATABASE=Ascon Ltd. + ++OUI:FCCD2F0* ++ ID_OUI_FROM_DATABASE=Ningbo Bull Digital Technology Co., LTD ++ ++OUI:FCCD2F1* ++ ID_OUI_FROM_DATABASE=Siren Care(Shanghai) information and technology company ++ ++OUI:FCCD2F2* ++ ID_OUI_FROM_DATABASE=Loupedeck Oy ++ ++OUI:FCCD2F3* ++ ID_OUI_FROM_DATABASE=Xmitech Technology Co., Limited ++ ++OUI:FCCD2F4* ++ ID_OUI_FROM_DATABASE=Genitek Engineering sprl ++ ++OUI:FCCD2F5* ++ ID_OUI_FROM_DATABASE=QCTEK CO.,LTD. ++ ++OUI:FCCD2F6* ++ ID_OUI_FROM_DATABASE=Annapurna labs ++ ++OUI:FCCD2F7* ++ ID_OUI_FROM_DATABASE=Suzhou lehui display co.,ltd ++ ++OUI:FCCD2F8* ++ ID_OUI_FROM_DATABASE=Asesorias y Servicios Innovaxxion SPA ++ ++OUI:FCCD2F9* ++ ID_OUI_FROM_DATABASE=Aroma Retail ++ ++OUI:FCCD2FA* ++ ID_OUI_FROM_DATABASE=SCOPUS INTERNATIONAL-BELGIUM ++ ++OUI:FCCD2FB* ++ ID_OUI_FROM_DATABASE=HEAD-DIRECT (KUNSHAN) Co. Ltd ++ ++OUI:FCCD2FC* ++ ID_OUI_FROM_DATABASE=Spedos ADS a.s. ++ ++OUI:FCCD2FD* ++ ID_OUI_FROM_DATABASE=Shenzhen Smartbyte Technology Co., Ltd. ++ ++OUI:FCCD2FE* ++ ID_OUI_FROM_DATABASE=Eltek brojila d.o.o. ++ + OUI:FCCF43* + ID_OUI_FROM_DATABASE=HUIZHOU CITY HUIYANG DISTRICT MEISIQI INDUSTRY DEVELOPMENT CO,.LTD + + OUI:FCCF62* + ID_OUI_FROM_DATABASE=IBM Corp + ++OUI:FCD2B60* ++ ID_OUI_FROM_DATABASE=CG POWER AND INDUSTRIAL SOLUTIONS LTD ++ ++OUI:FCD2B61* ++ ID_OUI_FROM_DATABASE=LINK (FAR-EAST) CORPORATION ++ ++OUI:FCD2B62* ++ ID_OUI_FROM_DATABASE=Soma GmbH ++ ++OUI:FCD2B63* ++ ID_OUI_FROM_DATABASE=Coet Costruzioni Elettrotecniche ++ ++OUI:FCD2B64* ++ ID_OUI_FROM_DATABASE=SHEN ZHEN XIN HAO YUAN PRECISION TECHNOLOGY CO.,L TD ++ ++OUI:FCD2B65* ++ ID_OUI_FROM_DATABASE=Grandway Technology (Shenzhen) Limited ++ ++OUI:FCD2B66* ++ ID_OUI_FROM_DATABASE=Cirque Audio Technology Co.,Ltd ++ ++OUI:FCD2B67* ++ ID_OUI_FROM_DATABASE=Teamly Digital ++ ++OUI:FCD2B68* ++ ID_OUI_FROM_DATABASE=Oviss Labs Inc. ++ ++OUI:FCD2B69* ++ ID_OUI_FROM_DATABASE=Winglet Systems Inc. ++ ++OUI:FCD2B6A* ++ ID_OUI_FROM_DATABASE=NREAL TECHNOLOGY LIMITED ++ ++OUI:FCD2B6B* ++ ID_OUI_FROM_DATABASE=T CHIP DIGITAL TECHNOLOGY CO.LTD ++ ++OUI:FCD2B6C* ++ ID_OUI_FROM_DATABASE=Silicon (Shenzhen) Electronic Technology Co.,Ltd. ++ ++OUI:FCD2B6D* ++ ID_OUI_FROM_DATABASE=Bee Smart(Changzhou) Information Technology Co., Ltd ++ ++OUI:FCD2B6E* ++ ID_OUI_FROM_DATABASE=Univer S.p.A. ++ ++OUI:FCD436* ++ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company ++ + OUI:FCD4F2* + ID_OUI_FROM_DATABASE=The Coca Cola Company + +@@ -88826,6 +114347,12 @@ OUI:FCD817* + OUI:FCD848* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:FCD908* ++ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd ++ ++OUI:FCDB21* ++ ID_OUI_FROM_DATABASE=SAMSARA NETWORKS INC ++ + OUI:FCDB96* + ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD + +@@ -88838,6 +114365,12 @@ OUI:FCDC4A* + OUI:FCDD55* + ID_OUI_FROM_DATABASE=Shenzhen WeWins wireless Co.,Ltd + ++OUI:FCDE90* ++ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd ++ ++OUI:FCE14F* ++ ID_OUI_FROM_DATABASE=BRK Brands, Inc. ++ + OUI:FCE186* + ID_OUI_FROM_DATABASE=A3M Co., LTD + +@@ -88862,12 +114395,18 @@ OUI:FCE557* + OUI:FCE66A* + ID_OUI_FROM_DATABASE=Industrial Software Co + ++OUI:FCE806* ++ ID_OUI_FROM_DATABASE=Edifier International ++ + OUI:FCE892* + ID_OUI_FROM_DATABASE=Hangzhou Lancable Technology Co.,Ltd + + OUI:FCE998* + ID_OUI_FROM_DATABASE=Apple, Inc. + ++OUI:FCEA50* ++ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd. ++ + OUI:FCECDA* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + +@@ -88886,12 +114425,21 @@ OUI:FCF152* + OUI:FCF1CD* + ID_OUI_FROM_DATABASE=OPTEX-FA CO.,LTD. + ++OUI:FCF29F* ++ ID_OUI_FROM_DATABASE=China Mobile Iot Limited company ++ + OUI:FCF528* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + ++OUI:FCF5C4* ++ ID_OUI_FROM_DATABASE=Espressif Inc. ++ + OUI:FCF647* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + ++OUI:FCF77B* ++ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd. ++ + OUI:FCF8AE* + ID_OUI_FROM_DATABASE=Intel Corporate + +diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb +index 4207f07144..aa61e0d62a 100644 +--- a/hwdb/20-acpi-vendor.hwdb ++++ b/hwdb/20-acpi-vendor.hwdb +@@ -1,8 +1,8 @@ + # This file is part of systemd. + # + # Data imported from: +-# http://www.uefi.org/uefi-pnp-export +-# http://www.uefi.org/uefi-acpi-export ++# https://uefi.org/uefi-pnp-export ++# https://uefi.org/uefi-acpi-export + # + # With various additions from other sources + +@@ -24,6 +24,9 @@ acpi:AMDI*: + acpi:AMPC*: + ID_VENDOR_FROM_DATABASE=Ampere Computing + ++acpi:AMZN*: ++ ID_VENDOR_FROM_DATABASE=Amazon Corporation ++ + acpi:APMC*: + ID_VENDOR_FROM_DATABASE=Applied Micro Circuits Corporation + +@@ -36,6 +39,9 @@ acpi:ARMH*: + acpi:ARML*: + ID_VENDOR_FROM_DATABASE=ARM Ltd. + ++acpi:ASEM*: ++ ID_VENDOR_FROM_DATABASE=ASEM S.p.A. ++ + acpi:ASUS*: + ID_VENDOR_FROM_DATABASE=ASUS + +@@ -45,6 +51,9 @@ acpi:ATML*: + acpi:AUTH*: + ID_VENDOR_FROM_DATABASE=AuthenTec + ++acpi:BABA*: ++ ID_VENDOR_FROM_DATABASE=Alibaba Co., Ltd. ++ + acpi:BOOT*: + ID_VENDOR_FROM_DATABASE=Coreboot Project + +@@ -54,6 +63,9 @@ acpi:BOSC*: + acpi:BRCM*: + ID_VENDOR_FROM_DATABASE=Broadcom Corporation + ++acpi:CMHR*: ++ ID_VENDOR_FROM_DATABASE=COMHEAR, INC. ++ + acpi:CORE*: + ID_VENDOR_FROM_DATABASE=CoreOS, Inc + +@@ -63,12 +75,21 @@ acpi:CPLM*: + acpi:DELL*: + ID_VENDOR_FROM_DATABASE=Dell, Inc. + ++acpi:DIOO*: ++ ID_VENDOR_FROM_DATABASE=Dioo Microcircuits Co., Ltd. Jiangsu ++ + acpi:DLGS*: + ID_VENDOR_FROM_DATABASE=Dialog Semiconductor PLC + + acpi:DLLK*: + ID_VENDOR_FROM_DATABASE=Dell, Inc. + ++acpi:DMST*: ++ ID_VENDOR_FROM_DATABASE=DMIST RESEARCH LTD ++ ++acpi:DNBK*: ++ ID_VENDOR_FROM_DATABASE=Dynabook Inc. ++ + acpi:DSUO*: + ID_VENDOR_FROM_DATABASE=Shenzhen DSO Microelectronics Co.,Ltd. + +@@ -81,18 +102,27 @@ acpi:ESSX*: + acpi:EXAR*: + ID_VENDOR_FROM_DATABASE=Exar Corporation + ++acpi:FRMW*: ++ ID_VENDOR_FROM_DATABASE=Framework Computer LLC ++ + acpi:FRSC*: + ID_VENDOR_FROM_DATABASE=Freescale, Inc + + acpi:FTSC*: + ID_VENDOR_FROM_DATABASE=FocalTech Systems Co., Ltd. + ++acpi:FUJI*: ++ ID_VENDOR_FROM_DATABASE=Fujitsu Limited ++ + acpi:GHSW*: + ID_VENDOR_FROM_DATABASE=Green Hills Software + + acpi:GOOG*: + ID_VENDOR_FROM_DATABASE=Google, Inc. + ++acpi:GTCH*: ++ ID_VENDOR_FROM_DATABASE=G2touch Co., LTD ++ + acpi:HIMX*: + ID_VENDOR_FROM_DATABASE=Himax Technologies, Inc. + +@@ -111,12 +141,21 @@ acpi:HTLM*: + acpi:HWPE*: + ID_VENDOR_FROM_DATABASE=Hewlett Packard Enterprise + ++acpi:HXTS*: ++ ID_VENDOR_FROM_DATABASE=Guizhou Huaxintong Semiconductor Technology Co., Ltd ++ ++acpi:HYGO*: ++ ID_VENDOR_FROM_DATABASE=CHENGDU HAIGUANG IC DESIGN CO., LTD ++ + acpi:IBMX*: + ID_VENDOR_FROM_DATABASE=IBM + + acpi:IDEA*: + ID_VENDOR_FROM_DATABASE=Lenovo Beijing Co. Ltd. + ++acpi:IDEM*: ++ ID_VENDOR_FROM_DATABASE=IDEMIA ++ + acpi:IHSE*: + ID_VENDOR_FROM_DATABASE=IHSE GmbH + +@@ -141,6 +180,9 @@ acpi:IP3T*: + acpi:IPHI*: + ID_VENDOR_FROM_DATABASE=Inphi Corporation + ++acpi:JSYS*: ++ ID_VENDOR_FROM_DATABASE=Juniper Systems, Inc. ++ + acpi:KIOX*: + ID_VENDOR_FROM_DATABASE=Kionix, Inc. + +@@ -150,6 +192,9 @@ acpi:LNRO*: + acpi:LNUX*: + ID_VENDOR_FROM_DATABASE=The Linux Foundation + ++acpi:LOON*: ++ ID_VENDOR_FROM_DATABASE=Loongson Technology Corporation Limited ++ + acpi:MCHP*: + ID_VENDOR_FROM_DATABASE=Microchip Technology Inc + +@@ -192,6 +237,18 @@ acpi:OVTI*: + acpi:PEGA*: + ID_VENDOR_FROM_DATABASE=Pegatron Corporation + ++acpi:PHYT*: ++ ID_VENDOR_FROM_DATABASE=Phytium Technology Co. Ltd. ++ ++acpi:PIXA*: ++ ID_VENDOR_FROM_DATABASE=PixArt imaging inc. ++ ++acpi:PNSO*: ++ ID_VENDOR_FROM_DATABASE=Pensando Systems, Inc. ++ ++acpi:PURI*: ++ ID_VENDOR_FROM_DATABASE=Purism SPC ++ + acpi:QCOM*: + ID_VENDOR_FROM_DATABASE=Qualcomm Inc + +@@ -207,9 +264,15 @@ acpi:RKCP*: + acpi:RZSN*: + ID_VENDOR_FROM_DATABASE=Rozsnyó, s.r.o. + ++acpi:SECC*: ++ ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation ++ + acpi:SHRP*: + ID_VENDOR_FROM_DATABASE=Sharp Corporation + ++acpi:SNSL*: ++ ID_VENDOR_FROM_DATABASE=Sensel, Inc. ++ + acpi:SONY*: + ID_VENDOR_FROM_DATABASE=Sony Corporation + +@@ -226,7 +289,7 @@ acpi:TCAG*: + ID_VENDOR_FROM_DATABASE=Teracue AG + + acpi:TOSB*: +- ID_VENDOR_FROM_DATABASE=Toshiba Corporation ++ ID_VENDOR_FROM_DATABASE=Dynabook Inc. + + acpi:TXNW*: + ID_VENDOR_FROM_DATABASE=Texas Instruments +@@ -240,6 +303,9 @@ acpi:VAIO*: + acpi:VFSI*: + ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc + ++acpi:VSHY*: ++ ID_VENDOR_FROM_DATABASE=Vishay Intertechnology, Inc. ++ + acpi:WCOM*: + ID_VENDOR_FROM_DATABASE=Wacom + +@@ -450,6 +516,9 @@ acpi:AGT*: + acpi:AHC*: + ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd. + ++acpi:AHQ*: ++ ID_VENDOR_FROM_DATABASE=Astro HQ LLC ++ + acpi:AHS*: + ID_VENDOR_FROM_DATABASE=Beijing AnHeng SecoTech Information Technology Co., Ltd. + +@@ -547,7 +616,7 @@ acpi:ALO*: + ID_VENDOR_FROM_DATABASE=Algolith Inc. + + acpi:ALP*: +- ID_VENDOR_FROM_DATABASE=Alps Electric Company Ltd ++ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD. + + acpi:ALR*: + ID_VENDOR_FROM_DATABASE=Advanced Logic +@@ -673,7 +742,7 @@ acpi:APD*: + ID_VENDOR_FROM_DATABASE=AppliAdata + + acpi:APE*: +- ID_VENDOR_FROM_DATABASE=Alpine Electronics, Inc. ++ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD. + + acpi:APG*: + ID_VENDOR_FROM_DATABASE=Horner Electric Inc +@@ -838,7 +907,7 @@ acpi:AUG*: + ID_VENDOR_FROM_DATABASE=August Home, Inc. + + acpi:AUI*: +- ID_VENDOR_FROM_DATABASE=Alps Electric Inc ++ ID_VENDOR_FROM_DATABASE=ALPS ALPINE CO., LTD. + + acpi:AUO*: + ID_VENDOR_FROM_DATABASE=AU Optronics +@@ -1053,6 +1122,9 @@ acpi:BIO*: + acpi:BIT*: + ID_VENDOR_FROM_DATABASE=Bit 3 Computer + ++acpi:BLD*: ++ ID_VENDOR_FROM_DATABASE=BILD INNOVATIVE TECHNOLOGY LLC ++ + acpi:BLI*: + ID_VENDOR_FROM_DATABASE=Busicom + +@@ -1317,6 +1389,9 @@ acpi:CET*: + acpi:CFG*: + ID_VENDOR_FROM_DATABASE=Atlantis + ++acpi:CFR*: ++ ID_VENDOR_FROM_DATABASE=Meta View, Inc. ++ + acpi:CGA*: + ID_VENDOR_FROM_DATABASE=Chunghwa Picture Tubes, LTD + +@@ -1371,6 +1446,9 @@ acpi:CHY*: + acpi:CIC*: + ID_VENDOR_FROM_DATABASE=Comm. Intelligence Corporation + ++acpi:CIE*: ++ ID_VENDOR_FROM_DATABASE=Convergent Engineering, Inc. ++ + acpi:CII*: + ID_VENDOR_FROM_DATABASE=Cromack Industries Inc + +@@ -1419,6 +1497,9 @@ acpi:CLM*: + acpi:CLO*: + ID_VENDOR_FROM_DATABASE=Clone Computers + ++acpi:CLR*: ++ ID_VENDOR_FROM_DATABASE=Clover Electronics ++ + acpi:CLT*: + ID_VENDOR_FROM_DATABASE=automated computer control systems + +@@ -1440,6 +1521,9 @@ acpi:CMG*: + acpi:CMI*: + ID_VENDOR_FROM_DATABASE=C-Media Electronics + ++acpi:CMK*: ++ ID_VENDOR_FROM_DATABASE=Comark LLC ++ + acpi:CMM*: + ID_VENDOR_FROM_DATABASE=Comtime GmbH + +@@ -1464,6 +1548,9 @@ acpi:CNB*: + acpi:CNC*: + ID_VENDOR_FROM_DATABASE=Alvedon Computers Ltd + ++acpi:CND*: ++ ID_VENDOR_FROM_DATABASE=Micro-Star Int'l Co., Ltd. ++ + acpi:CNE*: + ID_VENDOR_FROM_DATABASE=Cine-tal + +@@ -1563,6 +1650,9 @@ acpi:CRI*: + acpi:CRL*: + ID_VENDOR_FROM_DATABASE=Creative Logic + ++acpi:CRM*: ++ ID_VENDOR_FROM_DATABASE=CORSAIR MEMORY Inc. ++ + acpi:CRN*: + ID_VENDOR_FROM_DATABASE=Cornerstone Imaging + +@@ -1578,6 +1668,9 @@ acpi:CRS*: + acpi:CRV*: + ID_VENDOR_FROM_DATABASE=Cerevo Inc. + ++acpi:CRW*: ++ ID_VENDOR_FROM_DATABASE=Cammegh Limited ++ + acpi:CRX*: + ID_VENDOR_FROM_DATABASE=Cyrix Corporation + +@@ -1911,6 +2004,12 @@ acpi:DLK*: + acpi:DLL*: + ID_VENDOR_FROM_DATABASE=Dell Inc + ++acpi:DLM*: ++ ID_VENDOR_FROM_DATABASE=DLOGIC Ltd. ++ ++acpi:DLO*: ++ ID_VENDOR_FROM_DATABASE=Shenzhen Dlodlo Technologies Co., Ltd. ++ + acpi:DLT*: + ID_VENDOR_FROM_DATABASE=Digitelec Informatique Park Cadera + +@@ -1920,9 +2019,15 @@ acpi:DMB*: + acpi:DMC*: + ID_VENDOR_FROM_DATABASE=Dune Microsystems Corporation + ++acpi:DMG*: ++ ID_VENDOR_FROM_DATABASE=Monoprice.Inc ++ + acpi:DMM*: + ID_VENDOR_FROM_DATABASE=Dimond Multimedia Systems Inc + ++acpi:DMN*: ++ ID_VENDOR_FROM_DATABASE=Dimension Engineering LLC ++ + acpi:DMO*: + ID_VENDOR_FROM_DATABASE=Data Modul AG + +@@ -2019,6 +2124,9 @@ acpi:DSA*: + acpi:DSD*: + ID_VENDOR_FROM_DATABASE=DS Multimedia Pte Ltd + ++acpi:DSG*: ++ ID_VENDOR_FROM_DATABASE=Disguise Technologies ++ + acpi:DSI*: + ID_VENDOR_FROM_DATABASE=Digitan Systems Inc + +@@ -2229,6 +2337,9 @@ acpi:ELA*: + acpi:ELC*: + ID_VENDOR_FROM_DATABASE=Electro Scientific Ind + ++acpi:ELD*: ++ ID_VENDOR_FROM_DATABASE=Express Luck, Inc. ++ + acpi:ELE*: + ID_VENDOR_FROM_DATABASE=Elecom Company Ltd + +@@ -2283,6 +2394,9 @@ acpi:EMK*: + acpi:EMO*: + ID_VENDOR_FROM_DATABASE=ELMO COMPANY, LIMITED + ++acpi:EMR*: ++ ID_VENDOR_FROM_DATABASE=ICC Intelligent Platforms GmbH ++ + acpi:EMU*: + ID_VENDOR_FROM_DATABASE=Emulex Corporation + +@@ -2490,6 +2604,9 @@ acpi:FDI*: + acpi:FDT*: + ID_VENDOR_FROM_DATABASE=Fujitsu Display Technologies Corp. + ++acpi:FDX*: ++ ID_VENDOR_FROM_DATABASE=Findex, Inc. ++ + acpi:FEC*: + ID_VENDOR_FROM_DATABASE=FURUNO ELECTRIC CO., LTD. + +@@ -2658,6 +2775,9 @@ acpi:FTW*: + acpi:FUJ*: + ID_VENDOR_FROM_DATABASE=Fujitsu Ltd + ++acpi:FUL*: ++ ID_VENDOR_FROM_DATABASE=Fun Technology Innovation INC. ++ + acpi:FUN*: + ID_VENDOR_FROM_DATABASE=sisel muhendislik + +@@ -2697,6 +2817,9 @@ acpi:GAL*: + acpi:GAU*: + ID_VENDOR_FROM_DATABASE=Gaudi Co., Ltd. + ++acpi:GBT*: ++ ID_VENDOR_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO., LTD. ++ + acpi:GCC*: + ID_VENDOR_FROM_DATABASE=GCC Technologies Inc + +@@ -2842,7 +2965,7 @@ acpi:GSC*: + ID_VENDOR_FROM_DATABASE=General Standards Corporation + + acpi:GSM*: +- ID_VENDOR_FROM_DATABASE=Goldstar Company Ltd ++ ID_VENDOR_FROM_DATABASE=LG Electronics + + acpi:GSN*: + ID_VENDOR_FROM_DATABASE=Grandstream Networks, Inc. +@@ -2961,6 +3084,9 @@ acpi:HHC*: + acpi:HHI*: + ID_VENDOR_FROM_DATABASE=Fraunhofer Heinrich-Hertz-Institute + ++acpi:HHT*: ++ ID_VENDOR_FROM_DATABASE=Hitevision Group ++ + acpi:HIB*: + ID_VENDOR_FROM_DATABASE=Hibino Corporation + +@@ -3081,6 +3207,9 @@ acpi:HSL*: + acpi:HSM*: + ID_VENDOR_FROM_DATABASE=AT&T Microelectronics + ++acpi:HSN*: ++ ID_VENDOR_FROM_DATABASE=Hansung Co., Ltd ++ + acpi:HSP*: + ID_VENDOR_FROM_DATABASE=HannStar Display Corp + +@@ -3216,6 +3345,9 @@ acpi:ICO*: + acpi:ICP*: + ID_VENDOR_FROM_DATABASE=ICP Electronics, Inc./iEi Technology Corp. + ++acpi:ICR*: ++ ID_VENDOR_FROM_DATABASE=Icron ++ + acpi:ICS*: + ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems + +@@ -3405,6 +3537,9 @@ acpi:INZ*: + acpi:IOA*: + ID_VENDOR_FROM_DATABASE=CRE Technology Corporation + ++acpi:IOC*: ++ ID_VENDOR_FROM_DATABASE=Guangxi Century Innovation Display Electronics Co., Ltd ++ + acpi:IOD*: + ID_VENDOR_FROM_DATABASE=I-O Data Device Inc + +@@ -3753,6 +3888,9 @@ acpi:KOE*: + acpi:KOL*: + ID_VENDOR_FROM_DATABASE=Kollmorgen Motion Technologies Group + ++acpi:KOM*: ++ ID_VENDOR_FROM_DATABASE=Kontron GmbH ++ + acpi:KOU*: + ID_VENDOR_FROM_DATABASE=KOUZIRO Co.,Ltd. + +@@ -3807,6 +3945,9 @@ acpi:KTK*: + acpi:KTN*: + ID_VENDOR_FROM_DATABASE=Katron Tech Inc + ++acpi:KTS*: ++ ID_VENDOR_FROM_DATABASE=Kyokko Communication System Co., Ltd. ++ + acpi:KUR*: + ID_VENDOR_FROM_DATABASE=Kurta Corporation + +@@ -3882,6 +4023,9 @@ acpi:LCM*: + acpi:LCN*: + ID_VENDOR_FROM_DATABASE=LEXICON + ++acpi:LCP*: ++ ID_VENDOR_FROM_DATABASE=Silent Power Electronics GmbH ++ + acpi:LCS*: + ID_VENDOR_FROM_DATABASE=Longshine Electronics Company + +@@ -3933,6 +4077,9 @@ acpi:LGX*: + acpi:LHA*: + ID_VENDOR_FROM_DATABASE=Lars Haagh ApS + ++acpi:LHC*: ++ ID_VENDOR_FROM_DATABASE=Beihai Century Joint Innovation Technology Co.,Ltd ++ + acpi:LHE*: + ID_VENDOR_FROM_DATABASE=Lung Hwa Electronics Company Ltd + +@@ -3945,6 +4092,9 @@ acpi:LIN*: + acpi:LIP*: + ID_VENDOR_FROM_DATABASE=Linked IP GmbH + ++acpi:LIS*: ++ ID_VENDOR_FROM_DATABASE=Life is Style Inc. ++ + acpi:LIT*: + ID_VENDOR_FROM_DATABASE=Lithics Silicon Technology + +@@ -4152,6 +4302,9 @@ acpi:MCG*: + acpi:MCI*: + ID_VENDOR_FROM_DATABASE=Micronics Computers + ++acpi:MCJ*: ++ ID_VENDOR_FROM_DATABASE=Medicaroid Corporation ++ + acpi:MCL*: + ID_VENDOR_FROM_DATABASE=Motorola Communications Israel + +@@ -4293,6 +4446,9 @@ acpi:MGL*: + acpi:MGT*: + ID_VENDOR_FROM_DATABASE=Megatech R & D Company + ++acpi:MHQ*: ++ ID_VENDOR_FROM_DATABASE=Moxa Inc. ++ + acpi:MIC*: + ID_VENDOR_FROM_DATABASE=Micom Communications Inc + +@@ -4344,6 +4500,9 @@ acpi:MKT*: + acpi:MKV*: + ID_VENDOR_FROM_DATABASE=Trtheim Technology + ++acpi:MLC*: ++ ID_VENDOR_FROM_DATABASE=MILCOTS ++ + acpi:MLD*: + ID_VENDOR_FROM_DATABASE=Deep Video Imaging Ltd + +@@ -4395,6 +4554,9 @@ acpi:MMN*: + acpi:MMS*: + ID_VENDOR_FROM_DATABASE=MMS Electronics + ++acpi:MMT*: ++ ID_VENDOR_FROM_DATABASE=MIMO Monitors ++ + acpi:MNC*: + ID_VENDOR_FROM_DATABASE=Mini Micro Methods Ltd + +@@ -4443,6 +4605,9 @@ acpi:MPN*: + acpi:MPS*: + ID_VENDOR_FROM_DATABASE=mps Software GmbH + ++acpi:MPV*: ++ ID_VENDOR_FROM_DATABASE=Megapixel Visual Realty ++ + acpi:MPX*: + ID_VENDOR_FROM_DATABASE=Micropix Technologies, Ltd. + +@@ -4638,6 +4803,9 @@ acpi:NAC*: + acpi:NAD*: + ID_VENDOR_FROM_DATABASE=NAD Electronics + ++acpi:NAF*: ++ ID_VENDOR_FROM_DATABASE=NAFASAE INDIA Pvt. Ltd ++ + acpi:NAK*: + ID_VENDOR_FROM_DATABASE=Nakano Engineering Co.,Ltd. + +@@ -4740,6 +4908,9 @@ acpi:NGC*: + acpi:NGS*: + ID_VENDOR_FROM_DATABASE=A D S Exports + ++acpi:NHC*: ++ ID_VENDOR_FROM_DATABASE=New H3C Technology Co., Ltd. ++ + acpi:NHT*: + ID_VENDOR_FROM_DATABASE=Vinci Labs + +@@ -4884,6 +5055,9 @@ acpi:NVT*: + acpi:NWC*: + ID_VENDOR_FROM_DATABASE=NW Computer Engineering + ++acpi:NWL*: ++ ID_VENDOR_FROM_DATABASE=Newline Interactive Inc. ++ + acpi:NWP*: + ID_VENDOR_FROM_DATABASE=NovaWeb Technologies Inc + +@@ -4905,6 +5079,9 @@ acpi:NXQ*: + acpi:NXS*: + ID_VENDOR_FROM_DATABASE=Technology Nexus Secure Open Systems AB + ++acpi:NXT*: ++ ID_VENDOR_FROM_DATABASE=NZXT (PNP same EDID)_ ++ + acpi:NYC*: + ID_VENDOR_FROM_DATABASE=Nakayo Relecommunications, Inc. + +@@ -5085,6 +5262,9 @@ acpi:PAC*: + acpi:PAD*: + ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd. + ++acpi:PAE*: ++ ID_VENDOR_FROM_DATABASE=PreSonus Audio Electronics ++ + acpi:PAK*: + ID_VENDOR_FROM_DATABASE=Many CNC System Co., Ltd. + +@@ -5241,6 +5421,12 @@ acpi:PIM*: + acpi:PIO*: + ID_VENDOR_FROM_DATABASE=Pioneer Electronic Corporation + ++acpi:PIR*: ++ ID_VENDOR_FROM_DATABASE=Pico Technology Inc. ++ ++acpi:PIS*: ++ ID_VENDOR_FROM_DATABASE=TECNART CO.,LTD. ++ + acpi:PIX*: + ID_VENDOR_FROM_DATABASE=Pixie Tech Inc + +@@ -5514,6 +5700,9 @@ acpi:QLC*: + acpi:QQQ*: + ID_VENDOR_FROM_DATABASE=Chuomusen Co., Ltd. + ++acpi:QSC*: ++ ID_VENDOR_FROM_DATABASE=QSC, LLC ++ + acpi:QSI*: + ID_VENDOR_FROM_DATABASE=Quantum Solutions, Inc. + +@@ -5778,6 +5967,9 @@ acpi:RWC*: + acpi:RXT*: + ID_VENDOR_FROM_DATABASE=Tectona SoftSolutions (P) Ltd., + ++acpi:RZR*: ++ ID_VENDOR_FROM_DATABASE=Razer Taiwan Co. Ltd. ++ + acpi:RZS*: + ID_VENDOR_FROM_DATABASE=Rozsnyó, s.r.o. + +@@ -5835,6 +6027,9 @@ acpi:SCD*: + acpi:SCE*: + ID_VENDOR_FROM_DATABASE=Sun Corporation + ++acpi:SCG*: ++ ID_VENDOR_FROM_DATABASE=Seco S.p.A. ++ + acpi:SCH*: + ID_VENDOR_FROM_DATABASE=Schlumberger Cards + +@@ -6048,12 +6243,21 @@ acpi:SJE*: + acpi:SKD*: + ID_VENDOR_FROM_DATABASE=Schneider & Koch + ++acpi:SKG*: ++ ID_VENDOR_FROM_DATABASE=Shenzhen KTC Technology Group ++ ++acpi:SKI*: ++ ID_VENDOR_FROM_DATABASE=LLC SKTB “SKIT” ++ + acpi:SKM*: + ID_VENDOR_FROM_DATABASE=Guangzhou Teclast Information Technology Limited + + acpi:SKT*: + ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Company Ltd + ++acpi:SKW*: ++ ID_VENDOR_FROM_DATABASE=Skyworth ++ + acpi:SKY*: + ID_VENDOR_FROM_DATABASE=SKYDATA S.P.A. + +@@ -6612,6 +6816,9 @@ acpi:TGS*: + acpi:TGV*: + ID_VENDOR_FROM_DATABASE=Grass Valley Germany GmbH + ++acpi:TGW*: ++ ID_VENDOR_FROM_DATABASE=TECHNOGYM S.p.A. ++ + acpi:THN*: + ID_VENDOR_FROM_DATABASE=Thundercom Holdings Sdn. Bhd. + +@@ -6681,6 +6888,9 @@ acpi:TLV*: + acpi:TLX*: + ID_VENDOR_FROM_DATABASE=Telxon Corporation + ++acpi:TLY*: ++ ID_VENDOR_FROM_DATABASE=Truly Semiconductors Ltd. ++ + acpi:TMC*: + ID_VENDOR_FROM_DATABASE=Techmedia Computer Systems Corporation + +@@ -6693,6 +6903,9 @@ acpi:TMI*: + acpi:TMM*: + ID_VENDOR_FROM_DATABASE=Time Management, Inc. + ++acpi:TMO*: ++ ID_VENDOR_FROM_DATABASE=Terumo Corporation ++ + acpi:TMR*: + ID_VENDOR_FROM_DATABASE=Taicom International Inc + +@@ -6733,7 +6946,7 @@ acpi:TOP*: + ID_VENDOR_FROM_DATABASE=Orion Communications Co., Ltd. + + acpi:TOS*: +- ID_VENDOR_FROM_DATABASE=Toshiba Corporation ++ ID_VENDOR_FROM_DATABASE=Dynabook Inc. + + acpi:TOU*: + ID_VENDOR_FROM_DATABASE=Touchstone Technology +@@ -6879,6 +7092,9 @@ acpi:TTL*: + acpi:TTP*: + ID_VENDOR_FROM_DATABASE=Toshiba Corporation + ++acpi:TTR*: ++ ID_VENDOR_FROM_DATABASE=Hubei Century Joint Innovation Technology Co.Ltd ++ + acpi:TTS*: + ID_VENDOR_FROM_DATABASE=TechnoTrend Systemtechnik GmbH + +@@ -7071,6 +7287,9 @@ acpi:USI*: + acpi:USR*: + ID_VENDOR_FROM_DATABASE=U.S. Robotics Inc + ++acpi:UTC*: ++ ID_VENDOR_FROM_DATABASE=Unicompute Technology Co., Ltd. ++ + acpi:UTD*: + ID_VENDOR_FROM_DATABASE=Up to Date Tech + +@@ -7089,6 +7308,12 @@ acpi:VAL*: + acpi:VAR*: + ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd + ++acpi:VAT*: ++ ID_VENDOR_FROM_DATABASE=VADATECH INC ++ ++acpi:VAV*: ++ ID_VENDOR_FROM_DATABASE=aviica ++ + acpi:VBR*: + ID_VENDOR_FROM_DATABASE=VBrick Systems Inc. + +@@ -7164,6 +7389,9 @@ acpi:VIM*: + acpi:VIN*: + ID_VENDOR_FROM_DATABASE=Vine Micros Ltd + ++acpi:VIO*: ++ ID_VENDOR_FROM_DATABASE=Zake IP Holdings LLC (3B tech) ++ + acpi:VIR*: + ID_VENDOR_FROM_DATABASE=Visual Interface, Inc + +@@ -7185,6 +7413,9 @@ acpi:VLC*: + acpi:VLK*: + ID_VENDOR_FROM_DATABASE=Vislink International Ltd + ++acpi:VLM*: ++ ID_VENDOR_FROM_DATABASE=LENOVO BEIJING CO. LTD. ++ + acpi:VLT*: + ID_VENDOR_FROM_DATABASE=VideoLan Technologies + +@@ -7350,6 +7581,9 @@ acpi:WKH*: + acpi:WLD*: + ID_VENDOR_FROM_DATABASE=Wildfire Communications Inc + ++acpi:WLF*: ++ ID_VENDOR_FROM_DATABASE=WOLF Advanced Technology ++ + acpi:WML*: + ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics Ltd + +@@ -7366,7 +7600,7 @@ acpi:WNV*: + ID_VENDOR_FROM_DATABASE=Winnov L.P. + + acpi:WNX*: +- ID_VENDOR_FROM_DATABASE=Wincor Nixdorf International GmbH ++ ID_VENDOR_FROM_DATABASE=Diebold Nixdorf Systems GmbH + + acpi:WPA*: + ID_VENDOR_FROM_DATABASE=Matsushita Communication Industrial Co., Ltd. +@@ -7413,6 +7647,9 @@ acpi:WWV*: + acpi:WXT*: + ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd + ++acpi:WYR*: ++ ID_VENDOR_FROM_DATABASE=WyreStorm Technologies LLC ++ + acpi:WYS*: + ID_VENDOR_FROM_DATABASE=Wyse Technology + +@@ -7516,7 +7753,7 @@ acpi:ZAX*: + ID_VENDOR_FROM_DATABASE=Zefiro Acoustics + + acpi:ZAZ*: +- ID_VENDOR_FROM_DATABASE=Zazzle Technologies ++ ID_VENDOR_FROM_DATABASE=ZeeVee, Inc. + + acpi:ZBR*: + ID_VENDOR_FROM_DATABASE=Zebra Technologies International, LLC +diff --git a/hwdb/20-bluetooth-vendor-product.hwdb b/hwdb/20-bluetooth-vendor-product.hwdb +index 9cba3bfc05..1d92f57ecc 100644 +--- a/hwdb/20-bluetooth-vendor-product.hwdb ++++ b/hwdb/20-bluetooth-vendor-product.hwdb +@@ -46,7 +46,7 @@ bluetooth:v000D* + ID_VENDOR_FROM_DATABASE=Texas Instruments Inc. + + bluetooth:v000E* +- ID_VENDOR_FROM_DATABASE=Ceva, Inc. (formerly Parthus Technologies, Inc.) ++ ID_VENDOR_FROM_DATABASE=Parthus Technologies Inc. + + bluetooth:v000F* + ID_VENDOR_FROM_DATABASE=Broadcom Corporation +@@ -55,7 +55,7 @@ bluetooth:v0010* + ID_VENDOR_FROM_DATABASE=Mitel Semiconductor + + bluetooth:v0011* +- ID_VENDOR_FROM_DATABASE=Widcomm, Inc ++ ID_VENDOR_FROM_DATABASE=Widcomm, Inc. + + bluetooth:v0012* + ID_VENDOR_FROM_DATABASE=Zeevo, Inc. +@@ -73,7 +73,7 @@ bluetooth:v0016* + ID_VENDOR_FROM_DATABASE=KC Technology Inc. + + bluetooth:v0017* +- ID_VENDOR_FROM_DATABASE=NewLogic ++ ID_VENDOR_FROM_DATABASE=Newlogic + + bluetooth:v0018* + ID_VENDOR_FROM_DATABASE=Transilica, Inc. +@@ -172,13 +172,13 @@ bluetooth:v0037* + ID_VENDOR_FROM_DATABASE=Mobilian Corporation + + bluetooth:v0038* +- ID_VENDOR_FROM_DATABASE=Terax ++ ID_VENDOR_FROM_DATABASE=Syntronix Corporation + + bluetooth:v0039* + ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp. + + bluetooth:v003A* +- ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd. ++ ID_VENDOR_FROM_DATABASE=Panasonic Corporation (formerly Matsushita Electric Industrial Co., Ltd.) + + bluetooth:v003B* + ID_VENDOR_FROM_DATABASE=Gennum Corporation +@@ -190,10 +190,10 @@ bluetooth:v003D* + ID_VENDOR_FROM_DATABASE=IPextreme, Inc. + + bluetooth:v003E* +- ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc. ++ ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc + + bluetooth:v003F* +- ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc. ++ ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc + + bluetooth:v0040* + ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation +@@ -205,7 +205,7 @@ bluetooth:v0042* + ID_VENDOR_FROM_DATABASE=CONWISE Technology Corporation Ltd + + bluetooth:v0043* +- ID_VENDOR_FROM_DATABASE=PARROT SA ++ ID_VENDOR_FROM_DATABASE=PARROT AUTOMOTIVE SAS + + bluetooth:v0044* + ID_VENDOR_FROM_DATABASE=Socket Mobile +@@ -241,10 +241,10 @@ bluetooth:v004E* + ID_VENDOR_FROM_DATABASE=Avago Technologies + + bluetooth:v004F* +- ID_VENDOR_FROM_DATABASE=APT Licensing Ltd. ++ ID_VENDOR_FROM_DATABASE=APT Ltd. + + bluetooth:v0050* +- ID_VENDOR_FROM_DATABASE=SiRF Technology ++ ID_VENDOR_FROM_DATABASE=SiRF Technology, Inc. + + bluetooth:v0051* + ID_VENDOR_FROM_DATABASE=Tzero Technologies, Inc. +@@ -331,7 +331,7 @@ bluetooth:v006C* + ID_VENDOR_FROM_DATABASE=Beautiful Enterprise Co., Ltd. + + bluetooth:v006D* +- ID_VENDOR_FROM_DATABASE=BriarTek, Inc. ++ ID_VENDOR_FROM_DATABASE=BriarTek, Inc + + bluetooth:v006E* + ID_VENDOR_FROM_DATABASE=Summit Data Communications, Inc. +@@ -382,7 +382,7 @@ bluetooth:v007C* + ID_VENDOR_FROM_DATABASE=A & R Cambridge + + bluetooth:v007D* +- ID_VENDOR_FROM_DATABASE=Seers Technology Co. Ltd ++ ID_VENDOR_FROM_DATABASE=Seers Technology Co., Ltd. + + bluetooth:v007E* + ID_VENDOR_FROM_DATABASE=Sports Tracking Technologies Ltd. +@@ -409,7 +409,7 @@ bluetooth:v0085* + ID_VENDOR_FROM_DATABASE=BlueRadios, Inc. + + bluetooth:v0086* +- ID_VENDOR_FROM_DATABASE=equinox AG ++ ID_VENDOR_FROM_DATABASE=Equinux AG + + bluetooth:v0087* + ID_VENDOR_FROM_DATABASE=Garmin International, Inc. +@@ -433,16 +433,16 @@ bluetooth:v008D* + ID_VENDOR_FROM_DATABASE=Zscan Software + + bluetooth:v008E* +- ID_VENDOR_FROM_DATABASE=Quintic Corp. ++ ID_VENDOR_FROM_DATABASE=Quintic Corp + + bluetooth:v008F* +- ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions GmbH (Formerly Stollman E+V GmbH) ++ ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions GmbH (formerly Stollmann E+V GmbH) + + bluetooth:v0090* + ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd. + + bluetooth:v0091* +- ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL Systems GmbH & Co. KG ++ ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL systems GmbH & Co. KG + + bluetooth:v0092* + ID_VENDOR_FROM_DATABASE=ThinkOptics, Inc. +@@ -462,8 +462,11 @@ bluetooth:v0096* + bluetooth:v0097* + ID_VENDOR_FROM_DATABASE=ConnecteDevice Ltd. + ++bluetooth:v0097p0002* ++ ID_PRODUCT_FROM_DATABASE=COOKOO watch ++ + bluetooth:v0098* +- ID_VENDOR_FROM_DATABASE=zer01.tv GmbH ++ ID_VENDOR_FROM_DATABASE=zero1.tv GmbH + + bluetooth:v0099* + ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Global Distribution Ltd. +@@ -514,7 +517,7 @@ bluetooth:v00A8* + ID_VENDOR_FROM_DATABASE=ARP Devices Limited + + bluetooth:v00A9* +- ID_VENDOR_FROM_DATABASE=Magneti Marelli S.p.A ++ ID_VENDOR_FROM_DATABASE=MARELLI EUROPE S.P.A. (formerly Magneti Marelli S.p.A.) + + bluetooth:v00AA* + ID_VENDOR_FROM_DATABASE=CAEN RFID srl +@@ -712,7 +715,7 @@ bluetooth:v00EA* + ID_VENDOR_FROM_DATABASE=Nielsen-Kellerman Company + + bluetooth:v00EB* +- ID_VENDOR_FROM_DATABASE=Server Technology, Inc. ++ ID_VENDOR_FROM_DATABASE=Server Technology Inc. + + bluetooth:v00EC* + ID_VENDOR_FROM_DATABASE=BioResearch Associates +@@ -733,7 +736,7 @@ bluetooth:v00F1* + ID_VENDOR_FROM_DATABASE=Witron Technology Limited + + bluetooth:v00F2* +- ID_VENDOR_FROM_DATABASE=Aether Things Inc. (formerly Morse Project Inc.) ++ ID_VENDOR_FROM_DATABASE=Morse Project Inc. + + bluetooth:v00F3* + ID_VENDOR_FROM_DATABASE=Kent Displays Inc. +@@ -748,7 +751,7 @@ bluetooth:v00F6* + ID_VENDOR_FROM_DATABASE=Elcometer Limited + + bluetooth:v00F7* +- ID_VENDOR_FROM_DATABASE=VSN Technologies Inc. ++ ID_VENDOR_FROM_DATABASE=VSN Technologies, Inc. + + bluetooth:v00F8* + ID_VENDOR_FROM_DATABASE=AceUni Corp., Ltd. +@@ -769,7 +772,7 @@ bluetooth:v00FD* + ID_VENDOR_FROM_DATABASE=ValenceTech Limited + + bluetooth:v00FE* +- ID_VENDOR_FROM_DATABASE=Reserved ++ ID_VENDOR_FROM_DATABASE=Stanley Black and Decker + + bluetooth:v00FF* + ID_VENDOR_FROM_DATABASE=Typo Products, LLC +@@ -778,7 +781,7 @@ bluetooth:v0100* + ID_VENDOR_FROM_DATABASE=TomTom International BV + + bluetooth:v0101* +- ID_VENDOR_FROM_DATABASE=Fugoo, Inc ++ ID_VENDOR_FROM_DATABASE=Fugoo, Inc. + + bluetooth:v0102* + ID_VENDOR_FROM_DATABASE=Keiser Corporation +@@ -787,7 +790,7 @@ bluetooth:v0103* + ID_VENDOR_FROM_DATABASE=Bang & Olufsen A/S + + bluetooth:v0104* +- ID_VENDOR_FROM_DATABASE=PLUS Locations Systems Pty Ltd ++ ID_VENDOR_FROM_DATABASE=PLUS Location Systems Pty Ltd + + bluetooth:v0105* + ID_VENDOR_FROM_DATABASE=Ubiquitous Computing Technology Corporation +@@ -805,22 +808,22 @@ bluetooth:v0109* + ID_VENDOR_FROM_DATABASE=Atus BV + + bluetooth:v010A* +- ID_VENDOR_FROM_DATABASE=Codegate Ltd. ++ ID_VENDOR_FROM_DATABASE=Codegate Ltd + + bluetooth:v010B* +- ID_VENDOR_FROM_DATABASE=ERi, Inc. ++ ID_VENDOR_FROM_DATABASE=ERi, Inc + + bluetooth:v010C* + ID_VENDOR_FROM_DATABASE=Transducers Direct, LLC + + bluetooth:v010D* +- ID_VENDOR_FROM_DATABASE=Fujitsu Ten Limited ++ ID_VENDOR_FROM_DATABASE=DENSO TEN LIMITED (formerly Fujitsu Ten LImited) + + bluetooth:v010E* + ID_VENDOR_FROM_DATABASE=Audi AG + + bluetooth:v010F* +- ID_VENDOR_FROM_DATABASE=HiSilicon Technologies Co., Ltd. ++ ID_VENDOR_FROM_DATABASE=HiSilicon Technologies CO., LIMITED + + bluetooth:v0110* + ID_VENDOR_FROM_DATABASE=Nippon Seiki Co., Ltd. +@@ -841,7 +844,7 @@ bluetooth:v0115* + ID_VENDOR_FROM_DATABASE=e.solutions + + bluetooth:v0116* +- ID_VENDOR_FROM_DATABASE=1OAK Technologies ++ ID_VENDOR_FROM_DATABASE=10AK Technologies + + bluetooth:v0117* + ID_VENDOR_FROM_DATABASE=Wimoto Technologies Inc +@@ -880,7 +883,7 @@ bluetooth:v0122* + ID_VENDOR_FROM_DATABASE=AirTurn, Inc. + + bluetooth:v0123* +- ID_VENDOR_FROM_DATABASE=Kinsa, Inc. ++ ID_VENDOR_FROM_DATABASE=Kinsa, Inc + + bluetooth:v0124* + ID_VENDOR_FROM_DATABASE=HID Global +@@ -901,7 +904,7 @@ bluetooth:v0129* + ID_VENDOR_FROM_DATABASE=Nimble Devices Oy + + bluetooth:v012A* +- ID_VENDOR_FROM_DATABASE=Changzhou Yongse Infotech Co., Ltd ++ ID_VENDOR_FROM_DATABASE=Changzhou Yongse Infotech Co., Ltd. + + bluetooth:v012B* + ID_VENDOR_FROM_DATABASE=SportIQ +@@ -916,13 +919,13 @@ bluetooth:v012E* + ID_VENDOR_FROM_DATABASE=ASSA ABLOY + + bluetooth:v012F* +- ID_VENDOR_FROM_DATABASE=Clarion Co., Ltd. ++ ID_VENDOR_FROM_DATABASE=Clarion Co. Inc. + + bluetooth:v0130* + ID_VENDOR_FROM_DATABASE=Warehouse Innovations + + bluetooth:v0131* +- ID_VENDOR_FROM_DATABASE=Cypress Semiconductor Corporation ++ ID_VENDOR_FROM_DATABASE=Cypress Semiconductor + + bluetooth:v0132* + ID_VENDOR_FROM_DATABASE=MADS Inc +@@ -931,13 +934,13 @@ bluetooth:v0133* + ID_VENDOR_FROM_DATABASE=Blue Maestro Limited + + bluetooth:v0134* +- ID_VENDOR_FROM_DATABASE=Resolution Products, Inc. ++ ID_VENDOR_FROM_DATABASE=Resolution Products, Ltd. + + bluetooth:v0135* +- ID_VENDOR_FROM_DATABASE=Airewear LLC ++ ID_VENDOR_FROM_DATABASE=Aireware LLC + + bluetooth:v0136* +- ID_VENDOR_FROM_DATABASE=Seed Labs, Inc. (formerly ETC sp. z.o.o.) ++ ID_VENDOR_FROM_DATABASE=Silvair, Inc. + + bluetooth:v0137* + ID_VENDOR_FROM_DATABASE=Prestigio Plaza Ltd. +@@ -949,13 +952,13 @@ bluetooth:v0139* + ID_VENDOR_FROM_DATABASE=Focus Systems Corporation + + bluetooth:v013A* +- ID_VENDOR_FROM_DATABASE=Tencent Holdings Limited ++ ID_VENDOR_FROM_DATABASE=Tencent Holdings Ltd. + + bluetooth:v013B* + ID_VENDOR_FROM_DATABASE=Allegion + + bluetooth:v013C* +- ID_VENDOR_FROM_DATABASE=Murata Manufacuring Co., Ltd. ++ ID_VENDOR_FROM_DATABASE=Murata Manufacturing Co., Ltd. + + bluetooth:v013D* + ID_VENDOR_FROM_DATABASE=WirelessWERX +@@ -1006,7 +1009,7 @@ bluetooth:v014C* + ID_VENDOR_FROM_DATABASE=Mesh-Net Ltd + + bluetooth:v014D* +- ID_VENDOR_FROM_DATABASE=Huizhou Desay SV Automotive CO., LTD. ++ ID_VENDOR_FROM_DATABASE=HUIZHOU DESAY SV AUTOMOTIVE CO., LTD. + + bluetooth:v014E* + ID_VENDOR_FROM_DATABASE=Tangerine, Inc. +@@ -1069,7 +1072,7 @@ bluetooth:v0161* + ID_VENDOR_FROM_DATABASE=yikes + + bluetooth:v0162* +- ID_VENDOR_FROM_DATABASE=MADSGlobal NZ Ltd. ++ ID_VENDOR_FROM_DATABASE=MADSGlobalNZ Ltd. + + bluetooth:v0163* + ID_VENDOR_FROM_DATABASE=PCH International +@@ -1078,13 +1081,13 @@ bluetooth:v0164* + ID_VENDOR_FROM_DATABASE=Qingdao Yeelink Information Technology Co., Ltd. + + bluetooth:v0165* +- ID_VENDOR_FROM_DATABASE=Milwaukee Tool (formerly Milwaukee Electric Tools) ++ ID_VENDOR_FROM_DATABASE=Milwaukee Tool (Formally Milwaukee Electric Tools) + + bluetooth:v0166* + ID_VENDOR_FROM_DATABASE=MISHIK Pte Ltd + + bluetooth:v0167* +- ID_VENDOR_FROM_DATABASE=Bayer HealthCare ++ ID_VENDOR_FROM_DATABASE=Ascensia Diabetes Care US Inc. + + bluetooth:v0168* + ID_VENDOR_FROM_DATABASE=Spicebox LLC +@@ -1111,7 +1114,7 @@ bluetooth:v016F* + ID_VENDOR_FROM_DATABASE=Podo Labs, Inc + + bluetooth:v0170* +- ID_VENDOR_FROM_DATABASE=F. Hoffmann-La Roche AG ++ ID_VENDOR_FROM_DATABASE=Roche Diabetes Care AG + + bluetooth:v0171* + ID_VENDOR_FROM_DATABASE=Amazon Fulfillment Service +@@ -1123,7 +1126,7 @@ bluetooth:v0173* + ID_VENDOR_FROM_DATABASE=Kocomojo, LLC + + bluetooth:v0174* +- ID_VENDOR_FROM_DATABASE=Everykey LLC ++ ID_VENDOR_FROM_DATABASE=Everykey Inc. + + bluetooth:v0175* + ID_VENDOR_FROM_DATABASE=Dynamic Controls +@@ -1156,7 +1159,7 @@ bluetooth:v017E* + ID_VENDOR_FROM_DATABASE=BluDotz Ltd + + bluetooth:v017F* +- ID_VENDOR_FROM_DATABASE=XTel ApS ++ ID_VENDOR_FROM_DATABASE=XTel Wireless ApS + + bluetooth:v0180* + ID_VENDOR_FROM_DATABASE=Gigaset Communications GmbH +@@ -1168,7 +1171,7 @@ bluetooth:v0182* + ID_VENDOR_FROM_DATABASE=HOP Ubiquitous + + bluetooth:v0183* +- ID_VENDOR_FROM_DATABASE=To Be Assigned ++ ID_VENDOR_FROM_DATABASE=Walt Disney + + bluetooth:v0184* + ID_VENDOR_FROM_DATABASE=Nectar +@@ -1228,10 +1231,10 @@ bluetooth:v0196* + ID_VENDOR_FROM_DATABASE=Paxton Access Ltd + + bluetooth:v0197* +- ID_VENDOR_FROM_DATABASE=WiSilica Inc ++ ID_VENDOR_FROM_DATABASE=WiSilica Inc. + + bluetooth:v0198* +- ID_VENDOR_FROM_DATABASE=VENGIT Korlátolt Felelősségű Társaság ++ ID_VENDOR_FROM_DATABASE=VENGIT Korlatolt Felelossegu Tarsasag + + bluetooth:v0199* + ID_VENDOR_FROM_DATABASE=SALTO SYSTEMS S.L. +@@ -1273,7 +1276,7 @@ bluetooth:v01A5* + ID_VENDOR_FROM_DATABASE=Icon Health and Fitness + + bluetooth:v01A6* +- ID_VENDOR_FROM_DATABASE=Asandoo GmbH ++ ID_VENDOR_FROM_DATABASE=Wille Engineering (formely as Asandoo GmbH) + + bluetooth:v01A7* + ID_VENDOR_FROM_DATABASE=ENERGOUS CORPORATION +@@ -1291,7 +1294,7 @@ bluetooth:v01AB* + ID_VENDOR_FROM_DATABASE=Facebook, Inc. + + bluetooth:v01AC* +- ID_VENDOR_FROM_DATABASE=Nipro Diagnostics, Inc. ++ ID_VENDOR_FROM_DATABASE=Trividia Health, Inc. + + bluetooth:v01AD* + ID_VENDOR_FROM_DATABASE=FlightSafety International +@@ -1402,7 +1405,7 @@ bluetooth:v01D0* + ID_VENDOR_FROM_DATABASE=Primus Inter Pares Ltd + + bluetooth:v01D1* +- ID_VENDOR_FROM_DATABASE=August ++ ID_VENDOR_FROM_DATABASE=August Home, Inc + + bluetooth:v01D2* + ID_VENDOR_FROM_DATABASE=Gill Electronics +@@ -1474,7 +1477,7 @@ bluetooth:v01E8* + ID_VENDOR_FROM_DATABASE=STIR + + bluetooth:v01E9* +- ID_VENDOR_FROM_DATABASE=Sano, Inc ++ ID_VENDOR_FROM_DATABASE=Sano, Inc. + + bluetooth:v01EA* + ID_VENDOR_FROM_DATABASE=Advanced Application Design, Inc. +@@ -1522,10 +1525,10 @@ bluetooth:v01F8* + ID_VENDOR_FROM_DATABASE=Anyka (Guangzhou) Microelectronics Technology Co, LTD + + bluetooth:v01F9* +- ID_VENDOR_FROM_DATABASE=Medtronic, Inc. ++ ID_VENDOR_FROM_DATABASE=Medtronic Inc. + + bluetooth:v01FA* +- ID_VENDOR_FROM_DATABASE=Gozio, Inc. ++ ID_VENDOR_FROM_DATABASE=Gozio Inc. + + bluetooth:v01FB* + ID_VENDOR_FROM_DATABASE=Form Lifting, LLC +@@ -1537,13 +1540,13 @@ bluetooth:v01FD* + ID_VENDOR_FROM_DATABASE=Kontakt Micro-Location Sp. z o.o. + + bluetooth:v01FE* +- ID_VENDOR_FROM_DATABASE=Radio System Corporation ++ ID_VENDOR_FROM_DATABASE=Radio Systems Corporation + + bluetooth:v01FF* + ID_VENDOR_FROM_DATABASE=Freescale Semiconductor, Inc. + + bluetooth:v0200* +- ID_VENDOR_FROM_DATABASE=Verifone Systems PTe Ltd. Taiwan Branch ++ ID_VENDOR_FROM_DATABASE=Verifone Systems Pte Ltd. Taiwan Branch + + bluetooth:v0201* + ID_VENDOR_FROM_DATABASE=AR Timing +@@ -1624,7 +1627,7 @@ bluetooth:v021A* + ID_VENDOR_FROM_DATABASE=Blue Speck Labs, LLC + + bluetooth:v021B* +- ID_VENDOR_FROM_DATABASE=Cisco Systems Inc ++ ID_VENDOR_FROM_DATABASE=Cisco Systems, Inc + + bluetooth:v021C* + ID_VENDOR_FROM_DATABASE=Mobicomm Inc +@@ -1633,10 +1636,10 @@ bluetooth:v021D* + ID_VENDOR_FROM_DATABASE=Edamic + + bluetooth:v021E* +- ID_VENDOR_FROM_DATABASE=Goodnet Ltd ++ ID_VENDOR_FROM_DATABASE=Goodnet, Ltd + + bluetooth:v021F* +- ID_VENDOR_FROM_DATABASE=Luster Leaf Products Inc ++ ID_VENDOR_FROM_DATABASE=Luster Leaf Products Inc + + bluetooth:v0220* + ID_VENDOR_FROM_DATABASE=Manus Machina BV +@@ -1717,7 +1720,7 @@ bluetooth:v0239* + ID_VENDOR_FROM_DATABASE=JIN CO, Ltd + + bluetooth:v023A* +- ID_VENDOR_FROM_DATABASE=Alatech Technology ++ ID_VENDOR_FROM_DATABASE=Alatech Tehnology + + bluetooth:v023B* + ID_VENDOR_FROM_DATABASE=Beijing CarePulse Electronic Technology Co, Ltd +@@ -1732,7 +1735,7 @@ bluetooth:v023E* + ID_VENDOR_FROM_DATABASE=Raven Industries + + bluetooth:v023F* +- ID_VENDOR_FROM_DATABASE=WaveWare Technologies ++ ID_VENDOR_FROM_DATABASE=WaveWare Technologies Inc. + + bluetooth:v0240* + ID_VENDOR_FROM_DATABASE=Argenox Technologies +@@ -1747,10 +1750,10 @@ bluetooth:v0243* + ID_VENDOR_FROM_DATABASE=Masimo Corp + + bluetooth:v0244* +- ID_VENDOR_FROM_DATABASE=Iotera Inc. ++ ID_VENDOR_FROM_DATABASE=Iotera Inc + + bluetooth:v0245* +- ID_VENDOR_FROM_DATABASE=Endress+Hauser ++ ID_VENDOR_FROM_DATABASE=Endress+Hauser  + + bluetooth:v0246* + ID_VENDOR_FROM_DATABASE=ACKme Networks, Inc. +@@ -1819,7 +1822,7 @@ bluetooth:v025B* + ID_VENDOR_FROM_DATABASE=Five Interactive, LLC dba Zendo + + bluetooth:v025C* +- ID_VENDOR_FROM_DATABASE=NetEase (Hangzhou) Network co.Ltd. ++ ID_VENDOR_FROM_DATABASE=NetEase(Hangzhou)Network co.Ltd. + + bluetooth:v025D* + ID_VENDOR_FROM_DATABASE=Lexmark International Inc. +@@ -1897,7 +1900,7 @@ bluetooth:v0275* + ID_VENDOR_FROM_DATABASE=Geotab + + bluetooth:v0276* +- ID_VENDOR_FROM_DATABASE=E.G.O. Elektro-Gerätebau GmbH ++ ID_VENDOR_FROM_DATABASE=E.G.O. Elektro-Geraetebau GmbH + + bluetooth:v0277* + ID_VENDOR_FROM_DATABASE=bewhere inc +@@ -1918,7 +1921,7 @@ bluetooth:v027C* + ID_VENDOR_FROM_DATABASE=Aseptika Ltd + + bluetooth:v027D* +- ID_VENDOR_FROM_DATABASE=HUAWEI Technologies Co., Ltd. ( 华为技术有限公司 ) ++ ID_VENDOR_FROM_DATABASE=HUAWEI Technologies Co., Ltd. + + bluetooth:v027E* + ID_VENDOR_FROM_DATABASE=HabitAware, LLC +@@ -2323,7 +2326,7 @@ bluetooth:v0303* + ID_VENDOR_FROM_DATABASE=IACA electronique + + bluetooth:v0304* +- ID_VENDOR_FROM_DATABASE=Martians Inc ++ ID_VENDOR_FROM_DATABASE=Proxy Technologies, Inc. + + bluetooth:v0305* + ID_VENDOR_FROM_DATABASE=Swipp ApS +@@ -3082,7 +3085,7 @@ bluetooth:v0400* + ID_VENDOR_FROM_DATABASE=i-developer IT Beratung UG + + bluetooth:v0401* +- ID_VENDOR_FROM_DATABASE=リレーションズ株式会社 ++ ID_VENDOR_FROM_DATABASE=Relations Inc. + + bluetooth:v0402* + ID_VENDOR_FROM_DATABASE=Sears Holdings Corporation +@@ -3119,3 +3122,3555 @@ bluetooth:v040C* + + bluetooth:v040D* + ID_VENDOR_FROM_DATABASE=NorthStar Battery Company, LLC ++ ++bluetooth:v040E* ++ ID_VENDOR_FROM_DATABASE=SKF (U.K.) Limited ++ ++bluetooth:v040F* ++ ID_VENDOR_FROM_DATABASE=CO-AX Technology, Inc. ++ ++bluetooth:v0410* ++ ID_VENDOR_FROM_DATABASE=Fender Musical Instruments ++ ++bluetooth:v0411* ++ ID_VENDOR_FROM_DATABASE=Luidia Inc ++ ++bluetooth:v0412* ++ ID_VENDOR_FROM_DATABASE=SEFAM ++ ++bluetooth:v0413* ++ ID_VENDOR_FROM_DATABASE=Wireless Cables Inc ++ ++bluetooth:v0414* ++ ID_VENDOR_FROM_DATABASE=Lightning Protection International Pty Ltd ++ ++bluetooth:v0415* ++ ID_VENDOR_FROM_DATABASE=Uber Technologies Inc ++ ++bluetooth:v0416* ++ ID_VENDOR_FROM_DATABASE=SODA GmbH ++ ++bluetooth:v0417* ++ ID_VENDOR_FROM_DATABASE=Fatigue Science ++ ++bluetooth:v0418* ++ ID_VENDOR_FROM_DATABASE=Alpine Electronics Inc. ++ ++bluetooth:v0419* ++ ID_VENDOR_FROM_DATABASE=Novalogy LTD ++ ++bluetooth:v041A* ++ ID_VENDOR_FROM_DATABASE=Friday Labs Limited ++ ++bluetooth:v041B* ++ ID_VENDOR_FROM_DATABASE=OrthoAccel Technologies ++ ++bluetooth:v041C* ++ ID_VENDOR_FROM_DATABASE=WaterGuru, Inc. ++ ++bluetooth:v041D* ++ ID_VENDOR_FROM_DATABASE=Benning Elektrotechnik und Elektronik GmbH & Co. KG ++ ++bluetooth:v041E* ++ ID_VENDOR_FROM_DATABASE=Dell Computer Corporation ++ ++bluetooth:v041F* ++ ID_VENDOR_FROM_DATABASE=Kopin Corporation ++ ++bluetooth:v0420* ++ ID_VENDOR_FROM_DATABASE=TecBakery GmbH ++ ++bluetooth:v0421* ++ ID_VENDOR_FROM_DATABASE=Backbone Labs, Inc. ++ ++bluetooth:v0422* ++ ID_VENDOR_FROM_DATABASE=DELSEY SA ++ ++bluetooth:v0423* ++ ID_VENDOR_FROM_DATABASE=Chargifi Limited ++ ++bluetooth:v0424* ++ ID_VENDOR_FROM_DATABASE=Trainesense Ltd. ++ ++bluetooth:v0425* ++ ID_VENDOR_FROM_DATABASE=Unify Software and Solutions GmbH & Co. KG ++ ++bluetooth:v0426* ++ ID_VENDOR_FROM_DATABASE=Husqvarna AB ++ ++bluetooth:v0427* ++ ID_VENDOR_FROM_DATABASE=Focus fleet and fuel management inc ++ ++bluetooth:v0428* ++ ID_VENDOR_FROM_DATABASE=SmallLoop, LLC ++ ++bluetooth:v0429* ++ ID_VENDOR_FROM_DATABASE=Prolon Inc. ++ ++bluetooth:v042A* ++ ID_VENDOR_FROM_DATABASE=BD Medical ++ ++bluetooth:v042B* ++ ID_VENDOR_FROM_DATABASE=iMicroMed Incorporated ++ ++bluetooth:v042C* ++ ID_VENDOR_FROM_DATABASE=Ticto N.V. ++ ++bluetooth:v042D* ++ ID_VENDOR_FROM_DATABASE=Meshtech AS ++ ++bluetooth:v042E* ++ ID_VENDOR_FROM_DATABASE=MemCachier Inc. ++ ++bluetooth:v042F* ++ ID_VENDOR_FROM_DATABASE=Danfoss A/S ++ ++bluetooth:v0430* ++ ID_VENDOR_FROM_DATABASE=SnapStyk Inc. ++ ++bluetooth:v0431* ++ ID_VENDOR_FROM_DATABASE=Amway Corporation ++ ++bluetooth:v0432* ++ ID_VENDOR_FROM_DATABASE=Silk Labs, Inc. ++ ++bluetooth:v0433* ++ ID_VENDOR_FROM_DATABASE=Pillsy Inc. ++ ++bluetooth:v0434* ++ ID_VENDOR_FROM_DATABASE=Hatch Baby, Inc. ++ ++bluetooth:v0435* ++ ID_VENDOR_FROM_DATABASE=Blocks Wearables Ltd. ++ ++bluetooth:v0436* ++ ID_VENDOR_FROM_DATABASE=Drayson Technologies (Europe) Limited ++ ++bluetooth:v0437* ++ ID_VENDOR_FROM_DATABASE=eBest IOT Inc. ++ ++bluetooth:v0438* ++ ID_VENDOR_FROM_DATABASE=Helvar Ltd ++ ++bluetooth:v0439* ++ ID_VENDOR_FROM_DATABASE=Radiance Technologies ++ ++bluetooth:v043A* ++ ID_VENDOR_FROM_DATABASE=Nuheara Limited ++ ++bluetooth:v043B* ++ ID_VENDOR_FROM_DATABASE=Appside co., ltd. ++ ++bluetooth:v043C* ++ ID_VENDOR_FROM_DATABASE=DeLaval ++ ++bluetooth:v043D* ++ ID_VENDOR_FROM_DATABASE=Coiler Corporation ++ ++bluetooth:v043E* ++ ID_VENDOR_FROM_DATABASE=Thermomedics, Inc. ++ ++bluetooth:v043F* ++ ID_VENDOR_FROM_DATABASE=Tentacle Sync GmbH ++ ++bluetooth:v0440* ++ ID_VENDOR_FROM_DATABASE=Valencell, Inc. ++ ++bluetooth:v0441* ++ ID_VENDOR_FROM_DATABASE=iProtoXi Oy ++ ++bluetooth:v0442* ++ ID_VENDOR_FROM_DATABASE=SECOM CO., LTD. ++ ++bluetooth:v0443* ++ ID_VENDOR_FROM_DATABASE=Tucker International LLC ++ ++bluetooth:v0444* ++ ID_VENDOR_FROM_DATABASE=Metanate Limited ++ ++bluetooth:v0445* ++ ID_VENDOR_FROM_DATABASE=Kobian Canada Inc. ++ ++bluetooth:v0446* ++ ID_VENDOR_FROM_DATABASE=NETGEAR, Inc. ++ ++bluetooth:v0447* ++ ID_VENDOR_FROM_DATABASE=Fabtronics Australia Pty Ltd ++ ++bluetooth:v0448* ++ ID_VENDOR_FROM_DATABASE=Grand Centrix GmbH ++ ++bluetooth:v0449* ++ ID_VENDOR_FROM_DATABASE=1UP USA.com llc ++ ++bluetooth:v044A* ++ ID_VENDOR_FROM_DATABASE=SHIMANO INC. ++ ++bluetooth:v044B* ++ ID_VENDOR_FROM_DATABASE=Nain Inc. ++ ++bluetooth:v044C* ++ ID_VENDOR_FROM_DATABASE=LifeStyle Lock, LLC ++ ++bluetooth:v044D* ++ ID_VENDOR_FROM_DATABASE=VEGA Grieshaber KG ++ ++bluetooth:v044E* ++ ID_VENDOR_FROM_DATABASE=Xtrava Inc. ++ ++bluetooth:v044F* ++ ID_VENDOR_FROM_DATABASE=TTS Tooltechnic Systems AG & Co. KG ++ ++bluetooth:v0450* ++ ID_VENDOR_FROM_DATABASE=Teenage Engineering AB ++ ++bluetooth:v0451* ++ ID_VENDOR_FROM_DATABASE=Tunstall Nordic AB ++ ++bluetooth:v0452* ++ ID_VENDOR_FROM_DATABASE=Svep Design Center AB ++ ++bluetooth:v0453* ++ ID_VENDOR_FROM_DATABASE=GreenPeak Technologies BV ++ ++bluetooth:v0454* ++ ID_VENDOR_FROM_DATABASE=Sphinx Electronics GmbH & Co KG ++ ++bluetooth:v0455* ++ ID_VENDOR_FROM_DATABASE=Atomation ++ ++bluetooth:v0456* ++ ID_VENDOR_FROM_DATABASE=Nemik Consulting Inc ++ ++bluetooth:v0457* ++ ID_VENDOR_FROM_DATABASE=RF INNOVATION ++ ++bluetooth:v0458* ++ ID_VENDOR_FROM_DATABASE=Mini Solution Co., Ltd. ++ ++bluetooth:v0459* ++ ID_VENDOR_FROM_DATABASE=Lumenetix, Inc ++ ++bluetooth:v045A* ++ ID_VENDOR_FROM_DATABASE=2048450 Ontario Inc ++ ++bluetooth:v045B* ++ ID_VENDOR_FROM_DATABASE=SPACEEK LTD ++ ++bluetooth:v045C* ++ ID_VENDOR_FROM_DATABASE=Delta T Corporation ++ ++bluetooth:v045D* ++ ID_VENDOR_FROM_DATABASE=Boston Scientific Corporation ++ ++bluetooth:v045E* ++ ID_VENDOR_FROM_DATABASE=Nuviz, Inc. ++ ++bluetooth:v045F* ++ ID_VENDOR_FROM_DATABASE=Real Time Automation, Inc. ++ ++bluetooth:v0460* ++ ID_VENDOR_FROM_DATABASE=Kolibree ++ ++bluetooth:v0461* ++ ID_VENDOR_FROM_DATABASE=vhf elektronik GmbH ++ ++bluetooth:v0462* ++ ID_VENDOR_FROM_DATABASE=Bonsai Systems GmbH ++ ++bluetooth:v0463* ++ ID_VENDOR_FROM_DATABASE=Fathom Systems Inc. ++ ++bluetooth:v0464* ++ ID_VENDOR_FROM_DATABASE=Bellman & Symfon ++ ++bluetooth:v0465* ++ ID_VENDOR_FROM_DATABASE=International Forte Group LLC ++ ++bluetooth:v0466* ++ ID_VENDOR_FROM_DATABASE=CycleLabs Solutions inc. ++ ++bluetooth:v0467* ++ ID_VENDOR_FROM_DATABASE=Codenex Oy ++ ++bluetooth:v0468* ++ ID_VENDOR_FROM_DATABASE=Kynesim Ltd ++ ++bluetooth:v0469* ++ ID_VENDOR_FROM_DATABASE=Palago AB ++ ++bluetooth:v046A* ++ ID_VENDOR_FROM_DATABASE=INSIGMA INC. ++ ++bluetooth:v046B* ++ ID_VENDOR_FROM_DATABASE=PMD Solutions ++ ++bluetooth:v046C* ++ ID_VENDOR_FROM_DATABASE=Qingdao Realtime Technology Co., Ltd. ++ ++bluetooth:v046D* ++ ID_VENDOR_FROM_DATABASE=BEGA Gantenbrink-Leuchten KG ++ ++bluetooth:v046E* ++ ID_VENDOR_FROM_DATABASE=Pambor Ltd. ++ ++bluetooth:v046F* ++ ID_VENDOR_FROM_DATABASE=Develco Products A/S ++ ++bluetooth:v0470* ++ ID_VENDOR_FROM_DATABASE=iDesign s.r.l. ++ ++bluetooth:v0471* ++ ID_VENDOR_FROM_DATABASE=TiVo Corp ++ ++bluetooth:v0472* ++ ID_VENDOR_FROM_DATABASE=Control-J Pty Ltd ++ ++bluetooth:v0473* ++ ID_VENDOR_FROM_DATABASE=Steelcase, Inc. ++ ++bluetooth:v0474* ++ ID_VENDOR_FROM_DATABASE=iApartment co., ltd. ++ ++bluetooth:v0475* ++ ID_VENDOR_FROM_DATABASE=Icom inc. ++ ++bluetooth:v0476* ++ ID_VENDOR_FROM_DATABASE=Oxstren Wearable Technologies Private Limited ++ ++bluetooth:v0477* ++ ID_VENDOR_FROM_DATABASE=Blue Spark Technologies ++ ++bluetooth:v0478* ++ ID_VENDOR_FROM_DATABASE=FarSite Communications Limited ++ ++bluetooth:v0479* ++ ID_VENDOR_FROM_DATABASE=mywerk system GmbH ++ ++bluetooth:v047A* ++ ID_VENDOR_FROM_DATABASE=Sinosun Technology Co., Ltd. ++ ++bluetooth:v047B* ++ ID_VENDOR_FROM_DATABASE=MIYOSHI ELECTRONICS CORPORATION ++ ++bluetooth:v047C* ++ ID_VENDOR_FROM_DATABASE=POWERMAT LTD ++ ++bluetooth:v047D* ++ ID_VENDOR_FROM_DATABASE=Occly LLC ++ ++bluetooth:v047E* ++ ID_VENDOR_FROM_DATABASE=OurHub Dev IvS ++ ++bluetooth:v047F* ++ ID_VENDOR_FROM_DATABASE=Pro-Mark, Inc. ++ ++bluetooth:v0480* ++ ID_VENDOR_FROM_DATABASE=Dynometrics Inc. ++ ++bluetooth:v0481* ++ ID_VENDOR_FROM_DATABASE=Quintrax Limited ++ ++bluetooth:v0482* ++ ID_VENDOR_FROM_DATABASE=POS Tuning Udo Vosshenrich GmbH & Co. KG ++ ++bluetooth:v0483* ++ ID_VENDOR_FROM_DATABASE=Multi Care Systems B.V. ++ ++bluetooth:v0484* ++ ID_VENDOR_FROM_DATABASE=Revol Technologies Inc ++ ++bluetooth:v0485* ++ ID_VENDOR_FROM_DATABASE=SKIDATA AG ++ ++bluetooth:v0486* ++ ID_VENDOR_FROM_DATABASE=DEV TECNOLOGIA INDUSTRIA, COMERCIO E MANUTENCAO DE EQUIPAMENTOS LTDA. - ME ++ ++bluetooth:v0487* ++ ID_VENDOR_FROM_DATABASE=Centrica Connected Home ++ ++bluetooth:v0488* ++ ID_VENDOR_FROM_DATABASE=Automotive Data Solutions Inc ++ ++bluetooth:v0489* ++ ID_VENDOR_FROM_DATABASE=Igarashi Engineering ++ ++bluetooth:v048A* ++ ID_VENDOR_FROM_DATABASE=Taelek Oy ++ ++bluetooth:v048B* ++ ID_VENDOR_FROM_DATABASE=CP Electronics Limited ++ ++bluetooth:v048C* ++ ID_VENDOR_FROM_DATABASE=Vectronix AG ++ ++bluetooth:v048D* ++ ID_VENDOR_FROM_DATABASE=S-Labs Sp. z o.o. ++ ++bluetooth:v048E* ++ ID_VENDOR_FROM_DATABASE=Companion Medical, Inc. ++ ++bluetooth:v048F* ++ ID_VENDOR_FROM_DATABASE=BlueKitchen GmbH ++ ++bluetooth:v0490* ++ ID_VENDOR_FROM_DATABASE=Matting AB ++ ++bluetooth:v0491* ++ ID_VENDOR_FROM_DATABASE=SOREX - Wireless Solutions GmbH ++ ++bluetooth:v0492* ++ ID_VENDOR_FROM_DATABASE=ADC Technology, Inc. ++ ++bluetooth:v0493* ++ ID_VENDOR_FROM_DATABASE=Lynxemi Pte Ltd ++ ++bluetooth:v0494* ++ ID_VENDOR_FROM_DATABASE=SENNHEISER electronic GmbH & Co. KG ++ ++bluetooth:v0495* ++ ID_VENDOR_FROM_DATABASE=LMT Mercer Group, Inc ++ ++bluetooth:v0496* ++ ID_VENDOR_FROM_DATABASE=Polymorphic Labs LLC ++ ++bluetooth:v0497* ++ ID_VENDOR_FROM_DATABASE=Cochlear Limited ++ ++bluetooth:v0498* ++ ID_VENDOR_FROM_DATABASE=METER Group, Inc. USA ++ ++bluetooth:v0499* ++ ID_VENDOR_FROM_DATABASE=Ruuvi Innovations Ltd. ++ ++bluetooth:v049A* ++ ID_VENDOR_FROM_DATABASE=Situne AS ++ ++bluetooth:v049B* ++ ID_VENDOR_FROM_DATABASE=nVisti, LLC ++ ++bluetooth:v049C* ++ ID_VENDOR_FROM_DATABASE=DyOcean ++ ++bluetooth:v049D* ++ ID_VENDOR_FROM_DATABASE=Uhlmann & Zacher GmbH ++ ++bluetooth:v049E* ++ ID_VENDOR_FROM_DATABASE=AND!XOR LLC ++ ++bluetooth:v049F* ++ ID_VENDOR_FROM_DATABASE=tictote AB ++ ++bluetooth:v04A0* ++ ID_VENDOR_FROM_DATABASE=Vypin, LLC ++ ++bluetooth:v04A1* ++ ID_VENDOR_FROM_DATABASE=PNI Sensor Corporation ++ ++bluetooth:v04A2* ++ ID_VENDOR_FROM_DATABASE=ovrEngineered, LLC ++ ++bluetooth:v04A3* ++ ID_VENDOR_FROM_DATABASE=GT-tronics HK Ltd ++ ++bluetooth:v04A4* ++ ID_VENDOR_FROM_DATABASE=Herbert Waldmann GmbH & Co. KG ++ ++bluetooth:v04A5* ++ ID_VENDOR_FROM_DATABASE=Guangzhou FiiO Electronics Technology Co.,Ltd ++ ++bluetooth:v04A6* ++ ID_VENDOR_FROM_DATABASE=Vinetech Co., Ltd ++ ++bluetooth:v04A7* ++ ID_VENDOR_FROM_DATABASE=Dallas Logic Corporation ++ ++bluetooth:v04A8* ++ ID_VENDOR_FROM_DATABASE=BioTex, Inc. ++ ++bluetooth:v04A9* ++ ID_VENDOR_FROM_DATABASE=DISCOVERY SOUND TECHNOLOGY, LLC ++ ++bluetooth:v04AA* ++ ID_VENDOR_FROM_DATABASE=LINKIO SAS ++ ++bluetooth:v04AB* ++ ID_VENDOR_FROM_DATABASE=Harbortronics, Inc. ++ ++bluetooth:v04AC* ++ ID_VENDOR_FROM_DATABASE=Undagrid B.V. ++ ++bluetooth:v04AD* ++ ID_VENDOR_FROM_DATABASE=Shure Inc ++ ++bluetooth:v04AE* ++ ID_VENDOR_FROM_DATABASE=ERM Electronic Systems LTD ++ ++bluetooth:v04AF* ++ ID_VENDOR_FROM_DATABASE=BIOROWER Handelsagentur GmbH ++ ++bluetooth:v04B0* ++ ID_VENDOR_FROM_DATABASE=Weba Sport und Med. Artikel GmbH ++ ++bluetooth:v04B1* ++ ID_VENDOR_FROM_DATABASE=Kartographers Technologies Pvt. Ltd. ++ ++bluetooth:v04B2* ++ ID_VENDOR_FROM_DATABASE=The Shadow on the Moon ++ ++bluetooth:v04B3* ++ ID_VENDOR_FROM_DATABASE=mobike (Hong Kong) Limited ++ ++bluetooth:v04B4* ++ ID_VENDOR_FROM_DATABASE=Inuheat Group AB ++ ++bluetooth:v04B5* ++ ID_VENDOR_FROM_DATABASE=Swiftronix AB ++ ++bluetooth:v04B6* ++ ID_VENDOR_FROM_DATABASE=Diagnoptics Technologies ++ ++bluetooth:v04B7* ++ ID_VENDOR_FROM_DATABASE=Analog Devices, Inc. ++ ++bluetooth:v04B8* ++ ID_VENDOR_FROM_DATABASE=Soraa Inc. ++ ++bluetooth:v04B9* ++ ID_VENDOR_FROM_DATABASE=CSR Building Products Limited ++ ++bluetooth:v04BA* ++ ID_VENDOR_FROM_DATABASE=Crestron Electronics, Inc. ++ ++bluetooth:v04BB* ++ ID_VENDOR_FROM_DATABASE=Neatebox Ltd ++ ++bluetooth:v04BC* ++ ID_VENDOR_FROM_DATABASE=Draegerwerk AG & Co. KGaA ++ ++bluetooth:v04BD* ++ ID_VENDOR_FROM_DATABASE=AlbynMedical ++ ++bluetooth:v04BE* ++ ID_VENDOR_FROM_DATABASE=Averos FZCO ++ ++bluetooth:v04BF* ++ ID_VENDOR_FROM_DATABASE=VIT Initiative, LLC ++ ++bluetooth:v04C0* ++ ID_VENDOR_FROM_DATABASE=Statsports International ++ ++bluetooth:v04C1* ++ ID_VENDOR_FROM_DATABASE=Sospitas, s.r.o. ++ ++bluetooth:v04C2* ++ ID_VENDOR_FROM_DATABASE=Dmet Products Corp. ++ ++bluetooth:v04C3* ++ ID_VENDOR_FROM_DATABASE=Mantracourt Electronics Limited ++ ++bluetooth:v04C4* ++ ID_VENDOR_FROM_DATABASE=TeAM Hutchins AB ++ ++bluetooth:v04C5* ++ ID_VENDOR_FROM_DATABASE=Seibert Williams Glass, LLC ++ ++bluetooth:v04C6* ++ ID_VENDOR_FROM_DATABASE=Insta GmbH ++ ++bluetooth:v04C7* ++ ID_VENDOR_FROM_DATABASE=Svantek Sp. z o.o. ++ ++bluetooth:v04C8* ++ ID_VENDOR_FROM_DATABASE=Shanghai Flyco Electrical Appliance Co., Ltd. ++ ++bluetooth:v04C9* ++ ID_VENDOR_FROM_DATABASE=Thornwave Labs Inc ++ ++bluetooth:v04CA* ++ ID_VENDOR_FROM_DATABASE=Steiner-Optik GmbH ++ ++bluetooth:v04CB* ++ ID_VENDOR_FROM_DATABASE=Novo Nordisk A/S ++ ++bluetooth:v04CC* ++ ID_VENDOR_FROM_DATABASE=Enflux Inc. ++ ++bluetooth:v04CD* ++ ID_VENDOR_FROM_DATABASE=Safetech Products LLC ++ ++bluetooth:v04CE* ++ ID_VENDOR_FROM_DATABASE=GOOOLED S.R.L. ++ ++bluetooth:v04CF* ++ ID_VENDOR_FROM_DATABASE=DOM Sicherheitstechnik GmbH & Co. KG ++ ++bluetooth:v04D0* ++ ID_VENDOR_FROM_DATABASE=Olympus Corporation ++ ++bluetooth:v04D1* ++ ID_VENDOR_FROM_DATABASE=KTS GmbH ++ ++bluetooth:v04D2* ++ ID_VENDOR_FROM_DATABASE=Anloq Technologies Inc. ++ ++bluetooth:v04D3* ++ ID_VENDOR_FROM_DATABASE=Queercon, Inc ++ ++bluetooth:v04D4* ++ ID_VENDOR_FROM_DATABASE=5th Element Ltd ++ ++bluetooth:v04D5* ++ ID_VENDOR_FROM_DATABASE=Gooee Limited ++ ++bluetooth:v04D6* ++ ID_VENDOR_FROM_DATABASE=LUGLOC LLC ++ ++bluetooth:v04D7* ++ ID_VENDOR_FROM_DATABASE=Blincam, Inc. ++ ++bluetooth:v04D8* ++ ID_VENDOR_FROM_DATABASE=FUJIFILM Corporation ++ ++bluetooth:v04D9* ++ ID_VENDOR_FROM_DATABASE=RandMcNally ++ ++bluetooth:v04DA* ++ ID_VENDOR_FROM_DATABASE=Franceschi Marina snc ++ ++bluetooth:v04DB* ++ ID_VENDOR_FROM_DATABASE=Engineered Audio, LLC. ++ ++bluetooth:v04DC* ++ ID_VENDOR_FROM_DATABASE=IOTTIVE (OPC) PRIVATE LIMITED ++ ++bluetooth:v04DD* ++ ID_VENDOR_FROM_DATABASE=4MOD Technology ++ ++bluetooth:v04DE* ++ ID_VENDOR_FROM_DATABASE=Lutron Electronics Co., Inc. ++ ++bluetooth:v04DF* ++ ID_VENDOR_FROM_DATABASE=Emerson ++ ++bluetooth:v04E0* ++ ID_VENDOR_FROM_DATABASE=Guardtec, Inc. ++ ++bluetooth:v04E1* ++ ID_VENDOR_FROM_DATABASE=REACTEC LIMITED ++ ++bluetooth:v04E2* ++ ID_VENDOR_FROM_DATABASE=EllieGrid ++ ++bluetooth:v04E3* ++ ID_VENDOR_FROM_DATABASE=Under Armour ++ ++bluetooth:v04E4* ++ ID_VENDOR_FROM_DATABASE=Woodenshark ++ ++bluetooth:v04E5* ++ ID_VENDOR_FROM_DATABASE=Avack Oy ++ ++bluetooth:v04E6* ++ ID_VENDOR_FROM_DATABASE=Smart Solution Technology, Inc. ++ ++bluetooth:v04E7* ++ ID_VENDOR_FROM_DATABASE=REHABTRONICS INC. ++ ++bluetooth:v04E8* ++ ID_VENDOR_FROM_DATABASE=STABILO International ++ ++bluetooth:v04E9* ++ ID_VENDOR_FROM_DATABASE=Busch Jaeger Elektro GmbH ++ ++bluetooth:v04EA* ++ ID_VENDOR_FROM_DATABASE=Pacific Bioscience Laboratories, Inc ++ ++bluetooth:v04EB* ++ ID_VENDOR_FROM_DATABASE=Bird Home Automation GmbH ++ ++bluetooth:v04EC* ++ ID_VENDOR_FROM_DATABASE=Motorola Solutions ++ ++bluetooth:v04ED* ++ ID_VENDOR_FROM_DATABASE=R9 Technology, Inc. ++ ++bluetooth:v04EE* ++ ID_VENDOR_FROM_DATABASE=Auxivia ++ ++bluetooth:v04EF* ++ ID_VENDOR_FROM_DATABASE=DaisyWorks, Inc ++ ++bluetooth:v04F0* ++ ID_VENDOR_FROM_DATABASE=Kosi Limited ++ ++bluetooth:v04F1* ++ ID_VENDOR_FROM_DATABASE=Theben AG ++ ++bluetooth:v04F2* ++ ID_VENDOR_FROM_DATABASE=InDreamer Techsol Private Limited ++ ++bluetooth:v04F3* ++ ID_VENDOR_FROM_DATABASE=Cerevast Medical ++ ++bluetooth:v04F4* ++ ID_VENDOR_FROM_DATABASE=ZanCompute Inc. ++ ++bluetooth:v04F5* ++ ID_VENDOR_FROM_DATABASE=Pirelli Tyre S.P.A. ++ ++bluetooth:v04F6* ++ ID_VENDOR_FROM_DATABASE=McLear Limited ++ ++bluetooth:v04F7* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Huiding Technology Co.,Ltd. ++ ++bluetooth:v04F8* ++ ID_VENDOR_FROM_DATABASE=Convergence Systems Limited ++ ++bluetooth:v04F9* ++ ID_VENDOR_FROM_DATABASE=Interactio ++ ++bluetooth:v04FA* ++ ID_VENDOR_FROM_DATABASE=Androtec GmbH ++ ++bluetooth:v04FB* ++ ID_VENDOR_FROM_DATABASE=Benchmark Drives GmbH & Co. KG ++ ++bluetooth:v04FC* ++ ID_VENDOR_FROM_DATABASE=SwingLync L. L. C. ++ ++bluetooth:v04FD* ++ ID_VENDOR_FROM_DATABASE=Tapkey GmbH ++ ++bluetooth:v04FE* ++ ID_VENDOR_FROM_DATABASE=Woosim Systems Inc. ++ ++bluetooth:v04FF* ++ ID_VENDOR_FROM_DATABASE=Microsemi Corporation ++ ++bluetooth:v0500* ++ ID_VENDOR_FROM_DATABASE=Wiliot LTD. ++ ++bluetooth:v0501* ++ ID_VENDOR_FROM_DATABASE=Polaris IND ++ ++bluetooth:v0502* ++ ID_VENDOR_FROM_DATABASE=Specifi-Kali LLC ++ ++bluetooth:v0503* ++ ID_VENDOR_FROM_DATABASE=Locoroll, Inc ++ ++bluetooth:v0504* ++ ID_VENDOR_FROM_DATABASE=PHYPLUS Inc ++ ++bluetooth:v0505* ++ ID_VENDOR_FROM_DATABASE=Inplay Technologies LLC ++ ++bluetooth:v0506* ++ ID_VENDOR_FROM_DATABASE=Hager ++ ++bluetooth:v0507* ++ ID_VENDOR_FROM_DATABASE=Yellowcog ++ ++bluetooth:v0508* ++ ID_VENDOR_FROM_DATABASE=Axes System sp. z o. o. ++ ++bluetooth:v0509* ++ ID_VENDOR_FROM_DATABASE=myLIFTER Inc. ++ ++bluetooth:v050A* ++ ID_VENDOR_FROM_DATABASE=Shake-on B.V. ++ ++bluetooth:v050B* ++ ID_VENDOR_FROM_DATABASE=Vibrissa Inc. ++ ++bluetooth:v050C* ++ ID_VENDOR_FROM_DATABASE=OSRAM GmbH ++ ++bluetooth:v050D* ++ ID_VENDOR_FROM_DATABASE=TRSystems GmbH ++ ++bluetooth:v050E* ++ ID_VENDOR_FROM_DATABASE=Yichip Microelectronics (Hangzhou) Co.,Ltd. ++ ++bluetooth:v050F* ++ ID_VENDOR_FROM_DATABASE=Foundation Engineering LLC ++ ++bluetooth:v0510* ++ ID_VENDOR_FROM_DATABASE=UNI-ELECTRONICS, INC. ++ ++bluetooth:v0511* ++ ID_VENDOR_FROM_DATABASE=Brookfield Equinox LLC ++ ++bluetooth:v0512* ++ ID_VENDOR_FROM_DATABASE=Soprod SA ++ ++bluetooth:v0513* ++ ID_VENDOR_FROM_DATABASE=9974091 Canada Inc. ++ ++bluetooth:v0514* ++ ID_VENDOR_FROM_DATABASE=FIBRO GmbH ++ ++bluetooth:v0515* ++ ID_VENDOR_FROM_DATABASE=RB Controls Co., Ltd. ++ ++bluetooth:v0516* ++ ID_VENDOR_FROM_DATABASE=Footmarks ++ ++bluetooth:v0517* ++ ID_VENDOR_FROM_DATABASE=Amtronic Sverige AB (formerly Amcore AB) ++ ++bluetooth:v0518* ++ ID_VENDOR_FROM_DATABASE=MAMORIO.inc ++ ++bluetooth:v0519* ++ ID_VENDOR_FROM_DATABASE=Tyto Life LLC ++ ++bluetooth:v051A* ++ ID_VENDOR_FROM_DATABASE=Leica Camera AG ++ ++bluetooth:v051B* ++ ID_VENDOR_FROM_DATABASE=Angee Technologies Ltd. ++ ++bluetooth:v051C* ++ ID_VENDOR_FROM_DATABASE=EDPS ++ ++bluetooth:v051D* ++ ID_VENDOR_FROM_DATABASE=OFF Line Co., Ltd. ++ ++bluetooth:v051E* ++ ID_VENDOR_FROM_DATABASE=Detect Blue Limited ++ ++bluetooth:v051F* ++ ID_VENDOR_FROM_DATABASE=Setec Pty Ltd ++ ++bluetooth:v0520* ++ ID_VENDOR_FROM_DATABASE=Target Corporation ++ ++bluetooth:v0521* ++ ID_VENDOR_FROM_DATABASE=IAI Corporation ++ ++bluetooth:v0522* ++ ID_VENDOR_FROM_DATABASE=NS Tech, Inc. ++ ++bluetooth:v0523* ++ ID_VENDOR_FROM_DATABASE=MTG Co., Ltd. ++ ++bluetooth:v0524* ++ ID_VENDOR_FROM_DATABASE=Hangzhou iMagic Technology Co., Ltd ++ ++bluetooth:v0525* ++ ID_VENDOR_FROM_DATABASE=HONGKONG NANO IC TECHNOLOGIES CO., LIMITED ++ ++bluetooth:v0526* ++ ID_VENDOR_FROM_DATABASE=Honeywell International Inc. ++ ++bluetooth:v0527* ++ ID_VENDOR_FROM_DATABASE=Albrecht JUNG ++ ++bluetooth:v0528* ++ ID_VENDOR_FROM_DATABASE=Lunera Lighting Inc. ++ ++bluetooth:v0529* ++ ID_VENDOR_FROM_DATABASE=Lumen UAB ++ ++bluetooth:v052A* ++ ID_VENDOR_FROM_DATABASE=Keynes Controls Ltd ++ ++bluetooth:v052B* ++ ID_VENDOR_FROM_DATABASE=Novartis AG ++ ++bluetooth:v052C* ++ ID_VENDOR_FROM_DATABASE=Geosatis SA ++ ++bluetooth:v052D* ++ ID_VENDOR_FROM_DATABASE=EXFO, Inc. ++ ++bluetooth:v052E* ++ ID_VENDOR_FROM_DATABASE=LEDVANCE GmbH ++ ++bluetooth:v052F* ++ ID_VENDOR_FROM_DATABASE=Center ID Corp. ++ ++bluetooth:v0530* ++ ID_VENDOR_FROM_DATABASE=Adolene, Inc. ++ ++bluetooth:v0531* ++ ID_VENDOR_FROM_DATABASE=D&M Holdings Inc. ++ ++bluetooth:v0532* ++ ID_VENDOR_FROM_DATABASE=CRESCO Wireless, Inc. ++ ++bluetooth:v0533* ++ ID_VENDOR_FROM_DATABASE=Nura Operations Pty Ltd ++ ++bluetooth:v0534* ++ ID_VENDOR_FROM_DATABASE=Frontiergadget, Inc. ++ ++bluetooth:v0535* ++ ID_VENDOR_FROM_DATABASE=Smart Component Technologies Limited ++ ++bluetooth:v0536* ++ ID_VENDOR_FROM_DATABASE=ZTR Control Systems LLC ++ ++bluetooth:v0537* ++ ID_VENDOR_FROM_DATABASE=MetaLogics Corporation ++ ++bluetooth:v0538* ++ ID_VENDOR_FROM_DATABASE=Medela AG ++ ++bluetooth:v0539* ++ ID_VENDOR_FROM_DATABASE=OPPLE Lighting Co., Ltd ++ ++bluetooth:v053A* ++ ID_VENDOR_FROM_DATABASE=Savitech Corp., ++ ++bluetooth:v053B* ++ ID_VENDOR_FROM_DATABASE=prodigy ++ ++bluetooth:v053C* ++ ID_VENDOR_FROM_DATABASE=Screenovate Technologies Ltd ++ ++bluetooth:v053D* ++ ID_VENDOR_FROM_DATABASE=TESA SA ++ ++bluetooth:v053E* ++ ID_VENDOR_FROM_DATABASE=CLIM8 LIMITED ++ ++bluetooth:v053F* ++ ID_VENDOR_FROM_DATABASE=Silergy Corp ++ ++bluetooth:v0540* ++ ID_VENDOR_FROM_DATABASE=SilverPlus, Inc ++ ++bluetooth:v0541* ++ ID_VENDOR_FROM_DATABASE=Sharknet srl ++ ++bluetooth:v0542* ++ ID_VENDOR_FROM_DATABASE=Mist Systems, Inc. ++ ++bluetooth:v0543* ++ ID_VENDOR_FROM_DATABASE=MIWA LOCK CO.,Ltd ++ ++bluetooth:v0544* ++ ID_VENDOR_FROM_DATABASE=OrthoSensor, Inc. ++ ++bluetooth:v0545* ++ ID_VENDOR_FROM_DATABASE=Candy Hoover Group s.r.l ++ ++bluetooth:v0546* ++ ID_VENDOR_FROM_DATABASE=Apexar Technologies S.A. ++ ++bluetooth:v0547* ++ ID_VENDOR_FROM_DATABASE=LOGICDATA d.o.o. ++ ++bluetooth:v0548* ++ ID_VENDOR_FROM_DATABASE=Knick Elektronische Messgeraete GmbH & Co. KG ++ ++bluetooth:v0549* ++ ID_VENDOR_FROM_DATABASE=Smart Technologies and Investment Limited ++ ++bluetooth:v054A* ++ ID_VENDOR_FROM_DATABASE=Linough Inc. ++ ++bluetooth:v054B* ++ ID_VENDOR_FROM_DATABASE=Advanced Electronic Designs, Inc. ++ ++bluetooth:v054C* ++ ID_VENDOR_FROM_DATABASE=Carefree Scott Fetzer Co Inc ++ ++bluetooth:v054D* ++ ID_VENDOR_FROM_DATABASE=Sensome ++ ++bluetooth:v054E* ++ ID_VENDOR_FROM_DATABASE=FORTRONIK storitve d.o.o. ++ ++bluetooth:v054F* ++ ID_VENDOR_FROM_DATABASE=Sinnoz ++ ++bluetooth:v0550* ++ ID_VENDOR_FROM_DATABASE=Versa Networks, Inc. ++ ++bluetooth:v0551* ++ ID_VENDOR_FROM_DATABASE=Sylero ++ ++bluetooth:v0552* ++ ID_VENDOR_FROM_DATABASE=Avempace SARL ++ ++bluetooth:v0553* ++ ID_VENDOR_FROM_DATABASE=Nintendo Co., Ltd. ++ ++bluetooth:v0554* ++ ID_VENDOR_FROM_DATABASE=National Instruments ++ ++bluetooth:v0555* ++ ID_VENDOR_FROM_DATABASE=KROHNE Messtechnik GmbH ++ ++bluetooth:v0556* ++ ID_VENDOR_FROM_DATABASE=Otodynamics Ltd ++ ++bluetooth:v0557* ++ ID_VENDOR_FROM_DATABASE=Arwin Technology Limited ++ ++bluetooth:v0558* ++ ID_VENDOR_FROM_DATABASE=benegear, inc. ++ ++bluetooth:v0559* ++ ID_VENDOR_FROM_DATABASE=Newcon Optik ++ ++bluetooth:v055A* ++ ID_VENDOR_FROM_DATABASE=CANDY HOUSE, Inc. ++ ++bluetooth:v055B* ++ ID_VENDOR_FROM_DATABASE=FRANKLIN TECHNOLOGY INC ++ ++bluetooth:v055C* ++ ID_VENDOR_FROM_DATABASE=Lely ++ ++bluetooth:v055D* ++ ID_VENDOR_FROM_DATABASE=Valve Corporation ++ ++bluetooth:v055E* ++ ID_VENDOR_FROM_DATABASE=Hekatron Vertriebs GmbH ++ ++bluetooth:v055F* ++ ID_VENDOR_FROM_DATABASE=PROTECH S.A.S. DI GIRARDI ANDREA & C. ++ ++bluetooth:v0560* ++ ID_VENDOR_FROM_DATABASE=Sarita CareTech APS (formerly Sarita CareTech IVS) ++ ++bluetooth:v0561* ++ ID_VENDOR_FROM_DATABASE=Finder S.p.A. ++ ++bluetooth:v0562* ++ ID_VENDOR_FROM_DATABASE=Thalmic Labs Inc. ++ ++bluetooth:v0563* ++ ID_VENDOR_FROM_DATABASE=Steinel Vertrieb GmbH ++ ++bluetooth:v0564* ++ ID_VENDOR_FROM_DATABASE=Beghelli Spa ++ ++bluetooth:v0565* ++ ID_VENDOR_FROM_DATABASE=Beijing Smartspace Technologies Inc. ++ ++bluetooth:v0566* ++ ID_VENDOR_FROM_DATABASE=CORE TRANSPORT TECHNOLOGIES NZ LIMITED ++ ++bluetooth:v0567* ++ ID_VENDOR_FROM_DATABASE=Xiamen Everesports Goods Co., Ltd ++ ++bluetooth:v0568* ++ ID_VENDOR_FROM_DATABASE=Bodyport Inc. ++ ++bluetooth:v0569* ++ ID_VENDOR_FROM_DATABASE=Audionics System, INC. ++ ++bluetooth:v056A* ++ ID_VENDOR_FROM_DATABASE=Flipnavi Co.,Ltd. ++ ++bluetooth:v056B* ++ ID_VENDOR_FROM_DATABASE=Rion Co., Ltd. ++ ++bluetooth:v056C* ++ ID_VENDOR_FROM_DATABASE=Long Range Systems, LLC ++ ++bluetooth:v056D* ++ ID_VENDOR_FROM_DATABASE=Redmond Industrial Group LLC ++ ++bluetooth:v056E* ++ ID_VENDOR_FROM_DATABASE=VIZPIN INC. ++ ++bluetooth:v056F* ++ ID_VENDOR_FROM_DATABASE=BikeFinder AS ++ ++bluetooth:v0570* ++ ID_VENDOR_FROM_DATABASE=Consumer Sleep Solutions LLC ++ ++bluetooth:v0571* ++ ID_VENDOR_FROM_DATABASE=PSIKICK, INC. ++ ++bluetooth:v0572* ++ ID_VENDOR_FROM_DATABASE=AntTail.com ++ ++bluetooth:v0573* ++ ID_VENDOR_FROM_DATABASE=Lighting Science Group Corp. ++ ++bluetooth:v0574* ++ ID_VENDOR_FROM_DATABASE=AFFORDABLE ELECTRONICS INC ++ ++bluetooth:v0575* ++ ID_VENDOR_FROM_DATABASE=Integral Memroy Plc ++ ++bluetooth:v0576* ++ ID_VENDOR_FROM_DATABASE=Globalstar, Inc. ++ ++bluetooth:v0577* ++ ID_VENDOR_FROM_DATABASE=True Wearables, Inc. ++ ++bluetooth:v0578* ++ ID_VENDOR_FROM_DATABASE=Wellington Drive Technologies Ltd ++ ++bluetooth:v0579* ++ ID_VENDOR_FROM_DATABASE=Ensemble Tech Private Limited ++ ++bluetooth:v057A* ++ ID_VENDOR_FROM_DATABASE=OMNI Remotes ++ ++bluetooth:v057B* ++ ID_VENDOR_FROM_DATABASE=Duracell U.S. Operations Inc. ++ ++bluetooth:v057C* ++ ID_VENDOR_FROM_DATABASE=Toor Technologies LLC ++ ++bluetooth:v057D* ++ ID_VENDOR_FROM_DATABASE=Instinct Performance ++ ++bluetooth:v057E* ++ ID_VENDOR_FROM_DATABASE=Beco, Inc ++ ++bluetooth:v057F* ++ ID_VENDOR_FROM_DATABASE=Scuf Gaming International, LLC ++ ++bluetooth:v0580* ++ ID_VENDOR_FROM_DATABASE=ARANZ Medical Limited ++ ++bluetooth:v0581* ++ ID_VENDOR_FROM_DATABASE=LYS TECHNOLOGIES LTD ++ ++bluetooth:v0582* ++ ID_VENDOR_FROM_DATABASE=Breakwall Analytics, LLC ++ ++bluetooth:v0583* ++ ID_VENDOR_FROM_DATABASE=Code Blue Communications ++ ++bluetooth:v0584* ++ ID_VENDOR_FROM_DATABASE=Gira Giersiepen GmbH & Co. KG ++ ++bluetooth:v0585* ++ ID_VENDOR_FROM_DATABASE=Hearing Lab Technology ++ ++bluetooth:v0586* ++ ID_VENDOR_FROM_DATABASE=LEGRAND ++ ++bluetooth:v0587* ++ ID_VENDOR_FROM_DATABASE=Derichs GmbH ++ ++bluetooth:v0588* ++ ID_VENDOR_FROM_DATABASE=ALT-TEKNIK LLC ++ ++bluetooth:v0589* ++ ID_VENDOR_FROM_DATABASE=Star Technologies ++ ++bluetooth:v058A* ++ ID_VENDOR_FROM_DATABASE=START TODAY CO.,LTD. ++ ++bluetooth:v058B* ++ ID_VENDOR_FROM_DATABASE=Maxim Integrated Products ++ ++bluetooth:v058C* ++ ID_VENDOR_FROM_DATABASE=MERCK Kommanditgesellschaft auf Aktien ++ ++bluetooth:v058D* ++ ID_VENDOR_FROM_DATABASE=Jungheinrich Aktiengesellschaft ++ ++bluetooth:v058E* ++ ID_VENDOR_FROM_DATABASE=Oculus VR, LLC ++ ++bluetooth:v058F* ++ ID_VENDOR_FROM_DATABASE=HENDON SEMICONDUCTORS PTY LTD ++ ++bluetooth:v0590* ++ ID_VENDOR_FROM_DATABASE=Pur3 Ltd ++ ++bluetooth:v0591* ++ ID_VENDOR_FROM_DATABASE=Viasat Group S.p.A. ++ ++bluetooth:v0592* ++ ID_VENDOR_FROM_DATABASE=IZITHERM ++ ++bluetooth:v0593* ++ ID_VENDOR_FROM_DATABASE=Spaulding Clinical Research ++ ++bluetooth:v0594* ++ ID_VENDOR_FROM_DATABASE=Kohler Company ++ ++bluetooth:v0595* ++ ID_VENDOR_FROM_DATABASE=Inor Process AB ++ ++bluetooth:v0596* ++ ID_VENDOR_FROM_DATABASE=My Smart Blinds ++ ++bluetooth:v0597* ++ ID_VENDOR_FROM_DATABASE=RadioPulse Inc ++ ++bluetooth:v0598* ++ ID_VENDOR_FROM_DATABASE=rapitag GmbH ++ ++bluetooth:v0599* ++ ID_VENDOR_FROM_DATABASE=Lazlo326, LLC. ++ ++bluetooth:v059A* ++ ID_VENDOR_FROM_DATABASE=Teledyne Lecroy, Inc. ++ ++bluetooth:v059B* ++ ID_VENDOR_FROM_DATABASE=Dataflow Systems Limited ++ ++bluetooth:v059C* ++ ID_VENDOR_FROM_DATABASE=Macrogiga Electronics ++ ++bluetooth:v059D* ++ ID_VENDOR_FROM_DATABASE=Tandem Diabetes Care ++ ++bluetooth:v059E* ++ ID_VENDOR_FROM_DATABASE=Polycom, Inc. ++ ++bluetooth:v059F* ++ ID_VENDOR_FROM_DATABASE=Fisher & Paykel Healthcare ++ ++bluetooth:v05A0* ++ ID_VENDOR_FROM_DATABASE=RCP Software Oy ++ ++bluetooth:v05A1* ++ ID_VENDOR_FROM_DATABASE=Shanghai Xiaoyi Technology Co.,Ltd. ++ ++bluetooth:v05A2* ++ ID_VENDOR_FROM_DATABASE=ADHERIUM(NZ) LIMITED ++ ++bluetooth:v05A3* ++ ID_VENDOR_FROM_DATABASE=Axiomware Systems Incorporated ++ ++bluetooth:v05A4* ++ ID_VENDOR_FROM_DATABASE=O. E. M. Controls, Inc. ++ ++bluetooth:v05A5* ++ ID_VENDOR_FROM_DATABASE=Kiiroo BV ++ ++bluetooth:v05A6* ++ ID_VENDOR_FROM_DATABASE=Telecon Mobile Limited ++ ++bluetooth:v05A7* ++ ID_VENDOR_FROM_DATABASE=Sonos Inc ++ ++bluetooth:v05A8* ++ ID_VENDOR_FROM_DATABASE=Tom Allebrandi Consulting ++ ++bluetooth:v05A9* ++ ID_VENDOR_FROM_DATABASE=Monidor ++ ++bluetooth:v05AA* ++ ID_VENDOR_FROM_DATABASE=Tramex Limited ++ ++bluetooth:v05AB* ++ ID_VENDOR_FROM_DATABASE=Nofence AS ++ ++bluetooth:v05AC* ++ ID_VENDOR_FROM_DATABASE=GoerTek Dynaudio Co., Ltd. ++ ++bluetooth:v05AD* ++ ID_VENDOR_FROM_DATABASE=INIA ++ ++bluetooth:v05AE* ++ ID_VENDOR_FROM_DATABASE=CARMATE MFG.CO.,LTD ++ ++bluetooth:v05AF* ++ ID_VENDOR_FROM_DATABASE=ONvocal ++ ++bluetooth:v05B0* ++ ID_VENDOR_FROM_DATABASE=NewTec GmbH ++ ++bluetooth:v05B1* ++ ID_VENDOR_FROM_DATABASE=Medallion Instrumentation Systems ++ ++bluetooth:v05B2* ++ ID_VENDOR_FROM_DATABASE=CAREL INDUSTRIES S.P.A. ++ ++bluetooth:v05B3* ++ ID_VENDOR_FROM_DATABASE=Parabit Systems, Inc. ++ ++bluetooth:v05B4* ++ ID_VENDOR_FROM_DATABASE=White Horse Scientific ltd ++ ++bluetooth:v05B5* ++ ID_VENDOR_FROM_DATABASE=verisilicon ++ ++bluetooth:v05B6* ++ ID_VENDOR_FROM_DATABASE=Elecs Industry Co.,Ltd. ++ ++bluetooth:v05B7* ++ ID_VENDOR_FROM_DATABASE=Beijing Pinecone Electronics Co.,Ltd. ++ ++bluetooth:v05B8* ++ ID_VENDOR_FROM_DATABASE=Ambystoma Labs Inc. ++ ++bluetooth:v05B9* ++ ID_VENDOR_FROM_DATABASE=Suzhou Pairlink Network Technology ++ ++bluetooth:v05BA* ++ ID_VENDOR_FROM_DATABASE=igloohome ++ ++bluetooth:v05BB* ++ ID_VENDOR_FROM_DATABASE=Oxford Metrics plc ++ ++bluetooth:v05BC* ++ ID_VENDOR_FROM_DATABASE=Leviton Mfg. Co., Inc. ++ ++bluetooth:v05BD* ++ ID_VENDOR_FROM_DATABASE=ULC Robotics Inc. ++ ++bluetooth:v05BE* ++ ID_VENDOR_FROM_DATABASE=RFID Global by Softwork SrL ++ ++bluetooth:v05BF* ++ ID_VENDOR_FROM_DATABASE=Real-World-Systems Corporation ++ ++bluetooth:v05C0* ++ ID_VENDOR_FROM_DATABASE=Nalu Medical, Inc. ++ ++bluetooth:v05C1* ++ ID_VENDOR_FROM_DATABASE=P.I.Engineering ++ ++bluetooth:v05C2* ++ ID_VENDOR_FROM_DATABASE=Grote Industries ++ ++bluetooth:v05C3* ++ ID_VENDOR_FROM_DATABASE=Runtime, Inc. ++ ++bluetooth:v05C4* ++ ID_VENDOR_FROM_DATABASE=Codecoup sp. z o.o. sp. k. ++ ++bluetooth:v05C5* ++ ID_VENDOR_FROM_DATABASE=SELVE GmbH & Co. KG ++ ++bluetooth:v05C6* ++ ID_VENDOR_FROM_DATABASE=Smart Animal Training Systems, LLC ++ ++bluetooth:v05C7* ++ ID_VENDOR_FROM_DATABASE=Lippert Components, INC ++ ++bluetooth:v05C8* ++ ID_VENDOR_FROM_DATABASE=SOMFY SAS ++ ++bluetooth:v05C9* ++ ID_VENDOR_FROM_DATABASE=TBS Electronics B.V. ++ ++bluetooth:v05CA* ++ ID_VENDOR_FROM_DATABASE=MHL Custom Inc ++ ++bluetooth:v05CB* ++ ID_VENDOR_FROM_DATABASE=LucentWear LLC ++ ++bluetooth:v05CC* ++ ID_VENDOR_FROM_DATABASE=WATTS ELECTRONICS ++ ++bluetooth:v05CD* ++ ID_VENDOR_FROM_DATABASE=RJ Brands LLC ++ ++bluetooth:v05CE* ++ ID_VENDOR_FROM_DATABASE=V-ZUG Ltd ++ ++bluetooth:v05CF* ++ ID_VENDOR_FROM_DATABASE=Biowatch SA ++ ++bluetooth:v05D0* ++ ID_VENDOR_FROM_DATABASE=Anova Applied Electronics ++ ++bluetooth:v05D1* ++ ID_VENDOR_FROM_DATABASE=Lindab AB ++ ++bluetooth:v05D2* ++ ID_VENDOR_FROM_DATABASE=frogblue TECHNOLOGY GmbH ++ ++bluetooth:v05D3* ++ ID_VENDOR_FROM_DATABASE=Acurable Limited ++ ++bluetooth:v05D4* ++ ID_VENDOR_FROM_DATABASE=LAMPLIGHT Co., Ltd. ++ ++bluetooth:v05D5* ++ ID_VENDOR_FROM_DATABASE=TEGAM, Inc. ++ ++bluetooth:v05D6* ++ ID_VENDOR_FROM_DATABASE=Zhuhai Jieli technology Co.,Ltd ++ ++bluetooth:v05D7* ++ ID_VENDOR_FROM_DATABASE=modum.io AG ++ ++bluetooth:v05D8* ++ ID_VENDOR_FROM_DATABASE=Farm Jenny LLC ++ ++bluetooth:v05D9* ++ ID_VENDOR_FROM_DATABASE=Toyo Electronics Corporation ++ ++bluetooth:v05DA* ++ ID_VENDOR_FROM_DATABASE=Applied Neural Research Corp ++ ++bluetooth:v05DB* ++ ID_VENDOR_FROM_DATABASE=Avid Identification Systems, Inc. ++ ++bluetooth:v05DC* ++ ID_VENDOR_FROM_DATABASE=Petronics Inc. ++ ++bluetooth:v05DD* ++ ID_VENDOR_FROM_DATABASE=essentim GmbH ++ ++bluetooth:v05DE* ++ ID_VENDOR_FROM_DATABASE=QT Medical INC. ++ ++bluetooth:v05DF* ++ ID_VENDOR_FROM_DATABASE=VIRTUALCLINIC.DIRECT LIMITED ++ ++bluetooth:v05E0* ++ ID_VENDOR_FROM_DATABASE=Viper Design LLC ++ ++bluetooth:v05E1* ++ ID_VENDOR_FROM_DATABASE=Human, Incorporated ++ ++bluetooth:v05E2* ++ ID_VENDOR_FROM_DATABASE=stAPPtronics GmbH ++ ++bluetooth:v05E3* ++ ID_VENDOR_FROM_DATABASE=Elemental Machines, Inc. ++ ++bluetooth:v05E4* ++ ID_VENDOR_FROM_DATABASE=Taiyo Yuden Co., Ltd ++ ++bluetooth:v05E5* ++ ID_VENDOR_FROM_DATABASE=INEO ENERGY& SYSTEMS ++ ++bluetooth:v05E6* ++ ID_VENDOR_FROM_DATABASE=Motion Instruments Inc. ++ ++bluetooth:v05E7* ++ ID_VENDOR_FROM_DATABASE=PressurePro ++ ++bluetooth:v05E8* ++ ID_VENDOR_FROM_DATABASE=COWBOY ++ ++bluetooth:v05E9* ++ ID_VENDOR_FROM_DATABASE=iconmobile GmbH ++ ++bluetooth:v05EA* ++ ID_VENDOR_FROM_DATABASE=ACS-Control-System GmbH ++ ++bluetooth:v05EB* ++ ID_VENDOR_FROM_DATABASE=Bayerische Motoren Werke AG ++ ++bluetooth:v05EC* ++ ID_VENDOR_FROM_DATABASE=Gycom Svenska AB ++ ++bluetooth:v05ED* ++ ID_VENDOR_FROM_DATABASE=Fuji Xerox Co., Ltd ++ ++bluetooth:v05EE* ++ ID_VENDOR_FROM_DATABASE=Glide Inc. ++ ++bluetooth:v05EF* ++ ID_VENDOR_FROM_DATABASE=SIKOM AS ++ ++bluetooth:v05F0* ++ ID_VENDOR_FROM_DATABASE=beken ++ ++bluetooth:v05F1* ++ ID_VENDOR_FROM_DATABASE=The Linux Foundation ++ ++bluetooth:v05F2* ++ ID_VENDOR_FROM_DATABASE=Try and E CO.,LTD. ++ ++bluetooth:v05F3* ++ ID_VENDOR_FROM_DATABASE=SeeScan ++ ++bluetooth:v05F4* ++ ID_VENDOR_FROM_DATABASE=Clearity, LLC ++ ++bluetooth:v05F5* ++ ID_VENDOR_FROM_DATABASE=GS TAG ++ ++bluetooth:v05F6* ++ ID_VENDOR_FROM_DATABASE=DPTechnics ++ ++bluetooth:v05F7* ++ ID_VENDOR_FROM_DATABASE=TRACMO, INC. ++ ++bluetooth:v05F8* ++ ID_VENDOR_FROM_DATABASE=Anki Inc. ++ ++bluetooth:v05F9* ++ ID_VENDOR_FROM_DATABASE=Hagleitner Hygiene International GmbH ++ ++bluetooth:v05FA* ++ ID_VENDOR_FROM_DATABASE=Konami Sports Life Co., Ltd. ++ ++bluetooth:v05FB* ++ ID_VENDOR_FROM_DATABASE=Arblet Inc. ++ ++bluetooth:v05FC* ++ ID_VENDOR_FROM_DATABASE=Masbando GmbH ++ ++bluetooth:v05FD* ++ ID_VENDOR_FROM_DATABASE=Innoseis ++ ++bluetooth:v05FE* ++ ID_VENDOR_FROM_DATABASE=Niko nv ++ ++bluetooth:v05FF* ++ ID_VENDOR_FROM_DATABASE=Wellnomics Ltd ++ ++bluetooth:v0600* ++ ID_VENDOR_FROM_DATABASE=iRobot Corporation ++ ++bluetooth:v0601* ++ ID_VENDOR_FROM_DATABASE=Schrader Electronics ++ ++bluetooth:v0602* ++ ID_VENDOR_FROM_DATABASE=Geberit International AG ++ ++bluetooth:v0603* ++ ID_VENDOR_FROM_DATABASE=Fourth Evolution Inc ++ ++bluetooth:v0604* ++ ID_VENDOR_FROM_DATABASE=Cell2Jack LLC ++ ++bluetooth:v0605* ++ ID_VENDOR_FROM_DATABASE=FMW electronic Futterer u. Maier-Wolf OHG ++ ++bluetooth:v0606* ++ ID_VENDOR_FROM_DATABASE=John Deere ++ ++bluetooth:v0607* ++ ID_VENDOR_FROM_DATABASE=Rookery Technology Ltd ++ ++bluetooth:v0608* ++ ID_VENDOR_FROM_DATABASE=KeySafe-Cloud ++ ++bluetooth:v0609* ++ ID_VENDOR_FROM_DATABASE=BUCHI Labortechnik AG ++ ++bluetooth:v060A* ++ ID_VENDOR_FROM_DATABASE=IQAir AG ++ ++bluetooth:v060B* ++ ID_VENDOR_FROM_DATABASE=Triax Technologies Inc ++ ++bluetooth:v060C* ++ ID_VENDOR_FROM_DATABASE=Vuzix Corporation ++ ++bluetooth:v060D* ++ ID_VENDOR_FROM_DATABASE=TDK Corporation ++ ++bluetooth:v060E* ++ ID_VENDOR_FROM_DATABASE=Blueair AB ++ ++bluetooth:v060F* ++ ID_VENDOR_FROM_DATABASE=Signify Netherlands ++ ++bluetooth:v0610* ++ ID_VENDOR_FROM_DATABASE=ADH GUARDIAN USA LLC ++ ++bluetooth:v0611* ++ ID_VENDOR_FROM_DATABASE=Beurer GmbH ++ ++bluetooth:v0612* ++ ID_VENDOR_FROM_DATABASE=Playfinity AS ++ ++bluetooth:v0613* ++ ID_VENDOR_FROM_DATABASE=Hans Dinslage GmbH ++ ++bluetooth:v0614* ++ ID_VENDOR_FROM_DATABASE=OnAsset Intelligence, Inc. ++ ++bluetooth:v0615* ++ ID_VENDOR_FROM_DATABASE=INTER ACTION Corporation ++ ++bluetooth:v0616* ++ ID_VENDOR_FROM_DATABASE=OS42 UG (haftungsbeschraenkt) ++ ++bluetooth:v0617* ++ ID_VENDOR_FROM_DATABASE=WIZCONNECTED COMPANY LIMITED ++ ++bluetooth:v0618* ++ ID_VENDOR_FROM_DATABASE=Audio-Technica Corporation ++ ++bluetooth:v0619* ++ ID_VENDOR_FROM_DATABASE=Six Guys Labs, s.r.o. ++ ++bluetooth:v061A* ++ ID_VENDOR_FROM_DATABASE=R.W. Beckett Corporation ++ ++bluetooth:v061B* ++ ID_VENDOR_FROM_DATABASE=silex technology, inc. ++ ++bluetooth:v061C* ++ ID_VENDOR_FROM_DATABASE=Univations Limited ++ ++bluetooth:v061D* ++ ID_VENDOR_FROM_DATABASE=SENS Innovation ApS ++ ++bluetooth:v061E* ++ ID_VENDOR_FROM_DATABASE=Diamond Kinetics, Inc. ++ ++bluetooth:v061F* ++ ID_VENDOR_FROM_DATABASE=Phrame Inc. ++ ++bluetooth:v0620* ++ ID_VENDOR_FROM_DATABASE=Forciot Oy ++ ++bluetooth:v0621* ++ ID_VENDOR_FROM_DATABASE=Noordung d.o.o. ++ ++bluetooth:v0622* ++ ID_VENDOR_FROM_DATABASE=Beam Labs, LLC ++ ++bluetooth:v0623* ++ ID_VENDOR_FROM_DATABASE=Philadelphia Scientific (U.K.) Limited ++ ++bluetooth:v0624* ++ ID_VENDOR_FROM_DATABASE=Biovotion AG ++ ++bluetooth:v0625* ++ ID_VENDOR_FROM_DATABASE=Square Panda, Inc. ++ ++bluetooth:v0626* ++ ID_VENDOR_FROM_DATABASE=Amplifico ++ ++bluetooth:v0627* ++ ID_VENDOR_FROM_DATABASE=WEG S.A. ++ ++bluetooth:v0628* ++ ID_VENDOR_FROM_DATABASE=Ensto Oy ++ ++bluetooth:v0629* ++ ID_VENDOR_FROM_DATABASE=PHONEPE PVT LTD ++ ++bluetooth:v062A* ++ ID_VENDOR_FROM_DATABASE=Lunatico Astronomia SL ++ ++bluetooth:v062B* ++ ID_VENDOR_FROM_DATABASE=MinebeaMitsumi Inc. ++ ++bluetooth:v062C* ++ ID_VENDOR_FROM_DATABASE=ASPion GmbH ++ ++bluetooth:v062D* ++ ID_VENDOR_FROM_DATABASE=Vossloh-Schwabe Deutschland GmbH ++ ++bluetooth:v062E* ++ ID_VENDOR_FROM_DATABASE=Procept ++ ++bluetooth:v062F* ++ ID_VENDOR_FROM_DATABASE=ONKYO Corporation ++ ++bluetooth:v0630* ++ ID_VENDOR_FROM_DATABASE=Asthrea D.O.O. ++ ++bluetooth:v0631* ++ ID_VENDOR_FROM_DATABASE=Fortiori Design LLC ++ ++bluetooth:v0632* ++ ID_VENDOR_FROM_DATABASE=Hugo Muller GmbH & Co KG ++ ++bluetooth:v0633* ++ ID_VENDOR_FROM_DATABASE=Wangi Lai PLT ++ ++bluetooth:v0634* ++ ID_VENDOR_FROM_DATABASE=Fanstel Corp ++ ++bluetooth:v0635* ++ ID_VENDOR_FROM_DATABASE=Crookwood ++ ++bluetooth:v0636* ++ ID_VENDOR_FROM_DATABASE=ELECTRONICA INTEGRAL DE SONIDO S.A. ++ ++bluetooth:v0637* ++ ID_VENDOR_FROM_DATABASE=GiP Innovation Tools GmbH ++ ++bluetooth:v0638* ++ ID_VENDOR_FROM_DATABASE=LX SOLUTIONS PTY LIMITED ++ ++bluetooth:v0639* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Minew Technologies Co., Ltd. ++ ++bluetooth:v063A* ++ ID_VENDOR_FROM_DATABASE=Prolojik Limited ++ ++bluetooth:v063B* ++ ID_VENDOR_FROM_DATABASE=Kromek Group Plc ++ ++bluetooth:v063C* ++ ID_VENDOR_FROM_DATABASE=Contec Medical Systems Co., Ltd. ++ ++bluetooth:v063D* ++ ID_VENDOR_FROM_DATABASE=Xradio Technology Co.,Ltd. ++ ++bluetooth:v063E* ++ ID_VENDOR_FROM_DATABASE=The Indoor Lab, LLC ++ ++bluetooth:v063F* ++ ID_VENDOR_FROM_DATABASE=LDL TECHNOLOGY ++ ++bluetooth:v0640* ++ ID_VENDOR_FROM_DATABASE=Parkifi ++ ++bluetooth:v0641* ++ ID_VENDOR_FROM_DATABASE=Revenue Collection Systems FRANCE SAS ++ ++bluetooth:v0642* ++ ID_VENDOR_FROM_DATABASE=Bluetrum Technology Co.,Ltd ++ ++bluetooth:v0643* ++ ID_VENDOR_FROM_DATABASE=makita corporation ++ ++bluetooth:v0644* ++ ID_VENDOR_FROM_DATABASE=Apogee Instruments ++ ++bluetooth:v0645* ++ ID_VENDOR_FROM_DATABASE=BM3 ++ ++bluetooth:v0646* ++ ID_VENDOR_FROM_DATABASE=SGV Group Holding GmbH & Co. KG ++ ++bluetooth:v0647* ++ ID_VENDOR_FROM_DATABASE=MED-EL ++ ++bluetooth:v0648* ++ ID_VENDOR_FROM_DATABASE=Ultune Technologies ++ ++bluetooth:v0649* ++ ID_VENDOR_FROM_DATABASE=Ryeex Technology Co.,Ltd. ++ ++bluetooth:v064A* ++ ID_VENDOR_FROM_DATABASE=Open Research Institute, Inc. ++ ++bluetooth:v064B* ++ ID_VENDOR_FROM_DATABASE=Scale-Tec, Ltd ++ ++bluetooth:v064C* ++ ID_VENDOR_FROM_DATABASE=Zumtobel Group AG ++ ++bluetooth:v064D* ++ ID_VENDOR_FROM_DATABASE=iLOQ Oy ++ ++bluetooth:v064E* ++ ID_VENDOR_FROM_DATABASE=KRUXWorks Technologies Private Limited ++ ++bluetooth:v064F* ++ ID_VENDOR_FROM_DATABASE=Digital Matter Pty Ltd ++ ++bluetooth:v0650* ++ ID_VENDOR_FROM_DATABASE=Coravin, Inc. ++ ++bluetooth:v0651* ++ ID_VENDOR_FROM_DATABASE=Stasis Labs, Inc. ++ ++bluetooth:v0652* ++ ID_VENDOR_FROM_DATABASE=ITZ Innovations- und Technologiezentrum GmbH ++ ++bluetooth:v0653* ++ ID_VENDOR_FROM_DATABASE=Meggitt SA ++ ++bluetooth:v0654* ++ ID_VENDOR_FROM_DATABASE=Ledlenser GmbH & Co. KG ++ ++bluetooth:v0655* ++ ID_VENDOR_FROM_DATABASE=Renishaw PLC ++ ++bluetooth:v0656* ++ ID_VENDOR_FROM_DATABASE=ZhuHai AdvanPro Technology Company Limited ++ ++bluetooth:v0657* ++ ID_VENDOR_FROM_DATABASE=Meshtronix Limited ++ ++bluetooth:v0658* ++ ID_VENDOR_FROM_DATABASE=Payex Norge AS ++ ++bluetooth:v0659* ++ ID_VENDOR_FROM_DATABASE=UnSeen Technologies Oy ++ ++bluetooth:v065A* ++ ID_VENDOR_FROM_DATABASE=Zound Industries International AB ++ ++bluetooth:v065B* ++ ID_VENDOR_FROM_DATABASE=Sesam Solutions BV ++ ++bluetooth:v065C* ++ ID_VENDOR_FROM_DATABASE=PixArt Imaging Inc. ++ ++bluetooth:v065D* ++ ID_VENDOR_FROM_DATABASE=Panduit Corp. ++ ++bluetooth:v065E* ++ ID_VENDOR_FROM_DATABASE=Alo AB ++ ++bluetooth:v065F* ++ ID_VENDOR_FROM_DATABASE=Ricoh Company Ltd ++ ++bluetooth:v0660* ++ ID_VENDOR_FROM_DATABASE=RTC Industries, Inc. ++ ++bluetooth:v0661* ++ ID_VENDOR_FROM_DATABASE=Mode Lighting Limited ++ ++bluetooth:v0662* ++ ID_VENDOR_FROM_DATABASE=Particle Industries, Inc. ++ ++bluetooth:v0663* ++ ID_VENDOR_FROM_DATABASE=Advanced Telemetry Systems, Inc. ++ ++bluetooth:v0664* ++ ID_VENDOR_FROM_DATABASE=RHA TECHNOLOGIES LTD ++ ++bluetooth:v0665* ++ ID_VENDOR_FROM_DATABASE=Pure International Limited ++ ++bluetooth:v0666* ++ ID_VENDOR_FROM_DATABASE=WTO Werkzeug-Einrichtungen GmbH ++ ++bluetooth:v0667* ++ ID_VENDOR_FROM_DATABASE=Spark Technology Labs Inc. ++ ++bluetooth:v0668* ++ ID_VENDOR_FROM_DATABASE=Bleb Technology srl ++ ++bluetooth:v0669* ++ ID_VENDOR_FROM_DATABASE=Livanova USA, Inc. ++ ++bluetooth:v066A* ++ ID_VENDOR_FROM_DATABASE=Brady Worldwide Inc. ++ ++bluetooth:v066B* ++ ID_VENDOR_FROM_DATABASE=DewertOkin GmbH ++ ++bluetooth:v066C* ++ ID_VENDOR_FROM_DATABASE=Ztove ApS ++ ++bluetooth:v066D* ++ ID_VENDOR_FROM_DATABASE=Venso EcoSolutions AB ++ ++bluetooth:v066E* ++ ID_VENDOR_FROM_DATABASE=Eurotronik Kranj d.o.o. ++ ++bluetooth:v066F* ++ ID_VENDOR_FROM_DATABASE=Hug Technology Ltd ++ ++bluetooth:v0670* ++ ID_VENDOR_FROM_DATABASE=Gema Switzerland GmbH ++ ++bluetooth:v0671* ++ ID_VENDOR_FROM_DATABASE=Buzz Products Ltd. ++ ++bluetooth:v0672* ++ ID_VENDOR_FROM_DATABASE=Kopi ++ ++bluetooth:v0673* ++ ID_VENDOR_FROM_DATABASE=Innova Ideas Limited ++ ++bluetooth:v0674* ++ ID_VENDOR_FROM_DATABASE=BeSpoon ++ ++bluetooth:v0675* ++ ID_VENDOR_FROM_DATABASE=Deco Enterprises, Inc. ++ ++bluetooth:v0676* ++ ID_VENDOR_FROM_DATABASE=Expai Solutions Private Limited ++ ++bluetooth:v0677* ++ ID_VENDOR_FROM_DATABASE=Innovation First, Inc. ++ ++bluetooth:v0678* ++ ID_VENDOR_FROM_DATABASE=SABIK Offshore GmbH ++ ++bluetooth:v0679* ++ ID_VENDOR_FROM_DATABASE=4iiii Innovations Inc. ++ ++bluetooth:v067A* ++ ID_VENDOR_FROM_DATABASE=The Energy Conservatory, Inc. ++ ++bluetooth:v067B* ++ ID_VENDOR_FROM_DATABASE=I.FARM, INC. ++ ++bluetooth:v067C* ++ ID_VENDOR_FROM_DATABASE=Tile, Inc. ++ ++bluetooth:v067D* ++ ID_VENDOR_FROM_DATABASE=Form Athletica Inc. ++ ++bluetooth:v067E* ++ ID_VENDOR_FROM_DATABASE=MbientLab Inc ++ ++bluetooth:v067F* ++ ID_VENDOR_FROM_DATABASE=NETGRID S.N.C. DI BISSOLI MATTEO, CAMPOREALE SIMONE, TOGNETTI FEDERICO ++ ++bluetooth:v0680* ++ ID_VENDOR_FROM_DATABASE=Mannkind Corporation ++ ++bluetooth:v0681* ++ ID_VENDOR_FROM_DATABASE=Trade FIDES a.s. ++ ++bluetooth:v0682* ++ ID_VENDOR_FROM_DATABASE=Photron Limited ++ ++bluetooth:v0683* ++ ID_VENDOR_FROM_DATABASE=Eltako GmbH ++ ++bluetooth:v0684* ++ ID_VENDOR_FROM_DATABASE=Dermalapps, LLC ++ ++bluetooth:v0685* ++ ID_VENDOR_FROM_DATABASE=Greenwald Industries ++ ++bluetooth:v0686* ++ ID_VENDOR_FROM_DATABASE=inQs Co., Ltd. ++ ++bluetooth:v0687* ++ ID_VENDOR_FROM_DATABASE=Cherry GmbH ++ ++bluetooth:v0688* ++ ID_VENDOR_FROM_DATABASE=Amsted Digital Solutions Inc. ++ ++bluetooth:v0689* ++ ID_VENDOR_FROM_DATABASE=Tacx b.v. ++ ++bluetooth:v068A* ++ ID_VENDOR_FROM_DATABASE=Raytac Corporation ++ ++bluetooth:v068B* ++ ID_VENDOR_FROM_DATABASE=Jiangsu Teranovo Tech Co., Ltd. ++ ++bluetooth:v068C* ++ ID_VENDOR_FROM_DATABASE=Changzhou Sound Dragon Electronics and Acoustics Co., Ltd ++ ++bluetooth:v068D* ++ ID_VENDOR_FROM_DATABASE=JetBeep Inc. ++ ++bluetooth:v068E* ++ ID_VENDOR_FROM_DATABASE=Razer Inc. ++ ++bluetooth:v068F* ++ ID_VENDOR_FROM_DATABASE=JRM Group Limited ++ ++bluetooth:v0690* ++ ID_VENDOR_FROM_DATABASE=Eccrine Systems, Inc. ++ ++bluetooth:v0691* ++ ID_VENDOR_FROM_DATABASE=Curie Point AB ++ ++bluetooth:v0692* ++ ID_VENDOR_FROM_DATABASE=Georg Fischer AG ++ ++bluetooth:v0693* ++ ID_VENDOR_FROM_DATABASE=Hach - Danaher ++ ++bluetooth:v0694* ++ ID_VENDOR_FROM_DATABASE=T&A Laboratories LLC ++ ++bluetooth:v0695* ++ ID_VENDOR_FROM_DATABASE=Koki Holdings Co., Ltd. ++ ++bluetooth:v0696* ++ ID_VENDOR_FROM_DATABASE=Gunakar Private Limited ++ ++bluetooth:v0697* ++ ID_VENDOR_FROM_DATABASE=Stemco Products Inc ++ ++bluetooth:v0698* ++ ID_VENDOR_FROM_DATABASE=Wood IT Security, LLC ++ ++bluetooth:v0699* ++ ID_VENDOR_FROM_DATABASE=RandomLab SAS ++ ++bluetooth:v069A* ++ ID_VENDOR_FROM_DATABASE=Adero, Inc. (formerly as TrackR, Inc.) ++ ++bluetooth:v069B* ++ ID_VENDOR_FROM_DATABASE=Dragonchip Limited ++ ++bluetooth:v069C* ++ ID_VENDOR_FROM_DATABASE=Noomi AB ++ ++bluetooth:v069D* ++ ID_VENDOR_FROM_DATABASE=Vakaros LLC ++ ++bluetooth:v069E* ++ ID_VENDOR_FROM_DATABASE=Delta Electronics, Inc. ++ ++bluetooth:v069F* ++ ID_VENDOR_FROM_DATABASE=FlowMotion Technologies AS ++ ++bluetooth:v06A0* ++ ID_VENDOR_FROM_DATABASE=OBIQ Location Technology Inc. ++ ++bluetooth:v06A1* ++ ID_VENDOR_FROM_DATABASE=Cardo Systems, Ltd ++ ++bluetooth:v06A2* ++ ID_VENDOR_FROM_DATABASE=Globalworx GmbH ++ ++bluetooth:v06A3* ++ ID_VENDOR_FROM_DATABASE=Nymbus, LLC ++ ++bluetooth:v06A4* ++ ID_VENDOR_FROM_DATABASE=Sanyo Techno Solutions Tottori Co., Ltd. ++ ++bluetooth:v06A5* ++ ID_VENDOR_FROM_DATABASE=TEKZITEL PTY LTD ++ ++bluetooth:v06A6* ++ ID_VENDOR_FROM_DATABASE=Roambee Corporation ++ ++bluetooth:v06A7* ++ ID_VENDOR_FROM_DATABASE=Chipsea Technologies (ShenZhen) Corp. ++ ++bluetooth:v06A8* ++ ID_VENDOR_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co., Ltd. ++ ++bluetooth:v06A9* ++ ID_VENDOR_FROM_DATABASE=Soundmax Electronics Limited ++ ++bluetooth:v06AA* ++ ID_VENDOR_FROM_DATABASE=Produal Oy ++ ++bluetooth:v06AB* ++ ID_VENDOR_FROM_DATABASE=HMS Industrial Networks AB ++ ++bluetooth:v06AC* ++ ID_VENDOR_FROM_DATABASE=Ingchips Technology Co., Ltd. ++ ++bluetooth:v06AD* ++ ID_VENDOR_FROM_DATABASE=InnovaSea Systems Inc. ++ ++bluetooth:v06AE* ++ ID_VENDOR_FROM_DATABASE=SenseQ Inc. ++ ++bluetooth:v06AF* ++ ID_VENDOR_FROM_DATABASE=Shoof Technologies ++ ++bluetooth:v06B0* ++ ID_VENDOR_FROM_DATABASE=BRK Brands, Inc. ++ ++bluetooth:v06B1* ++ ID_VENDOR_FROM_DATABASE=SimpliSafe, Inc. ++ ++bluetooth:v06B2* ++ ID_VENDOR_FROM_DATABASE=Tussock Innovation 2013 Limited ++ ++bluetooth:v06B3* ++ ID_VENDOR_FROM_DATABASE=The Hablab ApS ++ ++bluetooth:v06B4* ++ ID_VENDOR_FROM_DATABASE=Sencilion Oy ++ ++bluetooth:v06B5* ++ ID_VENDOR_FROM_DATABASE=Wabilogic Ltd. ++ ++bluetooth:v06B6* ++ ID_VENDOR_FROM_DATABASE=Sociometric Solutions, Inc. ++ ++bluetooth:v06B7* ++ ID_VENDOR_FROM_DATABASE=iCOGNIZE GmbH ++ ++bluetooth:v06B8* ++ ID_VENDOR_FROM_DATABASE=ShadeCraft, Inc ++ ++bluetooth:v06B9* ++ ID_VENDOR_FROM_DATABASE=Beflex Inc. ++ ++bluetooth:v06BA* ++ ID_VENDOR_FROM_DATABASE=Beaconzone Ltd ++ ++bluetooth:v06BB* ++ ID_VENDOR_FROM_DATABASE=Leaftronix Analogic Solutions Private Limited ++ ++bluetooth:v06BC* ++ ID_VENDOR_FROM_DATABASE=TWS Srl ++ ++bluetooth:v06BD* ++ ID_VENDOR_FROM_DATABASE=ABB Oy ++ ++bluetooth:v06BE* ++ ID_VENDOR_FROM_DATABASE=HitSeed Oy ++ ++bluetooth:v06BF* ++ ID_VENDOR_FROM_DATABASE=Delcom Products Inc. ++ ++bluetooth:v06C0* ++ ID_VENDOR_FROM_DATABASE=CAME S.p.A. ++ ++bluetooth:v06C1* ++ ID_VENDOR_FROM_DATABASE=Alarm.com Holdings, Inc ++ ++bluetooth:v06C2* ++ ID_VENDOR_FROM_DATABASE=Measurlogic Inc. ++ ++bluetooth:v06C3* ++ ID_VENDOR_FROM_DATABASE=King I Electronics.Co.,Ltd ++ ++bluetooth:v06C4* ++ ID_VENDOR_FROM_DATABASE=Dream Labs GmbH ++ ++bluetooth:v06C5* ++ ID_VENDOR_FROM_DATABASE=Urban Compass, Inc ++ ++bluetooth:v06C6* ++ ID_VENDOR_FROM_DATABASE=Simm Tronic Limited ++ ++bluetooth:v06C7* ++ ID_VENDOR_FROM_DATABASE=Somatix Inc ++ ++bluetooth:v06C8* ++ ID_VENDOR_FROM_DATABASE=Storz & Bickel GmbH & Co. KG ++ ++bluetooth:v06C9* ++ ID_VENDOR_FROM_DATABASE=MYLAPS B.V. ++ ++bluetooth:v06CA* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Zhongguang Infotech Technology Development Co., Ltd ++ ++bluetooth:v06CB* ++ ID_VENDOR_FROM_DATABASE=Dyeware, LLC ++ ++bluetooth:v06CC* ++ ID_VENDOR_FROM_DATABASE=Dongguan SmartAction Technology Co.,Ltd. ++ ++bluetooth:v06CD* ++ ID_VENDOR_FROM_DATABASE=DIG Corporation ++ ++bluetooth:v06CE* ++ ID_VENDOR_FROM_DATABASE=FIOR & GENTZ ++ ++bluetooth:v06CF* ++ ID_VENDOR_FROM_DATABASE=Belparts N.V. ++ ++bluetooth:v06D0* ++ ID_VENDOR_FROM_DATABASE=Etekcity Corporation ++ ++bluetooth:v06D1* ++ ID_VENDOR_FROM_DATABASE=Meyer Sound Laboratories, Incorporated ++ ++bluetooth:v06D2* ++ ID_VENDOR_FROM_DATABASE=CeoTronics AG ++ ++bluetooth:v06D3* ++ ID_VENDOR_FROM_DATABASE=TriTeq Lock and Security, LLC ++ ++bluetooth:v06D4* ++ ID_VENDOR_FROM_DATABASE=DYNAKODE TECHNOLOGY PRIVATE LIMITED ++ ++bluetooth:v06D5* ++ ID_VENDOR_FROM_DATABASE=Sensirion AG ++ ++bluetooth:v06D6* ++ ID_VENDOR_FROM_DATABASE=JCT Healthcare Pty Ltd ++ ++bluetooth:v06D7* ++ ID_VENDOR_FROM_DATABASE=FUBA Automotive Electronics GmbH ++ ++bluetooth:v06D8* ++ ID_VENDOR_FROM_DATABASE=AW Company ++ ++bluetooth:v06D9* ++ ID_VENDOR_FROM_DATABASE=Shanghai Mountain View Silicon Co.,Ltd. ++ ++bluetooth:v06DA* ++ ID_VENDOR_FROM_DATABASE=Zliide Technologies ApS ++ ++bluetooth:v06DB* ++ ID_VENDOR_FROM_DATABASE=Automatic Labs, Inc. ++ ++bluetooth:v06DC* ++ ID_VENDOR_FROM_DATABASE=Industrial Network Controls, LLC ++ ++bluetooth:v06DD* ++ ID_VENDOR_FROM_DATABASE=Intellithings Ltd. ++ ++bluetooth:v06DE* ++ ID_VENDOR_FROM_DATABASE=Navcast, Inc. ++ ++bluetooth:v06DF* ++ ID_VENDOR_FROM_DATABASE=Hubbell Lighting, Inc. ++ ++bluetooth:v06E0* ++ ID_VENDOR_FROM_DATABASE=Avaya  ++ ++bluetooth:v06E1* ++ ID_VENDOR_FROM_DATABASE=Milestone AV Technologies LLC ++ ++bluetooth:v06E2* ++ ID_VENDOR_FROM_DATABASE=Alango Technologies Ltd ++ ++bluetooth:v06E3* ++ ID_VENDOR_FROM_DATABASE=Spinlock Ltd ++ ++bluetooth:v06E4* ++ ID_VENDOR_FROM_DATABASE=Aluna ++ ++bluetooth:v06E5* ++ ID_VENDOR_FROM_DATABASE=OPTEX CO.,LTD. ++ ++bluetooth:v06E6* ++ ID_VENDOR_FROM_DATABASE=NIHON DENGYO KOUSAKU ++ ++bluetooth:v06E7* ++ ID_VENDOR_FROM_DATABASE=VELUX A/S ++ ++bluetooth:v06E8* ++ ID_VENDOR_FROM_DATABASE=Almendo Technologies GmbH ++ ++bluetooth:v06E9* ++ ID_VENDOR_FROM_DATABASE=Zmartfun Electronics, Inc. ++ ++bluetooth:v06EA* ++ ID_VENDOR_FROM_DATABASE=SafeLine Sweden AB ++ ++bluetooth:v06EB* ++ ID_VENDOR_FROM_DATABASE=Houston Radar LLC ++ ++bluetooth:v06EC* ++ ID_VENDOR_FROM_DATABASE=Sigur ++ ++bluetooth:v06ED* ++ ID_VENDOR_FROM_DATABASE=J Neades Ltd ++ ++bluetooth:v06EE* ++ ID_VENDOR_FROM_DATABASE=Avantis Systems Limited ++ ++bluetooth:v06EF* ++ ID_VENDOR_FROM_DATABASE=ALCARE Co., Ltd. ++ ++bluetooth:v06F0* ++ ID_VENDOR_FROM_DATABASE=Chargy Technologies, SL ++ ++bluetooth:v06F1* ++ ID_VENDOR_FROM_DATABASE=Shibutani Co., Ltd. ++ ++bluetooth:v06F2* ++ ID_VENDOR_FROM_DATABASE=Trapper Data AB ++ ++bluetooth:v06F3* ++ ID_VENDOR_FROM_DATABASE=Alfred International Inc. ++ ++bluetooth:v06F4* ++ ID_VENDOR_FROM_DATABASE=Near Field Solutions Ltd ++ ++bluetooth:v06F5* ++ ID_VENDOR_FROM_DATABASE=Vigil Technologies Inc. ++ ++bluetooth:v06F6* ++ ID_VENDOR_FROM_DATABASE=Vitulo Plus BV ++ ++bluetooth:v06F7* ++ ID_VENDOR_FROM_DATABASE=WILKA Schliesstechnik GmbH ++ ++bluetooth:v06F8* ++ ID_VENDOR_FROM_DATABASE=BodyPlus Technology Co.,Ltd ++ ++bluetooth:v06F9* ++ ID_VENDOR_FROM_DATABASE=happybrush GmbH ++ ++bluetooth:v06FA* ++ ID_VENDOR_FROM_DATABASE=Enequi AB ++ ++bluetooth:v06FB* ++ ID_VENDOR_FROM_DATABASE=Sartorius AG ++ ++bluetooth:v06FC* ++ ID_VENDOR_FROM_DATABASE=Tom Communication Industrial Co.,Ltd. ++ ++bluetooth:v06FD* ++ ID_VENDOR_FROM_DATABASE=ESS Embedded System Solutions Inc. ++ ++bluetooth:v06FE* ++ ID_VENDOR_FROM_DATABASE=Mahr GmbH ++ ++bluetooth:v06FF* ++ ID_VENDOR_FROM_DATABASE=Redpine Signals Inc ++ ++bluetooth:v0700* ++ ID_VENDOR_FROM_DATABASE=TraqFreq LLC ++ ++bluetooth:v0701* ++ ID_VENDOR_FROM_DATABASE=PAFERS TECH ++ ++bluetooth:v0702* ++ ID_VENDOR_FROM_DATABASE=Akciju sabiedriba "SAF TEHNIKA" ++ ++bluetooth:v0703* ++ ID_VENDOR_FROM_DATABASE=Beijing Jingdong Century Trading Co., Ltd. ++ ++bluetooth:v0704* ++ ID_VENDOR_FROM_DATABASE=JBX Designs Inc. ++ ++bluetooth:v0705* ++ ID_VENDOR_FROM_DATABASE=AB Electrolux ++ ++bluetooth:v0706* ++ ID_VENDOR_FROM_DATABASE=Wernher von Braun Center for ASdvanced Research ++ ++bluetooth:v0707* ++ ID_VENDOR_FROM_DATABASE=Essity Hygiene and Health Aktiebolag ++ ++bluetooth:v0708* ++ ID_VENDOR_FROM_DATABASE=Be Interactive Co., Ltd ++ ++bluetooth:v0709* ++ ID_VENDOR_FROM_DATABASE=Carewear Corp. ++ ++bluetooth:v070A* ++ ID_VENDOR_FROM_DATABASE=Huf Hülsbeck & Fürst GmbH & Co. KG ++ ++bluetooth:v070B* ++ ID_VENDOR_FROM_DATABASE=Element Products, Inc. ++ ++bluetooth:v070C* ++ ID_VENDOR_FROM_DATABASE=Beijing Winner Microelectronics Co.,Ltd ++ ++bluetooth:v070D* ++ ID_VENDOR_FROM_DATABASE=SmartSnugg Pty Ltd ++ ++bluetooth:v070E* ++ ID_VENDOR_FROM_DATABASE=FiveCo Sarl ++ ++bluetooth:v070F* ++ ID_VENDOR_FROM_DATABASE=California Things Inc. ++ ++bluetooth:v0710* ++ ID_VENDOR_FROM_DATABASE=Audiodo AB ++ ++bluetooth:v0711* ++ ID_VENDOR_FROM_DATABASE=ABAX AS ++ ++bluetooth:v0712* ++ ID_VENDOR_FROM_DATABASE=Bull Group Company Limited ++ ++bluetooth:v0713* ++ ID_VENDOR_FROM_DATABASE=Respiri Limited ++ ++bluetooth:v0714* ++ ID_VENDOR_FROM_DATABASE=MindPeace Safety LLC ++ ++bluetooth:v0715* ++ ID_VENDOR_FROM_DATABASE=Vgyan Solutions ++ ++bluetooth:v0716* ++ ID_VENDOR_FROM_DATABASE=Altonics ++ ++bluetooth:v0717* ++ ID_VENDOR_FROM_DATABASE=iQsquare BV ++ ++bluetooth:v0718* ++ ID_VENDOR_FROM_DATABASE=IDIBAIX enginneering ++ ++bluetooth:v0719* ++ ID_VENDOR_FROM_DATABASE=ECSG ++ ++bluetooth:v071A* ++ ID_VENDOR_FROM_DATABASE=REVSMART WEARABLE HK CO LTD ++ ++bluetooth:v071B* ++ ID_VENDOR_FROM_DATABASE=Precor ++ ++bluetooth:v071C* ++ ID_VENDOR_FROM_DATABASE=F5 Sports, Inc ++ ++bluetooth:v071D* ++ ID_VENDOR_FROM_DATABASE=exoTIC Systems ++ ++bluetooth:v071E* ++ ID_VENDOR_FROM_DATABASE=DONGGUAN HELE ELECTRONICS CO., LTD ++ ++bluetooth:v071F* ++ ID_VENDOR_FROM_DATABASE=Dongguan Liesheng Electronic Co.Ltd ++ ++bluetooth:v0720* ++ ID_VENDOR_FROM_DATABASE=Oculeve, Inc. ++ ++bluetooth:v0721* ++ ID_VENDOR_FROM_DATABASE=Clover Network, Inc. ++ ++bluetooth:v0722* ++ ID_VENDOR_FROM_DATABASE=Xiamen Eholder Electronics Co.Ltd ++ ++bluetooth:v0723* ++ ID_VENDOR_FROM_DATABASE=Ford Motor Company ++ ++bluetooth:v0724* ++ ID_VENDOR_FROM_DATABASE=Guangzhou SuperSound Information Technology Co.,Ltd ++ ++bluetooth:v0725* ++ ID_VENDOR_FROM_DATABASE=Tedee Sp. z o.o. ++ ++bluetooth:v0726* ++ ID_VENDOR_FROM_DATABASE=PHC Corporation ++ ++bluetooth:v0727* ++ ID_VENDOR_FROM_DATABASE=STALKIT AS ++ ++bluetooth:v0728* ++ ID_VENDOR_FROM_DATABASE=Eli Lilly and Company ++ ++bluetooth:v0729* ++ ID_VENDOR_FROM_DATABASE=SwaraLink Technologies ++ ++bluetooth:v072A* ++ ID_VENDOR_FROM_DATABASE=JMR embedded systems GmbH ++ ++bluetooth:v072B* ++ ID_VENDOR_FROM_DATABASE=Bitkey Inc. ++ ++bluetooth:v072C* ++ ID_VENDOR_FROM_DATABASE=GWA Hygiene GmbH ++ ++bluetooth:v072D* ++ ID_VENDOR_FROM_DATABASE=Safera Oy ++ ++bluetooth:v072E* ++ ID_VENDOR_FROM_DATABASE=Open Platform Systems LLC ++ ++bluetooth:v072F* ++ ID_VENDOR_FROM_DATABASE=OnePlus Electronics (Shenzhen) Co., Ltd. ++ ++bluetooth:v0730* ++ ID_VENDOR_FROM_DATABASE=Wildlife Acoustics, Inc. ++ ++bluetooth:v0731* ++ ID_VENDOR_FROM_DATABASE=ABLIC Inc. ++ ++bluetooth:v0732* ++ ID_VENDOR_FROM_DATABASE=Dairy Tech, Inc. ++ ++bluetooth:v0733* ++ ID_VENDOR_FROM_DATABASE=Iguanavation, Inc. ++ ++bluetooth:v0734* ++ ID_VENDOR_FROM_DATABASE=DiUS Computing Pty Ltd ++ ++bluetooth:v0735* ++ ID_VENDOR_FROM_DATABASE=UpRight Technologies LTD ++ ++bluetooth:v0736* ++ ID_VENDOR_FROM_DATABASE=FrancisFund, LLC ++ ++bluetooth:v0737* ++ ID_VENDOR_FROM_DATABASE=LLC Navitek ++ ++bluetooth:v0738* ++ ID_VENDOR_FROM_DATABASE=Glass Security Pte Ltd ++ ++bluetooth:v0739* ++ ID_VENDOR_FROM_DATABASE=Jiangsu Qinheng Co., Ltd. ++ ++bluetooth:v073A* ++ ID_VENDOR_FROM_DATABASE=Chandler Systems Inc. ++ ++bluetooth:v073B* ++ ID_VENDOR_FROM_DATABASE=Fantini Cosmi s.p.a. ++ ++bluetooth:v073C* ++ ID_VENDOR_FROM_DATABASE=Acubit ApS ++ ++bluetooth:v073D* ++ ID_VENDOR_FROM_DATABASE=Beijing Hao Heng Tian Tech Co., Ltd. ++ ++bluetooth:v073E* ++ ID_VENDOR_FROM_DATABASE=Bluepack S.R.L. ++ ++bluetooth:v073F* ++ ID_VENDOR_FROM_DATABASE=Beijing Unisoc Technologies Co., Ltd. ++ ++bluetooth:v0740* ++ ID_VENDOR_FROM_DATABASE=HITIQ LIMITED ++ ++bluetooth:v0741* ++ ID_VENDOR_FROM_DATABASE=MAC SRL ++ ++bluetooth:v0742* ++ ID_VENDOR_FROM_DATABASE=DML LLC ++ ++bluetooth:v0743* ++ ID_VENDOR_FROM_DATABASE=Sanofi ++ ++bluetooth:v0744* ++ ID_VENDOR_FROM_DATABASE=SOCOMEC ++ ++bluetooth:v0745* ++ ID_VENDOR_FROM_DATABASE=WIZNOVA, Inc. ++ ++bluetooth:v0746* ++ ID_VENDOR_FROM_DATABASE=Seitec Elektronik GmbH ++ ++bluetooth:v0747* ++ ID_VENDOR_FROM_DATABASE=OR Technologies Pty Ltd ++ ++bluetooth:v0748* ++ ID_VENDOR_FROM_DATABASE=GuangZhou KuGou Computer Technology Co.Ltd ++ ++bluetooth:v0749* ++ ID_VENDOR_FROM_DATABASE=DIAODIAO (Beijing) Technology Co., Ltd. ++ ++bluetooth:v074A* ++ ID_VENDOR_FROM_DATABASE=Illusory Studios LLC ++ ++bluetooth:v074B* ++ ID_VENDOR_FROM_DATABASE=Sarvavid Software Solutions LLP ++ ++bluetooth:v074C* ++ ID_VENDOR_FROM_DATABASE=iopool s.a. ++ ++bluetooth:v074D* ++ ID_VENDOR_FROM_DATABASE=Amtech Systems, LLC ++ ++bluetooth:v074E* ++ ID_VENDOR_FROM_DATABASE=EAGLE DETECTION SA ++ ++bluetooth:v074F* ++ ID_VENDOR_FROM_DATABASE=MEDIATECH S.R.L. ++ ++bluetooth:v0750* ++ ID_VENDOR_FROM_DATABASE=Hamilton Professional Services of Canada Incorporated ++ ++bluetooth:v0751* ++ ID_VENDOR_FROM_DATABASE=Changsha JEMO IC Design Co.,Ltd ++ ++bluetooth:v0752* ++ ID_VENDOR_FROM_DATABASE=Elatec GmbH ++ ++bluetooth:v0753* ++ ID_VENDOR_FROM_DATABASE=JLG Industries, Inc. ++ ++bluetooth:v0754* ++ ID_VENDOR_FROM_DATABASE=Michael Parkin ++ ++bluetooth:v0755* ++ ID_VENDOR_FROM_DATABASE=Brother Industries, Ltd ++ ++bluetooth:v0756* ++ ID_VENDOR_FROM_DATABASE=Lumens For Less, Inc ++ ++bluetooth:v0757* ++ ID_VENDOR_FROM_DATABASE=ELA Innovation ++ ++bluetooth:v0758* ++ ID_VENDOR_FROM_DATABASE=umanSense AB ++ ++bluetooth:v0759* ++ ID_VENDOR_FROM_DATABASE=Shanghai InGeek Cyber Security Co., Ltd. ++ ++bluetooth:v075A* ++ ID_VENDOR_FROM_DATABASE=HARMAN CO.,LTD. ++ ++bluetooth:v075B* ++ ID_VENDOR_FROM_DATABASE=Smart Sensor Devices AB ++ ++bluetooth:v075C* ++ ID_VENDOR_FROM_DATABASE=Antitronics Inc. ++ ++bluetooth:v075D* ++ ID_VENDOR_FROM_DATABASE=RHOMBUS SYSTEMS, INC. ++ ++bluetooth:v075E* ++ ID_VENDOR_FROM_DATABASE=Katerra Inc. ++ ++bluetooth:v075F* ++ ID_VENDOR_FROM_DATABASE=Remote Solution Co., LTD. ++ ++bluetooth:v0760* ++ ID_VENDOR_FROM_DATABASE=Vimar SpA ++ ++bluetooth:v0761* ++ ID_VENDOR_FROM_DATABASE=Mantis Tech LLC ++ ++bluetooth:v0762* ++ ID_VENDOR_FROM_DATABASE=TerOpta Ltd ++ ++bluetooth:v0763* ++ ID_VENDOR_FROM_DATABASE=PIKOLIN S.L. ++ ++bluetooth:v0764* ++ ID_VENDOR_FROM_DATABASE=WWZN Information Technology Company Limited ++ ++bluetooth:v0765* ++ ID_VENDOR_FROM_DATABASE=Voxx International ++ ++bluetooth:v0766* ++ ID_VENDOR_FROM_DATABASE=ART AND PROGRAM, INC. ++ ++bluetooth:v0767* ++ ID_VENDOR_FROM_DATABASE=NITTO DENKO ASIA TECHNICAL CENTRE PTE. LTD. ++ ++bluetooth:v0768* ++ ID_VENDOR_FROM_DATABASE=Peloton Interactive Inc. ++ ++bluetooth:v0769* ++ ID_VENDOR_FROM_DATABASE=Force Impact Technologies ++ ++bluetooth:v076A* ++ ID_VENDOR_FROM_DATABASE=Dmac Mobile Developments, LLC ++ ++bluetooth:v076B* ++ ID_VENDOR_FROM_DATABASE=Engineered Medical Technologies ++ ++bluetooth:v076C* ++ ID_VENDOR_FROM_DATABASE=Noodle Technology inc ++ ++bluetooth:v076D* ++ ID_VENDOR_FROM_DATABASE=Graesslin GmbH ++ ++bluetooth:v076E* ++ ID_VENDOR_FROM_DATABASE=WuQi technologies, Inc. ++ ++bluetooth:v076F* ++ ID_VENDOR_FROM_DATABASE=Successful Endeavours Pty Ltd ++ ++bluetooth:v0770* ++ ID_VENDOR_FROM_DATABASE=InnoCon Medical ApS ++ ++bluetooth:v0771* ++ ID_VENDOR_FROM_DATABASE=Corvex Connected Safety ++ ++bluetooth:v0772* ++ ID_VENDOR_FROM_DATABASE=Thirdwayv Inc. ++ ++bluetooth:v0773* ++ ID_VENDOR_FROM_DATABASE=Echoflex Solutions Inc. ++ ++bluetooth:v0774* ++ ID_VENDOR_FROM_DATABASE=C-MAX Asia Limited ++ ++bluetooth:v0775* ++ ID_VENDOR_FROM_DATABASE=4eBusiness GmbH ++ ++bluetooth:v0776* ++ ID_VENDOR_FROM_DATABASE=Cyber Transport Control GmbH ++ ++bluetooth:v0777* ++ ID_VENDOR_FROM_DATABASE=Cue ++ ++bluetooth:v0778* ++ ID_VENDOR_FROM_DATABASE=KOAMTAC INC. ++ ++bluetooth:v0779* ++ ID_VENDOR_FROM_DATABASE=Loopshore Oy ++ ++bluetooth:v077A* ++ ID_VENDOR_FROM_DATABASE=Niruha Systems Private Limited ++ ++bluetooth:v077B* ++ ID_VENDOR_FROM_DATABASE=AmaterZ, Inc. ++ ++bluetooth:v077C* ++ ID_VENDOR_FROM_DATABASE=radius co., ltd. ++ ++bluetooth:v077D* ++ ID_VENDOR_FROM_DATABASE=Sensority, s.r.o. ++ ++bluetooth:v077E* ++ ID_VENDOR_FROM_DATABASE=Sparkage Inc. ++ ++bluetooth:v077F* ++ ID_VENDOR_FROM_DATABASE=Glenview Software Corporation ++ ++bluetooth:v0780* ++ ID_VENDOR_FROM_DATABASE=Finch Technologies Ltd. ++ ++bluetooth:v0781* ++ ID_VENDOR_FROM_DATABASE=Qingping Technology (Beijing) Co., Ltd. ++ ++bluetooth:v0782* ++ ID_VENDOR_FROM_DATABASE=DeviceDrive AS ++ ++bluetooth:v0783* ++ ID_VENDOR_FROM_DATABASE=ESEMBER LIMITED LIABILITY COMPANY ++ ++bluetooth:v0784* ++ ID_VENDOR_FROM_DATABASE=audifon GmbH & Co. KG ++ ++bluetooth:v0785* ++ ID_VENDOR_FROM_DATABASE=O2 Micro, Inc. ++ ++bluetooth:v0786* ++ ID_VENDOR_FROM_DATABASE=HLP Controls Pty Limited ++ ++bluetooth:v0787* ++ ID_VENDOR_FROM_DATABASE=Pangaea Solution ++ ++bluetooth:v0788* ++ ID_VENDOR_FROM_DATABASE=BubblyNet, LLC ++ ++bluetooth:v078A* ++ ID_VENDOR_FROM_DATABASE=The Wildflower Foundation ++ ++bluetooth:v078B* ++ ID_VENDOR_FROM_DATABASE=Optikam Tech Inc. ++ ++bluetooth:v078C* ++ ID_VENDOR_FROM_DATABASE=MINIBREW HOLDING B.V ++ ++bluetooth:v078D* ++ ID_VENDOR_FROM_DATABASE=Cybex GmbH ++ ++bluetooth:v078E* ++ ID_VENDOR_FROM_DATABASE=FUJIMIC NIIGATA, INC. ++ ++bluetooth:v078F* ++ ID_VENDOR_FROM_DATABASE=Hanna Instruments, Inc. ++ ++bluetooth:v0790* ++ ID_VENDOR_FROM_DATABASE=KOMPAN A/S ++ ++bluetooth:v0791* ++ ID_VENDOR_FROM_DATABASE=Scosche Industries, Inc. ++ ++bluetooth:v0792* ++ ID_VENDOR_FROM_DATABASE=Provo Craft ++ ++bluetooth:v0793* ++ ID_VENDOR_FROM_DATABASE=AEV spol. s r.o. ++ ++bluetooth:v0794* ++ ID_VENDOR_FROM_DATABASE=The Coca-Cola Company ++ ++bluetooth:v0795* ++ ID_VENDOR_FROM_DATABASE=GASTEC CORPORATION ++ ++bluetooth:v0796* ++ ID_VENDOR_FROM_DATABASE=StarLeaf Ltd ++ ++bluetooth:v0797* ++ ID_VENDOR_FROM_DATABASE=Water-i.d. GmbH ++ ++bluetooth:v0798* ++ ID_VENDOR_FROM_DATABASE=HoloKit, Inc. ++ ++bluetooth:v0799* ++ ID_VENDOR_FROM_DATABASE=PlantChoir Inc. ++ ++bluetooth:v079A* ++ ID_VENDOR_FROM_DATABASE=GuangDong Oppo Mobile Telecommunications Corp., Ltd. ++ ++bluetooth:v079B* ++ ID_VENDOR_FROM_DATABASE=CST ELECTRONICS (PROPRIETARY) LIMITED ++ ++bluetooth:v079C* ++ ID_VENDOR_FROM_DATABASE=Sky UK Limited ++ ++bluetooth:v079D* ++ ID_VENDOR_FROM_DATABASE=Digibale Pty Ltd ++ ++bluetooth:v079E* ++ ID_VENDOR_FROM_DATABASE=Smartloxx GmbH ++ ++bluetooth:v079F* ++ ID_VENDOR_FROM_DATABASE=Pune Scientific LLP ++ ++bluetooth:v07A0* ++ ID_VENDOR_FROM_DATABASE=Regent Beleuchtungskorper AG ++ ++bluetooth:v07A1* ++ ID_VENDOR_FROM_DATABASE=Apollo Neuroscience, Inc. ++ ++bluetooth:v07A2* ++ ID_VENDOR_FROM_DATABASE=Roku, Inc. ++ ++bluetooth:v07A3* ++ ID_VENDOR_FROM_DATABASE=Comcast Cable ++ ++bluetooth:v07A4* ++ ID_VENDOR_FROM_DATABASE=Xiamen Mage Information Technology Co., Ltd. ++ ++bluetooth:v07A5* ++ ID_VENDOR_FROM_DATABASE=RAB Lighting, Inc. ++ ++bluetooth:v07A6* ++ ID_VENDOR_FROM_DATABASE=Musen Connect, Inc. ++ ++bluetooth:v07A7* ++ ID_VENDOR_FROM_DATABASE=Zume, Inc. ++ ++bluetooth:v07A8* ++ ID_VENDOR_FROM_DATABASE=conbee GmbH ++ ++bluetooth:v07A9* ++ ID_VENDOR_FROM_DATABASE=Bruel & Kjaer Sound & Vibration ++ ++bluetooth:v07AA* ++ ID_VENDOR_FROM_DATABASE=The Kroger Co. ++ ++bluetooth:v07AB* ++ ID_VENDOR_FROM_DATABASE=Granite River Solutions, Inc. ++ ++bluetooth:v07AC* ++ ID_VENDOR_FROM_DATABASE=LoupeDeck Oy ++ ++bluetooth:v07AD* ++ ID_VENDOR_FROM_DATABASE=New H3C Technologies Co.,Ltd ++ ++bluetooth:v07AE* ++ ID_VENDOR_FROM_DATABASE=Aurea Solucoes Tecnologicas Ltda. ++ ++bluetooth:v07AF* ++ ID_VENDOR_FROM_DATABASE=Hong Kong Bouffalo Lab Limited ++ ++bluetooth:v07B0* ++ ID_VENDOR_FROM_DATABASE=GV Concepts Inc. ++ ++bluetooth:v07B1* ++ ID_VENDOR_FROM_DATABASE=Thomas Dynamics, LLC ++ ++bluetooth:v07B2* ++ ID_VENDOR_FROM_DATABASE=Moeco IOT Inc. ++ ++bluetooth:v07B3* ++ ID_VENDOR_FROM_DATABASE=2N TELEKOMUNIKACE a.s. ++ ++bluetooth:v07B4* ++ ID_VENDOR_FROM_DATABASE=Hormann KG Antriebstechnik ++ ++bluetooth:v07B5* ++ ID_VENDOR_FROM_DATABASE=CRONO CHIP, S.L. ++ ++bluetooth:v07B6* ++ ID_VENDOR_FROM_DATABASE=Soundbrenner Limited ++ ++bluetooth:v07B7* ++ ID_VENDOR_FROM_DATABASE=ETABLISSEMENTS GEORGES RENAULT ++ ++bluetooth:v07B8* ++ ID_VENDOR_FROM_DATABASE=iSwip ++ ++bluetooth:v07B9* ++ ID_VENDOR_FROM_DATABASE=Epona Biotec Limited ++ ++bluetooth:v07BA* ++ ID_VENDOR_FROM_DATABASE=Battery-Biz Inc. ++ ++bluetooth:v07BB* ++ ID_VENDOR_FROM_DATABASE=EPIC S.R.L. ++ ++bluetooth:v07BC* ++ ID_VENDOR_FROM_DATABASE=KD CIRCUITS LLC ++ ++bluetooth:v07BD* ++ ID_VENDOR_FROM_DATABASE=Genedrive Diagnostics Ltd ++ ++bluetooth:v07BE* ++ ID_VENDOR_FROM_DATABASE=Axentia Technologies AB ++ ++bluetooth:v07BF* ++ ID_VENDOR_FROM_DATABASE=REGULA Ltd. ++ ++bluetooth:v07C0* ++ ID_VENDOR_FROM_DATABASE=Biral AG ++ ++bluetooth:v07C1* ++ ID_VENDOR_FROM_DATABASE=A.W. Chesterton Company ++ ++bluetooth:v07C2* ++ ID_VENDOR_FROM_DATABASE=Radinn AB ++ ++bluetooth:v07C3* ++ ID_VENDOR_FROM_DATABASE=CIMTechniques, Inc. ++ ++bluetooth:v07C4* ++ ID_VENDOR_FROM_DATABASE=Johnson Health Tech NA ++ ++bluetooth:v07C5* ++ ID_VENDOR_FROM_DATABASE=June Life, Inc. ++ ++bluetooth:v07C6* ++ ID_VENDOR_FROM_DATABASE=Bluenetics GmbH ++ ++bluetooth:v07C7* ++ ID_VENDOR_FROM_DATABASE=iaconicDesign Inc. ++ ++bluetooth:v07C8* ++ ID_VENDOR_FROM_DATABASE=WRLDS Creations AB ++ ++bluetooth:v07C9* ++ ID_VENDOR_FROM_DATABASE=Skullcandy, Inc. ++ ++bluetooth:v07CA* ++ ID_VENDOR_FROM_DATABASE=Modul-System HH AB ++ ++bluetooth:v07CB* ++ ID_VENDOR_FROM_DATABASE=West Pharmaceutical Services, Inc. ++ ++bluetooth:v07CC* ++ ID_VENDOR_FROM_DATABASE=Barnacle Systems Inc. ++ ++bluetooth:v07CD* ++ ID_VENDOR_FROM_DATABASE=Smart Wave Technologies Canada Inc ++ ++bluetooth:v07CE* ++ ID_VENDOR_FROM_DATABASE=Shanghai Top-Chip Microelectronics Tech. Co., LTD ++ ++bluetooth:v07CF* ++ ID_VENDOR_FROM_DATABASE=NeoSensory, Inc. ++ ++bluetooth:v07D0* ++ ID_VENDOR_FROM_DATABASE=Hangzhou Tuya Information Technology Co., Ltd ++ ++bluetooth:v07D1* ++ ID_VENDOR_FROM_DATABASE=Shanghai Panchip Microelectronics Co., Ltd ++ ++bluetooth:v07D2* ++ ID_VENDOR_FROM_DATABASE=React Accessibility Limited ++ ++bluetooth:v07D3* ++ ID_VENDOR_FROM_DATABASE=LIVNEX Co.,Ltd. ++ ++bluetooth:v07D4* ++ ID_VENDOR_FROM_DATABASE=Kano Computing Limited ++ ++bluetooth:v07D5* ++ ID_VENDOR_FROM_DATABASE=hoots classic GmbH ++ ++bluetooth:v07D6* ++ ID_VENDOR_FROM_DATABASE=ecobee Inc. ++ ++bluetooth:v07D7* ++ ID_VENDOR_FROM_DATABASE=Nanjing Qinheng Microelectronics Co., Ltd ++ ++bluetooth:v07D8* ++ ID_VENDOR_FROM_DATABASE=SOLUTIONS AMBRA INC. ++ ++bluetooth:v07D9* ++ ID_VENDOR_FROM_DATABASE=Micro-Design, Inc. ++ ++bluetooth:v07DA* ++ ID_VENDOR_FROM_DATABASE=STARLITE Co., Ltd. ++ ++bluetooth:v07DB* ++ ID_VENDOR_FROM_DATABASE=Remedee Labs ++ ++bluetooth:v07DC* ++ ID_VENDOR_FROM_DATABASE=ThingOS GmbH ++ ++bluetooth:v07DD* ++ ID_VENDOR_FROM_DATABASE=Linear Circuits ++ ++bluetooth:v07DE* ++ ID_VENDOR_FROM_DATABASE=Unlimited Engineering SL ++ ++bluetooth:v07DF* ++ ID_VENDOR_FROM_DATABASE=Snap-on Incorporated ++ ++bluetooth:v07E0* ++ ID_VENDOR_FROM_DATABASE=Edifier International Limited ++ ++bluetooth:v07E1* ++ ID_VENDOR_FROM_DATABASE=Lucie Labs ++ ++bluetooth:v07E2* ++ ID_VENDOR_FROM_DATABASE=Alfred Kaercher SE & Co. KG ++ ++bluetooth:v07E3* ++ ID_VENDOR_FROM_DATABASE=Audiowise Technology Inc. ++ ++bluetooth:v07E4* ++ ID_VENDOR_FROM_DATABASE=Geeksme S.L. ++ ++bluetooth:v07E5* ++ ID_VENDOR_FROM_DATABASE=Minut, Inc. ++ ++bluetooth:v07E6* ++ ID_VENDOR_FROM_DATABASE=Autogrow Systems Limited ++ ++bluetooth:v07E7* ++ ID_VENDOR_FROM_DATABASE=Komfort IQ, Inc. ++ ++bluetooth:v07E8* ++ ID_VENDOR_FROM_DATABASE=Packetcraft, Inc. ++ ++bluetooth:v07E9* ++ ID_VENDOR_FROM_DATABASE=Häfele GmbH & Co KG ++ ++bluetooth:v07EA* ++ ID_VENDOR_FROM_DATABASE=ShapeLog, Inc. ++ ++bluetooth:v07EB* ++ ID_VENDOR_FROM_DATABASE=NOVABASE S.R.L. ++ ++bluetooth:v07EC* ++ ID_VENDOR_FROM_DATABASE=Frecce LLC ++ ++bluetooth:v07ED* ++ ID_VENDOR_FROM_DATABASE=Joule IQ, INC. ++ ++bluetooth:v07EE* ++ ID_VENDOR_FROM_DATABASE=KidzTek LLC ++ ++bluetooth:v07EF* ++ ID_VENDOR_FROM_DATABASE=Aktiebolaget Sandvik Coromant ++ ++bluetooth:v07F0* ++ ID_VENDOR_FROM_DATABASE=e-moola.com Pty Ltd ++ ++bluetooth:v07F1* ++ ID_VENDOR_FROM_DATABASE=GSM Innovations Pty Ltd ++ ++bluetooth:v07F2* ++ ID_VENDOR_FROM_DATABASE=SERENE GROUP, INC ++ ++bluetooth:v07F3* ++ ID_VENDOR_FROM_DATABASE=DIGISINE ENERGYTECH CO. LTD. ++ ++bluetooth:v07F4* ++ ID_VENDOR_FROM_DATABASE=MEDIRLAB Orvosbiologiai Fejleszto Korlatolt Felelossegu Tarsasag ++ ++bluetooth:v07F5* ++ ID_VENDOR_FROM_DATABASE=Byton North America Corporation ++ ++bluetooth:v07F6* ++ ID_VENDOR_FROM_DATABASE=Shenzhen TonliScience and Technology Development Co.,Ltd ++ ++bluetooth:v07F7* ++ ID_VENDOR_FROM_DATABASE=Cesar Systems Ltd. ++ ++bluetooth:v07F8* ++ ID_VENDOR_FROM_DATABASE=quip NYC Inc. ++ ++bluetooth:v07F9* ++ ID_VENDOR_FROM_DATABASE=Direct Communication Solutions, Inc. ++ ++bluetooth:v07FA* ++ ID_VENDOR_FROM_DATABASE=Klipsch Group, Inc. ++ ++bluetooth:v07FB* ++ ID_VENDOR_FROM_DATABASE=Access Co., Ltd ++ ++bluetooth:v07FC* ++ ID_VENDOR_FROM_DATABASE=Renault SA ++ ++bluetooth:v07FD* ++ ID_VENDOR_FROM_DATABASE=JSK CO., LTD. ++ ++bluetooth:v07FE* ++ ID_VENDOR_FROM_DATABASE=BIROTA ++ ++bluetooth:v07FF* ++ ID_VENDOR_FROM_DATABASE=maxon motor ltd. ++ ++bluetooth:v0800* ++ ID_VENDOR_FROM_DATABASE=Optek ++ ++bluetooth:v0801* ++ ID_VENDOR_FROM_DATABASE=CRONUS ELECTRONICS LTD ++ ++bluetooth:v0802* ++ ID_VENDOR_FROM_DATABASE=NantSound, Inc. ++ ++bluetooth:v0803* ++ ID_VENDOR_FROM_DATABASE=Domintell s.a. ++ ++bluetooth:v0804* ++ ID_VENDOR_FROM_DATABASE=Andon Health Co.,Ltd ++ ++bluetooth:v0805* ++ ID_VENDOR_FROM_DATABASE=Urbanminded Ltd ++ ++bluetooth:v0806* ++ ID_VENDOR_FROM_DATABASE=TYRI Sweden AB ++ ++bluetooth:v0807* ++ ID_VENDOR_FROM_DATABASE=ECD Electronic Components GmbH Dresden ++ ++bluetooth:v0808* ++ ID_VENDOR_FROM_DATABASE=SISTEMAS KERN, SOCIEDAD ANÓMINA ++ ++bluetooth:v0809* ++ ID_VENDOR_FROM_DATABASE=Trulli Audio ++ ++bluetooth:v080A* ++ ID_VENDOR_FROM_DATABASE=Altaneos ++ ++bluetooth:v080B* ++ ID_VENDOR_FROM_DATABASE=Nanoleaf Canada Limited ++ ++bluetooth:v080C* ++ ID_VENDOR_FROM_DATABASE=Ingy B.V. ++ ++bluetooth:v080D* ++ ID_VENDOR_FROM_DATABASE=Azbil Co. ++ ++bluetooth:v080E* ++ ID_VENDOR_FROM_DATABASE=TATTCOM LLC ++ ++bluetooth:v080F* ++ ID_VENDOR_FROM_DATABASE=Paradox Engineering SA ++ ++bluetooth:v0810* ++ ID_VENDOR_FROM_DATABASE=LECO Corporation ++ ++bluetooth:v0811* ++ ID_VENDOR_FROM_DATABASE=Becker Antriebe GmbH ++ ++bluetooth:v0812* ++ ID_VENDOR_FROM_DATABASE=Mstream Technologies., Inc. ++ ++bluetooth:v0813* ++ ID_VENDOR_FROM_DATABASE=Flextronics International USA Inc. ++ ++bluetooth:v0814* ++ ID_VENDOR_FROM_DATABASE=Ossur hf. ++ ++bluetooth:v0815* ++ ID_VENDOR_FROM_DATABASE=SKC Inc ++ ++bluetooth:v0816* ++ ID_VENDOR_FROM_DATABASE=SPICA SYSTEMS LLC ++ ++bluetooth:v0817* ++ ID_VENDOR_FROM_DATABASE=Wangs Alliance Corporation ++ ++bluetooth:v0818* ++ ID_VENDOR_FROM_DATABASE=tatwah SA ++ ++bluetooth:v0819* ++ ID_VENDOR_FROM_DATABASE=Hunter Douglas Inc ++ ++bluetooth:v081A* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Conex ++ ++bluetooth:v081B* ++ ID_VENDOR_FROM_DATABASE=DIM3 ++ ++bluetooth:v081C* ++ ID_VENDOR_FROM_DATABASE=Bobrick Washroom Equipment, Inc. ++ ++bluetooth:v081D* ++ ID_VENDOR_FROM_DATABASE=Potrykus Holdings and Development LLC ++ ++bluetooth:v081E* ++ ID_VENDOR_FROM_DATABASE=iNFORM Technology GmbH ++ ++bluetooth:v081F* ++ ID_VENDOR_FROM_DATABASE=eSenseLab LTD ++ ++bluetooth:v0820* ++ ID_VENDOR_FROM_DATABASE=Brilliant Home Technology, Inc. ++ ++bluetooth:v0821* ++ ID_VENDOR_FROM_DATABASE=INOVA Geophysical, Inc. ++ ++bluetooth:v0822* ++ ID_VENDOR_FROM_DATABASE=adafruit industries ++ ++bluetooth:v0823* ++ ID_VENDOR_FROM_DATABASE=Nexite Ltd ++ ++bluetooth:v0824* ++ ID_VENDOR_FROM_DATABASE=8Power Limited ++ ++bluetooth:v0825* ++ ID_VENDOR_FROM_DATABASE=CME PTE. LTD. ++ ++bluetooth:v0826* ++ ID_VENDOR_FROM_DATABASE=Hyundai Motor Company ++ ++bluetooth:v0827* ++ ID_VENDOR_FROM_DATABASE=Kickmaker ++ ++bluetooth:v0828* ++ ID_VENDOR_FROM_DATABASE=Shanghai Suisheng Information Technology Co., Ltd. ++ ++bluetooth:v0829* ++ ID_VENDOR_FROM_DATABASE=HEXAGON ++ ++bluetooth:v082A* ++ ID_VENDOR_FROM_DATABASE=Mitutoyo Corporation ++ ++bluetooth:v082B* ++ ID_VENDOR_FROM_DATABASE=shenzhen fitcare electronics Co.,Ltd ++ ++bluetooth:v082C* ++ ID_VENDOR_FROM_DATABASE=INGICS TECHNOLOGY CO., LTD. ++ ++bluetooth:v082D* ++ ID_VENDOR_FROM_DATABASE=INCUS PERFORMANCE LTD. ++ ++bluetooth:v082E* ++ ID_VENDOR_FROM_DATABASE=ABB S.p.A. ++ ++bluetooth:v082F* ++ ID_VENDOR_FROM_DATABASE=Blippit AB ++ ++bluetooth:v0830* ++ ID_VENDOR_FROM_DATABASE=Core Health and Fitness LLC ++ ++bluetooth:v0831* ++ ID_VENDOR_FROM_DATABASE=Foxble, LLC ++ ++bluetooth:v0832* ++ ID_VENDOR_FROM_DATABASE=Intermotive,Inc. ++ ++bluetooth:v0833* ++ ID_VENDOR_FROM_DATABASE=Conneqtech B.V. ++ ++bluetooth:v0834* ++ ID_VENDOR_FROM_DATABASE=RIKEN KEIKI CO., LTD., ++ ++bluetooth:v0835* ++ ID_VENDOR_FROM_DATABASE=Canopy Growth Corporation ++ ++bluetooth:v0836* ++ ID_VENDOR_FROM_DATABASE=Bitwards Oy ++ ++bluetooth:v0837* ++ ID_VENDOR_FROM_DATABASE=vivo Mobile Communication Co., Ltd. ++ ++bluetooth:v0838* ++ ID_VENDOR_FROM_DATABASE=Etymotic Research, Inc. ++ ++bluetooth:v0839* ++ ID_VENDOR_FROM_DATABASE=A puissance 3 ++ ++bluetooth:v083A* ++ ID_VENDOR_FROM_DATABASE=BPW Bergische Achsen Kommanditgesellschaft ++ ++bluetooth:v083B* ++ ID_VENDOR_FROM_DATABASE=Piaggio Fast Forward ++ ++bluetooth:v083C* ++ ID_VENDOR_FROM_DATABASE=BeerTech LTD ++ ++bluetooth:v083D* ++ ID_VENDOR_FROM_DATABASE=Tokenize, Inc. ++ ++bluetooth:v083E* ++ ID_VENDOR_FROM_DATABASE=Zorachka LTD ++ ++bluetooth:v083F* ++ ID_VENDOR_FROM_DATABASE=D-Link Corp. ++ ++bluetooth:v0840* ++ ID_VENDOR_FROM_DATABASE=Down Range Systems LLC ++ ++bluetooth:v0841* ++ ID_VENDOR_FROM_DATABASE=General Luminaire (Shanghai) Co., Ltd. ++ ++bluetooth:v0842* ++ ID_VENDOR_FROM_DATABASE=Tangshan HongJia electronic technology co., LTD. ++ ++bluetooth:v0843* ++ ID_VENDOR_FROM_DATABASE=FRAGRANCE DELIVERY TECHNOLOGIES LTD ++ ++bluetooth:v0844* ++ ID_VENDOR_FROM_DATABASE=Pepperl + Fuchs GmbH ++ ++bluetooth:v0845* ++ ID_VENDOR_FROM_DATABASE=Dometic Corporation ++ ++bluetooth:v0846* ++ ID_VENDOR_FROM_DATABASE=USound GmbH ++ ++bluetooth:v0847* ++ ID_VENDOR_FROM_DATABASE=DNANUDGE LIMITED ++ ++bluetooth:v0848* ++ ID_VENDOR_FROM_DATABASE=JUJU JOINTS CANADA CORP. ++ ++bluetooth:v0849* ++ ID_VENDOR_FROM_DATABASE=Dopple Technologies B.V. ++ ++bluetooth:v084A* ++ ID_VENDOR_FROM_DATABASE=ARCOM ++ ++bluetooth:v084B* ++ ID_VENDOR_FROM_DATABASE=Biotechware SRL ++ ++bluetooth:v084C* ++ ID_VENDOR_FROM_DATABASE=ORSO Inc. ++ ++bluetooth:v084D* ++ ID_VENDOR_FROM_DATABASE=SafePort ++ ++bluetooth:v084E* ++ ID_VENDOR_FROM_DATABASE=Carol Cole Company ++ ++bluetooth:v084F* ++ ID_VENDOR_FROM_DATABASE=Embedded Fitness B.V. ++ ++bluetooth:v0850* ++ ID_VENDOR_FROM_DATABASE=Yealink (Xiamen) Network Technology Co.,LTD ++ ++bluetooth:v0851* ++ ID_VENDOR_FROM_DATABASE=Subeca, Inc. ++ ++bluetooth:v0852* ++ ID_VENDOR_FROM_DATABASE=Cognosos, Inc. ++ ++bluetooth:v0853* ++ ID_VENDOR_FROM_DATABASE=Pektron Group Limited ++ ++bluetooth:v0854* ++ ID_VENDOR_FROM_DATABASE=Tap Sound System ++ ++bluetooth:v0855* ++ ID_VENDOR_FROM_DATABASE=Helios Hockey, Inc. ++ ++bluetooth:v0856* ++ ID_VENDOR_FROM_DATABASE=Canopy Growth Corporation ++ ++bluetooth:v0857* ++ ID_VENDOR_FROM_DATABASE=Parsyl Inc ++ ++bluetooth:v0858* ++ ID_VENDOR_FROM_DATABASE=SOUNDBOKS ++ ++bluetooth:v0859* ++ ID_VENDOR_FROM_DATABASE=BlueUp ++ ++bluetooth:v085A* ++ ID_VENDOR_FROM_DATABASE=DAKATECH ++ ++bluetooth:v085B* ++ ID_VENDOR_FROM_DATABASE=RICOH ELECTRONIC DEVICES CO., LTD. ++ ++bluetooth:v085C* ++ ID_VENDOR_FROM_DATABASE=ACOS CO.,LTD. ++ ++bluetooth:v085D* ++ ID_VENDOR_FROM_DATABASE=Guilin Zhishen Information Technology Co.,Ltd. ++ ++bluetooth:v085E* ++ ID_VENDOR_FROM_DATABASE=Krog Systems LLC ++ ++bluetooth:v085F* ++ ID_VENDOR_FROM_DATABASE=COMPEGPS TEAM,SOCIEDAD LIMITADA ++ ++bluetooth:v0860* ++ ID_VENDOR_FROM_DATABASE=Alflex Products B.V. ++ ++bluetooth:v0861* ++ ID_VENDOR_FROM_DATABASE=SmartSensor Labs Ltd ++ ++bluetooth:v0862* ++ ID_VENDOR_FROM_DATABASE=SmartDrive Inc. ++ ++bluetooth:v0863* ++ ID_VENDOR_FROM_DATABASE=Yo-tronics Technology Co., Ltd. ++ ++bluetooth:v0864* ++ ID_VENDOR_FROM_DATABASE=Rafaelmicro ++ ++bluetooth:v0865* ++ ID_VENDOR_FROM_DATABASE=Emergency Lighting Products Limited ++ ++bluetooth:v0866* ++ ID_VENDOR_FROM_DATABASE=LAONZ Co.,Ltd ++ ++bluetooth:v0867* ++ ID_VENDOR_FROM_DATABASE=Western Digital Techologies, Inc. ++ ++bluetooth:v0868* ++ ID_VENDOR_FROM_DATABASE=WIOsense GmbH & Co. KG ++ ++bluetooth:v0869* ++ ID_VENDOR_FROM_DATABASE=EVVA Sicherheitstechnologie GmbH ++ ++bluetooth:v086A* ++ ID_VENDOR_FROM_DATABASE=Odic Incorporated ++ ++bluetooth:v086B* ++ ID_VENDOR_FROM_DATABASE=Pacific Track, LLC ++ ++bluetooth:v086C* ++ ID_VENDOR_FROM_DATABASE=Revvo Technologies, Inc. ++ ++bluetooth:v086D* ++ ID_VENDOR_FROM_DATABASE=Biometrika d.o.o. ++ ++bluetooth:v086E* ++ ID_VENDOR_FROM_DATABASE=Vorwerk Elektrowerke GmbH & Co. KG ++ ++bluetooth:v086F* ++ ID_VENDOR_FROM_DATABASE=Trackunit A/S ++ ++bluetooth:v0870* ++ ID_VENDOR_FROM_DATABASE=Wyze Labs, Inc ++ ++bluetooth:v0871* ++ ID_VENDOR_FROM_DATABASE=Dension Elektronikai Kft. (formerly: Dension Audio Systems Ltd.) ++ ++bluetooth:v0872* ++ ID_VENDOR_FROM_DATABASE=11 Health & Technologies Limited ++ ++bluetooth:v0873* ++ ID_VENDOR_FROM_DATABASE=Innophase Incorporated ++ ++bluetooth:v0874* ++ ID_VENDOR_FROM_DATABASE=Treegreen Limited ++ ++bluetooth:v0875* ++ ID_VENDOR_FROM_DATABASE=Berner International LLC ++ ++bluetooth:v0876* ++ ID_VENDOR_FROM_DATABASE=SmartResQ ApS ++ ++bluetooth:v0877* ++ ID_VENDOR_FROM_DATABASE=Tome, Inc. ++ ++bluetooth:v0878* ++ ID_VENDOR_FROM_DATABASE=The Chamberlain Group, Inc. ++ ++bluetooth:v0879* ++ ID_VENDOR_FROM_DATABASE=MIZUNO Corporation ++ ++bluetooth:v087A* ++ ID_VENDOR_FROM_DATABASE=ZRF, LLC ++ ++bluetooth:v087B* ++ ID_VENDOR_FROM_DATABASE=BYSTAMP ++ ++bluetooth:v087C* ++ ID_VENDOR_FROM_DATABASE=Crosscan GmbH ++ ++bluetooth:v087D* ++ ID_VENDOR_FROM_DATABASE=Konftel AB ++ ++bluetooth:v087E* ++ ID_VENDOR_FROM_DATABASE=1bar.net Limited ++ ++bluetooth:v087F* ++ ID_VENDOR_FROM_DATABASE=Phillips Connect Technologies LLC ++ ++bluetooth:v0880* ++ ID_VENDOR_FROM_DATABASE=imagiLabs AB ++ ++bluetooth:v0881* ++ ID_VENDOR_FROM_DATABASE=Optalert ++ ++bluetooth:v0882* ++ ID_VENDOR_FROM_DATABASE=PSYONIC, Inc. ++ ++bluetooth:v0883* ++ ID_VENDOR_FROM_DATABASE=Wintersteiger AG ++ ++bluetooth:v0884* ++ ID_VENDOR_FROM_DATABASE=Controlid Industria, Comercio de Hardware e Servicos de Tecnologia Ltda ++ ++bluetooth:v0885* ++ ID_VENDOR_FROM_DATABASE=LEVOLOR, INC. ++ ++bluetooth:v0886* ++ ID_VENDOR_FROM_DATABASE=Xsens Technologies B.V. ++ ++bluetooth:v0887* ++ ID_VENDOR_FROM_DATABASE=Hydro-Gear Limited Partnership ++ ++bluetooth:v0888* ++ ID_VENDOR_FROM_DATABASE=EnPointe Fencing Pty Ltd ++ ++bluetooth:v0889* ++ ID_VENDOR_FROM_DATABASE=XANTHIO ++ ++bluetooth:v088A* ++ ID_VENDOR_FROM_DATABASE=sclak s.r.l. ++ ++bluetooth:v088B* ++ ID_VENDOR_FROM_DATABASE=Tricorder Arraay Technologies LLC ++ ++bluetooth:v088C* ++ ID_VENDOR_FROM_DATABASE=GB Solution co.,Ltd ++ ++bluetooth:v088D* ++ ID_VENDOR_FROM_DATABASE=Soliton Systems K.K. ++ ++bluetooth:v088E* ++ ID_VENDOR_FROM_DATABASE=GIGA-TMS INC ++ ++bluetooth:v088F* ++ ID_VENDOR_FROM_DATABASE=Tait International Limited ++ ++bluetooth:v0890* ++ ID_VENDOR_FROM_DATABASE=NICHIEI INTEC CO., LTD. ++ ++bluetooth:v0891* ++ ID_VENDOR_FROM_DATABASE=SmartWireless GmbH & Co. KG ++ ++bluetooth:v0892* ++ ID_VENDOR_FROM_DATABASE=Ingenieurbuero Birnfeld UG (haftungsbeschraenkt) ++ ++bluetooth:v0893* ++ ID_VENDOR_FROM_DATABASE=Maytronics Ltd ++ ++bluetooth:v0894* ++ ID_VENDOR_FROM_DATABASE=EPIFIT ++ ++bluetooth:v0895* ++ ID_VENDOR_FROM_DATABASE=Gimer medical ++ ++bluetooth:v0896* ++ ID_VENDOR_FROM_DATABASE=Nokian Renkaat Oyj ++ ++bluetooth:v0897* ++ ID_VENDOR_FROM_DATABASE=Current Lighting Solutions LLC ++ ++bluetooth:v0898* ++ ID_VENDOR_FROM_DATABASE=Sensibo, Inc. ++ ++bluetooth:v0899* ++ ID_VENDOR_FROM_DATABASE=SFS unimarket AG ++ ++bluetooth:v089A* ++ ID_VENDOR_FROM_DATABASE=Private limited company "Teltonika" ++ ++bluetooth:v089B* ++ ID_VENDOR_FROM_DATABASE=Saucon Technologies ++ ++bluetooth:v089C* ++ ID_VENDOR_FROM_DATABASE=Embedded Devices Co. Company ++ ++bluetooth:v089D* ++ ID_VENDOR_FROM_DATABASE=J-J.A.D.E. Enterprise LLC ++ ++bluetooth:v089E* ++ ID_VENDOR_FROM_DATABASE=i-SENS, inc. ++ ++bluetooth:v089F* ++ ID_VENDOR_FROM_DATABASE=Witschi Electronic Ltd ++ ++bluetooth:v08A0* ++ ID_VENDOR_FROM_DATABASE=Aclara Technologies LLC ++ ++bluetooth:v08A1* ++ ID_VENDOR_FROM_DATABASE=EXEO TECH CORPORATION ++ ++bluetooth:v08A2* ++ ID_VENDOR_FROM_DATABASE=Epic Systems Co., Ltd. ++ ++bluetooth:v08A3* ++ ID_VENDOR_FROM_DATABASE=Hoffmann SE ++ ++bluetooth:v08A4* ++ ID_VENDOR_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp., Ltd. ++ ++bluetooth:v08A5* ++ ID_VENDOR_FROM_DATABASE=UMEHEAL Ltd ++ ++bluetooth:v08A6* ++ ID_VENDOR_FROM_DATABASE=Intelligenceworks Inc. ++ ++bluetooth:v08A7* ++ ID_VENDOR_FROM_DATABASE=TGR 1.618 Limited ++ ++bluetooth:v08A8* ++ ID_VENDOR_FROM_DATABASE=Shanghai Kfcube Inc ++ ++bluetooth:v08A9* ++ ID_VENDOR_FROM_DATABASE=Fraunhofer IIS ++ ++bluetooth:v08AA* ++ ID_VENDOR_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD ++ ++bluetooth:v08AB* ++ ID_VENDOR_FROM_DATABASE=Coburn Technology, LLC ++ ++bluetooth:v08AC* ++ ID_VENDOR_FROM_DATABASE=Topre Corporation ++ ++bluetooth:v08AD* ++ ID_VENDOR_FROM_DATABASE=Kayamatics Limited ++ ++bluetooth:v08AE* ++ ID_VENDOR_FROM_DATABASE=Moticon ReGo AG +diff --git a/hwdb/20-dmi-id.hwdb b/hwdb/20-dmi-id.hwdb +new file mode 100644 +index 0000000000..a614473bd9 +--- /dev/null ++++ b/hwdb/20-dmi-id.hwdb +@@ -0,0 +1,6 @@ ++# This file is part of systemd ++ ++# Fix "Lenovo" capitalization in /sys/class/dmi/id/sys_vendor ++dmi:bvnLENOVO* ++ ID_SYSFS_ATTRIBUTE_MODEL=product_version ++ ID_VENDOR_FROM_DATABASE=Lenovo +diff --git a/hwdb/20-pci-classes.hwdb b/hwdb/20-pci-classes.hwdb +index c994679c37..2af181c52b 100644 +--- a/hwdb/20-pci-classes.hwdb ++++ b/hwdb/20-pci-classes.hwdb +@@ -11,6 +11,9 @@ pci:v*d*sv*sd*bc00sc00* + pci:v*d*sv*sd*bc00sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible unclassified device + ++pci:v*d*sv*sd*bc00sc05* ++ ID_PCI_SUBCLASS_FROM_DATABASE=Image coprocessor ++ + pci:v*d*sv*sd*bc01* + ID_PCI_CLASS_FROM_DATABASE=Mass storage controller + +@@ -377,6 +380,12 @@ pci:v*d*sv*sd*bc08sc06* + pci:v*d*sv*sd*bc08sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=System peripheral + ++pci:v*d*sv*sd*bc08sc99* ++ ID_PCI_SUBCLASS_FROM_DATABASE=Timing Card ++ ++pci:v*d*sv*sd*bc08sc99i01* ++ ID_PCI_INTERFACE_FROM_DATABASE=TAP Timing Card ++ + pci:v*d*sv*sd*bc09* + ID_PCI_CLASS_FROM_DATABASE=Input device controller + +@@ -470,6 +479,9 @@ pci:v*d*sv*sd*bc0Csc03i20* + pci:v*d*sv*sd*bc0Csc03i30* + ID_PCI_INTERFACE_FROM_DATABASE=XHCI + ++pci:v*d*sv*sd*bc0Csc03i40* ++ ID_PCI_INTERFACE_FROM_DATABASE=USB4 Host Interface ++ + pci:v*d*sv*sd*bc0Csc03i80* + ID_PCI_INTERFACE_FROM_DATABASE=Unspecified + +@@ -587,6 +599,9 @@ pci:v*d*sv*sd*bc12* + pci:v*d*sv*sd*bc12sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Processing accelerators + ++pci:v*d*sv*sd*bc12sc01* ++ ID_PCI_SUBCLASS_FROM_DATABASE=AI Inference Accelerator ++ + pci:v*d*sv*sd*bc13* + ID_PCI_CLASS_FROM_DATABASE=Non-Essential Instrumentation + +diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb +index 94e495c280..0020046d60 100644 +--- a/hwdb/20-pci-vendor-model.hwdb ++++ b/hwdb/20-pci-vendor-model.hwdb +@@ -50,6 +50,9 @@ pci:v00000014d00007A0C* + pci:v00000014d00007A0F* + ID_MODEL_FROM_DATABASE=DMA (Direct Memory Access) Controller + ++pci:v00000014d00007A10* ++ ID_MODEL_FROM_DATABASE=Hyper Transport Bridge Controller ++ + pci:v00000014d00007A14* + ID_MODEL_FROM_DATABASE=EHCI USB Controller + +@@ -102,7 +105,7 @@ pci:v000000A7* + ID_VENDOR_FROM_DATABASE=Teles AG (Wrong ID) + + pci:v00000100* +- ID_VENDOR_FROM_DATABASE=Thales e-Security ++ ID_VENDOR_FROM_DATABASE=nCipher Security + + pci:v00000123* + ID_VENDOR_FROM_DATABASE=General Dynamics +@@ -116,6 +119,12 @@ pci:v0000018A* + pci:v0000018Ad00000106* + ID_MODEL_FROM_DATABASE=FPC-0106TX misprogrammed [RTL81xx] + ++pci:v000001DE* ++ ID_VENDOR_FROM_DATABASE=Oxide Computer Company ++ ++pci:v00000200* ++ ID_VENDOR_FROM_DATABASE=Dell (wrong ID) ++ + pci:v0000021B* + ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation + +@@ -179,6 +188,12 @@ pci:v00000675d00001704* + pci:v00000721* + ID_VENDOR_FROM_DATABASE=Sapphire, Inc. + ++pci:v00000731* ++ ID_VENDOR_FROM_DATABASE=Jingjia Microelectronics Co Ltd ++ ++pci:v00000731d00007200* ++ ID_MODEL_FROM_DATABASE=JM7200 Series GPU ++ + pci:v00000777* + ID_VENDOR_FROM_DATABASE=Ubiquiti Networks, Inc. + +@@ -194,6 +209,9 @@ pci:v00000795d00006666* + pci:v000007D1* + ID_VENDOR_FROM_DATABASE=D-Link System Inc + ++pci:v00000824* ++ ID_VENDOR_FROM_DATABASE=T1042 [Freescale] ++ + pci:v00000925* + ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. (Wrong ID) + +@@ -579,7 +597,7 @@ pci:v00000F62* + ID_VENDOR_FROM_DATABASE=Acrox Technologies Co., Ltd. + + pci:v00001000* +- ID_VENDOR_FROM_DATABASE=LSI Logic / Symbios Logic ++ ID_VENDOR_FROM_DATABASE=Broadcom / LSI + + pci:v00001000d00000001* + ID_MODEL_FROM_DATABASE=53c810 +@@ -713,9 +731,27 @@ pci:v00001000d00000013sv00001000sd00001000* + pci:v00001000d00000014* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 + ++pci:v00001000d00000014sv00001000sd00009460* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (MegaRAID 9460-16i) ++ ++pci:v00001000d00000014sv00001000sd00009480* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (MegaRAID 9480-8i8e) ++ ++pci:v00001000d00000014sv00001000sd00009481* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (MegaRAID 9480-8e) ++ ++pci:v00001000d00000014sv00001028sd00001F3A* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (PERC H745 Adapter) ++ ++pci:v00001000d00000014sv00001028sd00001F3B* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (PERC H745 Front) ++ + pci:v00001000d00000014sv00001028sd00001FD4* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (PERC H745P MX) + ++pci:v00001000d00000014sv00001137sd0000020E* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (UCSC-RAID-M5 12G Modular RAID Controller) ++ + pci:v00001000d00000014sv00001D49sd00000602* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter) + +@@ -737,9 +773,33 @@ pci:v00001000d00000014sv00008086sd00009480* + pci:v00001000d00000015* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416 + ++pci:v00001000d00000015sv00001000sd00009441* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416 (MegaRAID 9440-16i) ++ ++pci:v00001000d00000015sv00001028sd00001F3C* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416 (PERC H345 Adapter) ++ ++pci:v00001000d00000015sv00001028sd00001F3D* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416 (PERC H345 Front) ++ ++pci:v00001000d00000015sv00001D49sd00000503* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416 (ThinkSystem RAID 530-16i PCIe 12Gb Adapter) ++ + pci:v00001000d00000016* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 + ++pci:v00001000d00000016sv00001000sd00009461* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (MegaRAID 9460-8i) ++ ++pci:v00001000d00000016sv00001000sd00009462* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (MegaRAID 9460-4i) ++ ++pci:v00001000d00000016sv00001000sd00009463* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (MegaRAID 9365-28i) ++ ++pci:v00001000d00000016sv00001000sd00009464* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (MegaRAID 9365-24i) ++ + pci:v00001000d00000016sv00001028sd00001FC9* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (PERC H840 Adapter) + +@@ -758,9 +818,6 @@ pci:v00001000d00000016sv00001D49sd00000601* + pci:v00001000d00000016sv00001D49sd00000603* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (ThinkSystem RAID 930-24i 4GB Flash PCIe 12Gb Adapter) + +-pci:v00001000d00000016sv00001D49sd00000604* +- ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter) +- + pci:v00001000d00000016sv00008086sd0000352E* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508 (Integrated RAID Module RMSP3CD080F) + +@@ -773,6 +830,12 @@ pci:v00001000d00000016sv00008086sd00009461* + pci:v00001000d00000017* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 + ++pci:v00001000d00000017sv00001000sd00009440* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (MegaRAID 9440-8i) ++ ++pci:v00001000d00000017sv00001000sd00009442* ++ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (MegaRAID 9440-4i) ++ + pci:v00001000d00000017sv00001D49sd00000500* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3408 (ThinkSystem RAID 530-8i PCIe 12Gb Adapter) + +@@ -1116,7 +1179,7 @@ pci:v00001000d0000005Bsv00008086sd00003512* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (RMT3PB080 RAID Controller) + + pci:v00001000d0000005Bsv00008086sd00003513* +- ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (RMS25CB080 RAID Controller) ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (Integrated RAID Module RMS25CB080) + + pci:v00001000d0000005Bsv00008086sd00003514* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (RMS25CB040 RAID Controller) +@@ -1148,12 +1211,18 @@ pci:v00001000d0000005D* + pci:v00001000d0000005Dsv00001000sd00009361* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (MegaRAID SAS 9361-8i) + ++pci:v00001000d0000005Dsv00001000sd00009363* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (MegaRAID SAS 9361-4i) ++ + pci:v00001000d0000005Dsv00001000sd00009364* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (MegaRAID SAS 9364-8i) + + pci:v00001000d0000005Dsv00001000sd0000936A* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (MegaRAID SAS 9364-8i) + ++pci:v00001000d0000005Dsv00001000sd00009380* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (MegaRAID SAS 9380-8e) ++ + pci:v00001000d0000005Dsv00001028sd00001F41* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H830 Adapter) + +@@ -1193,9 +1262,18 @@ pci:v00001000d0000005Dsv000017AAsd00001052* + pci:v00001000d0000005Dsv000017AAsd00001053* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkServer RAID 720ix) + ++pci:v00001000d0000005Dsv00001BD4sd00000014* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (12G SAS3108 2G) ++ ++pci:v00001000d0000005Dsv00001BD4sd00000015* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (12G SAS3108 4G) ++ + pci:v00001000d0000005Dsv00001D49sd00000600* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkSystem RAID 730-8i 1GB Cache PCIe 12Gb Adapter) + ++pci:v00001000d0000005Dsv00001D49sd00000608* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkSystem RAID 730-8i 2GB Flash PCIe 12Gb Adapter) ++ + pci:v00001000d0000005Dsv00001D49sd00000609* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkSystem RAID 730-8i 4GB Flash PCIe 12Gb Adapter) + +@@ -1238,9 +1316,15 @@ pci:v00001000d0000005Fsv00001028sd00001F4D* + pci:v00001000d0000005Fsv00001054sd0000306A* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (SAS 3004 iMR ROMB) + ++pci:v00001000d0000005Fsv00001734sd00001211* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (PRAID CP400i [D3307-A12]) ++ + pci:v00001000d0000005Fsv00001D49sd000004DB* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (ServeRAID M1210 SAS/SATA Controller) + ++pci:v00001000d0000005Fsv00001D49sd00000504* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (ThinkSystem RAID 520-8i PCIe 12Gb Adapter) ++ + pci:v00001000d00000060* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 + +@@ -1343,9 +1427,15 @@ pci:v00001000d00000062sv00001000sd00000062* + pci:v00001000d00000064* + ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] + ++pci:v00001000d00000064sv00001000sd00003030* ++ ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] (9200-16e 6Gb/s SAS/SATA PCIe x8 External HBA) ++ + pci:v00001000d00000064sv00001000sd000030C0* + ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] (SAS 9201-16i) + ++pci:v00001000d00000064sv00001000sd000030D0* ++ ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] (9201-16e 6Gb/s SAS/SATA PCIe x8 External HBA) ++ + pci:v00001000d00000065* + ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] + +@@ -1355,12 +1445,30 @@ pci:v00001000d0000006E* + pci:v00001000d00000070* + ID_MODEL_FROM_DATABASE=SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire] + ++pci:v00001000d00000070sv00001000sd00003010* ++ ID_MODEL_FROM_DATABASE=SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire] (SAS9211-4i) ++ ++pci:v00001000d00000070sv00001014sd0000040E* ++ ID_MODEL_FROM_DATABASE=SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire] (ServeRAID H1110) ++ + pci:v00001000d00000071* + ID_MODEL_FROM_DATABASE=MR SAS HBA 2004 + + pci:v00001000d00000072* + ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] + ++pci:v00001000d00000072sv00001000sd00003040* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (9210-8i) ++ ++pci:v00001000d00000072sv00001000sd00003080* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (9200-8e [LSI SAS 6Gb/s SAS/SATA PCIe x8 External HBA]) ++ ++pci:v00001000d00000072sv00001000sd000030B0* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (9200-8e [LSI SAS 6Gb/s SAS/SATA PCIe x8 External HBA]) ++ ++pci:v00001000d00000072sv00001014sd000003CA* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (IBM 6Gb SAS HBA [9212-4i4e]) ++ + pci:v00001000d00000072sv00001028sd00001F1C* + ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6Gbps SAS HBA Adapter) + +@@ -1377,7 +1485,22 @@ pci:v00001000d00000072sv00001028sd00001F20* + ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Embedded) + + pci:v00001000d00000072sv00001028sd00001F22* +- ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (Internal Tape Adapter) ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Internal Tape Adapter) ++ ++pci:v00001000d00000072sv00001734sd00001177* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (HBA Ctrl SAS 6G 0/1 [D2607]) ++ ++pci:v00001000d00000072sv00001BD4sd0000000D* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6G SAS2008IT) ++ ++pci:v00001000d00000072sv00001BD4sd0000000E* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6G SAS2008IR) ++ ++pci:v00001000d00000072sv00001BD4sd0000000F* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6G SAS2008IT SA5248) ++ ++pci:v00001000d00000072sv00001BD4sd00000010* ++ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6G SAS2008IR SA5248) + + pci:v00001000d00000072sv00008086sd0000350F* + ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (RMS2LL040 RAID Controller) +@@ -1400,6 +1523,9 @@ pci:v00001000d00000073sv00001000sd000092A0* + pci:v00001000d00000073sv00001014sd000003B1* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (ServeRAID M1015 SAS/SATA Controller) + ++pci:v00001000d00000073sv00001014sd0000040D* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (ServeRAID M1115 SAS/SATA Controller) ++ + pci:v00001000d00000073sv00001028sd00001F4E* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Adapter) + +@@ -1421,6 +1547,9 @@ pci:v00001000d00000073sv00001028sd00001F53* + pci:v00001000d00000073sv00001028sd00001F54* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Reserved) + ++pci:v00001000d00000073sv00001028sd00001F78* ++ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310) ++ + pci:v00001000d00000073sv00001054sd00003035* + ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (LSI MegaRAID SAS 9240-8i) + +@@ -1661,21 +1790,48 @@ pci:v00001000d00000085* + pci:v00001000d00000086* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 + ++pci:v00001000d00000086sv000015D9sd00000690* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (Onboard MegaRAID SAS2208 [Thunderbolt]) ++ ++pci:v00001000d00000086sv000015D9sd00000691* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (Onboard SAS2308 PCI-Express Fusion-MPT SAS-2) ++ + pci:v00001000d00000087* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 + + pci:v00001000d00000087sv00001000sd00003020* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (9207-8i SAS2.1 HBA) + ++pci:v00001000d00000087sv00001000sd00003030* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (SAS9207-4i4e) ++ + pci:v00001000d00000087sv00001000sd00003040* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (9207-8e SAS2.1 HBA) + + pci:v00001000d00000087sv00001000sd00003050* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (SAS9217-8i) + ++pci:v00001000d00000087sv00001000sd00003060* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (SAS9217-4i4e) ++ ++pci:v00001000d00000087sv00001014sd00000472* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (N2125 External Host Bus Adapter) ++ ++pci:v00001000d00000087sv00001590sd00000041* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (H220i) ++ ++pci:v00001000d00000087sv00001590sd00000042* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (H221 / 9207-8e) ++ + pci:v00001000d00000087sv00001590sd00000044* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (H220i) + ++pci:v00001000d00000087sv00001BD4sd00000009* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (6G SAS2308IR) ++ ++pci:v00001000d00000087sv00001BD4sd0000000A* ++ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (6G SAS2308IT) ++ + pci:v00001000d00000087sv00008086sd00003000* + ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (RS25GB008 RAID Controller) + +@@ -1754,18 +1910,141 @@ pci:v00001000d00000097sv00001028sd00001FD2* + pci:v00001000d00000097sv00001028sd00001FD3* + ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (HBA330 MMZ) + ++pci:v00001000d00000097sv000015D9sd00000808* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (AOC-S3008L-L8e) ++ ++pci:v00001000d00000097sv00001BD4sd00000008* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IMR Onboard) ++ ++pci:v00001000d00000097sv00001BD4sd0000000B* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IR) ++ ++pci:v00001000d00000097sv00001BD4sd0000000C* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IT) ++ + pci:v00001000d00000097sv00001BD4sd00000011* + ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (Inspur 12Gb 8i-3008 IT SAS HBA) + ++pci:v00001000d00000097sv00001BD4sd00000012* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12Gb SAS3008IR UDM) ++ ++pci:v00001000d00000097sv00001BD4sd0000001F* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IR Onboard) ++ ++pci:v00001000d00000097sv00001BD4sd00000020* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IT Onboard) ++ ++pci:v00001000d00000097sv00001BD4sd00000026* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IT RACK) ++ ++pci:v00001000d00000097sv00001BD4sd00000027* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IMR RACK) ++ ++pci:v00001000d00000097sv00001BD4sd00000028* ++ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12G SAS3008IR RACK) ++ ++pci:v00001000d000000A5* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx ++ ++pci:v00001000d000000A5sv00001000sd00004600* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9670W-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004610* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9670-24i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004620* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9660-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004630* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9660-8i8e Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004640* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9600W-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004650* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9600W-16e Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004660* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9600-24i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004670* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9600-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004680* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9600-16e Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd00004690* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (eHBA 9620-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd000046A0* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9660-24i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd000046B0* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9665W-16i Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001000sd000046C0* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (MegaRAID 9680W-16e Tri-Mode Storage Adapter) ++ ++pci:v00001000d000000A5sv00001028sd00002114* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H965 Adapter) ++ ++pci:v00001000d000000A5sv00001028sd00002115* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H965 Front) ++ ++pci:v00001000d000000A5sv00001028sd00002117* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H965 MX) ++ ++pci:v00001000d000000A5sv00001028sd0000213A* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H965e Adapter) ++ ++pci:v00001000d000000A5sv00001028sd0000213B* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H765 Adapter) ++ ++pci:v00001000d000000A5sv00001028sd0000213C* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H765 Front) ++ ++pci:v00001000d000000A5sv00001028sd0000213D* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H765N Front) ++ ++pci:v00001000d000000A5sv00001028sd0000213E* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H765 MX) ++ ++pci:v00001000d000000A5sv00001028sd0000213F* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H365 Adapter) ++ ++pci:v00001000d000000A5sv00001028sd00002140* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H365 Front) ++ ++pci:v00001000d000000A5sv00001028sd00002141* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (PERC H360 MX) ++ ++pci:v00001000d000000A5sv00001028sd00002142* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 24GSAS/PCIe SAS40xx (HBA 465e Adapter) ++ + pci:v00001000d000000AB* + ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) + ++pci:v00001000d000000ABsv00001000sd00003040* ++ ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) (HBA 9400-8i8e) ++ + pci:v00001000d000000ABsv00008086sd00003530* + ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) (Integrated RAID Module RMSP3JD160J) + + pci:v00001000d000000AC* + ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + ++pci:v00001000d000000ACsv00001000sd00003000* ++ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9400-16i) ++ ++pci:v00001000d000000ACsv00001000sd00003020* ++ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9400-16e) ++ ++pci:v00001000d000000ACsv00001028sd00001FE3* ++ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA345 Adapter) ++ ++pci:v00001000d000000ACsv00001028sd00001FE4* ++ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA345 Front) ++ + pci:v00001000d000000ACsv00001D49sd00000201* + ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-16i SAS/SATA 12Gb HBA) + +@@ -1784,6 +2063,12 @@ pci:v00001000d000000AE* + pci:v00001000d000000AF* + ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + ++pci:v00001000d000000AFsv00001000sd00003010* ++ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9400-8i) ++ ++pci:v00001000d000000AFsv00001000sd00003030* ++ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9400-8e) ++ + pci:v00001000d000000AFsv00001D49sd00000200* + ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8i SAS/SATA 12Gb HBA) + +@@ -1793,6 +2078,12 @@ pci:v00001000d000000AFsv00001D49sd00000202* + pci:v00001000d000000AFsv00001D49sd00000204* + ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8i SAS/SATA 12Gb Dense HBA) + ++pci:v00001000d000000B2* ++ ID_MODEL_FROM_DATABASE=PCIe Switch management endpoint ++ ++pci:v00001000d000000B2sv00001D49sd00000003* ++ ID_MODEL_FROM_DATABASE=PCIe Switch management endpoint (ThinkSystem 1611-8P PCIe Gen4 NVMe Switch Adapter) ++ + pci:v00001000d000000BE* + ID_MODEL_FROM_DATABASE=SAS3504 Fusion-MPT Tri-Mode RAID On Chip (ROC) + +@@ -1814,6 +2105,15 @@ pci:v00001000d000000C3* + pci:v00001000d000000C4* + ID_MODEL_FROM_DATABASE=SAS3224 PCI-Express Fusion-MPT SAS-3 + ++pci:v00001000d000000C4sv00001000sd00003190* ++ ID_MODEL_FROM_DATABASE=SAS3224 PCI-Express Fusion-MPT SAS-3 (SAS9305-16i) ++ ++pci:v00001000d000000C4sv00001000sd000031A0* ++ ID_MODEL_FROM_DATABASE=SAS3224 PCI-Express Fusion-MPT SAS-3 (SAS9305-24i) ++ ++pci:v00001000d000000C4sv00001170sd00000002* ++ ID_MODEL_FROM_DATABASE=SAS3224 PCI-Express Fusion-MPT SAS-3 (SAS3224 PCI Express to 12Gb HBA MEZZ CARD) ++ + pci:v00001000d000000C5* + ID_MODEL_FROM_DATABASE=SAS3316 PCI-Express Fusion-MPT SAS-3 + +@@ -1829,6 +2129,9 @@ pci:v00001000d000000C8* + pci:v00001000d000000C9* + ID_MODEL_FROM_DATABASE=SAS3216 PCI-Express Fusion-MPT SAS-3 + ++pci:v00001000d000000C9sv00001000sd00003180* ++ ID_MODEL_FROM_DATABASE=SAS3216 PCI-Express Fusion-MPT SAS-3 (SAS9305-16e) ++ + pci:v00001000d000000CE* + ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3316 [Intruder] + +@@ -1847,12 +2150,129 @@ pci:v00001000d000000CFsv00001000sd00009370* + pci:v00001000d000000D0* + ID_MODEL_FROM_DATABASE=SAS3716 Fusion-MPT Tri-Mode RAID Controller Chip (ROC) + ++pci:v00001000d000000D0sv00001000sd00003050* ++ ID_MODEL_FROM_DATABASE=SAS3716 Fusion-MPT Tri-Mode RAID Controller Chip (ROC) (HBA 9405W-16i) ++ ++pci:v00001000d000000D0sv00001000sd00003070* ++ ID_MODEL_FROM_DATABASE=SAS3716 Fusion-MPT Tri-Mode RAID Controller Chip (ROC) (HBA 9405W-8i8e) ++ + pci:v00001000d000000D1* + ID_MODEL_FROM_DATABASE=SAS3616 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + ++pci:v00001000d000000D1sv00001000sd00003080* ++ ID_MODEL_FROM_DATABASE=SAS3616 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9405W-16e) ++ ++pci:v00001000d000000D1sv00001000sd00003090* ++ ID_MODEL_FROM_DATABASE=SAS3616 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (HBA 9405W-16i) ++ + pci:v00001000d000000D3* + ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3716W + ++pci:v00001000d000000E0* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS39xx ++ ++pci:v00001000d000000E1* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS39xx ++ ++pci:v00001000d000000E2* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS39xx ++ ++pci:v00001000d000000E3* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS39xx ++ ++pci:v00001000d000000E4* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx ++ ++pci:v00001000d000000E4sv00001028sd0000200B* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355i Adapter Invalid) ++ ++pci:v00001000d000000E4sv00001028sd0000200C* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355i Front Invalid) ++ ++pci:v00001000d000000E4sv00001028sd0000200D* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355e Adapter Invalid) ++ ++pci:v00001000d000000E4sv00001028sd0000200E* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA350i MX Invalid) ++ ++pci:v00001000d000000E5* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx ++ ++pci:v00001000d000000E5sv00001028sd0000200B* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (HBA355i Adapter) ++ ++pci:v00001000d000000E5sv00001028sd0000200C* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (HBA355i Front) ++ ++pci:v00001000d000000E5sv00001028sd0000200D* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (HBA355e Adapter) ++ ++pci:v00001000d000000E5sv00001028sd0000200E* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (HBA350i MX) ++ ++pci:v00001000d000000E5sv00001D49sd00000205* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (ThinkSystem 440-16i SAS/SATA PCIe Gen4 12Gb Internal HBA) ++ ++pci:v00001000d000000E5sv00001D49sd00000206* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe SAS38xx (ThinkSystem 440-16e SAS/SATA PCIe Gen4 12Gb HBA) ++ ++pci:v00001000d000000E6* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx ++ ++pci:v00001000d000000E6sv00001000sd00004050* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (9500-16i Tri-Mode HBA) ++ ++pci:v00001000d000000E6sv00001000sd00004060* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (9500-8i Tri-Mode HBA) ++ ++pci:v00001000d000000E6sv00001000sd00004070* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (9500-16e Tri-Mode HBA) ++ ++pci:v00001000d000000E6sv00001000sd00004080* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (9500-8e Tri-Mode HBA) ++ ++pci:v00001000d000000E6sv00001028sd0000200B* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (HBA355i Adapter) ++ ++pci:v00001000d000000E6sv00001028sd0000200C* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (HBA355i Front) ++ ++pci:v00001000d000000E6sv00001028sd0000200D* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (HBA355e Adapter) ++ ++pci:v00001000d000000E6sv00001028sd0000200E* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (HBA350i MX) ++ ++pci:v00001000d000000E6sv00001028sd00002175* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (HBA350i Adapter) ++ ++pci:v00001000d000000E6sv00001D49sd00000205* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (ThinkSystem 440-16i SAS/SATA PCIe Gen4 12Gb Internal HBA) ++ ++pci:v00001000d000000E6sv00001D49sd00000206* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (ThinkSystem 440-16e SAS/SATA PCIe Gen4 12Gb HBA) ++ ++pci:v00001000d000000E6sv00001D49sd00000207* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (ThinkSystem 440-8i SAS/SATA PCIe Gen4 12Gb HBA) ++ ++pci:v00001000d000000E6sv00001D49sd00000208* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Secure SAS38xx (ThinkSystem 440-16i SAS/SATA PCIe Gen4 12Gb HBA) ++ ++pci:v00001000d000000E7* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx ++ ++pci:v00001000d000000E7sv00001028sd0000200B* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355i Adapter Tampered) ++ ++pci:v00001000d000000E7sv00001028sd0000200C* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355i Front Tampered) ++ ++pci:v00001000d000000E7sv00001028sd0000200D* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA355e Adapter Tampered) ++ ++pci:v00001000d000000E7sv00001028sd0000200E* ++ ID_MODEL_FROM_DATABASE=Fusion-MPT 12GSAS/PCIe Unsupported SAS38xx (HBA350i MX Tampered) ++ + pci:v00001000d000002B0* + ID_MODEL_FROM_DATABASE=Virtual Endpoint on PCIe Switch + +@@ -1862,6 +2282,12 @@ pci:v00001000d000002B0sv00001D49sd00000001* + pci:v00001000d000002B0sv00001D49sd00000002* + ID_MODEL_FROM_DATABASE=Virtual Endpoint on PCIe Switch (ThinkSystem 810-4P NVMe Switch Adapter) + ++pci:v00001000d000002B1* ++ ID_MODEL_FROM_DATABASE=Virtual Endpoint on PCIe Switch (9749) ++ ++pci:v00001000d000002B1sv00001D49sd00000004* ++ ID_MODEL_FROM_DATABASE=Virtual Endpoint on PCIe Switch (9749) (ThinkSystem 1610-8P NVMe Switch Adapter) ++ + pci:v00001000d00000407* + ID_MODEL_FROM_DATABASE=MegaRAID + +@@ -2072,6 +2498,153 @@ pci:v00001000d00000901* + pci:v00001000d00001000* + ID_MODEL_FROM_DATABASE=63C815 + ++pci:v00001000d000010E0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx ++ ++pci:v00001000d000010E0sv00001028sd00001AE0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 Adapter - Invalid Device) ++ ++pci:v00001000d000010E0sv00001028sd00001AE1* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 Front - Invalid Device) ++ ++pci:v00001000d000010E0sv00001028sd00001AE2* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755N Front - Invalid Device) ++ ++pci:v00001000d000010E0sv00001028sd00001AE3* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 MX - Invalid Device) ++ ++pci:v00001000d000010E1* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx ++ ++pci:v00001000d000010E1sv00001028sd00001AE0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (PERC H755 Adapter) ++ ++pci:v00001000d000010E1sv00001028sd00001AE1* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (PERC H755 Front) ++ ++pci:v00001000d000010E1sv00001028sd00001AE2* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (PERC H755N Front) ++ ++pci:v00001000d000010E1sv00001028sd00001AE3* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (PERC H755 MX) ++ ++pci:v00001000d000010E1sv00001D49sd0000060A* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-8i 4GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E1sv00001D49sd0000060B* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-8i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E1sv00001D49sd0000060C* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-16i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E1sv00001D49sd0000060D* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-16i 8GB Flash PCIe Gen4 12Gb Internal Adapter) ++ ++pci:v00001000d000010E1sv00001D49sd0000060E* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-32i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E1sv00001D49sd0000060F* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS39xx (ThinkSystem RAID 940-8e 4GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx ++ ++pci:v00001000d000010E2sv00001000sd00004000* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9560-16i) ++ ++pci:v00001000d000010E2sv00001000sd00004010* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9560-8i) ++ ++pci:v00001000d000010E2sv00001000sd00004020* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9580-8i8e) ++ ++pci:v00001000d000010E2sv00001000sd000040B0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (MegaRAID 9562-16i) ++ ++pci:v00001000d000010E2sv00001028sd00001AE0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H755 Adapter) ++ ++pci:v00001000d000010E2sv00001028sd00001AE1* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H755 Front) ++ ++pci:v00001000d000010E2sv00001028sd00001AE2* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H755N Front) ++ ++pci:v00001000d000010E2sv00001028sd00001AE3* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H755 MX) ++ ++pci:v00001000d000010E2sv00001028sd00002171* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H750 Mini) ++ ++pci:v00001000d000010E2sv00001028sd00002172* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H355 Adapter) ++ ++pci:v00001000d000010E2sv00001028sd00002173* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H355 Front) ++ ++pci:v00001000d000010E2sv00001028sd00002174* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H350 Mini) ++ ++pci:v00001000d000010E2sv00001028sd00002176* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H750 Adapter) ++ ++pci:v00001000d000010E2sv00001028sd00002177* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (PERC H350 Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060A* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-8i 4GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060B* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-8i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060C* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-16i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060D* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-16i 8GB Flash PCIe Gen4 12Gb Internal Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060E* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-32i 8GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd0000060F* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-8e 4GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E2sv00001D49sd00000610* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS39xx (ThinkSystem RAID 940-16i 4GB Flash PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E3* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx ++ ++pci:v00001000d000010E3sv00001028sd00001AE0* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 Adapter - Tampered Device) ++ ++pci:v00001000d000010E3sv00001028sd00001AE1* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 Front - Tampered Device) ++ ++pci:v00001000d000010E3sv00001028sd00001AE2* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755N Front - Tampered Device) ++ ++pci:v00001000d000010E3sv00001028sd00001AE3* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS39xx (PERC H755 MX - Tampered Device) ++ ++pci:v00001000d000010E4* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS38xx ++ ++pci:v00001000d000010E5* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe SAS38xx ++ ++pci:v00001000d000010E6* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS38xx ++ ++pci:v00001000d000010E6sv00001D49sd00000505* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS38xx (ThinkSystem RAID 540-8i PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E6sv00001D49sd00000506* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Secure SAS38xx (ThinkSystem RAID 540-16i PCIe Gen4 12Gb Adapter) ++ ++pci:v00001000d000010E7* ++ ID_MODEL_FROM_DATABASE=MegaRAID 12GSAS/PCIe Unsupported SAS38xx ++ + pci:v00001000d00001960* + ID_MODEL_FROM_DATABASE=MegaRAID + +@@ -2117,6 +2690,15 @@ pci:v00001000d00003050* + pci:v00001000d00006001* + ID_MODEL_FROM_DATABASE=DX1 Multiformat Broadcast HD/SD Encoder/Decoder + ++pci:v00001000d0000C010* ++ ID_MODEL_FROM_DATABASE=PEX88048 50 lane, 50 port, PCI Express Gen 4.0 ExpressFabric Platform ++ ++pci:v00001000d0000C012* ++ ID_MODEL_FROM_DATABASE=PEX880xx PCIe Gen 4 Switch ++ ++pci:v00001000d0000C012sv00001D49sd00000003* ++ ID_MODEL_FROM_DATABASE=PEX880xx PCIe Gen 4 Switch (ThinkSystem 1611-8P PCIe Gen4 NVMe Switch Adapter) ++ + pci:v00001001* + ID_VENDOR_FROM_DATABASE=Kolter Electronic + +@@ -2165,9 +2747,15 @@ pci:v00001002d00001307* + pci:v00001002d00001308* + ID_MODEL_FROM_DATABASE=Kaveri HDMI/DP Audio Controller + ++pci:v00001002d00001308sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=Kaveri HDMI/DP Audio Controller (Z50-75) ++ + pci:v00001002d00001309* + ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6/R7 Graphics] + ++pci:v00001002d00001309sv000017AAsd00003830* ++ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6/R7 Graphics] (Z50-75) ++ + pci:v00001002d0000130A* + ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics] + +@@ -2225,17 +2813,110 @@ pci:v00001002d0000131C* + pci:v00001002d0000131D* + ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics] + ++pci:v00001002d000013E9* ++ ID_MODEL_FROM_DATABASE=Ariel ++ ++pci:v00001002d00001478* ++ ID_MODEL_FROM_DATABASE=Navi 10 XL Upstream Port of PCI Express Switch ++ ++pci:v00001002d00001479* ++ ID_MODEL_FROM_DATABASE=Navi 10 XL Downstream Port of PCI Express Switch ++ ++pci:v00001002d0000154C* ++ ID_MODEL_FROM_DATABASE=Kryptos [Radeon RX 350] ++ ++pci:v00001002d0000154Csv00001462sd00007C28* ++ ID_MODEL_FROM_DATABASE=Kryptos [Radeon RX 350] (MS-7C28 Motherboard) ++ ++pci:v00001002d0000154E* ++ ID_MODEL_FROM_DATABASE=Garfield ++ ++pci:v00001002d00001551* ++ ID_MODEL_FROM_DATABASE=Arlene ++ ++pci:v00001002d00001552* ++ ID_MODEL_FROM_DATABASE=Pooky ++ ++pci:v00001002d00001561* ++ ID_MODEL_FROM_DATABASE=Anubis ++ ++pci:v00001002d000015D8* ++ ID_MODEL_FROM_DATABASE=Picasso ++ ++pci:v00001002d000015D8sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Picasso (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001002d000015D8sv000017AAsd00003181* ++ ID_MODEL_FROM_DATABASE=Picasso (ThinkCentre M75n IoT) ++ ++pci:v00001002d000015D8sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Picasso (ThinkPad E595) ++ ++pci:v00001002d000015D8sv0000EA50sd0000CC10* ++ ID_MODEL_FROM_DATABASE=Picasso (RXi2-BP) ++ + pci:v00001002d000015DD* + ID_MODEL_FROM_DATABASE=Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] + + pci:v00001002d000015DDsv0000103Csd000083C6* + ID_MODEL_FROM_DATABASE=Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] (Radeon Vega 8 Mobile) + ++pci:v00001002d000015DDsv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] (PRIME Motherboard) ++ + pci:v00001002d000015DDsv00001458sd0000D000* + ID_MODEL_FROM_DATABASE=Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] (Radeon RX Vega 11) + ++pci:v00001002d000015DDsv0000EA50sd0000CC10* ++ ID_MODEL_FROM_DATABASE=Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] (RXi2-BP) ++ ++pci:v00001002d000015DE* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang HDMI/DP Audio Controller ++ ++pci:v00001002d000015DEsv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang HDMI/DP Audio Controller (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001002d000015DEsv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang HDMI/DP Audio Controller (PRIME B450M-A Motherboard) ++ ++pci:v00001002d000015DEsv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang HDMI/DP Audio Controller (ThinkPad E595) ++ ++pci:v00001002d000015DEsv0000EA50sd0000CC10* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang HDMI/DP Audio Controller (RXi2-BP) ++ ++pci:v00001002d000015DF* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang/Renoir Cryptographic Coprocessor ++ ++pci:v00001002d000015DFsv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang/Renoir Cryptographic Coprocessor (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001002d000015DFsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Fenghuang/Renoir Cryptographic Coprocessor (mCOM10-L1900) ++ + pci:v00001002d000015FF* +- ID_MODEL_FROM_DATABASE=Vega 11 [Radeon Vega 28 Mobile] ++ ID_MODEL_FROM_DATABASE=Fenghuang [Zhongshan Subor Z+] ++ ++pci:v00001002d00001607* ++ ID_MODEL_FROM_DATABASE=Arden ++ ++pci:v00001002d00001636* ++ ID_MODEL_FROM_DATABASE=Renoir ++ ++pci:v00001002d00001637* ++ ID_MODEL_FROM_DATABASE=Renoir Radeon High Definition Audio Controller ++ ++pci:v00001002d00001638* ++ ID_MODEL_FROM_DATABASE=Cezanne ++ ++pci:v00001002d0000163F* ++ ID_MODEL_FROM_DATABASE=VanGogh ++ ++pci:v00001002d0000164C* ++ ID_MODEL_FROM_DATABASE=Lucienne ++ ++pci:v00001002d0000164D* ++ ID_MODEL_FROM_DATABASE=Rembrandt + + pci:v00001002d00001714* + ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] +@@ -2265,13 +2946,13 @@ pci:v00001002d00003171* + ID_MODEL_FROM_DATABASE=RV380 GL [FireMV 2400] (Secondary) + + pci:v00001002d00003E50* +- ID_MODEL_FROM_DATABASE=RV380 [Radeon X600] ++ ID_MODEL_FROM_DATABASE=RV380 [Radeon X550/X600] + + pci:v00001002d00003E54* + ID_MODEL_FROM_DATABASE=RV380 GL [FireGL V3200] + + pci:v00001002d00003E70* +- ID_MODEL_FROM_DATABASE=RV380 [Radeon X600] (Secondary) ++ ID_MODEL_FROM_DATABASE=RV380 [Radeon X550/X600] (Secondary) + + pci:v00001002d00004136* + ID_MODEL_FROM_DATABASE=RS100 [Mobility IGP 320M] +@@ -2481,28 +3162,34 @@ pci:v00001002d00004337sv0000103Csd00000850* + ID_MODEL_FROM_DATABASE=RS200M [Radeon IGP 330M/340M/345M/350M] (Radeon IGP 345M) + + pci:v00001002d00004341* +- ID_MODEL_FROM_DATABASE=IXP150 AC'97 Audio Controller ++ ID_MODEL_FROM_DATABASE=SB200 AC97 Audio Controller + + pci:v00001002d00004342* +- ID_MODEL_FROM_DATABASE=IXP200 3COM 3C920B Ethernet Controller ++ ID_MODEL_FROM_DATABASE=SB200 PCI to PCI Bridge + + pci:v00001002d00004345* +- ID_MODEL_FROM_DATABASE=EHCI USB Controller ++ ID_MODEL_FROM_DATABASE=SB200 EHCI USB Controller ++ ++pci:v00001002d00004346* ++ ID_MODEL_FROM_DATABASE=Crayola 6 [XENOS Parent Die (XBOX 360)] + + pci:v00001002d00004347* +- ID_MODEL_FROM_DATABASE=OHCI USB Controller #1 ++ ID_MODEL_FROM_DATABASE=SB200 OHCI USB Controller #1 + + pci:v00001002d00004348* +- ID_MODEL_FROM_DATABASE=OHCI USB Controller #2 ++ ID_MODEL_FROM_DATABASE=SB200 OHCI USB Controller #2 + + pci:v00001002d00004349* +- ID_MODEL_FROM_DATABASE=Dual Channel Bus Master PCI IDE Controller ++ ID_MODEL_FROM_DATABASE=SB200 IDE Controller ++ ++pci:v00001002d0000434C* ++ ID_MODEL_FROM_DATABASE=SB200 PCI to LPC Bridge + + pci:v00001002d0000434D* +- ID_MODEL_FROM_DATABASE=IXP AC'97 Modem ++ ID_MODEL_FROM_DATABASE=SB200 AC97 Modem Controller + + pci:v00001002d00004353* +- ID_MODEL_FROM_DATABASE=SMBus ++ ID_MODEL_FROM_DATABASE=SB200 SMBus Controller + + pci:v00001002d00004354* + ID_MODEL_FROM_DATABASE=215CT [Mach64 CT PCI] +@@ -2511,13 +3198,34 @@ pci:v00001002d00004358* + ID_MODEL_FROM_DATABASE=Mach64 CX [Graphics Xpression] + + pci:v00001002d00004361* +- ID_MODEL_FROM_DATABASE=IXP SB300 AC'97 Audio Controller ++ ID_MODEL_FROM_DATABASE=SB300 AC'97 Audio Controller ++ ++pci:v00001002d00004362* ++ ID_MODEL_FROM_DATABASE=SB300 PCI to PCI Bridge + + pci:v00001002d00004363* +- ID_MODEL_FROM_DATABASE=SMBus ++ ID_MODEL_FROM_DATABASE=SB300 SMBus Controller ++ ++pci:v00001002d00004365* ++ ID_MODEL_FROM_DATABASE=SB300 USB Controller (EHCI) ++ ++pci:v00001002d00004367* ++ ID_MODEL_FROM_DATABASE=SB300 USB Controller (EHCI) ++ ++pci:v00001002d00004368* ++ ID_MODEL_FROM_DATABASE=SB300 USB Controller (EHCI) ++ ++pci:v00001002d00004369* ++ ID_MODEL_FROM_DATABASE=SB300 IDE Controller ++ ++pci:v00001002d0000436C* ++ ID_MODEL_FROM_DATABASE=SB300 PCI to LPC Bridge ++ ++pci:v00001002d0000436D* ++ ID_MODEL_FROM_DATABASE=SB300 AC97 Modem Controller + + pci:v00001002d0000436E* +- ID_MODEL_FROM_DATABASE=436E Serial ATA Controller ++ ID_MODEL_FROM_DATABASE=SB300 Serial ATA Controller + + pci:v00001002d00004370* + ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller +@@ -2724,7 +3432,7 @@ pci:v00001002d00004383sv00001019sd00002120* + ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (A785GM-M) + + pci:v00001002d00004383sv0000103Csd00001611* +- ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (Pavilion DM1Z-3000) ++ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (Pavilion dm1z-3000) + + pci:v00001002d00004383sv0000103Csd0000280A* + ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (DC5750 Microtower) +@@ -2753,6 +3461,12 @@ pci:v00001002d00004383sv00001179sd0000FF50* + pci:v00001002d00004383sv00001458sd0000A022* + ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (GA-MA770-DS3rev2.0 Motherboard) + ++pci:v00001002d00004383sv00001458sd0000A102* ++ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (GA-880GMA-USB3) ++ ++pci:v00001002d00004383sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004383sv000017F2sd00005000* + ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (KI690-AM2 Motherboard) + +@@ -2789,6 +3503,9 @@ pci:v00001002d00004385sv00001458sd00004385* + pci:v00001002d00004385sv00001462sd00007368* + ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (K9AG Neo2) + ++pci:v00001002d00004385sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004385sv000015D9sd0000A811* + ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (H8DGU) + +@@ -2939,12 +3656,18 @@ pci:v00001002d00004390sv0000105Bsd00000E13* + pci:v00001002d00004390sv00001458sd0000B002* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (GA-MA770-DS3rev2.0 Motherboard) + ++pci:v00001002d00004390sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004390sv00001849sd00004390* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (Motherboard (one of many)) + + pci:v00001002d00004391* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] + ++pci:v00001002d00004391sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (ProLiant MicroServer N36L) ++ + pci:v00001002d00004391sv0000103Csd00001611* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (Pavilion DM1Z-3000) + +@@ -2954,9 +3677,15 @@ pci:v00001002d00004391sv00001043sd000082EF* + pci:v00001002d00004391sv00001043sd00008443* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (M5A88-V EVO) + ++pci:v00001002d00004391sv00001043sd000084DD* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (M5A99X EVO (R1.0) SB950) ++ + pci:v00001002d00004391sv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d00004391sv00001458sd0000B002* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (GA-880GMA-USB3) ++ + pci:v00001002d00004391sv0000174Bsd00001001* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (PURE Fusion Mini) + +@@ -2981,6 +3710,9 @@ pci:v00001002d00004396* + pci:v00001002d00004396sv00001019sd00002120* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (A785GM-M) + ++pci:v00001002d00004396sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (ProLiant MicroServer N36L) ++ + pci:v00001002d00004396sv0000103Csd00001611* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (Pavilion DM1Z-3000) + +@@ -2993,6 +3725,12 @@ pci:v00001002d00004396sv00001043sd00008443* + pci:v00001002d00004396sv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d00004396sv00001458sd00005004* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (GA-880GMA-USB3) ++ ++pci:v00001002d00004396sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004396sv000015D9sd0000A811* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (H8DGU) + +@@ -3005,6 +3743,9 @@ pci:v00001002d00004397* + pci:v00001002d00004397sv00001019sd00002120* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (A785GM-M) + ++pci:v00001002d00004397sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (ProLiant MicroServer N36L) ++ + pci:v00001002d00004397sv0000103Csd00001611* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (Pavilion DM1Z-3000) + +@@ -3017,6 +3758,12 @@ pci:v00001002d00004397sv00001043sd00008443* + pci:v00001002d00004397sv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d00004397sv00001458sd00005004* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (GA-880GMA-USB3) ++ ++pci:v00001002d00004397sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004397sv000015D9sd0000A811* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (H8DGU) + +@@ -3035,6 +3782,9 @@ pci:v00001002d00004398sv00001043sd000082EF* + pci:v00001002d00004398sv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d00004398sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004398sv000015D9sd0000A811* + ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (H8DGU) + +@@ -3053,27 +3803,45 @@ pci:v00001002d00004399sv00001043sd00008443* + pci:v00001002d00004399sv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d00004399sv00001458sd00005004* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (GA-880GMA-USB3) ++ ++pci:v00001002d00004399sv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00004399sv0000174Bsd00001001* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (PURE Fusion Mini) + + pci:v00001002d0000439C* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller + ++pci:v00001002d0000439Csv00001002sd00004392* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (MSI MS-7713 motherboard) ++ + pci:v00001002d0000439Csv00001019sd00002120* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (A785GM-M) + ++pci:v00001002d0000439Csv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (ProLiant MicroServer N36L) ++ + pci:v00001002d0000439Csv00001043sd000082EF* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (M3A78-EH Motherboard) + + pci:v00001002d0000439Csv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d0000439Csv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d0000439D* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller + + pci:v00001002d0000439Dsv00001019sd00002120* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (A785GM-M) + ++pci:v00001002d0000439Dsv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (ProLiant MicroServer N36L) ++ + pci:v00001002d0000439Dsv0000103Csd00001611* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (Pavilion DM1Z-3000) + +@@ -3086,6 +3854,9 @@ pci:v00001002d0000439Dsv00001043sd00008443* + pci:v00001002d0000439Dsv0000105Bsd00000E13* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (N15235/A74MX mainboard / AMD SB700) + ++pci:v00001002d0000439Dsv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d0000439Dsv0000174Bsd00001001* + ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (PURE Fusion Mini) + +@@ -3107,6 +3878,12 @@ pci:v00001002d00004437* + pci:v00001002d00004554* + ID_MODEL_FROM_DATABASE=210888ET [Mach64 ET] + ++pci:v00001002d00004630* ++ ID_MODEL_FROM_DATABASE=XENOS Parent Die (XBOX 360) ++ ++pci:v00001002d00004631* ++ ID_MODEL_FROM_DATABASE=XENOS Daughter Die (XBOX 360) ++ + pci:v00001002d00004654* + ID_MODEL_FROM_DATABASE=Mach64 VT + +@@ -3347,6 +4124,168 @@ pci:v00001002d0000475Asv00001002sd00000087* + pci:v00001002d0000475Asv00001002sd0000475A* + ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage IIC AGP) + ++pci:v00001002d00004845* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 HBIU for HDTV2 ++ ++pci:v00001002d00004846* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 IDE for HDTV2 ++ ++pci:v00001002d00004847* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 USB for HDTV2 ++ ++pci:v00001002d00004848* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 DAIO-0 for HDTV2 ++ ++pci:v00001002d00004849* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 DAIO-1 for HDTV2 ++ ++pci:v00001002d0000484A* ++ ID_MODEL_FROM_DATABASE=Xilleon 220 LPC for HDTV2 ++ ++pci:v00001002d00004850* ++ ID_MODEL_FROM_DATABASE=Xilleon 215 HBIU for X215 ++ ++pci:v00001002d00004851* ++ ID_MODEL_FROM_DATABASE=Xilleon 215 IDE for X215 ++ ++pci:v00001002d00004852* ++ ID_MODEL_FROM_DATABASE=Xilleon 215 USB for X215 ++ ++pci:v00001002d00004853* ++ ID_MODEL_FROM_DATABASE=Xilleon 215 DAIO-0 for X215 ++ ++pci:v00001002d00004854* ++ ID_MODEL_FROM_DATABASE=Xilleon 215 DAIO-1 for X215 ++ ++pci:v00001002d00004855* ++ ID_MODEL_FROM_DATABASE=Xilleon 225 HBIU for X225 ++ ++pci:v00001002d00004856* ++ ID_MODEL_FROM_DATABASE=Xilleon 225 IDE for X225 ++ ++pci:v00001002d00004857* ++ ID_MODEL_FROM_DATABASE=Xilleon 225 USB for X225 ++ ++pci:v00001002d00004858* ++ ID_MODEL_FROM_DATABASE=Xilleon 225 DAIO-0 for X225 ++ ++pci:v00001002d00004859* ++ ID_MODEL_FROM_DATABASE=Xilleon 225 DAIO-1 for X225 ++ ++pci:v00001002d00004860* ++ ID_MODEL_FROM_DATABASE=Xilleon 210 HBIU for X210 ++ ++pci:v00001002d00004861* ++ ID_MODEL_FROM_DATABASE=Xilleon 210 IDE for X210 ++ ++pci:v00001002d00004862* ++ ID_MODEL_FROM_DATABASE=Xilleon 210 USB for X210 ++ ++pci:v00001002d00004863* ++ ID_MODEL_FROM_DATABASE=Xilleon 210 DAIO-0 for X210 ++ ++pci:v00001002d00004864* ++ ID_MODEL_FROM_DATABASE=Xilleon 210 DAIO-1 for X210 ++ ++pci:v00001002d00004865* ++ ID_MODEL_FROM_DATABASE=Xilleon 226 HBIU for X226 ++ ++pci:v00001002d00004866* ++ ID_MODEL_FROM_DATABASE=Xilleon 226 IDE for X226 ++ ++pci:v00001002d00004867* ++ ID_MODEL_FROM_DATABASE=Xilleon 226 USB for X226 ++ ++pci:v00001002d00004868* ++ ID_MODEL_FROM_DATABASE=Xilleon 226 DAIO-0 for X226 ++ ++pci:v00001002d00004869* ++ ID_MODEL_FROM_DATABASE=Xilleon 226 DAIO-1 for X226 ++ ++pci:v00001002d0000486A* ++ ID_MODEL_FROM_DATABASE=Xilleon 240S HBIU for X240S ++ ++pci:v00001002d0000486B* ++ ID_MODEL_FROM_DATABASE=Xilleon 240H HBIU for X240H ++ ++pci:v00001002d0000486C* ++ ID_MODEL_FROM_DATABASE=Xilleon 240S USB for X240S ++ ++pci:v00001002d0000486D* ++ ID_MODEL_FROM_DATABASE=Xilleon 240H USB for X240H ++ ++pci:v00001002d0000486E* ++ ID_MODEL_FROM_DATABASE=Xilleon 250 USB 1.1 for X250 ++ ++pci:v00001002d0000486F* ++ ID_MODEL_FROM_DATABASE=Xilleon 260 USB 1.1 for X260 ++ ++pci:v00001002d00004870* ++ ID_MODEL_FROM_DATABASE=Xilleon 250 HBIU for X250 ++ ++pci:v00001002d00004871* ++ ID_MODEL_FROM_DATABASE=Xilleon 250 IDE for X250 ++ ++pci:v00001002d00004872* ++ ID_MODEL_FROM_DATABASE=Xilleon 234/235 HBIU for X234/X235 ++ ++pci:v00001002d00004873* ++ ID_MODEL_FROM_DATABASE=Xilleon 244/245 HBIU for X244/X245 ++ ++pci:v00001002d00004874* ++ ID_MODEL_FROM_DATABASE=Xilleon 234/235 USB 1.1 for X234/X235 ++ ++pci:v00001002d00004875* ++ ID_MODEL_FROM_DATABASE=Xilleon 260 HBIU for X260 ++ ++pci:v00001002d00004876* ++ ID_MODEL_FROM_DATABASE=Xilleon 260 IDE for X260 ++ ++pci:v00001002d00004877* ++ ID_MODEL_FROM_DATABASE=Xilleon 244/245 USB 1.1 for X244/X245 ++ ++pci:v00001002d00004878* ++ ID_MODEL_FROM_DATABASE=Xilleon 270 HBIU for X270 ++ ++pci:v00001002d0000487B* ++ ID_MODEL_FROM_DATABASE=Xilleon 242 HBIU for X242 ++ ++pci:v00001002d0000487D* ++ ID_MODEL_FROM_DATABASE=Xilleon 242 USB 1.1 for X242 ++ ++pci:v00001002d00004880* ++ ID_MODEL_FROM_DATABASE=Xilleon 254 HBIU for X254 ++ ++pci:v00001002d00004881* ++ ID_MODEL_FROM_DATABASE=Xilleon 254 USB 1.1 for X254 ++ ++pci:v00001002d00004882* ++ ID_MODEL_FROM_DATABASE=Xilleon 255 HBIU for X255 ++ ++pci:v00001002d00004883* ++ ID_MODEL_FROM_DATABASE=Xilleon 255 USB 1.1 for X255 ++ ++pci:v00001002d00004884* ++ ID_MODEL_FROM_DATABASE=Xilleon 243 HBIU for X243 ++ ++pci:v00001002d00004885* ++ ID_MODEL_FROM_DATABASE=Xilleon 243 USB 1.1 for X243 ++ ++pci:v00001002d00004886* ++ ID_MODEL_FROM_DATABASE=Xilleon 233 HBIU for X233 ++ ++pci:v00001002d00004887* ++ ID_MODEL_FROM_DATABASE=Xilleon 233 USB 1.1 for X233 ++ ++pci:v00001002d00004888* ++ ID_MODEL_FROM_DATABASE=Xilleon 143 HBIU for X143 ++ ++pci:v00001002d00004889* ++ ID_MODEL_FROM_DATABASE=Xilleon 143 HBIU for X143L ++ ++pci:v00001002d0000488A* ++ ID_MODEL_FROM_DATABASE=Xilleon 143 HBIU for X143S ++ + pci:v00001002d00004966* + ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] + +@@ -3735,43 +4674,43 @@ pci:v00001002d00005044sv00001002sd00000029* + ID_MODEL_FROM_DATABASE=All-In-Wonder 128 PCI (Rage 128 AIW) + + pci:v00001002d00005046* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] + + pci:v00001002d00005046sv00001002sd00000004* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury Pro) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury Pro) + + pci:v00001002d00005046sv00001002sd00000008* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury Pro/Xpert 2000 Pro) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury Pro/Xpert 2000 Pro) + + pci:v00001002d00005046sv00001002sd00000014* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury Pro) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury Pro) + + pci:v00001002d00005046sv00001002sd00000018* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury Pro/Xpert 2000 Pro) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury Pro/Xpert 2000 Pro) + + pci:v00001002d00005046sv00001002sd00000028* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage 128 Pro AIW AGP) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage 128 Pro AIW AGP) + + pci:v00001002d00005046sv00001002sd0000002A* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage 128 Pro AIW AGP) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage 128 Pro AIW AGP) + + pci:v00001002d00005046sv00001002sd00000048* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury Pro) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury Pro) + + pci:v00001002d00005046sv00001002sd00002000* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury MAXX AGP 4x (TMDS) (VGA device)) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury MAXX AGP 4x (TMDS) (VGA device)) + + pci:v00001002d00005046sv00001002sd00002001* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X TMDS] (Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] (Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)) + + pci:v00001002d00005050* +- ID_MODEL_FROM_DATABASE=Rage128 [Xpert 128 PCI] ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO PCI / Xpert 128 PCI] + + pci:v00001002d00005050sv00001002sd00000008* +- ID_MODEL_FROM_DATABASE=Rage128 [Xpert 128 PCI] (Xpert 128) ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO PCI / Xpert 128 PCI] (Xpert 128) + + pci:v00001002d00005052* +- ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4X TMDS ++ ID_MODEL_FROM_DATABASE=Rage 4 [Rage 128 PRO AGP 4X] + + pci:v00001002d00005144* + ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] +@@ -4032,25 +4971,25 @@ pci:v00001002d00005245sv00001002sd00000068* + ID_MODEL_FROM_DATABASE=Rage 128 GL PCI (Rage 128 AIW) + + pci:v00001002d00005246* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series + + pci:v00001002d00005246sv00001002sd00000004* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Magnum/Xpert 128/Xpert 99) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Magnum/Xpert 128/Xpert 99) + + pci:v00001002d00005246sv00001002sd00000008* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Magnum/Xpert128/X99/Xpert2000) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Rage 128 AGP 2x) + + pci:v00001002d00005246sv00001002sd00000028* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Rage 128 AIW AGP) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Rage 128 AIW AGP) + + pci:v00001002d00005246sv00001002sd00000044* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Rage Fury/Xpert 128/Xpert 2000) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Rage Fury/Xpert 128/Xpert 2000) + + pci:v00001002d00005246sv00001002sd00000068* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Rage 128 AIW AGP) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Rage 128 AIW AGP) + + pci:v00001002d00005246sv00001002sd00000448* +- ID_MODEL_FROM_DATABASE=Rage 4 [Rage Fury/Xpert 128/Xpert 2000 AGP] (Rage Fury) ++ ID_MODEL_FROM_DATABASE=Rage 128 (Rage 4) series (Rage Fury) + + pci:v00001002d0000524B* + ID_MODEL_FROM_DATABASE=Rage 128 VR PCI +@@ -4064,12 +5003,6 @@ pci:v00001002d0000524Csv00001002sd00000008* + pci:v00001002d0000524Csv00001002sd00000088* + ID_MODEL_FROM_DATABASE=Rage 128 VR AGP (Xpert 99) + +-pci:v00001002d00005346* +- ID_MODEL_FROM_DATABASE=Rage 128 SF/4x AGP 2x +- +-pci:v00001002d00005346sv00001002sd00000048* +- ID_MODEL_FROM_DATABASE=Rage 128 SF/4x AGP 2x (RAGE 128 16MB VGA TVOUT AMC PAL) +- + pci:v00001002d0000534D* + ID_MODEL_FROM_DATABASE=Rage 128 4X AGP 4x + +@@ -4149,13 +5082,13 @@ pci:v00001002d0000554Bsv00001002sd00000302* + ID_MODEL_FROM_DATABASE=R423 [Radeon X800 GT/SE] (Radeon X800 SE) + + pci:v00001002d0000554D* +- ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] ++ ID_MODEL_FROM_DATABASE=R480 [Radeon X800 GTO2/XL] + + pci:v00001002d0000554Dsv00001002sd00000322* +- ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (All-In-Wonder X800 XL) ++ ID_MODEL_FROM_DATABASE=R480 [Radeon X800 GTO2/XL] (All-In-Wonder X800 XL) + + pci:v00001002d0000554Dsv00001458sd00002124* +- ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (GV-R80L256V-B (AGP)) ++ ID_MODEL_FROM_DATABASE=R480 [Radeon X800 GTO2/XL] (GV-R80L256V-B (AGP)) + + pci:v00001002d0000554E* + ID_MODEL_FROM_DATABASE=R430 [All-In-Wonder X800 GT] +@@ -4176,10 +5109,10 @@ pci:v00001002d0000556B* + ID_MODEL_FROM_DATABASE=R423 [Radeon X800 GT] (Secondary) + + pci:v00001002d0000556D* +- ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (Secondary) ++ ID_MODEL_FROM_DATABASE=R480 [Radeon X800 GTO2/XL] (Secondary) + + pci:v00001002d0000556Dsv00001458sd00002125* +- ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (Secondary) (GV-R80L256V-B (AGP)) ++ ID_MODEL_FROM_DATABASE=R480 [Radeon X800 GTO2/XL] (Secondary) (GV-R80L256V-B (AGP)) + + pci:v00001002d0000556F* + ID_MODEL_FROM_DATABASE=R430 [Radeon X800] (Secondary) +@@ -4329,10 +5262,10 @@ pci:v00001002d00005958* + ID_MODEL_FROM_DATABASE=RD780 Host Bridge + + pci:v00001002d00005960* +- ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO] ++ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO / 9250] + + pci:v00001002d00005960sv000017AFsd00002020* +- ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Excalibur Radeon 9250) ++ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO / 9250] (Excalibur Radeon 9250) + + pci:v00001002d00005961* + ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] +@@ -4377,7 +5310,7 @@ pci:v00001002d00005964sv00001043sd0000C006* + ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE / TD / 128M) + + pci:v00001002d00005964sv00001458sd00004018* +- ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE) ++ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (R92S128T (Radeon 9200 SE 128MB)) + + pci:v00001002d00005964sv00001458sd00004032* + ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE 128MB) +@@ -4641,7 +5574,7 @@ pci:v00001002d00005D44* + ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) + + pci:v00001002d00005D44sv00001458sd00004019* +- ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE (Secondary)) ++ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (R92S128T (Radeon 9200 SE 128MB Secondary)) + + pci:v00001002d00005D44sv00001458sd00004032* + ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE 128MB) +@@ -4752,10 +5685,10 @@ pci:v00001002d00005F57* + ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT] + + pci:v00001002d00006600* +- ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M] ++ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M / R7 M370] + + pci:v00001002d00006600sv0000103Csd00001952* +- ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M] (ProBook 455 G1) ++ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M / R7 M370] (ProBook 455 G1) + + pci:v00001002d00006601* + ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8730M] +@@ -4763,12 +5696,6 @@ pci:v00001002d00006601* + pci:v00001002d00006601sv0000103Csd00002100* + ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8730M] (FirePro M4100) + +-pci:v00001002d00006602* +- ID_MODEL_FROM_DATABASE=Mars +- +-pci:v00001002d00006603* +- ID_MODEL_FROM_DATABASE=Mars +- + pci:v00001002d00006604* + ID_MODEL_FROM_DATABASE=Opal XT [Radeon R7 M265/M365X/M465] + +@@ -4808,53 +5735,80 @@ pci:v00001002d00006608* + pci:v00001002d00006608sv000013CCsd00003D28* + ID_MODEL_FROM_DATABASE=Oland GL [FirePro W2100] (MXRT-2600) + ++pci:v00001002d00006609* ++ ID_MODEL_FROM_DATABASE=Oland GL [FirePro W2100 / Barco MXRT 2600] ++ + pci:v00001002d00006610* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] + + pci:v00001002d00006610sv00001019sd00000030* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon HD 8670) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon HD 8670) ++ ++pci:v00001002d00006610sv00001028sd00000081* ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R7 350X OEM) ++ ++pci:v00001002d00006610sv00001028sd00000083* ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R5 340X OEM) + + pci:v00001002d00006610sv00001028sd00002120* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon R7 250) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R7 250) + + pci:v00001002d00006610sv00001028sd00002322* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon R7 250) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R7 250) + + pci:v00001002d00006610sv00001462sd00002910* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon HD 8670) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon HD 8670) + + pci:v00001002d00006610sv00001462sd00002911* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon HD 8670) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon HD 8670) + + pci:v00001002d00006610sv0000148Csd00007350* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon R7 350) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R7 350) + + pci:v00001002d00006610sv00001642sd00003C81* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon HD 8670) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon HD 8670) + + pci:v00001002d00006610sv00001642sd00003C91* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon HD 8670) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon HD 8670) + + pci:v00001002d00006610sv00001642sd00003F09* +- ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250/350] (Radeon R7 350) ++ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R5 340X OEM / R7 250/350/350X OEM] (Radeon R7 350) + + pci:v00001002d00006611* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] ++ ++pci:v00001002d00006611sv00001028sd00001001* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R5 430 OEM (1024 MByte)) ++ ++pci:v00001002d00006611sv00001028sd00001002* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R5 430 OEM (2048 MByte)) ++ ++pci:v00001002d00006611sv00001028sd00001711* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (R5 430 OEM (2048 MByte)) + + pci:v00001002d00006611sv00001028sd0000210B* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] (Radeon R5 240 OEM) ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R5 240 OEM) ++ ++pci:v00001002d00006611sv00001028sd00002121* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon HD 8570 OEM) ++ ++pci:v00001002d00006611sv000010CFsd00001889* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon HD 8570 OEM) ++ ++pci:v00001002d00006611sv00001642sd00001869* ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon 520 OEM) + + pci:v00001002d00006611sv0000174Bsd00004248* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] (Radeon R7 240 OEM) ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R7 240 OEM) + + pci:v00001002d00006611sv0000174Bsd0000A240* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] (Radeon R7 240 OEM) ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R7 240 OEM) + + pci:v00001002d00006611sv0000174Bsd0000D340* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] (Radeon R7 340 OEM) ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R7 340 OEM) + + pci:v00001002d00006611sv00001B0Asd000090D3* +- ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240/340 OEM] (Radeon R7 240 OEM) ++ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R5 430 OEM / R7 240/340 / Radeon 520 OEM] (Radeon R7 240 OEM) + + pci:v00001002d00006613* + ID_MODEL_FROM_DATABASE=Oland PRO [Radeon R7 240/340] +@@ -4865,15 +5819,6 @@ pci:v00001002d00006613sv0000148Csd00007340* + pci:v00001002d00006613sv00001682sd00007240* + ID_MODEL_FROM_DATABASE=Oland PRO [Radeon R7 240/340] (R7 240 2048 MB) + +-pci:v00001002d00006620* +- ID_MODEL_FROM_DATABASE=Mars +- +-pci:v00001002d00006621* +- ID_MODEL_FROM_DATABASE=Mars PRO +- +-pci:v00001002d00006623* +- ID_MODEL_FROM_DATABASE=Mars +- + pci:v00001002d00006631* + ID_MODEL_FROM_DATABASE=Oland + +@@ -4890,7 +5835,10 @@ pci:v00001002d00006646* + ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon R9 M280X] + + pci:v00001002d00006647* +- ID_MODEL_FROM_DATABASE=Bonaire PRO [Radeon R9 M270X] ++ ID_MODEL_FROM_DATABASE=Saturn PRO/XT [Radeon R9 M270X/M280X] ++ ++pci:v00001002d00006647sv00001043sd0000223D* ++ ID_MODEL_FROM_DATABASE=Saturn PRO/XT [Radeon R9 M270X/M280X] (N551ZU laptop Radeon R9 M280X) + + pci:v00001002d00006649* + ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100] +@@ -4907,6 +5855,9 @@ pci:v00001002d00006649sv0000103Csd0000230C* + pci:v00001002d00006649sv000013CCsd00003D2A* + ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100] (MXRT-5600) + ++pci:v00001002d0000664D* ++ ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100 / Barco MXRT-5600] ++ + pci:v00001002d00006650* + ID_MODEL_FROM_DATABASE=Bonaire + +@@ -4916,6 +5867,12 @@ pci:v00001002d00006651* + pci:v00001002d00006658* + ID_MODEL_FROM_DATABASE=Bonaire XTX [Radeon R7 260X/360] + ++pci:v00001002d00006658sv00001043sd0000048F* ++ ID_MODEL_FROM_DATABASE=Bonaire XTX [Radeon R7 260X/360] (R7260X-DC2OC-2GD5) ++ ++pci:v00001002d00006658sv00001043sd000004D3* ++ ID_MODEL_FROM_DATABASE=Bonaire XTX [Radeon R7 260X/360] (AMD Radeon R7 260X) ++ + pci:v00001002d00006658sv0000148Csd00000907* + ID_MODEL_FROM_DATABASE=Bonaire XTX [Radeon R7 260X/360] (Radeon R7 360) + +@@ -4983,40 +5940,40 @@ pci:v00001002d0000665Fsv00001682sd00007360* + ID_MODEL_FROM_DATABASE=Tobago PRO [Radeon R7 360 / R9 360 OEM] (Radeon R7 360) + + pci:v00001002d00006660* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] + + pci:v00001002d00006660sv00001028sd000005EA* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon HD 8670M) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon HD 8670M) + + pci:v00001002d00006660sv00001028sd000006BF* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M335) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M335) + + pci:v00001002d00006660sv0000103Csd00001970* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon HD 8670M) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon HD 8670M) + + pci:v00001002d00006660sv0000103Csd000080BE* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M330) + + pci:v00001002d00006660sv0000103Csd00008136* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M330) + + pci:v00001002d00006660sv0000103Csd00008329* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R7 M520) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R7 M520) + + pci:v00001002d00006660sv000017AAsd00003633* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 A330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 A330) + + pci:v00001002d00006660sv000017AAsd00003804* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M330) + + pci:v00001002d00006660sv000017AAsd00003809* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M330) + + pci:v00001002d00006660sv000017AAsd0000381A* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M430) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M430) + + pci:v00001002d00006660sv000017AAsd0000390C* +- ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / R7 M520] (Radeon R5 M330) ++ ID_MODEL_FROM_DATABASE=Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430 / Radeon 520 Mobile] (Radeon R5 M330) + + pci:v00001002d00006663* + ID_MODEL_FROM_DATABASE=Sun PRO [Radeon HD 8570A/8570M] +@@ -5031,10 +5988,13 @@ pci:v00001002d00006664* + ID_MODEL_FROM_DATABASE=Jet XT [Radeon R5 M240] + + pci:v00001002d00006665* +- ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230] ++ ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230 / R7 M260DX / Radeon 520 Mobile] ++ ++pci:v00001002d00006665sv000017AAsd00001309* ++ ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230 / R7 M260DX / Radeon 520 Mobile] (Z50-75 Radeon R7 M260DX) + + pci:v00001002d00006665sv000017AAsd0000368F* +- ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230] (Radeon R5 A230) ++ ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230 / R7 M260DX / Radeon 520 Mobile] (Radeon R5 A230) + + pci:v00001002d00006667* + ID_MODEL_FROM_DATABASE=Jet ULT [Radeon R5 M230] +@@ -5046,19 +6006,19 @@ pci:v00001002d000066A0* + ID_MODEL_FROM_DATABASE=Vega 20 [Radeon Instinct] + + pci:v00001002d000066A1* +- ID_MODEL_FROM_DATABASE=Vega 20 ++ ID_MODEL_FROM_DATABASE=Vega 20 WKS GL-XE [Radeon Pro VII] + + pci:v00001002d000066A2* + ID_MODEL_FROM_DATABASE=Vega 20 + + pci:v00001002d000066A3* +- ID_MODEL_FROM_DATABASE=Vega 20 ++ ID_MODEL_FROM_DATABASE=Vega 20 [Radeon Pro Vega II/Radeon Pro Vega II Duo] + + pci:v00001002d000066A7* +- ID_MODEL_FROM_DATABASE=Vega 20 ++ ID_MODEL_FROM_DATABASE=Vega 20 [Radeon Pro Vega 20] + + pci:v00001002d000066AF* +- ID_MODEL_FROM_DATABASE=Vega 20 ++ ID_MODEL_FROM_DATABASE=Vega 20 [Radeon VII] + + pci:v00001002d00006704* + ID_MODEL_FROM_DATABASE=Cayman PRO GL [FirePro V7900] +@@ -5631,7 +6591,7 @@ pci:v00001002d00006749* + ID_MODEL_FROM_DATABASE=Turks GL [FirePro V4900] + + pci:v00001002d00006749sv000015C3sd00002B06* +- ID_MODEL_FROM_DATABASE=Turks GL [FirePro V4900] (MED-X4900) ++ ID_MODEL_FROM_DATABASE=Turks GL [FirePro V4900] (MED-X4900 (EIZO)) + + pci:v00001002d0000674A* + ID_MODEL_FROM_DATABASE=Turks GL [FirePro V3900] +@@ -5718,61 +6678,79 @@ pci:v00001002d00006758sv00001787sd00002309* + ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670) + + pci:v00001002d00006759* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] + + pci:v00001002d00006759sv0000103Csd00003130* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001043sd00000403* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001462sd00002500* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001462sd00002509* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) + + pci:v00001002d00006759sv0000148Csd00007570* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) + + pci:v00001002d00006759sv00001642sd00003A67* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001682sd00003280* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) + + pci:v00001002d00006759sv00001682sd00003530* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 8550) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 8550) ++ ++pci:v00001002d00006759sv00001682sd00005230* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon R5 230 series) ++ ++pci:v00001002d00006759sv00001682sd00006450* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6450 series) + + pci:v00001002d00006759sv0000174Bsd00007570* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) ++ ++pci:v00001002d00006759sv0000174Bsd00008550* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD8550 OEM) ++ ++pci:v00001002d00006759sv0000174Bsd00008570* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD8550 OEM) + + pci:v00001002d00006759sv0000174Bsd0000E142* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv0000174Bsd0000E181* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) ++ ++pci:v00001002d00006759sv00001787sd0000A230* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon R5 230 series) ++ ++pci:v00001002d00006759sv00001787sd0000A450* ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6450 series) + + pci:v00001002d00006759sv00001B0Asd0000908F* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001B0Asd00009090* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001B0Asd00009091* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001B0Asd00009092* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001B0Asd0000909E* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 6570) + + pci:v00001002d00006759sv00001B0Asd000090B5* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) + + pci:v00001002d00006759sv00001B0Asd000090B6* +- ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570) ++ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550 / R5 230] (Radeon HD 7570) + + pci:v00001002d0000675B* + ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7600 Series] +@@ -6419,6 +7397,9 @@ pci:v00001002d00006779sv0000103Csd00002128* + pci:v00001002d00006779sv0000103Csd00002AEE* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450A) + ++pci:v00001002d00006779sv00001092sd00006450* ++ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450) ++ + pci:v00001002d00006779sv00001462sd00002125* + ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450) + +@@ -6812,6 +7793,9 @@ pci:v00001002d000067B1sv0000148Csd00002358* + pci:v00001002d000067B1sv0000174Bsd0000E324* + ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290/390] (Sapphire Nitro R9 390) + ++pci:v00001002d000067B8* ++ ID_MODEL_FROM_DATABASE=Hawaii XT [Radeon R9 290X Engineering Sample] ++ + pci:v00001002d000067B9* + ID_MODEL_FROM_DATABASE=Vesuvius [Radeon R9 295X2] + +@@ -6848,92 +7832,140 @@ pci:v00001002d000067CF* + pci:v00001002d000067D0* + ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro V7300X / V7350x2] + ++pci:v00001002d000067D7* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 5100 / Barco MXRT-6700] ++ + pci:v00001002d000067DF* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] + + pci:v00001002d000067DFsv00001002sd00000B37* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480) + + pci:v00001002d000067DFsv00001028sd00001722* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 570X) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570X) + + pci:v00001002d000067DFsv00001028sd00001723* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 580X) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580X) ++ ++pci:v00001002d000067DFsv0000103Csd0000840E* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580 4GB) + + pci:v00001002d000067DFsv00001043sd000004A8* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480) + + pci:v00001002d000067DFsv00001043sd000004B0* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) + + pci:v00001002d000067DFsv00001043sd000004FB* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480) + + pci:v00001002d000067DFsv00001043sd000004FD* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480 8GB) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480 8GB) ++ ++pci:v00001002d000067DFsv00001043sd0000056A* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 590) + + pci:v00001002d000067DFsv0000106Bsd00000161* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon Pro 580) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon Pro 580) + + pci:v00001002d000067DFsv0000106Bsd00000162* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon Pro 575) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon Pro 575) + + pci:v00001002d000067DFsv0000106Bsd00000163* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon Pro 570) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon Pro 570) + + pci:v00001002d000067DFsv00001458sd000022F0* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 570) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570) + + pci:v00001002d000067DFsv00001458sd000022F7* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 570 Gaming 4G) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 Gaming 4G) + + pci:v00001002d000067DFsv00001462sd00003411* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) + + pci:v00001002d000067DFsv00001462sd00003413* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480 Gaming X 8GB) + + pci:v00001002d000067DFsv00001462sd00003416* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 570) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570) + + pci:v00001002d000067DFsv00001462sd00003418* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 580 Armor 4G OC) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580 Armor 4G OC) ++ ++pci:v00001002d000067DFsv00001462sd0000341B* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 Armor 8G OC) ++ ++pci:v00001002d000067DFsv00001462sd0000341E* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 Armor 4G OC) ++ ++pci:v00001002d000067DFsv00001462sd0000809E* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480 4GB) ++ ++pci:v00001002d000067DFsv00001462sd00008A92* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580) + + pci:v00001002d000067DFsv0000148Csd00002372* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480 [Red Dragon]) + + pci:v00001002d000067DFsv0000148Csd00002373* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) ++ ++pci:v00001002d000067DFsv0000148Csd00002377* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Red Devil RX 580 8G Golden) ++ ++pci:v00001002d000067DFsv0000148Csd00002378* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580) ++ ++pci:v00001002d000067DFsv0000148Csd00002379* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 4G [Red Dragon]) ++ ++pci:v00001002d000067DFsv0000148Csd00002391* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 590 [Red Devil]) + + pci:v00001002d000067DFsv00001682sd00009470* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) + + pci:v00001002d000067DFsv00001682sd00009480* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480) ++ ++pci:v00001002d000067DFsv00001682sd00009587* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 590 FATBOY 8GB) + + pci:v00001002d000067DFsv00001682sd00009588* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 580 XTR) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580 XTR) ++ ++pci:v00001002d000067DFsv00001682sd0000C570* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570) ++ ++pci:v00001002d000067DFsv00001682sd0000C580* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 580) + + pci:v00001002d000067DFsv0000174Bsd0000E347* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470/480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470/480) + + pci:v00001002d000067DFsv0000174Bsd0000E349* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) + + pci:v00001002d000067DFsv00001787sd0000A470* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 470) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 470) + + pci:v00001002d000067DFsv00001787sd0000A480* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Radeon RX 480) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 480) + + pci:v00001002d000067DFsv00001849sd00005001* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Phantom Gaming X RX 580 OC) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Phantom Gaming X RX 580 OC) ++ ++pci:v00001002d000067DFsv00001849sd00005030* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Phantom Gaming D Radeon RX580 8G OC) + + pci:v00001002d000067DFsv00001DA2sd0000E353* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Sapphire Radeon RX 580 Pulse 8GB) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 Pulse 4GB) + + pci:v00001002d000067DFsv00001DA2sd0000E366* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X] (Nitro+ Radeon RX 580 4GB) ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Nitro+ Radeon RX 570/580/590) ++ ++pci:v00001002d000067DFsv00001DA2sd0000E387* ++ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (Radeon RX 570 Pulse 4GB) + + pci:v00001002d000067E0* + ID_MODEL_FROM_DATABASE=Baffin [Radeon Pro WX 4170] +@@ -6984,28 +8016,46 @@ pci:v00001002d000067EB* + ID_MODEL_FROM_DATABASE=Baffin [Radeon Pro V5300X] + + pci:v00001002d000067EF* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] ++ ++pci:v00001002d000067EFsv00001025sd00001367* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (RX560X 4GB) ++ ++pci:v00001002d000067EFsv00001028sd00001703* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (RX 560D OEM OC 2 GB) ++ ++pci:v00001002d000067EFsv0000103Csd00003421* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon RX 460) ++ ++pci:v00001002d000067EFsv00001043sd00000561* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (AREZ Radeon RX 560) + + pci:v00001002d000067EFsv0000106Bsd00000160* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Radeon Pro 460) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 460) + + pci:v00001002d000067EFsv0000106Bsd00000166* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Radeon Pro 455) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 455) + + pci:v00001002d000067EFsv0000106Bsd00000167* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Radeon Pro 450) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 450) + + pci:v00001002d000067EFsv0000106Bsd00000179* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Radeon Pro 560) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 560) + + pci:v00001002d000067EFsv0000106Bsd0000017A* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Radeon Pro 555) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 555) ++ ++pci:v00001002d000067EFsv0000106Bsd0000018F* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 560X) ++ ++pci:v00001002d000067EFsv0000106Bsd00000190* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Radeon Pro 555X) + + pci:v00001002d000067EFsv00001642sd00001727* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Polaris 21 XL [Radeon RX 560D]) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Polaris 21 XL [Radeon RX 560D]) + + pci:v00001002d000067EFsv00001682sd0000956D* +- ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/560] (Polaris 21 XL [Radeon RX 560D]) ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460/560D / Pro 450/455/460/555/555X/560/560X] (Polaris 21 XL [Radeon RX 560D]) + + pci:v00001002d000067FF* + ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 550 640SP / RX 560/560X] +@@ -7025,6 +8075,9 @@ pci:v00001002d000067FFsv0000103Csd00008479* + pci:v00001002d000067FFsv00001043sd000004BC* + ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 550 640SP / RX 560/560X] (Radeon RX 560) + ++pci:v00001002d000067FFsv00001043sd0000052F* ++ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 550 640SP / RX 560/560X] (Radeon RX 560) ++ + pci:v00001002d000067FFsv00001458sd000022ED* + ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 550 640SP / RX 560/560X] (Radeon RX 560) + +@@ -7199,6 +8252,9 @@ pci:v00001002d00006820sv000017AAsd00003801* + pci:v00001002d00006820sv000017AAsd00003824* + ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M / R9 M275X/M375X] (Radeon R9 M375) + ++pci:v00001002d00006820sv00001DA2sd0000E26A* ++ ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M / R9 M275X/M375X] (Radeon R7 250) ++ + pci:v00001002d00006821* + ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M / R9 M270X/M370X] + +@@ -7257,10 +8313,13 @@ pci:v00001002d0000682A* + ID_MODEL_FROM_DATABASE=Venus PRO + + pci:v00001002d0000682B* +- ID_MODEL_FROM_DATABASE=Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 M465X] ++ ID_MODEL_FROM_DATABASE=Cape Verde PRO / Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 250 / R7 M465X] + + pci:v00001002d0000682Bsv00000128sd0000079C* +- ID_MODEL_FROM_DATABASE=Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 M465X] (Radeon R7 465X) ++ ID_MODEL_FROM_DATABASE=Cape Verde PRO / Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 250 / R7 M465X] (Radeon R7 465X) ++ ++pci:v00001002d0000682Bsv00001462sd00003012* ++ ID_MODEL_FROM_DATABASE=Cape Verde PRO / Venus LE / Tropo PRO-L [Radeon HD 8830M / R7 250 / R7 M465X] (Radeon R7 250) + + pci:v00001002d0000682C* + ID_MODEL_FROM_DATABASE=Cape Verde GL [FirePro W4100] +@@ -7658,6 +8717,12 @@ pci:v00001002d00006843* + pci:v00001002d00006860* + ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25] + ++pci:v00001002d00006860sv00001002sd00000C35* ++ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25] (Radeon PRO V320) ++ ++pci:v00001002d00006860sv00001002sd00006C75* ++ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25] (Radeon PRO V320) ++ + pci:v00001002d00006860sv0000106Bsd0000017C* + ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25] (Radeon Pro Vega 64) + +@@ -7671,19 +8736,52 @@ pci:v00001002d00006863* + ID_MODEL_FROM_DATABASE=Vega 10 XTX [Radeon Vega Frontier Edition] + + pci:v00001002d00006864* +- ID_MODEL_FROM_DATABASE=Vega ++ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Pro V340] + + pci:v00001002d00006867* + ID_MODEL_FROM_DATABASE=Vega 10 XL [Radeon Pro Vega 56] + + pci:v00001002d00006868* +- ID_MODEL_FROM_DATABASE=Vega ++ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon PRO WX 8100/8200] ++ ++pci:v00001002d00006869* ++ ID_MODEL_FROM_DATABASE=Vega 10 XGA [Radeon Pro Vega 48] ++ ++pci:v00001002d0000686A* ++ ID_MODEL_FROM_DATABASE=Vega 10 LEA ++ ++pci:v00001002d0000686B* ++ ID_MODEL_FROM_DATABASE=Vega 10 XTXA [Radeon Pro Vega 64X] + + pci:v00001002d0000686C* + ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Instinct MI25 MxGPU] + ++pci:v00001002d0000686D* ++ ID_MODEL_FROM_DATABASE=Vega 10 GLXTA ++ ++pci:v00001002d0000686E* ++ ID_MODEL_FROM_DATABASE=Vega 10 GLXLA ++ + pci:v00001002d0000687F* +- ID_MODEL_FROM_DATABASE=Vega 10 XT [Radeon RX Vega 64] ++ ID_MODEL_FROM_DATABASE=Vega 10 XL/XT [Radeon RX Vega 56/64] ++ ++pci:v00001002d0000687Fsv00001002sd00000B36* ++ ID_MODEL_FROM_DATABASE=Vega 10 XL/XT [Radeon RX Vega 56/64] (RX Vega64) ++ ++pci:v00001002d0000687Fsv00001002sd00006B76* ++ ID_MODEL_FROM_DATABASE=Vega 10 XL/XT [Radeon RX Vega 56/64] (RX Vega64) ++ ++pci:v00001002d0000687Fsv00001458sd0000230C* ++ ID_MODEL_FROM_DATABASE=Vega 10 XL/XT [Radeon RX Vega 56/64] (Radeon RX VEGA 56 GAMING OC 8G) ++ ++pci:v00001002d0000687Fsv00001DA2sd0000E376* ++ ID_MODEL_FROM_DATABASE=Vega 10 XL/XT [Radeon RX Vega 56/64] (Radeon RX VEGA 56 Pulse 8GB OC HBM2) ++ ++pci:v00001002d00006880* ++ ID_MODEL_FROM_DATABASE=Lexington [Radeon HD 6550M] ++ ++pci:v00001002d00006880sv0000103Csd0000163C* ++ ID_MODEL_FROM_DATABASE=Lexington [Radeon HD 6550M] (Pavilion dv6 Radeon HD 6550M) + + pci:v00001002d00006888* + ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V8800] +@@ -8408,6 +9506,9 @@ pci:v00001002d000068D9sv000017AFsd00003010* + pci:v00001002d000068DA* + ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] + ++pci:v00001002d000068DAsv00001462sd00008071* ++ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (VR5550-MD1G (Radeon HD 5550)) ++ + pci:v00001002d000068DAsv0000148Csd00003000* + ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6390) + +@@ -9075,85 +10176,88 @@ pci:v00001002d000068FE* + ID_MODEL_FROM_DATABASE=Cedar LE + + pci:v00001002d00006900* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] + + pci:v00001002d00006900sv00001025sd00001056* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360 / R8 M365DX) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360 / R8 M365DX) + + pci:v00001002d00006900sv00001028sd00000640* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260/M265) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260/M265) + + pci:v00001002d00006900sv00001028sd00000643* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260/M265) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260/M265) + + pci:v00001002d00006900sv00001028sd0000067F* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv00001028sd00000767* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M445) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M445) ++ ++pci:v00001002d00006900sv00001028sd00000810* ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon 530) + + pci:v00001002d00006900sv00001028sd0000130A* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd00002263* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd00002269* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd000022C6* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd000022C8* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd00002B45* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 A360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 A360) + + pci:v00001002d00006900sv0000103Csd0000808C* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv0000103Csd00008099* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv0000103Csd000080B5* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv0000103Csd000080B9* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv0000103Csd0000811C* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M340) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M340) + + pci:v00001002d00006900sv0000103Csd00008226* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M440) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M440) + + pci:v00001002d00006900sv000010CFsd00001906* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv00001170sd00009979* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv00001179sd0000F903* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv00001179sd0000F922* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv00001179sd0000F923* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv00001179sd0000F934* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006900sv000017AAsd00003822* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv000017AAsd00003824* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M360) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M360) + + pci:v00001002d00006900sv000017AAsd00005021* +- ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (Radeon R7 M260) ++ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445 / 530/535 / 620/625 Mobile] (Radeon R7 M260) + + pci:v00001002d00006901* + ID_MODEL_FROM_DATABASE=Topaz PRO [Radeon R5 M255] +@@ -9164,8 +10268,11 @@ pci:v00001002d00006901sv0000103Csd00001318* + pci:v00001002d00006907* + ID_MODEL_FROM_DATABASE=Meso XT [Radeon R5 M315] + ++pci:v00001002d00006920* ++ ID_MODEL_FROM_DATABASE=Amethyst [Radeon R9 M395/ M395X Mac Edition] ++ + pci:v00001002d00006921* +- ID_MODEL_FROM_DATABASE=Amethyst XT [Radeon R9 M295X] ++ ID_MODEL_FROM_DATABASE=Amethyst XT [Radeon R9 M295X / M390X] + + pci:v00001002d00006929* + ID_MODEL_FROM_DATABASE=Tonga XT GL [FirePro S7150] +@@ -9209,23 +10316,35 @@ pci:v00001002d00006938sv000017AFsd00002006* + pci:v00001002d00006939* + ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] + ++pci:v00001002d00006939sv00001462sd00002015* ++ ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 380 Gaming 4G) ++ + pci:v00001002d00006939sv0000148Csd00009380* + ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 380) + + pci:v00001002d00006939sv0000174Bsd0000E308* + ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 380 Nitro 4G D5) + ++pci:v00001002d00006939sv0000174Bsd0000E315* ++ ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 285) ++ ++pci:v00001002d0000693B* ++ ID_MODEL_FROM_DATABASE=Tonga PRO GL [FirePro W7100 / Barco MXRT-7600] ++ + pci:v00001002d0000694C* +- ID_MODEL_FROM_DATABASE=Polaris 22 [Radeon RX Vega M GH] ++ ID_MODEL_FROM_DATABASE=Polaris 22 XT [Radeon RX Vega M GH] + + pci:v00001002d0000694E* +- ID_MODEL_FROM_DATABASE=Polaris 22 [Radeon RX Vega M GL] ++ ID_MODEL_FROM_DATABASE=Polaris 22 XL [Radeon RX Vega M GL] ++ ++pci:v00001002d0000694F* ++ ID_MODEL_FROM_DATABASE=Polaris 22 MGL XL [Radeon Pro WX Vega M GL] + + pci:v00001002d00006980* + ID_MODEL_FROM_DATABASE=Polaris12 + + pci:v00001002d00006981* +- ID_MODEL_FROM_DATABASE=Polaris12 ++ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 3200] + + pci:v00001002d00006985* + ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 3100] +@@ -9234,22 +10353,25 @@ pci:v00001002d00006986* + ID_MODEL_FROM_DATABASE=Polaris12 + + pci:v00001002d00006987* +- ID_MODEL_FROM_DATABASE=Lexa [Radeon E9171 MCM] ++ ID_MODEL_FROM_DATABASE=Lexa [Radeon 540X/550X/630 / RX 640 / E9171 MCM] ++ ++pci:v00001002d0000698F* ++ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 3100 / Barco MXRT 4700] + + pci:v00001002d00006995* + ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 2100] + + pci:v00001002d0000699F* +- ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550/550X] ++ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] + + pci:v00001002d0000699Fsv00001028sd00001720* +- ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550/550X] (Radeon RX 550X) ++ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] (Radeon RX 550X) + + pci:v00001002d0000699Fsv0000148Csd00002380* +- ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550/550X] (Lexa XL [Radeon RX 550]) ++ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] (Lexa XL [Radeon RX 550]) + + pci:v00001002d0000699Fsv00001DA2sd0000E367* +- ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550/550X] (Lexa PRO [Radeon RX 550]) ++ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] (Lexa PRO [Radeon RX 550]) + + pci:v00001002d000069A0* + ID_MODEL_FROM_DATABASE=Vega 12 +@@ -9264,7 +10386,10 @@ pci:v00001002d000069A3* + ID_MODEL_FROM_DATABASE=Vega 12 + + pci:v00001002d000069AF* +- ID_MODEL_FROM_DATABASE=Vega 12 ++ ID_MODEL_FROM_DATABASE=Vega 12 [Radeon Pro Vega 20] ++ ++pci:v00001002d00006FDF* ++ ID_MODEL_FROM_DATABASE=Polaris 20 XL [Radeon RX 580 2048SP] + + pci:v00001002d0000700F* + ID_MODEL_FROM_DATABASE=RS100 AGP Bridge +@@ -9282,10 +10407,10 @@ pci:v00001002d00007102* + ID_MODEL_FROM_DATABASE=R520/M58 [Mobility Radeon X1800] + + pci:v00001002d00007104* +- ID_MODEL_FROM_DATABASE=R520 GL [FireGL V7200] ++ ID_MODEL_FROM_DATABASE=R520 GL [FireGL V7200 / Barco MXTR-5100] + + pci:v00001002d00007104sv000013CCsd00003D0A* +- ID_MODEL_FROM_DATABASE=R520 GL [FireGL V7200] (MXRT-5100) ++ ID_MODEL_FROM_DATABASE=R520 GL [FireGL V7200 / Barco MXTR-5100] (MXRT-5100) + + pci:v00001002d00007109* + ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 XL] +@@ -9512,6 +10637,9 @@ pci:v00001002d000071C1sv0000174Bsd00000880* + pci:v00001002d000071C2* + ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 PRO] + ++pci:v00001002d000071C3* ++ ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 PRO] ++ + pci:v00001002d000071C4* + ID_MODEL_FROM_DATABASE=RV530/M56 GL [Mobility FireGL V5200] + +@@ -9692,6 +10820,102 @@ pci:v00001002d00007300sv00001043sd000004A0* + pci:v00001002d00007300sv0000174Bsd0000E329* + ID_MODEL_FROM_DATABASE=Fiji [Radeon R9 FURY / NANO Series] (Radeon R9 FURY) + ++pci:v00001002d00007310* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon Pro W5700X] ++ ++pci:v00001002d00007312* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon Pro W5700] ++ ++pci:v00001002d00007314* ++ ID_MODEL_FROM_DATABASE=Navi 10 USB ++ ++pci:v00001002d0000731F* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] ++ ++pci:v00001002d0000731Fsv00001458sd00002313* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] (Radeon RX 5700 XT Gaming OC) ++ ++pci:v00001002d0000731Fsv00001682sd00005701* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] (RX 5700 XT RAW II) ++ ++pci:v00001002d0000731Fsv00001849sd00005120* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] (Radeon RX 5600 XT) ++ ++pci:v00001002d0000731Fsv00001DA2sd0000E411* ++ ID_MODEL_FROM_DATABASE=Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] (Radeon RX 5600 XT) ++ ++pci:v00001002d00007340* ++ ID_MODEL_FROM_DATABASE=Navi 14 [Radeon RX 5500/5500M / Pro 5500M] ++ ++pci:v00001002d00007341* ++ ID_MODEL_FROM_DATABASE=Navi 14 [Radeon Pro W5500] ++ ++pci:v00001002d00007347* ++ ID_MODEL_FROM_DATABASE=Navi 14 [Radeon Pro W5500M] ++ ++pci:v00001002d0000734F* ++ ID_MODEL_FROM_DATABASE=Navi 14 [Radeon Pro W5300M] ++ ++pci:v00001002d00007360* ++ ID_MODEL_FROM_DATABASE=Navi 12 [Radeon Pro 5600M / V520] ++ ++pci:v00001002d00007362* ++ ID_MODEL_FROM_DATABASE=Navi 12 [Radeon Pro V520] ++ ++pci:v00001002d00007388* ++ ID_MODEL_FROM_DATABASE=Arcturus GL-XL ++ ++pci:v00001002d0000738C* ++ ID_MODEL_FROM_DATABASE=Arcturus GL-XL [AMD Instinct MI100] ++ ++pci:v00001002d0000738E* ++ ID_MODEL_FROM_DATABASE=Arcturus GL-XL ++ ++pci:v00001002d000073A3* ++ ID_MODEL_FROM_DATABASE=Navi 21 [Radeon PRO W6800] ++ ++pci:v00001002d000073A4* ++ ID_MODEL_FROM_DATABASE=Navi 21 USB ++ ++pci:v00001002d000073AF* ++ ID_MODEL_FROM_DATABASE=Navi 21 [Radeon RX 6900 XT] ++ ++pci:v00001002d000073BF* ++ ID_MODEL_FROM_DATABASE=Navi 21 [Radeon RX 6800/6800 XT / 6900 XT] ++ ++pci:v00001002d000073BFsv00001EAEsd00006701* ++ ID_MODEL_FROM_DATABASE=Navi 21 [Radeon RX 6800/6800 XT / 6900 XT] (XFX Speedster MERC 319 AMD Radeon RX 6800 XT Black) ++ ++pci:v00001002d000073C3* ++ ID_MODEL_FROM_DATABASE=Navi 22 ++ ++pci:v00001002d000073C4* ++ ID_MODEL_FROM_DATABASE=Navi 22 USB ++ ++pci:v00001002d000073DF* ++ ID_MODEL_FROM_DATABASE=Navi 22 [Radeon RX 6700/6700 XT / 6800M] ++ ++pci:v00001002d000073E0* ++ ID_MODEL_FROM_DATABASE=Navi 23 ++ ++pci:v00001002d000073E1* ++ ID_MODEL_FROM_DATABASE=Navi 23 ++ ++pci:v00001002d000073E4* ++ ID_MODEL_FROM_DATABASE=Navi 23 USB ++ ++pci:v00001002d000073FF* ++ ID_MODEL_FROM_DATABASE=Navi 23 [Radeon RX 6600/6600 XT/6600M] ++ ++pci:v00001002d00007408* ++ ID_MODEL_FROM_DATABASE=Aldebaran ++ ++pci:v00001002d0000740C* ++ ID_MODEL_FROM_DATABASE=Aldebaran ++ ++pci:v00001002d0000740F* ++ ID_MODEL_FROM_DATABASE=Aldebaran ++ + pci:v00001002d00007833* + ID_MODEL_FROM_DATABASE=RS350 Host Bridge + +@@ -10158,7 +11382,7 @@ pci:v00001002d00009555sv0000103Csd00001411* + ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4350/4550] (ProBook 4720s GPU (Mobility Radeon HD 4350)) + + pci:v00001002d00009557* +- ID_MODEL_FROM_DATABASE=RV711 GL [FirePro RG220] ++ ID_MODEL_FROM_DATABASE=RV711/M93 GL [FirePro RG220] + + pci:v00001002d0000955F* + ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330] +@@ -10262,6 +11486,9 @@ pci:v00001002d000095C0* + pci:v00001002d000095C0sv00001002sd000095C0* + ID_MODEL_FROM_DATABASE=RV620 PRO [Radeon HD 3470] (Mobility Radeon HD 3470) + ++pci:v00001002d000095C0sv00001028sd00003243* ++ ID_MODEL_FROM_DATABASE=RV620 PRO [Radeon HD 3470] (C120D) ++ + pci:v00001002d000095C2* + ID_MODEL_FROM_DATABASE=RV620/M82 [Mobility Radeon HD 3410/3430] + +@@ -10295,6 +11522,9 @@ pci:v00001002d000095CF* + pci:v00001002d0000960F* + ID_MODEL_FROM_DATABASE=RS780 HDMI Audio [Radeon 3000/3100 / HD 3200/3300] + ++pci:v00001002d0000960Fsv00001462sd00007596* ++ ID_MODEL_FROM_DATABASE=RS780 HDMI Audio [Radeon 3000/3100 / HD 3200/3300] (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00009610* + ID_MODEL_FROM_DATABASE=RS780 [Radeon HD 3200] + +@@ -10313,38 +11543,44 @@ pci:v00001002d00009613* + pci:v00001002d00009614* + ID_MODEL_FROM_DATABASE=RS780D [Radeon HD 3300] + ++pci:v00001002d00009615* ++ ID_MODEL_FROM_DATABASE=RS780E [Radeon HD 3200] ++ + pci:v00001002d00009616* + ID_MODEL_FROM_DATABASE=RS780L [Radeon 3000] + ++pci:v00001002d00009616sv00001462sd00007501* ++ ID_MODEL_FROM_DATABASE=RS780L [Radeon 3000] (760GM-E51(MS-7596) Motherboard) ++ + pci:v00001002d00009640* +- ID_MODEL_FROM_DATABASE=BeaverCreek [Radeon HD 6550D] ++ ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6550D] + + pci:v00001002d00009641* +- ID_MODEL_FROM_DATABASE=BeaverCreek [Radeon HD 6620G] ++ ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6620G] + + pci:v00001002d00009642* +- ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6370D] ++ ID_MODEL_FROM_DATABASE=SuperSumo [Radeon HD 6370D] + + pci:v00001002d00009643* +- ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6380G] ++ ID_MODEL_FROM_DATABASE=SuperSumo [Radeon HD 6380G] + + pci:v00001002d00009644* +- ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6410D] ++ ID_MODEL_FROM_DATABASE=SuperSumo [Radeon HD 6410D] + + pci:v00001002d00009645* +- ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6410D] ++ ID_MODEL_FROM_DATABASE=SuperSumo [Radeon HD 6410D] + + pci:v00001002d00009647* +- ID_MODEL_FROM_DATABASE=BeaverCreek [Radeon HD 6520G] ++ ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6520G] + + pci:v00001002d00009648* + ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6480G] + + pci:v00001002d00009649* +- ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6480G] ++ ID_MODEL_FROM_DATABASE=SuperSumo [Radeon HD 6480G] + + pci:v00001002d0000964A* +- ID_MODEL_FROM_DATABASE=BeaverCreek [Radeon HD 6530D] ++ ID_MODEL_FROM_DATABASE=Sumo [Radeon HD 6530D] + + pci:v00001002d0000964B* + ID_MODEL_FROM_DATABASE=Sumo +@@ -10382,6 +11618,9 @@ pci:v00001002d00009710sv00001043sd000083A2* + pci:v00001002d00009712* + ID_MODEL_FROM_DATABASE=RS880M [Mobility Radeon HD 4225/4250] + ++pci:v00001002d00009712sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=RS880M [Mobility Radeon HD 4225/4250] (ProLiant MicroServer N36L) ++ + pci:v00001002d00009713* + ID_MODEL_FROM_DATABASE=RS880M [Mobility Radeon HD 4100] + +@@ -10427,12 +11666,18 @@ pci:v00001002d0000980A* + pci:v00001002d00009830* + ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400 / R3 Series] + ++pci:v00001002d00009830sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400 / R3 Series] (AM1I-A Motherboard) ++ + pci:v00001002d00009831* + ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400E] + + pci:v00001002d00009832* + ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8330] + ++pci:v00001002d00009832sv00001849sd00009832* ++ ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8330] (QC5000-ITX/PH) ++ + pci:v00001002d00009833* + ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8330E] + +@@ -10460,6 +11705,12 @@ pci:v00001002d0000983D* + pci:v00001002d00009840* + ID_MODEL_FROM_DATABASE=Kabini HDMI/DP Audio + ++pci:v00001002d00009840sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=Kabini HDMI/DP Audio (AM1I-A Motherboard) ++ ++pci:v00001002d00009840sv00001849sd00009840* ++ ID_MODEL_FROM_DATABASE=Kabini HDMI/DP Audio (QC5000-ITX/PH) ++ + pci:v00001002d00009850* + ID_MODEL_FROM_DATABASE=Mullins [Radeon R3 Graphics] + +@@ -10550,6 +11801,12 @@ pci:v00001002d00009874sv000017AAsd00005116* + pci:v00001002d00009874sv000017AAsd00005118* + ID_MODEL_FROM_DATABASE=Wani [Radeon R5/R6/R7 Graphics] (Radeon R5 Graphics) + ++pci:v00001002d00009890* ++ ID_MODEL_FROM_DATABASE=Amur ++ ++pci:v00001002d000098C0* ++ ID_MODEL_FROM_DATABASE=Nolan ++ + pci:v00001002d000098E4* + ID_MODEL_FROM_DATABASE=Stoney [Radeon R2/R3/R4/R5 Graphics] + +@@ -10631,26 +11888,44 @@ pci:v00001002d00009918* + pci:v00001002d00009919* + ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7500G] + ++pci:v00001002d0000991E* ++ ID_MODEL_FROM_DATABASE=Bishop [Xbox One S APU] ++ + pci:v00001002d00009920* + ID_MODEL_FROM_DATABASE=Liverpool [Playstation 4 APU] + + pci:v00001002d00009921* + ID_MODEL_FROM_DATABASE=Liverpool HDMI/DP Audio Controller + ++pci:v00001002d00009922* ++ ID_MODEL_FROM_DATABASE=Starshp ++ ++pci:v00001002d00009923* ++ ID_MODEL_FROM_DATABASE=Starsha2 [Kingston/Clayton] ++ ++pci:v00001002d00009924* ++ ID_MODEL_FROM_DATABASE=Gladius ++ ++pci:v00001002d00009925* ++ ID_MODEL_FROM_DATABASE=Kingston/Clayton/Jupiter/Gladius/Montego HDMI Controller ++ ++pci:v00001002d00009926* ++ ID_MODEL_FROM_DATABASE=Jupiter ++ + pci:v00001002d00009990* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7520G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7520G] + + pci:v00001002d00009991* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7540D] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7540D] + + pci:v00001002d00009992* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7420G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7420G] + + pci:v00001002d00009993* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7480D] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7480D] + + pci:v00001002d00009994* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7400G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7400G] + + pci:v00001002d00009995* + ID_MODEL_FROM_DATABASE=Richland [Radeon HD 8450G] +@@ -10674,19 +11949,19 @@ pci:v00001002d0000999B* + ID_MODEL_FROM_DATABASE=Richland [Radeon HD 8310G] + + pci:v00001002d0000999C* +- ID_MODEL_FROM_DATABASE=Richland ++ ID_MODEL_FROM_DATABASE=Richland [Radeon HD 8650D] + + pci:v00001002d0000999D* + ID_MODEL_FROM_DATABASE=Richland [Radeon HD 8550D] + + pci:v00001002d000099A0* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7520G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7520G] + + pci:v00001002d000099A2* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7420G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7420G] + + pci:v00001002d000099A4* +- ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7400G] ++ ID_MODEL_FROM_DATABASE=Trinity 2 [Radeon HD 7400G] + + pci:v00001002d0000AA00* + ID_MODEL_FROM_DATABASE=R600 HDMI Audio [Radeon HD 2900 GT/PRO/XT] +@@ -10770,11 +12045,17 @@ pci:v00001002d0000AAA0* + ID_MODEL_FROM_DATABASE=Tahiti HDMI Audio [Radeon HD 7870 XT / 7950/7970] + + pci:v00001002d0000AAB0* +- ID_MODEL_FROM_DATABASE=Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series] ++ ID_MODEL_FROM_DATABASE=Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] ++ ++pci:v00001002d0000AAB8* ++ ID_MODEL_FROM_DATABASE=Tiran HDMI Audio + + pci:v00001002d0000AAC0* + ID_MODEL_FROM_DATABASE=Tobago HDMI Audio [Radeon R7 360 / R9 360 OEM] + ++pci:v00001002d0000AAC0sv00001043sd0000AAC0* ++ ID_MODEL_FROM_DATABASE=Tobago HDMI Audio [Radeon R7 360 / R9 360 OEM] (R7260X-DC2OC-2GD5) ++ + pci:v00001002d0000AAC8* + ID_MODEL_FROM_DATABASE=Hawaii HDMI Audio [Radeon R9 290/290X / 390/390X] + +@@ -10784,18 +12065,87 @@ pci:v00001002d0000AAD8* + pci:v00001002d0000AAD8sv0000174Bsd0000AAD8* + ID_MODEL_FROM_DATABASE=Tonga HDMI Audio [Radeon R9 285/380] (Radeon R9 285/380 HDMI Audio) + ++pci:v00001002d0000AAE0* ++ ID_MODEL_FROM_DATABASE=Baffin HDMI/DP Audio [Radeon RX 550 640SP / RX 560/560X] ++ + pci:v00001002d0000AAE8* + ID_MODEL_FROM_DATABASE=Fiji HDMI/DP Audio [Radeon R9 Nano / FURY/FURY X] + + pci:v00001002d0000AAF0* +- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 580] ++ ID_MODEL_FROM_DATABASE=Ellesmere HDMI Audio [Radeon RX 470/480 / 570/580/590] ++ ++pci:v00001002d0000AAF8* ++ ID_MODEL_FROM_DATABASE=Vega 10 HDMI Audio [Radeon Vega 56/64] ++ ++pci:v00001002d0000AB00* ++ ID_MODEL_FROM_DATABASE=Baffin HDMI/DP Audio [Radeon RX 550 640SP / RX 560/560X] ++ ++pci:v00001002d0000AB08* ++ ID_MODEL_FROM_DATABASE=Polaris 22 HDMI Audio ++ ++pci:v00001002d0000AB10* ++ ID_MODEL_FROM_DATABASE=Lexa HDMI Audio ++ ++pci:v00001002d0000AB18* ++ ID_MODEL_FROM_DATABASE=Vega 12 HDMI Audio ++ ++pci:v00001002d0000AB20* ++ ID_MODEL_FROM_DATABASE=Vega 20 HDMI Audio [Radeon VII] ++ ++pci:v00001002d0000AB28* ++ ID_MODEL_FROM_DATABASE=Navi 21 HDMI Audio [Radeon RX 6800/6800 XT / 6900 XT] ++ ++pci:v00001002d0000AB38* ++ ID_MODEL_FROM_DATABASE=Navi 10 HDMI Audio + + pci:v00001002d0000AC00* +- ID_MODEL_FROM_DATABASE=Theater 600 Pro ++ ID_MODEL_FROM_DATABASE=Theater 506 World-Wide Analog Decoder ++ ++pci:v00001002d0000AC01* ++ ID_MODEL_FROM_DATABASE=Theater 506 World-Wide Analog Decoder + + pci:v00001002d0000AC02* + ID_MODEL_FROM_DATABASE=TV Wonder HD 600 PCIe + ++pci:v00001002d0000AC03* ++ ID_MODEL_FROM_DATABASE=Theater 506 PCIe ++ ++pci:v00001002d0000AC04* ++ ID_MODEL_FROM_DATABASE=Theater 506 USB ++ ++pci:v00001002d0000AC05* ++ ID_MODEL_FROM_DATABASE=Theater 506 USB ++ ++pci:v00001002d0000AC06* ++ ID_MODEL_FROM_DATABASE=Theater 506 External USB ++ ++pci:v00001002d0000AC07* ++ ID_MODEL_FROM_DATABASE=Theater 506 External USB ++ ++pci:v00001002d0000AC08* ++ ID_MODEL_FROM_DATABASE=Theater 506A World-Wide Analog Decoder + Demodulator ++ ++pci:v00001002d0000AC09* ++ ID_MODEL_FROM_DATABASE=Theater 506A World-Wide Analog Decoder + Demodulator ++ ++pci:v00001002d0000AC0A* ++ ID_MODEL_FROM_DATABASE=Theater 506A PCIe ++ ++pci:v00001002d0000AC0B* ++ ID_MODEL_FROM_DATABASE=Theater 506A PCIe ++ ++pci:v00001002d0000AC0C* ++ ID_MODEL_FROM_DATABASE=Theater 506A USB ++ ++pci:v00001002d0000AC0D* ++ ID_MODEL_FROM_DATABASE=Theater 506A USB ++ ++pci:v00001002d0000AC0E* ++ ID_MODEL_FROM_DATABASE=Theater 506A External USB ++ ++pci:v00001002d0000AC0F* ++ ID_MODEL_FROM_DATABASE=Theater 506A External USB ++ + pci:v00001002d0000AC12* + ID_MODEL_FROM_DATABASE=Theater HD T507 (DVB-T) TV tuner/capture device + +@@ -11196,13 +12546,13 @@ pci:v00001011d0000000D* + ID_MODEL_FROM_DATABASE=PBXGB [TGA2] + + pci:v00001011d0000000F* +- ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI] ++ ID_MODEL_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI] FDDI (DEFPA) + + pci:v00001011d0000000Fsv00001011sd0000DEF1* +- ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI] (FDDI controller (DEFPA)) ++ ID_MODEL_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI] FDDI (DEFPA) (FDDIcontroller/PCI (DEFPA)) + + pci:v00001011d0000000Fsv0000103Csd0000DEF1* +- ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI] (FDDI controller (3X-DEFPA)) ++ ID_MODEL_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI] FDDI (DEFPA) (FDDIcontroller/PCI (3X-DEFPA)) + + pci:v00001011d00000014* + ID_MODEL_FROM_DATABASE=DECchip 21041 [Tulip Pass 3] +@@ -11211,7 +12561,7 @@ pci:v00001011d00000014sv00001186sd00000100* + ID_MODEL_FROM_DATABASE=DECchip 21041 [Tulip Pass 3] (DE-530+) + + pci:v00001011d00000016* +- ID_MODEL_FROM_DATABASE=DGLPB [OPPO] ++ ID_MODEL_FROM_DATABASE=ATMworks 350 Adapter [OPPO] (DGLPB) + + pci:v00001011d00000017* + ID_MODEL_FROM_DATABASE=PV-PCI Graphics Controller (ZLXp-L) +@@ -12050,6 +13400,9 @@ pci:v00001014d0000044B* + pci:v00001014d000004AA* + ID_MODEL_FROM_DATABASE=Flash Adapter 90 (PCIe2 0.9TB) + ++pci:v00001014d000004C1* ++ ID_MODEL_FROM_DATABASE=POWER9 Host Bridge (PHB4) ++ + pci:v00001014d000004DA* + ID_MODEL_FROM_DATABASE=PCI-E IPR SAS+ Adapter (ASIC) + +@@ -12317,6 +13670,93 @@ pci:v00001022d00001303* + pci:v00001022d00001304* + ID_MODEL_FROM_DATABASE=Family 11h Processor Link Control + ++pci:v00001022d00001305* ++ ID_MODEL_FROM_DATABASE=Griffin Function 5 ++ ++pci:v00001022d00001306* ++ ID_MODEL_FROM_DATABASE=Griffin Function 6 ++ ++pci:v00001022d00001307* ++ ID_MODEL_FROM_DATABASE=Griffin Function 7 ++ ++pci:v00001022d00001308* ++ ID_MODEL_FROM_DATABASE=Kaveri Audio Controller ++ ++pci:v00001022d00001314* ++ ID_MODEL_FROM_DATABASE=Wrestler/Bheem/Ontario/Krishna Audio Controller ++ ++pci:v00001022d000013E0* ++ ID_MODEL_FROM_DATABASE=Ariel Root Complex ++ ++pci:v00001022d000013E1* ++ ID_MODEL_FROM_DATABASE=Ariel IOMMU ++ ++pci:v00001022d000013E2* ++ ID_MODEL_FROM_DATABASE=Ariel PCIe Dummy Host Bridge ++ ++pci:v00001022d000013E3* ++ ID_MODEL_FROM_DATABASE=Ariel PCIe GPP Bridge ++ ++pci:v00001022d000013E4* ++ ID_MODEL_FROM_DATABASE=Ariel PCIe Dummy Host Bridge ++ ++pci:v00001022d000013E5* ++ ID_MODEL_FROM_DATABASE=Ariel Internal PCIe GPP Bridge 0 to Bus A ++ ++pci:v00001022d000013E6* ++ ID_MODEL_FROM_DATABASE=Ariel Internal PCIe GPP Bridge 0 to Bus B ++ ++pci:v00001022d000013E7* ++ ID_MODEL_FROM_DATABASE=Ariel SMBus Controller ++ ++pci:v00001022d000013E8* ++ ID_MODEL_FROM_DATABASE=Ariel LPC Bridge ++ ++pci:v00001022d000013E9* ++ ID_MODEL_FROM_DATABASE=Ariel Internal GPU ++ ++pci:v00001022d000013EA* ++ ID_MODEL_FROM_DATABASE=Ariel HD Audio Controller ++ ++pci:v00001022d000013EB* ++ ID_MODEL_FROM_DATABASE=Ariel HD Audio Coprocessor ++ ++pci:v00001022d000013EC* ++ ID_MODEL_FROM_DATABASE=Ariel Cryptographic Coprocessor ++ ++pci:v00001022d000013ED* ++ ID_MODEL_FROM_DATABASE=Ariel USB 3.1 Type C: Gen2 x 1port + DP Alt Mode ++ ++pci:v00001022d000013EE* ++ ID_MODEL_FROM_DATABASE=Ariel USB 3.1 Type A: Gen2 x 2 ports ++ ++pci:v00001022d000013EF* ++ ID_MODEL_FROM_DATABASE=Ariel ZCN/MP4 ++ ++pci:v00001022d000013F0* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 0 ++ ++pci:v00001022d000013F1* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 1 ++ ++pci:v00001022d000013F2* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 2 ++ ++pci:v00001022d000013F3* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 3 ++ ++pci:v00001022d000013F4* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 4 ++ ++pci:v00001022d000013F5* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 5 ++ ++pci:v00001022d000013F6* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 6 ++ ++pci:v00001022d000013F7* ++ ID_MODEL_FROM_DATABASE=Ariel Device 24: Function 7 ++ + pci:v00001022d00001400* + ID_MODEL_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 0 + +@@ -12398,23 +13838,32 @@ pci:v00001022d00001423* + pci:v00001022d00001424* + ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port + ++pci:v00001022d00001425* ++ ID_MODEL_FROM_DATABASE=Kaveri P2P Bridge for GFX PCIe Port [1:0] ++ + pci:v00001022d00001426* + ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port + + pci:v00001022d0000142E* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Function 0 ++ ID_MODEL_FROM_DATABASE=Liverpool Processor HT configuration + + pci:v00001022d0000142F* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Function 1 ++ ID_MODEL_FROM_DATABASE=Liverpool Processor Address Maps + + pci:v00001022d00001430* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Function 2 ++ ID_MODEL_FROM_DATABASE=Liverpool Processor DRAM configuration + + pci:v00001022d00001431* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Function 3 ++ ID_MODEL_FROM_DATABASE=Liverpool Processor Misc configuration + + pci:v00001022d00001432* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Function 4 ++ ID_MODEL_FROM_DATABASE=Liverpool Processor PM configuration ++ ++pci:v00001022d00001433* ++ ID_MODEL_FROM_DATABASE=Liverpool Processor NB Performance Monitor ++ ++pci:v00001022d00001434* ++ ID_MODEL_FROM_DATABASE=Liverpool Processor SPLL Configuration + + pci:v00001022d00001436* + ID_MODEL_FROM_DATABASE=Liverpool Processor Root Complex +@@ -12423,11 +13872,65 @@ pci:v00001022d00001437* + ID_MODEL_FROM_DATABASE=Liverpool I/O Memory Management Unit + + pci:v00001022d00001438* +- ID_MODEL_FROM_DATABASE=Liverpool Processor Root Port ++ ID_MODEL_FROM_DATABASE=Liverpool UMI PCIe Dummy Host Bridge + + pci:v00001022d00001439* + ID_MODEL_FROM_DATABASE=Family 16h Processor Functions 5:1 + ++pci:v00001022d0000143A* ++ ID_MODEL_FROM_DATABASE=Kingston/Clayton/Gladius/Montego Root Complex ++ ++pci:v00001022d0000143B* ++ ID_MODEL_FROM_DATABASE=Kingston/Clayton/Gladius/Montego P2P Bridge for UMI Link ++ ++pci:v00001022d00001440* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 0 ++ ++pci:v00001022d00001441* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 1 ++ ++pci:v00001022d00001442* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 2 ++ ++pci:v00001022d00001443* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 3 ++ ++pci:v00001022d00001444* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 4 ++ ++pci:v00001022d00001445* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 5 ++ ++pci:v00001022d00001446* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 6 ++ ++pci:v00001022d00001447* ++ ID_MODEL_FROM_DATABASE=Matisse Device 24: Function 7 ++ ++pci:v00001022d00001448* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 0 ++ ++pci:v00001022d00001449* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 1 ++ ++pci:v00001022d0000144A* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 2 ++ ++pci:v00001022d0000144B* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 3 ++ ++pci:v00001022d0000144C* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 4 ++ ++pci:v00001022d0000144D* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 5 ++ ++pci:v00001022d0000144E* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 6 ++ ++pci:v00001022d0000144F* ++ ID_MODEL_FROM_DATABASE=Renoir Device 24: Function 7 ++ + pci:v00001022d00001450* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Root Complex + +@@ -12435,7 +13938,10 @@ pci:v00001022d00001451* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) I/O Memory Management Unit + + pci:v00001022d00001452* +- ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) PCIe Dummy Host Bridge ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge ++ ++pci:v00001022d00001452sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge (mCOM10-L1900) + + pci:v00001022d00001453* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) PCIe GPP Bridge +@@ -12443,20 +13949,32 @@ pci:v00001022d00001453* + pci:v00001022d00001454* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Internal PCIe GPP Bridge 0 to Bus B + ++pci:v00001022d00001455* ++ ID_MODEL_FROM_DATABASE=Zeppelin/Renoir PCIe Dummy Function ++ + pci:v00001022d00001456* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Platform Security Processor + + pci:v00001022d00001457* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) HD Audio Controller + ++pci:v00001022d0000145A* ++ ID_MODEL_FROM_DATABASE=Zeppelin/Raven/Raven2 PCIe Dummy Function ++ + pci:v00001022d0000145B* + ID_MODEL_FROM_DATABASE=Zeppelin Non-Transparent Bridge + + pci:v00001022d0000145C* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) USB 3.0 Host Controller + ++pci:v00001022d0000145D* ++ ID_MODEL_FROM_DATABASE=Zeppelin Switch Upstream (PCIE SW.US) ++ ++pci:v00001022d0000145E* ++ ID_MODEL_FROM_DATABASE=Zeppelin Switch Downstream (PCIE SW.DS) ++ + pci:v00001022d0000145F* +- ID_MODEL_FROM_DATABASE=USB 3.0 Host controller ++ ID_MODEL_FROM_DATABASE=Zeppelin USB 3.0 Host controller + + pci:v00001022d00001460* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 0 +@@ -12482,6 +14000,114 @@ pci:v00001022d00001466* + pci:v00001022d00001467* + ID_MODEL_FROM_DATABASE=Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 7 + ++pci:v00001022d00001468* ++ ID_MODEL_FROM_DATABASE=Zeppelin Cryptographic Coprocessor NTBCCP ++ ++pci:v00001022d00001470* ++ ID_MODEL_FROM_DATABASE=Vega 10 PCIe Bridge ++ ++pci:v00001022d00001471* ++ ID_MODEL_FROM_DATABASE=Vega 10 PCIe Bridge ++ ++pci:v00001022d00001480* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Root Complex ++ ++pci:v00001022d00001480sv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Root Complex (X570-A PRO motherboard) ++ ++pci:v00001022d00001481* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse IOMMU ++ ++pci:v00001022d00001482* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse PCIe Dummy Host Bridge ++ ++pci:v00001022d00001483* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse GPP Bridge ++ ++pci:v00001022d00001484* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Internal PCIe GPP Bridge 0 to bus[E:B] ++ ++pci:v00001022d00001485* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Reserved SPP ++ ++pci:v00001022d00001486* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Cryptographic Coprocessor PSPCPP ++ ++pci:v00001022d00001487* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse HD Audio Controller ++ ++pci:v00001022d00001487sv00001462sd00009C37* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse HD Audio Controller (X570-A PRO motherboard) ++ ++pci:v00001022d00001488* ++ ID_MODEL_FROM_DATABASE=Starship Reserved SSP ++ ++pci:v00001022d00001489* ++ ID_MODEL_FROM_DATABASE=Starship Reserved SSP ++ ++pci:v00001022d0000148A* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse PCIe Dummy Function ++ ++pci:v00001022d0000148B* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Non-Transparent Bridge ++ ++pci:v00001022d0000148C* ++ ID_MODEL_FROM_DATABASE=Starship USB 3.0 Host Controller ++ ++pci:v00001022d0000148D* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Switch Upstream (PCIE SW.US) ++ ++pci:v00001022d0000148E* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse Switch Downstream (PCIE SW.DS) ++ ++pci:v00001022d0000148F* ++ ID_MODEL_FROM_DATABASE=Starship Reserved SSP ++ ++pci:v00001022d00001490* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 0 ++ ++pci:v00001022d00001491* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 1 ++ ++pci:v00001022d00001492* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 2 ++ ++pci:v00001022d00001493* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 3 ++ ++pci:v00001022d00001494* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 4 ++ ++pci:v00001022d00001495* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 5 ++ ++pci:v00001022d00001496* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 6 ++ ++pci:v00001022d00001497* ++ ID_MODEL_FROM_DATABASE=Starship Device 24; Function 7 ++ ++pci:v00001022d00001498* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse PTDMA ++ ++pci:v00001022d00001499* ++ ID_MODEL_FROM_DATABASE=Starship/Matisse NVMe ++ ++pci:v00001022d0000149A* ++ ID_MODEL_FROM_DATABASE=Starship PCIe GPP Bridge [1:0] ++ ++pci:v00001022d0000149B* ++ ID_MODEL_FROM_DATABASE=Starship Reserved SSP ++ ++pci:v00001022d0000149C* ++ ID_MODEL_FROM_DATABASE=Matisse USB 3.0 Host Controller ++ ++pci:v00001022d0000149Csv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=Matisse USB 3.0 Host Controller (X570-A PRO motherboard) ++ ++pci:v00001022d0000149D* ++ ID_MODEL_FROM_DATABASE=Vangogh CVIP ++ + pci:v00001022d00001510* + ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex + +@@ -12524,9 +14150,93 @@ pci:v00001022d00001535* + pci:v00001022d00001536* + ID_MODEL_FROM_DATABASE=Family 16h Processor Root Complex + ++pci:v00001022d00001536sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=Family 16h Processor Root Complex (AM1I-A Motherboard) ++ ++pci:v00001022d00001536sv00001849sd00001536* ++ ID_MODEL_FROM_DATABASE=Family 16h Processor Root Complex (QC5000-ITX/PH) ++ ++pci:v00001022d00001537* ++ ID_MODEL_FROM_DATABASE=Kabini/Mullins PSP-Platform Security Processor ++ + pci:v00001022d00001538* + ID_MODEL_FROM_DATABASE=Family 16h Processor Function 0 + ++pci:v00001022d00001539* ++ ID_MODEL_FROM_DATABASE=Kabini P2P Bridge for PCIe Ports[4:0] ++ ++pci:v00001022d00001540* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky HT Configuration ++ ++pci:v00001022d00001541* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky Address Maps ++ ++pci:v00001022d00001542* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky DRAM Configuration ++ ++pci:v00001022d00001543* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky Miscellaneous Configuration ++ ++pci:v00001022d00001544* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky PM Configuration ++ ++pci:v00001022d00001545* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky NB Performance Monitor ++ ++pci:v00001022d00001546* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky Root Complex ++ ++pci:v00001022d00001547* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky IOMMU ++ ++pci:v00001022d00001548* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky UMI PCIe Dummy Host Bridge ++ ++pci:v00001022d00001549* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+ P2P Bridge for PCIe Port [3:0] ++ ++pci:v00001022d0000154A* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky Audio Processor ++ ++pci:v00001022d0000154B* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky Security Processor ++ ++pci:v00001022d0000154D* ++ ID_MODEL_FROM_DATABASE=Kryptos/Cato/Garfield/Garfield+/Arlene/Pooky/Anubis HDMI Controller ++ ++pci:v00001022d0000154F* ++ ID_MODEL_FROM_DATABASE=Anubis Audio Processor ++ ++pci:v00001022d00001550* ++ ID_MODEL_FROM_DATABASE=Garfield+/Arlene/Pooky/Anubis SPLL Configuration ++ ++pci:v00001022d00001553* ++ ID_MODEL_FROM_DATABASE=Arlene/Pooky P2P Bridge for PCIE (3:0) ++ ++pci:v00001022d0000155B* ++ ID_MODEL_FROM_DATABASE=Anubis Root Complex ++ ++pci:v00001022d0000155C* ++ ID_MODEL_FROM_DATABASE=Anubis IOMMU ++ ++pci:v00001022d0000155D* ++ ID_MODEL_FROM_DATABASE=Anubis UMI PCIe Dummy Bridge ++ ++pci:v00001022d0000155E* ++ ID_MODEL_FROM_DATABASE=Anubis P2P Bridge for PCIe Ports [4:0] ++ ++pci:v00001022d00001560* ++ ID_MODEL_FROM_DATABASE=Anubis Security Processor ++ ++pci:v00001022d00001566* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Root Complex ++ ++pci:v00001022d00001567* ++ ID_MODEL_FROM_DATABASE=Mullins IOMMU ++ ++pci:v00001022d0000156B* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Host Bridge ++ + pci:v00001022d00001570* + ID_MODEL_FROM_DATABASE=Family 15h (Models 60h-6fh) Processor Function 0 + +@@ -12551,6 +14261,12 @@ pci:v00001022d00001576* + pci:v00001022d00001577* + ID_MODEL_FROM_DATABASE=Family 15h (Models 60h-6fh) I/O Memory Management Unit + ++pci:v00001022d00001578* ++ ID_MODEL_FROM_DATABASE=Carrizo Platform Security Processor ++ ++pci:v00001022d00001579* ++ ID_MODEL_FROM_DATABASE=Carrizo Audio Processor ++ + pci:v00001022d0000157A* + ID_MODEL_FROM_DATABASE=Family 15h (Models 60h-6fh) Audio Controller + +@@ -12560,6 +14276,297 @@ pci:v00001022d0000157B* + pci:v00001022d0000157C* + ID_MODEL_FROM_DATABASE=Family 15h (Models 60h-6fh) Processor Root Port + ++pci:v00001022d0000157D* ++ ID_MODEL_FROM_DATABASE=Carrizo Audio Dummy Host Bridge ++ ++pci:v00001022d0000157E* ++ ID_MODEL_FROM_DATABASE=Carrizo Audio Controller ++ ++pci:v00001022d00001580* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 0 ++ ++pci:v00001022d00001581* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 1 ++ ++pci:v00001022d00001582* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 2 ++ ++pci:v00001022d00001583* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 3 ++ ++pci:v00001022d00001584* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 4 ++ ++pci:v00001022d00001585* ++ ID_MODEL_FROM_DATABASE=Family 16h (Models 30h-3fh) Processor Function 5 ++ ++pci:v00001022d00001590* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan HT Configuration ++ ++pci:v00001022d00001591* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan Address Maps ++ ++pci:v00001022d00001592* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan DRAM Configuration ++ ++pci:v00001022d00001593* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan Miscellaneous Configuration ++ ++pci:v00001022d00001594* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan PM Configuration ++ ++pci:v00001022d00001595* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan NB Performance Monitor ++ ++pci:v00001022d00001596* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan Root Complex ++ ++pci:v00001022d00001597* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan IOMMU ++ ++pci:v00001022d00001598* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan Platform Security Processor ++ ++pci:v00001022d00001599* ++ ID_MODEL_FROM_DATABASE=Amur/Nolan PCIe Dummy Host Bridge ++ ++pci:v00001022d0000159D* ++ ID_MODEL_FROM_DATABASE=Amur Function 6: Gasket ++ ++pci:v00001022d000015B0* ++ ID_MODEL_FROM_DATABASE=Stoney HT Configuration ++ ++pci:v00001022d000015B1* ++ ID_MODEL_FROM_DATABASE=Stoney Address Maps ++ ++pci:v00001022d000015B2* ++ ID_MODEL_FROM_DATABASE=Stoney DRAM Configuration ++ ++pci:v00001022d000015B3* ++ ID_MODEL_FROM_DATABASE=Stoney Miscellaneous Configuration ++ ++pci:v00001022d000015B4* ++ ID_MODEL_FROM_DATABASE=Stoney PM Configuration ++ ++pci:v00001022d000015B5* ++ ID_MODEL_FROM_DATABASE=Stoney NB Performance Monitor ++ ++pci:v00001022d000015BC* ++ ID_MODEL_FROM_DATABASE=Stoney PCIe [GFX,GPP] Bridge [4:0] ++ ++pci:v00001022d000015BE* ++ ID_MODEL_FROM_DATABASE=Stoney Audio Processor ++ ++pci:v00001022d000015D0* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Root Complex ++ ++pci:v00001022d000015D0sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Root Complex (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d000015D0sv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Root Complex (PRIME B450M-A Motherboard) ++ ++pci:v00001022d000015D0sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Root Complex (mCOM10-L1900) ++ ++pci:v00001022d000015D1* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 IOMMU ++ ++pci:v00001022d000015D1sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 IOMMU (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d000015D1sv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 IOMMU (PRIME B450M-A Motherboard) ++ ++pci:v00001022d000015D1sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 IOMMU (mCOM10-L1900) ++ ++pci:v00001022d000015D2* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 PCIe Dummy Host Bridge ++ ++pci:v00001022d000015D3* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 PCIe GPP Bridge [6:0] ++ ++pci:v00001022d000015D3sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 PCIe GPP Bridge [6:0] (mCOM10-L1900) ++ ++pci:v00001022d000015D4* ++ ID_MODEL_FROM_DATABASE=FireFlight USB 3.1 ++ ++pci:v00001022d000015D5* ++ ID_MODEL_FROM_DATABASE=FireFlight USB 3.1 ++ ++pci:v00001022d000015DA* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 PCIe Dummy Host Bridge ++ ++pci:v00001022d000015DB* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Internal PCIe GPP Bridge 0 to Bus A ++ ++pci:v00001022d000015DBsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Internal PCIe GPP Bridge 0 to Bus A (mCOM10-L1900) ++ ++pci:v00001022d000015DC* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Internal PCIe GPP Bridge 0 to Bus B ++ ++pci:v00001022d000015DCsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Internal PCIe GPP Bridge 0 to Bus B (mCOM10-L1900) ++ ++pci:v00001022d000015DE* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/FireFlight HD Audio Controller ++ ++pci:v00001022d000015DF* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) Platform Security Processor ++ ++pci:v00001022d000015DFsv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) Platform Security Processor (PRIME Motherboard) ++ ++pci:v00001022d000015DFsv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) Platform Security Processor (ThinkPad E595) ++ ++pci:v00001022d000015DFsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) Platform Security Processor (mCOM10-L1900) ++ ++pci:v00001022d000015E0* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 ++ ++pci:v00001022d000015E0sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d000015E0sv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (PRIME Motherboard) ++ ++pci:v00001022d000015E0sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (ThinkPad E595) ++ ++pci:v00001022d000015E0sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (mCOM10-L1900) ++ ++pci:v00001022d000015E1* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 ++ ++pci:v00001022d000015E1sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d000015E1sv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (PRIME Motherboard) ++ ++pci:v00001022d000015E1sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (ThinkPad E595) ++ ++pci:v00001022d000015E1sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven USB 3.1 (mCOM10-L1900) ++ ++pci:v00001022d000015E2* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/FireFlight/Renoir Audio Processor ++ ++pci:v00001022d000015E2sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/FireFlight/Renoir Audio Processor (ThinkPad E595) ++ ++pci:v00001022d000015E2sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/FireFlight/Renoir Audio Processor (mCOM10-L1900) ++ ++pci:v00001022d000015E3* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) HD Audio Controller ++ ++pci:v00001022d000015E3sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) HD Audio Controller (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d000015E3sv00001043sd000086C7* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) HD Audio Controller (PRIME B450M-A Motherboard) ++ ++pci:v00001022d000015E3sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=Family 17h (Models 10h-1fh) HD Audio Controller (ThinkPad E595) ++ ++pci:v00001022d000015E4* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Renoir Sensor Fusion Hub ++ ++pci:v00001022d000015E5* ++ ID_MODEL_FROM_DATABASE=Raven2 USB 3.1 ++ ++pci:v00001022d000015E5sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven2 USB 3.1 (mCOM10-L1900) ++ ++pci:v00001022d000015E6* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Renoir Non-Sensor Fusion Hub KMDF driver ++ ++pci:v00001022d000015E6sv00001022sd000015E4* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Renoir Non-Sensor Fusion Hub KMDF driver (Raven/Raven2/Renoir Sensor Fusion Hub) ++ ++pci:v00001022d000015E6sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2/Renoir Non-Sensor Fusion Hub KMDF driver (mCOM10-L1900) ++ ++pci:v00001022d000015E8* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 0 ++ ++pci:v00001022d000015E9* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 1 ++ ++pci:v00001022d000015EA* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 2 ++ ++pci:v00001022d000015EB* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 3 ++ ++pci:v00001022d000015EC* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 4 ++ ++pci:v00001022d000015ED* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 5 ++ ++pci:v00001022d000015EE* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 6 ++ ++pci:v00001022d000015EF* ++ ID_MODEL_FROM_DATABASE=Raven/Raven2 Device 24: Function 7 ++ ++pci:v00001022d000015F0* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 0 ++ ++pci:v00001022d000015F1* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 1 ++ ++pci:v00001022d000015F2* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 2 ++ ++pci:v00001022d000015F3* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 3 ++ ++pci:v00001022d000015F4* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 4 ++ ++pci:v00001022d000015F5* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 5 ++ ++pci:v00001022d000015F6* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 6 ++ ++pci:v00001022d000015F7* ++ ID_MODEL_FROM_DATABASE=FireFlight Device 24: Function 7 ++ ++pci:v00001022d000015F8* ++ ID_MODEL_FROM_DATABASE=FireFlight Root Complex ++ ++pci:v00001022d000015F9* ++ ID_MODEL_FROM_DATABASE=FireFlight IOMMU ++ ++pci:v00001022d000015FA* ++ ID_MODEL_FROM_DATABASE=FireFlight PCIe Dummy Host Bridge ++ ++pci:v00001022d000015FB* ++ ID_MODEL_FROM_DATABASE=FireFlight PCIe GPP Bride 3:0 ++ ++pci:v00001022d000015FC* ++ ID_MODEL_FROM_DATABASE=FireFlight PCIe Dummy Host Bridge ++ ++pci:v00001022d000015FD* ++ ID_MODEL_FROM_DATABASE=FireFlight Internal PCIe GPP Bridge 0 to Bus A ++ ++pci:v00001022d000015FE* ++ ID_MODEL_FROM_DATABASE=FireFlight Internal PCIe GPP Bridge 0 to Bus B ++ ++pci:v00001022d000015FF* ++ ID_MODEL_FROM_DATABASE=FireFlight Bus A; Device 0: Function 0: Internal GPU ++ + pci:v00001022d00001600* + ID_MODEL_FROM_DATABASE=Family 15h Processor Function 0 + +@@ -12578,6 +14585,126 @@ pci:v00001022d00001604* + pci:v00001022d00001605* + ID_MODEL_FROM_DATABASE=Family 15h Processor Function 5 + ++pci:v00001022d00001606* ++ ID_MODEL_FROM_DATABASE=Arden Security Processor ++ ++pci:v00001022d00001608* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 0 ++ ++pci:v00001022d00001609* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 1 ++ ++pci:v00001022d0000160A* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 2 ++ ++pci:v00001022d0000160B* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 3 ++ ++pci:v00001022d0000160C* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 4 ++ ++pci:v00001022d0000160D* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 5 ++ ++pci:v00001022d0000160E* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 6 ++ ++pci:v00001022d0000160F* ++ ID_MODEL_FROM_DATABASE=Arden Device 18h: Function 7 ++ ++pci:v00001022d00001620* ++ ID_MODEL_FROM_DATABASE=Anubis HT Configuration ++ ++pci:v00001022d00001621* ++ ID_MODEL_FROM_DATABASE=Anubis Address Maps ++ ++pci:v00001022d00001622* ++ ID_MODEL_FROM_DATABASE=Anubis DRAM Configuration ++ ++pci:v00001022d00001623* ++ ID_MODEL_FROM_DATABASE=Anubis Miscellaneous Configuration ++ ++pci:v00001022d00001624* ++ ID_MODEL_FROM_DATABASE=Anubis PM Configuration ++ ++pci:v00001022d00001625* ++ ID_MODEL_FROM_DATABASE=Anubis NB Performance Monitor ++ ++pci:v00001022d00001626* ++ ID_MODEL_FROM_DATABASE=Arden Root Complex ++ ++pci:v00001022d00001627* ++ ID_MODEL_FROM_DATABASE=Arden IOMMU ++ ++pci:v00001022d00001628* ++ ID_MODEL_FROM_DATABASE=Arden PCIe Dummy Host Bridge ++ ++pci:v00001022d00001629* ++ ID_MODEL_FROM_DATABASE=Arden PCIe GPP Bridge ++ ++pci:v00001022d0000162A* ++ ID_MODEL_FROM_DATABASE=Arden Internal PCIe GPP Bridge 0 to bus X ++ ++pci:v00001022d0000162B* ++ ID_MODEL_FROM_DATABASE=Arden PCIe Non-Transparent Bridge ++ ++pci:v00001022d00001630* ++ ID_MODEL_FROM_DATABASE=Renoir/Cezanne Root Complex ++ ++pci:v00001022d00001631* ++ ID_MODEL_FROM_DATABASE=Renoir/Cezanne IOMMU ++ ++pci:v00001022d00001632* ++ ID_MODEL_FROM_DATABASE=Renoir PCIe Dummy Host Bridge ++ ++pci:v00001022d00001633* ++ ID_MODEL_FROM_DATABASE=Renoir PCIe GPP Bridge ++ ++pci:v00001022d00001634* ++ ID_MODEL_FROM_DATABASE=Renoir/Cezanne PCIe GPP Bridge ++ ++pci:v00001022d00001635* ++ ID_MODEL_FROM_DATABASE=Renoir Internal PCIe GPP Bridge to Bus ++ ++pci:v00001022d00001637* ++ ID_MODEL_FROM_DATABASE=Renoir HD Audio Controller ++ ++pci:v00001022d00001639* ++ ID_MODEL_FROM_DATABASE=Renoir/Cezanne USB 3.1 ++ ++pci:v00001022d0000163A* ++ ID_MODEL_FROM_DATABASE=VanGogh USB0 ++ ++pci:v00001022d0000163B* ++ ID_MODEL_FROM_DATABASE=VanGogh USB1 ++ ++pci:v00001022d0000163C* ++ ID_MODEL_FROM_DATABASE=VanGogh SecUSB ++ ++pci:v00001022d0000163D* ++ ID_MODEL_FROM_DATABASE=VanGogh SecureFunction ++ ++pci:v00001022d0000163E* ++ ID_MODEL_FROM_DATABASE=VanGogh HSP ++ ++pci:v00001022d00001641* ++ ID_MODEL_FROM_DATABASE=Renoir 10GbE Controller Port 0 (XGBE0/1) ++ ++pci:v00001022d00001642* ++ ID_MODEL_FROM_DATABASE=Renoir WLAN ++ ++pci:v00001022d00001643* ++ ID_MODEL_FROM_DATABASE=Renoir BT ++ ++pci:v00001022d00001644* ++ ID_MODEL_FROM_DATABASE=Renoir I2S ++ ++pci:v00001022d00001648* ++ ID_MODEL_FROM_DATABASE=VanGogh Root Complex ++ ++pci:v00001022d00001649* ++ ID_MODEL_FROM_DATABASE=VanGogh PSP/CCP ++ + pci:v00001022d00001700* + ID_MODEL_FROM_DATABASE=Family 12h/14h Processor Function 0 + +@@ -12596,6 +14723,9 @@ pci:v00001022d00001704* + pci:v00001022d00001705* + ID_MODEL_FROM_DATABASE=Family 12h Processor Root Complex + ++pci:v00001022d00001706* ++ ID_MODEL_FROM_DATABASE=Llano P2P Bridge to external GPU ++ + pci:v00001022d00001707* + ID_MODEL_FROM_DATABASE=Family 12h Processor Root Port + +@@ -12696,13 +14826,13 @@ pci:v00001022d00002000sv00004C53sd00001060* + ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (PC7 mainboard) + + pci:v00001022d00002001* +- ID_MODEL_FROM_DATABASE=79c978 [HomePNA] ++ ID_MODEL_FROM_DATABASE=Am79C978 PCnet Home (HomePNA) 1/10 PCI Ethernet Adapter [Am79C971 PHY] + + pci:v00001022d00002001sv00001092sd00000A78* +- ID_MODEL_FROM_DATABASE=79c978 [HomePNA] (Multimedia Home Network Adapter) ++ ID_MODEL_FROM_DATABASE=Am79C978 PCnet Home (HomePNA) 1/10 PCI Ethernet Adapter [Am79C971 PHY] (Multimedia Home Network Adapter) + + pci:v00001022d00002001sv00001668sd00000299* +- ID_MODEL_FROM_DATABASE=79c978 [HomePNA] (ActionLink Home Network Adapter) ++ ID_MODEL_FROM_DATABASE=Am79C978 PCnet Home (HomePNA) 1/10 PCI Ethernet Adapter [Am79C971 PHY] (ActionLink Home Network Adapter) + + pci:v00001022d00002003* + ID_MODEL_FROM_DATABASE=Am 1771 MBW [Alchemy] +@@ -12752,6 +14882,12 @@ pci:v00001022d00002097* + pci:v00001022d0000209A* + ID_MODEL_FROM_DATABASE=CS5536 [Geode companion] IDE + ++pci:v00001022d00002625* ++ ID_MODEL_FROM_DATABASE=Am79C973 [Lance/PCI PCNet/32] ++ ++pci:v00001022d00002627* ++ ID_MODEL_FROM_DATABASE=Am79C975 [Lance/PCI PCNet/32] ++ + pci:v00001022d00003000* + ID_MODEL_FROM_DATABASE=ELanSC520 Microcontroller + +@@ -12767,24 +14903,63 @@ pci:v00001022d000043A2* + pci:v00001022d000043A3* + ID_MODEL_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3) + ++pci:v00001022d000043B0* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset PCIe Upstream Port ++ ++pci:v00001022d000043B0sv00001849sd000043C6* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset PCIe Upstream Port (Fatal1ty X370 Professional Gaming) ++ + pci:v00001022d000043B1* + ID_MODEL_FROM_DATABASE=X399 Series Chipset PCIe Bridge + + pci:v00001022d000043B4* + ID_MODEL_FROM_DATABASE=300 Series Chipset PCIe Port + ++pci:v00001022d000043B5* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset SATA Controller ++ ++pci:v00001022d000043B5sv00001849sd000043C8* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset SATA Controller (Fatal1ty X370 Professional Gaming) ++ + pci:v00001022d000043B6* + ID_MODEL_FROM_DATABASE=X399 Series Chipset SATA Controller + + pci:v00001022d000043B7* + ID_MODEL_FROM_DATABASE=300 Series Chipset SATA Controller + ++pci:v00001022d000043B9* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset USB 3.1 xHCI Controller ++ ++pci:v00001022d000043B9sv00001849sd000043D0* ++ ID_MODEL_FROM_DATABASE=X370 Series Chipset USB 3.1 xHCI Controller (Fatal1ty X370 Professional Gaming) ++ + pci:v00001022d000043BA* + ID_MODEL_FROM_DATABASE=X399 Series Chipset USB 3.1 xHCI Controller + + pci:v00001022d000043BB* + ID_MODEL_FROM_DATABASE=300 Series Chipset USB 3.1 xHCI Controller + ++pci:v00001022d000043C6* ++ ID_MODEL_FROM_DATABASE=400 Series Chipset PCIe Bridge ++ ++pci:v00001022d000043C7* ++ ID_MODEL_FROM_DATABASE=400 Series Chipset PCIe Port ++ ++pci:v00001022d000043C8* ++ ID_MODEL_FROM_DATABASE=400 Series Chipset SATA Controller ++ ++pci:v00001022d000043D5* ++ ID_MODEL_FROM_DATABASE=400 Series Chipset USB 3.1 XHCI Controller ++ ++pci:v00001022d000057A3* ++ ID_MODEL_FROM_DATABASE=Matisse PCIe GPP Bridge ++ ++pci:v00001022d000057A4* ++ ID_MODEL_FROM_DATABASE=Matisse PCIe GPP Bridge ++ ++pci:v00001022d000057AD* ++ ID_MODEL_FROM_DATABASE=Matisse Switch Upstream ++ + pci:v00001022d00007006* + ID_MODEL_FROM_DATABASE=AMD-751 [Irongate] System Controller + +@@ -12959,6 +15134,15 @@ pci:v00001022d00007801sv0000103Csd0000168B* + pci:v00001022d00007801sv0000103Csd0000194E* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (ProBook 455 G1 Notebook) + ++pci:v00001022d00007801sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (AM1I-A Motherboard) ++ ++pci:v00001022d00007801sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (Z50-75) ++ ++pci:v00001022d00007801sv00001849sd00007801* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (QC5000-ITX/PH) ++ + pci:v00001022d00007802* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [RAID mode] + +@@ -12986,6 +15170,15 @@ pci:v00001022d00007807sv0000103Csd0000194E* + pci:v00001022d00007807sv0000103Csd00001985* + ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (Pavilion 17-e163sg Notebook PC) + ++pci:v00001022d00007807sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (AM1I-A Motherboard) ++ ++pci:v00001022d00007807sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (Z50-75) ++ ++pci:v00001022d00007807sv00001849sd00007807* ++ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (QC5000-ITX/PH) ++ + pci:v00001022d00007808* + ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller + +@@ -12995,12 +15188,27 @@ pci:v00001022d00007808sv0000103Csd0000194E* + pci:v00001022d00007808sv0000103Csd00001985* + ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller (Pavilion 17-e163sg Notebook PC) + ++pci:v00001022d00007808sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller (AM1I-A Motherboard) ++ ++pci:v00001022d00007808sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller (Z50-75) ++ ++pci:v00001022d00007808sv00001849sd00007808* ++ ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller (QC5000-ITX/PH) ++ + pci:v00001022d00007809* + ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller + + pci:v00001022d00007809sv0000103Csd0000194E* + ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (ProBook 455 G1 Notebook) + ++pci:v00001022d00007809sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (Z50-75) ++ ++pci:v00001022d0000780A* ++ ID_MODEL_FROM_DATABASE=Kabini/Mullins SATA Raid/AHCI Mode (DotHill driver) ++ + pci:v00001022d0000780B* + ID_MODEL_FROM_DATABASE=FCH SMBus Controller + +@@ -13010,6 +15218,15 @@ pci:v00001022d0000780Bsv0000103Csd0000194E* + pci:v00001022d0000780Bsv0000103Csd00001985* + ID_MODEL_FROM_DATABASE=FCH SMBus Controller (Pavilion 17-e163sg Notebook PC) + ++pci:v00001022d0000780Bsv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (AM1I-A Motherboard) ++ ++pci:v00001022d0000780Bsv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (Z50-75) ++ ++pci:v00001022d0000780Bsv00001849sd0000780B* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (QC5000-ITX/PH) ++ + pci:v00001022d0000780C* + ID_MODEL_FROM_DATABASE=FCH IDE Controller + +@@ -13025,6 +15242,15 @@ pci:v00001022d0000780Dsv0000103Csd00001985* + pci:v00001022d0000780Dsv00001043sd00008444* + ID_MODEL_FROM_DATABASE=FCH Azalia Controller (F2A85-M Series) + ++pci:v00001022d0000780Dsv00001043sd00008576* ++ ID_MODEL_FROM_DATABASE=FCH Azalia Controller (AM1I-A Motherboard) ++ ++pci:v00001022d0000780Dsv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH Azalia Controller (Z50-75) ++ ++pci:v00001022d0000780Dsv00001849sd00008892* ++ ID_MODEL_FROM_DATABASE=FCH Azalia Controller (QC5000-ITX/PH) ++ + pci:v00001022d0000780E* + ID_MODEL_FROM_DATABASE=FCH LPC Bridge + +@@ -13034,6 +15260,15 @@ pci:v00001022d0000780Esv0000103Csd0000194E* + pci:v00001022d0000780Esv0000103Csd00001985* + ID_MODEL_FROM_DATABASE=FCH LPC Bridge (Pavilion 17-e163sg Notebook PC) + ++pci:v00001022d0000780Esv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (AM1I-A Motherboard) ++ ++pci:v00001022d0000780Esv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (Z50-75) ++ ++pci:v00001022d0000780Esv00001849sd0000780E* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (QC5000-ITX/PH) ++ + pci:v00001022d0000780F* + ID_MODEL_FROM_DATABASE=FCH PCI Bridge + +@@ -13052,12 +15287,33 @@ pci:v00001022d00007814sv0000103Csd0000194E* + pci:v00001022d00007814sv0000103Csd00001985* + ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller (Pavilion 17-e163sg Notebook PC) + ++pci:v00001022d00007814sv00001043sd00008623* ++ ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller (AM1I-A Motherboard) ++ ++pci:v00001022d00007814sv000017AAsd00003988* ++ ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller (Z50-75) ++ ++pci:v00001022d00007814sv00001849sd00007814* ++ ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller (QC5000-ITX/PH) ++ + pci:v00001022d00007900* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [IDE mode] + + pci:v00001022d00007901* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] + ++pci:v00001022d00007901sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d00007901sv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (PRIME Motherboard) ++ ++pci:v00001022d00007901sv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (X570-A PRO motherboard) ++ ++pci:v00001022d00007901sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (mCOM10-L1900) ++ + pci:v00001022d00007902* + ID_MODEL_FROM_DATABASE=FCH SATA Controller [RAID mode] + +@@ -13076,9 +15332,39 @@ pci:v00001022d00007908* + pci:v00001022d0000790B* + ID_MODEL_FROM_DATABASE=FCH SMBus Controller + ++pci:v00001022d0000790Bsv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d0000790Bsv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (PRIME Motherboard) ++ ++pci:v00001022d0000790Bsv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (X570-A PRO motherboard) ++ ++pci:v00001022d0000790Bsv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (ThinkPad E595) ++ ++pci:v00001022d0000790Bsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (mCOM10-L1900) ++ + pci:v00001022d0000790E* + ID_MODEL_FROM_DATABASE=FCH LPC Bridge + ++pci:v00001022d0000790Esv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (Pavilion Laptop 15-cw1xxx) ++ ++pci:v00001022d0000790Esv00001043sd0000876B* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (PRIME B450M-A Motherboard) ++ ++pci:v00001022d0000790Esv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (X570-A PRO motherboard) ++ ++pci:v00001022d0000790Esv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (ThinkPad E595) ++ ++pci:v00001022d0000790Esv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (mCOM10-L1900) ++ + pci:v00001022d0000790F* + ID_MODEL_FROM_DATABASE=FCH PCI Bridge + +@@ -13100,6 +15386,12 @@ pci:v00001022d00009601* + pci:v00001022d00009601sv00001019sd00002120* + ID_MODEL_FROM_DATABASE=RS880 Host Bridge (A785GM-M) + ++pci:v00001022d00009601sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=RS880 Host Bridge (ProLiant MicroServer N36L) ++ ++pci:v00001022d00009601sv00001043sd000083A2* ++ ID_MODEL_FROM_DATABASE=RS880 Host Bridge (M4A785-M Mainboard) ++ + pci:v00001022d00009601sv00001043sd0000843E* + ID_MODEL_FROM_DATABASE=RS880 Host Bridge (M5A88-V EVO) + +@@ -13109,6 +15401,9 @@ pci:v00001022d00009602* + pci:v00001022d00009603* + ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 0) + ++pci:v00001022d00009603sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 0) (ProLiant MicroServer N36L) ++ + pci:v00001022d00009604* + ID_MODEL_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 0) + +@@ -13118,6 +15413,9 @@ pci:v00001022d00009605* + pci:v00001022d00009606* + ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 2) + ++pci:v00001022d00009606sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 2) (ProLiant MicroServer N36L) ++ + pci:v00001022d00009607* + ID_MODEL_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 3) + +@@ -13664,6 +15962,9 @@ pci:v0000102Bd0000051A* + pci:v0000102Bd0000051Asv0000102Bsd00000100* + ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1064SG Mystique) + ++pci:v0000102Bd0000051Asv0000102Bsd0000051A* ++ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1164SG Mystique 220) ++ + pci:v0000102Bd0000051Asv0000102Bsd00001100* + ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1084SG Mystique) + +@@ -14120,9 +16421,15 @@ pci:v0000102Bd00000532sv00001028sd0000029C* + pci:v0000102Bd00000532sv00001028sd000002A4* + ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge T310 MGA G200eW WPCM450) + ++pci:v0000102Bd00000532sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (X8SIL) ++ + pci:v0000102Bd00000532sv000015D9sd00000624* + ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (X9SCM-F Motherboard) + ++pci:v0000102Bd00000532sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (X9SRL-F) ++ + pci:v0000102Bd00000532sv000015D9sd0000A811* + ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (H8DGU) + +@@ -14135,6 +16442,9 @@ pci:v0000102Bd00000533sv0000103Csd00003381* + pci:v0000102Bd00000534* + ID_MODEL_FROM_DATABASE=G200eR2 + ++pci:v0000102Bd00000534sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=G200eR2 (PowerEdge R320 server) ++ + pci:v0000102Bd00000536* + ID_MODEL_FROM_DATABASE=Integrated Matrox G200eW3 Graphics Controller + +@@ -14792,6 +17102,9 @@ pci:v00001033d00000035sv00001931sd0000000B* + pci:v00001033d00000035sv0000807Dsd00000035* + ID_MODEL_FROM_DATABASE=OHCI USB Controller (PCI-USB2 (OHCI subsystem)) + ++pci:v00001033d00000035sv00008086sd00004D44* ++ ID_MODEL_FROM_DATABASE=OHCI USB Controller (D850EMV2 motherboard) ++ + pci:v00001033d0000003B* + ID_MODEL_FROM_DATABASE=PCI to C-bus Bridge + +@@ -14882,6 +17195,9 @@ pci:v00001033d000000E0sv00001799sd00000002* + pci:v00001033d000000E0sv0000807Dsd00001043* + ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (PCI-USB2 (EHCI subsystem)) + ++pci:v00001033d000000E0sv00008086sd00004D44* ++ ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (D850EMV2 motherboard) ++ + pci:v00001033d000000E7* + ID_MODEL_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller + +@@ -15048,7 +17364,7 @@ pci:v00001039d00000406* + ID_MODEL_FROM_DATABASE=85C501/2 + + pci:v00001039d00000496* +- ID_MODEL_FROM_DATABASE=85C496 ++ ID_MODEL_FROM_DATABASE=SiS85C496 PCI & CPU Memory Controller (PCM) + + pci:v00001039d00000530* + ID_MODEL_FROM_DATABASE=530 Host +@@ -15650,6 +17966,9 @@ pci:v0000103Cd0000127B* + pci:v0000103Cd0000127C* + ID_MODEL_FROM_DATABASE=sx1000 I/O Controller + ++pci:v0000103Cd0000128D* ++ ID_MODEL_FROM_DATABASE=Diva [GSP] Management Board ++ + pci:v0000103Cd00001290* + ID_MODEL_FROM_DATABASE=Auxiliary Diva Serial Port + +@@ -15911,6 +18230,9 @@ pci:v0000103Cd00003306sv0000103Csd0000330E* + pci:v0000103Cd00003306sv0000103Csd00003381* + ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support (iLO4) + ++pci:v0000103Cd00003306sv00001590sd000000E4* ++ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support (iLO5) ++ + pci:v0000103Cd00003307* + ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging + +@@ -15944,6 +18266,9 @@ pci:v0000103Cd00004037* + pci:v0000103Cd00009602* + ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx) + ++pci:v0000103Cd00009602sv0000103Csd00001609* ++ ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx) (ProLiant MicroServer N36L) ++ + pci:v0000103E* + ID_VENDOR_FROM_DATABASE=Solliday Engineering + +@@ -17216,18 +19541,48 @@ pci:v0000104Dd00008004* + pci:v0000104Dd00008009* + ID_MODEL_FROM_DATABASE=CXD1947Q i.LINK Controller + ++pci:v0000104Dd0000800C* ++ ID_MODEL_FROM_DATABASE=DTL-H800 [PS1 sound development board] ++ + pci:v0000104Dd00008039* + ID_MODEL_FROM_DATABASE=CXD3222 i.LINK Controller + ++pci:v0000104Dd00008047* ++ ID_MODEL_FROM_DATABASE=PS2 TOOL MRP ++ + pci:v0000104Dd00008056* + ID_MODEL_FROM_DATABASE=Rockwell HCF 56K modem + + pci:v0000104Dd0000808A* + ID_MODEL_FROM_DATABASE=Memory Stick Controller + ++pci:v0000104Dd000080FF* ++ ID_MODEL_FROM_DATABASE=PS2 Performance Analyzer ++ ++pci:v0000104Dd0000814A* ++ ID_MODEL_FROM_DATABASE=PS2 Performance Analyzer ++ ++pci:v0000104Dd00008183* ++ ID_MODEL_FROM_DATABASE=ATHENS [PS3 prototype developer interface card] ++ ++pci:v0000104Dd000081B0* ++ ID_MODEL_FROM_DATABASE=BM-1 [PSP TOOL Board Management Device] ++ ++pci:v0000104Dd000081C3* ++ ID_MODEL_FROM_DATABASE=VO-4 [PSP TOOL Video Output Device] ++ + pci:v0000104Dd000081CE* + ID_MODEL_FROM_DATABASE=SxS Pro memory card + ++pci:v0000104Dd000081FF* ++ ID_MODEL_FROM_DATABASE=PS3 TOOL MRP ++ ++pci:v0000104Dd00008200* ++ ID_MODEL_FROM_DATABASE=PS3 TOOL RSX Tracing FPGA ++ ++pci:v0000104Dd0000820E* ++ ID_MODEL_FROM_DATABASE=CXD9208GP [PS3 PS2 emulation subsystem adapter] ++ + pci:v0000104Dd0000905C* + ID_MODEL_FROM_DATABASE=SxS Pro memory card + +@@ -17648,6 +20003,9 @@ pci:v00001057d00004803* + pci:v00001057d00004806* + ID_MODEL_FROM_DATABASE=CPX8216 + ++pci:v00001057d0000480B* ++ ID_MODEL_FROM_DATABASE=MPC7410 ++ + pci:v00001057d00004D68* + ID_MODEL_FROM_DATABASE=20268 + +@@ -18027,58 +20385,58 @@ pci:v0000105Dd00002339sv0000105Dsd0000000B* + ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 8Mb H-VRAM) + + pci:v0000105Dd00002339sv000011A4sd0000000A* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000000* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000004* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000005* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000006* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000008* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd00000009* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd0000000A* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd00002339sv000013CCsd0000000C* +- ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel) ++ ID_MODEL_FROM_DATABASE=Imagine 128-II (Metheus 5 Megapixel) + + pci:v0000105Dd0000493D* + ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] + + pci:v0000105Dd0000493Dsv000011A4sd0000000A* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000011A4sd0000000B* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd00000002* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 4 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 4 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd00000003* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd00000007* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd00000008* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd00000009* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd0000493Dsv000013CCsd0000000A* +- ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head) ++ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Metheus 5 Megapixel, Dual Head) + + pci:v0000105Dd00005348* + ID_MODEL_FROM_DATABASE=Revolution 4 +@@ -18329,6 +20687,9 @@ pci:v0000106Bd00000004* + pci:v0000106Bd00000007* + ID_MODEL_FROM_DATABASE=O'Hare I/O + ++pci:v0000106Bd0000000B* ++ ID_MODEL_FROM_DATABASE=Apple Camera ++ + pci:v0000106Bd0000000C* + ID_MODEL_FROM_DATABASE=DOS on Mac + +@@ -18521,6 +20882,15 @@ pci:v0000106Bd00000074* + pci:v0000106Bd00001645* + ID_MODEL_FROM_DATABASE=Broadcom NetXtreme BCM5701 Gigabit Ethernet + ++pci:v0000106Bd00001801* ++ ID_MODEL_FROM_DATABASE=T2 Bridge Controller ++ ++pci:v0000106Bd00001802* ++ ID_MODEL_FROM_DATABASE=T2 Secure Enclave Processor ++ ++pci:v0000106Bd00001803* ++ ID_MODEL_FROM_DATABASE=Apple Audio Device ++ + pci:v0000106Bd00002001* + ID_MODEL_FROM_DATABASE=S1X NVMe Controller + +@@ -18731,6 +21101,9 @@ pci:v00001077d00001654sv00001077sd00000032* + pci:v00001077d00001654sv00001590sd00000223* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 50GbE Controller (Synergy 6810C 25/50Gb Ethernet Adapter) + ++pci:v00001077d00001654sv00001590sd00000287* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 50GbE Controller (Synergy 6820C 25/50Gb CNA) ++ + pci:v00001077d00001656* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller + +@@ -18746,6 +21119,9 @@ pci:v00001077d00001656sv00001077sd0000E4F6* + pci:v00001077d00001656sv00001077sd0000E4F7* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (FastLinQ QL45212H 25GbE Adapter) + ++pci:v00001077d00001656sv00001590sd00000245* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (10/20/25GbE 2P 4820c CNA) ++ + pci:v00001077d0000165C* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (FCoE) + +@@ -18758,6 +21134,9 @@ pci:v00001077d0000165Csv00001077sd0000E4F1* + pci:v00001077d0000165Csv00001077sd0000E4F2* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL45461H 40GbE FCoE Adapter) + ++pci:v00001077d0000165Csv00001590sd00000245* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (FCoE) (10/20/25GbE 2P 4820c CNA FCoE) ++ + pci:v00001077d0000165E* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (iSCSI) + +@@ -18770,6 +21149,9 @@ pci:v00001077d0000165Esv00001077sd0000E4F1* + pci:v00001077d0000165Esv00001077sd0000E4F2* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL45461H 40GbE iSCSI Adapter) + ++pci:v00001077d0000165Esv00001590sd00000245* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 10/25/40/50GbE Controller (iSCSI) (10/20/25GbE 2P 4820c CNA iSCSI) ++ + pci:v00001077d00001664* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series Gigabit Ethernet Controller (SR-IOV VF) + +@@ -18794,6 +21176,9 @@ pci:v00001077d00001664sv00001077sd0000E4F7* + pci:v00001077d00001664sv00001077sd0000E4F8* + ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL45611H 100GbE Adapter (SR-IOV VF)) + ++pci:v00001077d00001664sv00001590sd00000245* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series Gigabit Ethernet Controller (SR-IOV VF) (10/20/25GbE 2P 4820c CNA SRIOV) ++ + pci:v00001077d00002020* + ID_MODEL_FROM_DATABASE=ISP2020A Fast!SCSI Basic Adapter + +@@ -18812,6 +21197,9 @@ pci:v00001077d00002031sv0000103Csd00001939* + pci:v00001077d00002031sv0000103Csd00008002* + ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (3830C 16G Fibre Channel Host Bus Adapter) + ++pci:v00001077d00002031sv00001077sd00000241* ++ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (QLE2670 16Gb Single Port Fibre Channel Adapter) ++ + pci:v00001077d00002071* + ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter + +@@ -18827,6 +21215,24 @@ pci:v00001077d00002071sv00001077sd000002A2* + pci:v00001077d00002071sv00001077sd000002AD* + ID_MODEL_FROM_DATABASE=ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2694U Quad Port 16/32Gb Fibre Channel to PCIe Adapter) + ++pci:v00001077d00002081* ++ ID_MODEL_FROM_DATABASE=ISP2814-based 64/32G Fibre Channel to PCIe Controller ++ ++pci:v00001077d00002081sv00001077sd000002E1* ++ ID_MODEL_FROM_DATABASE=ISP2814-based 64/32G Fibre Channel to PCIe Controller (QLE2874 Quad Port 64GFC PCIe Gen4 x16 Adapter) ++ ++pci:v00001077d00002081sv00001077sd000002E3* ++ ID_MODEL_FROM_DATABASE=ISP2814-based 64/32G Fibre Channel to PCIe Controller (QLE2774 Quad Port 32GFC PCIe Gen4 x16 Adapter) ++ ++pci:v00001077d00002089* ++ ID_MODEL_FROM_DATABASE=ISP2854-based 64/32G Fibre Channel to PCIe Controller with StorCryption ++ ++pci:v00001077d00002089sv00001077sd000002E8* ++ ID_MODEL_FROM_DATABASE=ISP2854-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2884 Quad Port 64GFC PCIe Gen4 x16 Adapter with StorCryption) ++ ++pci:v00001077d00002089sv00001077sd000002EA* ++ ID_MODEL_FROM_DATABASE=ISP2854-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2784 Quad Port 32GFC PCIe Gen4 x16 Adapter with StorCryption) ++ + pci:v00001077d00002100* + ID_MODEL_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter + +@@ -18866,6 +21272,12 @@ pci:v00001077d00002261sv00001077sd000002AB* + pci:v00001077d00002261sv00001077sd000002AC* + ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2742 Dual Port 32Gb FC to PCIe Gen3 x8 Adapter) + ++pci:v00001077d00002261sv00001077sd000002B8* ++ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (2x16Gb QME2692 FC HBA) ++ ++pci:v00001077d00002261sv00001077sd000002B9* ++ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (2x32Gb QME2742 FC HBA) ++ + pci:v00001077d00002261sv00001590sd000000F9* + ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter) + +@@ -18878,6 +21290,54 @@ pci:v00001077d00002261sv00001590sd00000203* + pci:v00001077d00002261sv00001590sd00000204* + ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter) + ++pci:v00001077d00002261sv00001590sd0000022D* ++ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (5830C 32Gb Dual Port Fibre Channel Adapter) ++ ++pci:v00001077d00002261sv0000193Dsd0000100D* ++ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (NIC-FC680i-Mb-2x16G) ++ ++pci:v00001077d00002281* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller ++ ++pci:v00001077d00002281sv00001077sd000002E2* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLE2872 Dual Port 64GFC PCIe Gen4 x8 Adapter) ++ ++pci:v00001077d00002281sv00001077sd000002E4* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLE2772 Dual Port 32GFC PCIe Gen4 x8 Adapter) ++ ++pci:v00001077d00002281sv00001077sd000002EE* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLE2870 Single Port 64GFC PCIe Gen4 x8 Adapter) ++ ++pci:v00001077d00002281sv00001077sd000002F0* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLE2770 Single Port 32GFC PCIe Gen4 x8 Adapter) ++ ++pci:v00001077d00002281sv00001077sd000002F2* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLogic 1x32Gb QLE2770 FC HBA) ++ ++pci:v00001077d00002281sv00001077sd000002F3* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (QLogic 2x32Gb QLE2772 FC HBA) ++ ++pci:v00001077d00002281sv00001590sd000002D3* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (SN1610Q - 1P Enhanced 32GFC Single Port Fibre Channel Host Bus Adapter) ++ ++pci:v00001077d00002281sv00001590sd000002D4* ++ ID_MODEL_FROM_DATABASE=ISP2812-based 64/32G Fibre Channel to PCIe Controller (SN1610Q – 2P Enhanced 32GFC Dual Port Fibre Channel Host Bus Adapter) ++ ++pci:v00001077d00002289* ++ ID_MODEL_FROM_DATABASE=ISP2852-based 64/32G Fibre Channel to PCIe Controller with StorCryption ++ ++pci:v00001077d00002289sv00001077sd000002E9* ++ ID_MODEL_FROM_DATABASE=ISP2852-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2882 Dual Port 64GFC PCIe Gen4 x8 Adapter with StorCryption) ++ ++pci:v00001077d00002289sv00001077sd000002EB* ++ ID_MODEL_FROM_DATABASE=ISP2852-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2782 Dual Port 32GFC PCIe Gen4 x8 Adapter with StorCryption) ++ ++pci:v00001077d00002289sv00001077sd000002EF* ++ ID_MODEL_FROM_DATABASE=ISP2852-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2880 Single Port 64GFC PCIe Gen4 x8 Adapter with StorCryption) ++ ++pci:v00001077d00002289sv00001077sd000002F1* ++ ID_MODEL_FROM_DATABASE=ISP2852-based 64/32G Fibre Channel to PCIe Controller with StorCryption (QLE2780 Single Port 32GFC PCIe Gen4 x8 Adapter with StorCryption) ++ + pci:v00001077d00002300* + ID_MODEL_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter + +@@ -18909,7 +21369,10 @@ pci:v00001077d00002432sv0000103Csd00007040* + ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (FC1142SR 4Gb 1-port PCIe Fibre Channel Host Bus Adapter [HPAE311A]) + + pci:v00001077d00002432sv00001077sd00000137* +- ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (QLE2460 4 GB PCI-X Host-Bus-Adapter) ++ ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (QLE2460 Single-Port 4Gbps FC-to-PCI-X/PCIe Host Bus Adapter) ++ ++pci:v00001077d00002432sv00001077sd00000138* ++ ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (QLE2462 Dual-Port 4Gbps FC-to-PCI-X/PCIe Host Bus Adapter) + + pci:v00001077d00002532* + ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA +@@ -19073,6 +21536,12 @@ pci:v00001077d00008070sv00001077sd00000009* + pci:v00001077d00008070sv00001077sd0000000B* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (25GE 2P QL41262HxCU-DE Adapter) + ++pci:v00001077d00008070sv00001077sd0000000F* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (2x25GE QL41262HMKR CNA) ++ ++pci:v00001077d00008070sv00001077sd00000010* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (2x25GE QL41232HMKR NIC) ++ + pci:v00001077d00008070sv00001077sd00000011* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41212HLCU 25GbE Adapter) + +@@ -19085,6 +21554,54 @@ pci:v00001077d00008070sv00001077sd00000019* + pci:v00001077d00008070sv00001077sd00000039* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic QL41262 PCIe 25Gb 2-Port SFP28 Ethernet Adapter) + ++pci:v00001077d00008070sv00001077sd00000053* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 2x25GE QL41232HQCU NIC) ++ ++pci:v00001077d00008070sv00001077sd00000054* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (2x10GE QL41132HQRJ NIC) ++ ++pci:v00001077d00008070sv00001077sd00000055* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 2x10GE QL41132HQCU NIC) ++ ++pci:v00001077d00008070sv00001077sd00000056* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (2x10GE QL41132HxRJ NIC) ++ ++pci:v00001077d00008070sv00001077sd00000057* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (2x25GE QL41232HxCU NIC) ++ ++pci:v00001077d00008070sv00001077sd00000065* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 4x10GE QL41154HQRJ CNA) ++ ++pci:v00001077d00008070sv00001077sd00000066* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (QLogic 4x10GE QL41154HQCU CNA) ++ ++pci:v00001077d00008070sv00001077sd00000068* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2p SFP+ QL41132HLCU-HC Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000069* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2p BASE-T QL41132HQRJ-HC OCP3 Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000070* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2p BASE-T QL41132HLRJ-HC Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000071* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2p SFP+ QL41132HQCU-HC OCP3 Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000072* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 4p SFP+ QL41134HLCU-HC Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000073* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2p SFP28 QL41232HQCU-HC OCP3 Adapter) ++ ++pci:v00001077d00008070sv00001077sd00000074* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2p SFP28 QL41232HLCU-HC Adapter) ++ ++pci:v00001077d00008070sv00001590sd0000021A* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2P QL41162HLRJ-HP Adapter) ++ ++pci:v00001077d00008070sv00001590sd0000021B* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GbE 2P QL41162HLRJ-HP Adapter) ++ + pci:v00001077d00008070sv00001590sd0000021D* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41222HLCU-HP Adapter) + +@@ -19097,6 +21614,15 @@ pci:v00001077d00008070sv00001590sd0000021F* + pci:v00001077d00008070sv00001590sd00000220* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10/25GbE 2P QL41122HLRJ-HP Adapter) + ++pci:v00001077d00008070sv00001590sd000002BD* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10Gb 2P 524SFP+ NIC) ++ ++pci:v00001077d00008070sv0000193Dsd00001030* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (NIC-ETH681i-Mb-2x25G) ++ ++pci:v00001077d00008070sv0000193Dsd00001032* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (NIC-ETH682i-Mb-2x25G) ++ + pci:v00001077d00008080* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) + +@@ -19133,6 +21659,15 @@ pci:v00001077d00008080sv00001077sd0000000D* + pci:v00001077d00008080sv00001077sd0000000E* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41162H 10GbE FCoE Adapter) + ++pci:v00001077d00008080sv00001077sd0000000F* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (2x25GE QL41262HMKR CNA) ++ ++pci:v00001077d00008080sv00001590sd0000021A* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GbE 2P QL41162HLRJ-HP Adapter) ++ ++pci:v00001077d00008080sv00001590sd0000021B* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GbE 2P QL41162HLRJ-HP Adapter) ++ + pci:v00001077d00008084* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) + +@@ -19172,6 +21707,21 @@ pci:v00001077d00008084sv00001077sd0000000D* + pci:v00001077d00008084sv00001077sd0000000E* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41162H 10GbE iSCSI Adapter) + ++pci:v00001077d00008084sv00001077sd0000000F* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (2x25GE QL41262HMKR CNA) ++ ++pci:v00001077d00008084sv00001077sd00000065* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 4x10GE QL41154HQRJ CNA) ++ ++pci:v00001077d00008084sv00001077sd00000066* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (QLogic 4x10GE QL41154HQCU CNA) ++ ++pci:v00001077d00008084sv00001590sd0000021A* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GbE 2P QL41162HLRJ-HP Adapter) ++ ++pci:v00001077d00008084sv00001590sd0000021B* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GbE 2P QL41162HLRJ-HP Adapter) ++ + pci:v00001077d00008090* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) + +@@ -19211,18 +21761,54 @@ pci:v00001077d00008090sv00001077sd0000000D* + pci:v00001077d00008090sv00001077sd0000000E* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41162H 10GbE iSCSI Adapter (SR-IOV VF)) + ++pci:v00001077d00008090sv00001077sd0000000F* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (2x25GE QL41262HMKR CNA) ++ ++pci:v00001077d00008090sv00001077sd00000010* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (2x25GE QL41232HMKR NIC) ++ + pci:v00001077d00008090sv00001077sd00000011* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41212H 25GbE Adapter (SR-IOV VF)) + + pci:v00001077d00008090sv00001077sd00000012* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41112H 10GbE Adapter (SR-IOV VF)) + ++pci:v00001077d00008090sv00001077sd00000053* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x25GE QL41232HQCU NIC) ++ ++pci:v00001077d00008090sv00001077sd00000054* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x10GE QL41132HQRJ NIC) ++ ++pci:v00001077d00008090sv00001077sd00000055* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 2x10GE QL41132HQCU NIC) ++ ++pci:v00001077d00008090sv00001077sd00000056* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (2x10GE QL41132HxRJ NIC) ++ ++pci:v00001077d00008090sv00001077sd00000057* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (2x25GE QL41232HxCU NIC) ++ ++pci:v00001077d00008090sv00001077sd00000065* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 4x10GE QL41154HQRJ CNA) ++ ++pci:v00001077d00008090sv00001077sd00000066* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (QLogic 4x10GE QL41154HQCU CNA) ++ ++pci:v00001077d00008090sv00001590sd0000021A* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10GbE 2P QL41162HLRJ-HP Adapter) ++ ++pci:v00001077d00008090sv00001590sd0000021B* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10GbE 2P QL41162HLRJ-HP Adapter) ++ + pci:v00001077d00008090sv00001590sd0000021E* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10/25GbE 2P QL41162HMRJ-HP Adapter) + + pci:v00001077d00008090sv00001590sd0000021F* + ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10/25GbE 2P QL41262HMCU-HP Adapter) + ++pci:v00001077d00008090sv00001590sd000002BD* ++ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10Gb 2P 524SFP+ NIC) ++ + pci:v00001077d00008430* + ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller (NIC VF) + +@@ -21908,9 +24494,42 @@ pci:v00001093d0000C4C4sv00001093sd00007803* + pci:v00001093d0000C4C4sv00001093sd00007805* + ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-4305) + ++pci:v00001093d0000C4C4sv00001093sd0000786F* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-4163) ++ + pci:v00001093d0000C4C4sv00001093sd0000788E* + ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-4304) + ++pci:v00001093d0000C4C4sv00001093sd000078F8* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO Module (KU035)) ++ ++pci:v00001093d0000C4C4sv00001093sd000078F9* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO Module (KU040)) ++ ++pci:v00001093d0000C4C4sv00001093sd000078FA* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO Module (KU060)) ++ ++pci:v00001093d0000C4C4sv00001093sd000078FF* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-4162) ++ ++pci:v00001093d0000C4C4sv00001093sd00007995* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7911R) ++ ++pci:v00001093d0000C4C4sv00001093sd00007996* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7912R) ++ ++pci:v00001093d0000C4C4sv00001093sd00007997* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7915R) ++ ++pci:v00001093d0000C4C4sv00001093sd000079D3* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO PCIe Module (KU035)) ++ ++pci:v00001093d0000C4C4sv00001093sd000079D4* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO PCIe Module (KU040)) ++ ++pci:v00001093d0000C4C4sv00001093sd000079D5* ++ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (NI FlexRIO PCIe Module (KU060)) ++ + pci:v00001093d0000C801* + ID_MODEL_FROM_DATABASE=PCI-GPIB + +@@ -22214,6 +24833,9 @@ pci:v0000109Ed0000036Csv000013E9sd00000070* + pci:v0000109Ed0000036E* + ID_MODEL_FROM_DATABASE=Bt878 Video Capture + ++pci:v0000109Ed0000036Esv00000000sd00000001* ++ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Euresys Picolo PCIe) ++ + pci:v0000109Ed0000036Esv00000070sd000013EB* + ID_MODEL_FROM_DATABASE=Bt878 Video Capture (WinTV Series) + +@@ -22448,6 +25070,9 @@ pci:v0000109Ed00000370sv00001852sd00001852* + pci:v0000109Ed00000878* + ID_MODEL_FROM_DATABASE=Bt878 Audio Capture + ++pci:v0000109Ed00000878sv00000000sd00000001* ++ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Euresys Picolo PCIe) ++ + pci:v0000109Ed00000878sv00000070sd000013EB* + ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (WinTV Series) + +@@ -23246,6 +25871,9 @@ pci:v000010B5d00009050sv000010B5sd00003196* + pci:v000010B5d00009050sv000010B5sd00009050* + ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCI-I04 PCI Passive PC/CAN Interface) + ++pci:v000010B5d00009050sv000012FEsd00000001* ++ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (CAN-PCI/331 CAN bus controller) ++ + pci:v000010B5d00009050sv00001369sd00008901* + ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCX11+ PCI) + +@@ -23411,6 +26039,9 @@ pci:v000010B5d00009056sv000010B5sd00002979* + pci:v000010B5d00009056sv000010B5sd00003268* + ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (IXXAT iPC-I XC16/PCIe CAN Board) + ++pci:v000010B5d00009056sv000010B5sd00003334* ++ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Cambridge Pixel HPx Radar Input Card) ++ + pci:v000010B5d00009056sv000010B5sd00003352* + ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe HD: Timecode Reader Board) + +@@ -23429,6 +26060,9 @@ pci:v000010B5d00009056sv000010B5sd00003415* + pci:v000010B5d00009056sv000010B5sd00003493* + ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe 3G: Timecode Reader Board) + ++pci:v000010B5d00009056sv000010B5sd00003565* ++ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Cambridge Pixel HPx Radar Output Card) ++ + pci:v000010B5d00009056sv00001369sd0000C001* + ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (LX6464ES) + +@@ -23531,6 +26165,9 @@ pci:v000010B5d00009733sv00001D49sd00000002* + pci:v000010B5d00009749* + ID_MODEL_FROM_DATABASE=PEX 9749 49-lane, 13-port PCI Express Gen 3 (8.0 GT/s) Switch + ++pci:v000010B5d00009749sv00001D49sd00000004* ++ ID_MODEL_FROM_DATABASE=PEX 9749 49-lane, 13-port PCI Express Gen 3 (8.0 GT/s) Switch (ThinkSystem 1610-8P NVMe Switch Adapter) ++ + pci:v000010B5d0000A100* + ID_MODEL_FROM_DATABASE=Blackmagic Design DeckLink + +@@ -25941,7 +28578,7 @@ pci:v000010DEd000000F4* + ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 LE] + + pci:v000010DEd000000F5* +- ID_MODEL_FROM_DATABASE=G71 [GeForce 7800 GS] ++ ID_MODEL_FROM_DATABASE=G70/G71 [GeForce 7800 GS AGP] + + pci:v000010DEd000000F6* + ID_MODEL_FROM_DATABASE=NV43 [GeForce 6800 GS/XT] +@@ -26120,6 +28757,9 @@ pci:v000010DEd00000112* + pci:v000010DEd00000113* + ID_MODEL_FROM_DATABASE=NV11GL [Quadro2 MXR/EX/Go] + ++pci:v000010DEd00000113sv00001028sd000000E5* ++ ID_MODEL_FROM_DATABASE=NV11GL [Quadro2 MXR/EX/Go] (Quadro2 Go) ++ + pci:v000010DEd00000140* + ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] + +@@ -26423,9 +29063,6 @@ pci:v000010DEd0000018C* + pci:v000010DEd0000018D* + ID_MODEL_FROM_DATABASE=NV18M [GeForce4 448 Go] + +-pci:v000010DEd0000018F* +- ID_MODEL_FROM_DATABASE=NV18 +- + pci:v000010DEd00000190* + ID_MODEL_FROM_DATABASE=G80 [GeForce 8800 GTS / 8800 GTX] + +@@ -26454,7 +29091,7 @@ pci:v000010DEd0000019E* + ID_MODEL_FROM_DATABASE=G80GL [Quadro FX 4600] + + pci:v000010DEd000001A0* +- ID_MODEL_FROM_DATABASE=nForce 220/420 NV11 [GeForce2 MX] ++ ID_MODEL_FROM_DATABASE=nForce 220/420 NV1A [GeForce2 MX] + + pci:v000010DEd000001A4* + ID_MODEL_FROM_DATABASE=nForce CPU bridge +@@ -26613,10 +29250,10 @@ pci:v000010DEd000001EFsv0000A0A0sd000003B9* + ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 5 (UK79G-1394 motherboard) + + pci:v000010DEd000001F0* +- ID_MODEL_FROM_DATABASE=C17 [GeForce4 MX IGP] ++ ID_MODEL_FROM_DATABASE=NV1F C17 [GeForce4 MX IGP] + + pci:v000010DEd000001F0sv0000A0A0sd000003B5* +- ID_MODEL_FROM_DATABASE=C17 [GeForce4 MX IGP] (UK79G-1394 motherboard) ++ ID_MODEL_FROM_DATABASE=NV1F C17 [GeForce4 MX IGP] (UK79G-1394 motherboard) + + pci:v000010DEd00000200* + ID_MODEL_FROM_DATABASE=NV20 [GeForce3] +@@ -27120,31 +29757,34 @@ pci:v000010DEd000002A6* + ID_MODEL_FROM_DATABASE=MCPX Memory Controller + + pci:v000010DEd000002E0* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT] ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT AGP] + + pci:v000010DEd000002E0sv000002E0sd00002249* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT] (GF 7600GT 560M 256MB DDR3 DUAL DVI TV) ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT AGP] (GF 7600GT 560M 256MB DDR3 DUAL DVI TV) + + pci:v000010DEd000002E1* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS AGP] + + pci:v000010DEd000002E1sv00001682sd0000222B* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] (PV-T73K-UAL3 (256MB)) ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS AGP] (PV-T73K-UAL3 (256MB)) + + pci:v000010DEd000002E1sv00001682sd00002247* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] (GF 7600GS 512MB DDR2) ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS AGP] (GF 7600GS 512MB DDR2) + + pci:v000010DEd000002E2* +- ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT] ++ ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT AGP] + + pci:v000010DEd000002E3* +- ID_MODEL_FROM_DATABASE=G71 [GeForce 7900 GS] ++ ID_MODEL_FROM_DATABASE=G71 [GeForce 7900 GS AGP] + + pci:v000010DEd000002E4* +- ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] ++ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT AGP] + + pci:v000010DEd000002E4sv00001682sd00002271* +- ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] (PV-T71A-YDF7 (512MB)) ++ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT AGP] (PV-T71A-YDF7 (512MB)) ++ ++pci:v000010DEd000002E5* ++ ID_MODEL_FROM_DATABASE=G71 [GeForce 7600 GS AGP] + + pci:v000010DEd000002F0* + ID_MODEL_FROM_DATABASE=C51 Host Bridge +@@ -27435,7 +30075,7 @@ pci:v000010DEd00000332* + ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900XT] + + pci:v000010DEd00000333* +- ID_MODEL_FROM_DATABASE=NV38 [GeForce FX 5950 Ultra] ++ ID_MODEL_FROM_DATABASE=NV38 [GeForce FX 5950 Ultra / PCX 5950] + + pci:v000010DEd00000334* + ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900ZT] +@@ -28046,6 +30686,9 @@ pci:v000010DEd00000410* + pci:v000010DEd00000414* + ID_MODEL_FROM_DATABASE=G92 [GeForce 9800 GT] + ++pci:v000010DEd00000418* ++ ID_MODEL_FROM_DATABASE=G92 [GeForce GT 330 OEM] ++ + pci:v000010DEd00000420* + ID_MODEL_FROM_DATABASE=G86 [GeForce 8400 SE] + +@@ -28728,13 +31371,13 @@ pci:v000010DEd0000063F* + ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GE] + + pci:v000010DEd00000640* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9500 GT] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9500 GT] + + pci:v000010DEd00000641* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9400 GT] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9400 GT] + + pci:v000010DEd00000641sv00001682sd00004009* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9400 GT] (PV-T94G-ZAFG) ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9400 GT] (PV-T94G-ZAFG) + + pci:v000010DEd00000642* + ID_MODEL_FROM_DATABASE=G96 [D9M-10] +@@ -28749,22 +31392,22 @@ pci:v000010DEd00000644sv0000174Bsd00009600* + ID_MODEL_FROM_DATABASE=G96 [GeForce 9500 GS] (Geforce 9500GS 512M DDR2 V/D/HDMI) + + pci:v000010DEd00000645* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9500 GS] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9500 GS] + + pci:v000010DEd00000646* +- ID_MODEL_FROM_DATABASE=G96 [GeForce GT 120] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce GT 120] + + pci:v000010DEd00000647* +- ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GT] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce 9600M GT] + + pci:v000010DEd00000648* +- ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GS] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce 9600M GS] + + pci:v000010DEd00000649* +- ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GT] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce 9600M GT] + + pci:v000010DEd00000649sv00001043sd0000202D* +- ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GT] (GeForce GT 220M) ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce 9600M GT] (GeForce GT 220M) + + pci:v000010DEd0000064A* + ID_MODEL_FROM_DATABASE=G96M [GeForce 9700M GT] +@@ -28773,52 +31416,49 @@ pci:v000010DEd0000064B* + ID_MODEL_FROM_DATABASE=G96M [GeForce 9500M G] + + pci:v000010DEd0000064C* +- ID_MODEL_FROM_DATABASE=G96M [GeForce 9650M GT] +- +-pci:v000010DEd0000064D* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9600 GT] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce 9650M GT] + + pci:v000010DEd0000064E* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9600 GT / 9800 GT] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9600 GSO / 9800 GT] + + pci:v000010DEd00000651* +- ID_MODEL_FROM_DATABASE=G96M [GeForce G 110M] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce G 110M] + + pci:v000010DEd00000652* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 130M] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 130M] + + pci:v000010DEd00000652sv0000152Dsd00000850* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 130M] (GeForce GT 240M LE) ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 130M] (GeForce GT 240M LE) + + pci:v000010DEd00000653* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 120M] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 120M] + + pci:v000010DEd00000654* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M] ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 220M] + + pci:v000010DEd00000654sv00001043sd000014A2* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M] (GeForce GT 320M) ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 220M] (GeForce GT 320M) + + pci:v000010DEd00000654sv00001043sd000014D2* +- ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M] (GeForce GT 320M) ++ ID_MODEL_FROM_DATABASE=G96CM [GeForce GT 220M] (GeForce GT 320M) + + pci:v000010DEd00000655* +- ID_MODEL_FROM_DATABASE=G96 [GeForce GT 120] ++ ID_MODEL_FROM_DATABASE=G96 [GeForce GT 120 Mac Edition] + + pci:v000010DEd00000656* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9650 S] ++ ID_MODEL_FROM_DATABASE=G96 [GeForce GT 120 Mac Edition] + + pci:v000010DEd00000658* + ID_MODEL_FROM_DATABASE=G96GL [Quadro FX 380] + + pci:v000010DEd00000659* +- ID_MODEL_FROM_DATABASE=G96GL [Quadro FX 580] ++ ID_MODEL_FROM_DATABASE=G96CGL [Quadro FX 580] + + pci:v000010DEd0000065A* + ID_MODEL_FROM_DATABASE=G96GLM [Quadro FX 1700M] + + pci:v000010DEd0000065B* +- ID_MODEL_FROM_DATABASE=G96 [GeForce 9400 GT] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce 9400 GT] + + pci:v000010DEd0000065C* + ID_MODEL_FROM_DATABASE=G96GLM [Quadro FX 770M] +@@ -28827,7 +31467,7 @@ pci:v000010DEd0000065D* + ID_MODEL_FROM_DATABASE=G96 [GeForce 9500 GA / 9600 GT / GTS 250] + + pci:v000010DEd0000065F* +- ID_MODEL_FROM_DATABASE=G96 [GeForce G210] ++ ID_MODEL_FROM_DATABASE=G96C [GeForce G210] + + pci:v000010DEd000006C0* + ID_MODEL_FROM_DATABASE=GF100 [GeForce GTX 480] +@@ -28844,6 +31484,9 @@ pci:v000010DEd000006CB* + pci:v000010DEd000006CD* + ID_MODEL_FROM_DATABASE=GF100 [GeForce GTX 470] + ++pci:v000010DEd000006D0* ++ ID_MODEL_FROM_DATABASE=GF100GL ++ + pci:v000010DEd000006D1* + ID_MODEL_FROM_DATABASE=GF100GL [Tesla C2050 / C2070] + +@@ -28977,7 +31620,7 @@ pci:v000010DEd000006ED* + ID_MODEL_FROM_DATABASE=G98 [GeForce 9600 GT / 9800 GT] + + pci:v000010DEd000006EE* +- ID_MODEL_FROM_DATABASE=G98 [GeForce 9600 GT / 9800 GT] ++ ID_MODEL_FROM_DATABASE=G98 [GeForce 9600 GT / 9800 GT / GT 240] + + pci:v000010DEd000006EF* + ID_MODEL_FROM_DATABASE=G98M [GeForce G 103M] +@@ -29708,6 +32351,9 @@ pci:v000010DEd00000A22* + pci:v000010DEd00000A23* + ID_MODEL_FROM_DATABASE=GT216 [GeForce 210] + ++pci:v000010DEd00000A24* ++ ID_MODEL_FROM_DATABASE=GT216 [GeForce 405] ++ + pci:v000010DEd00000A26* + ID_MODEL_FROM_DATABASE=GT216 [GeForce 405] + +@@ -30564,7 +33210,7 @@ pci:v000010DEd00000E13* + ID_MODEL_FROM_DATABASE=TegraK1 PCIe x1 Bridge + + pci:v000010DEd00000E1A* +- ID_MODEL_FROM_DATABASE=GK110 HDMI Audio ++ ID_MODEL_FROM_DATABASE=GK110 High Definition Audio Controller + + pci:v000010DEd00000E1B* + ID_MODEL_FROM_DATABASE=GK107 HDMI Audio Controller +@@ -30614,6 +33260,9 @@ pci:v000010DEd00000F01* + pci:v000010DEd00000F02* + ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 730] + ++pci:v000010DEd00000F03* ++ ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 610] ++ + pci:v000010DEd00000F06* + ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 730] + +@@ -30626,9 +33275,15 @@ pci:v000010DEd00000FB8* + pci:v000010DEd00000FB9* + ID_MODEL_FROM_DATABASE=GP107GL High Definition Audio Controller + ++pci:v000010DEd00000FBA* ++ ID_MODEL_FROM_DATABASE=GM206 High Definition Audio Controller ++ + pci:v000010DEd00000FBB* + ID_MODEL_FROM_DATABASE=GM204 High Definition Audio Controller + ++pci:v000010DEd00000FBC* ++ ID_MODEL_FROM_DATABASE=GM107 High Definition Audio Controller [GeForce 940MX] ++ + pci:v000010DEd00000FC0* + ID_MODEL_FROM_DATABASE=GK107 [GeForce GT 640 OEM] + +@@ -30639,7 +33294,7 @@ pci:v000010DEd00000FC2* + ID_MODEL_FROM_DATABASE=GK107 [GeForce GT 630 OEM] + + pci:v000010DEd00000FC5* +- ID_MODEL_FROM_DATABASE=GK107 ++ ID_MODEL_FROM_DATABASE=GK107 [GeForce GT 1030] + + pci:v000010DEd00000FC6* + ID_MODEL_FROM_DATABASE=GK107 [GeForce GTX 650] +@@ -30701,6 +33356,9 @@ pci:v000010DEd00000FD4* + pci:v000010DEd00000FD5* + ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M Mac Edition] + ++pci:v000010DEd00000FD6* ++ ID_MODEL_FROM_DATABASE=GK107M ++ + pci:v000010DEd00000FD8* + ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M Mac Edition] + +@@ -30746,6 +33404,9 @@ pci:v000010DEd00000FE7* + pci:v000010DEd00000FE7sv000010DEsd0000101E* + ID_MODEL_FROM_DATABASE=GK107GL [GRID K100 vGPU] (GRID K100) + ++pci:v000010DEd00000FE8* ++ ID_MODEL_FROM_DATABASE=GK107M ++ + pci:v000010DEd00000FE9* + ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 750M Mac Edition] + +@@ -30858,7 +33519,7 @@ pci:v000010DEd00001007* + ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780 Rev. 2] + + pci:v000010DEd00001008* +- ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780 Ti Rev. 2] ++ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780 Ti 6GB] + + pci:v000010DEd0000100A* + ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX 780 Ti] +@@ -30888,7 +33549,7 @@ pci:v000010DEd00001023sv000010DEsd0000097E* + ID_MODEL_FROM_DATABASE=GK110BGL [Tesla K40m] (12GB Computational Accelerator) + + pci:v000010DEd00001024* +- ID_MODEL_FROM_DATABASE=GK110BGL [Tesla K40c] ++ ID_MODEL_FROM_DATABASE=GK180GL [Tesla K40c] + + pci:v000010DEd00001026* + ID_MODEL_FROM_DATABASE=GK110GL [Tesla K20s] +@@ -31142,6 +33803,18 @@ pci:v000010DEd000010F0* + pci:v000010DEd000010F1* + ID_MODEL_FROM_DATABASE=GP106 High Definition Audio Controller + ++pci:v000010DEd000010F7* ++ ID_MODEL_FROM_DATABASE=TU102 High Definition Audio Controller ++ ++pci:v000010DEd000010F8* ++ ID_MODEL_FROM_DATABASE=TU104 HD Audio Controller ++ ++pci:v000010DEd000010F9* ++ ID_MODEL_FROM_DATABASE=TU106 High Definition Audio Controller ++ ++pci:v000010DEd000010F9sv00001043sd00008673* ++ ID_MODEL_FROM_DATABASE=TU106 High Definition Audio Controller (TURBO-RTX2070-8G) ++ + pci:v000010DEd00001140* + ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M] + +@@ -32198,6 +34871,9 @@ pci:v000010DEd00001185* + pci:v000010DEd00001185sv000010DEsd0000106F* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 OEM] (GK104 [GeForce GTX 760 OEM]) + ++pci:v000010DEd00001186* ++ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 Ti] ++ + pci:v000010DEd00001187* + ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760] + +@@ -32279,17 +34955,20 @@ pci:v000010DEd000011A3sv0000106Bsd0000010D* + pci:v000010DEd000011A7* + ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 675MX] + ++pci:v000010DEd000011A9* ++ ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 870M] ++ + pci:v000010DEd000011AF* + ID_MODEL_FROM_DATABASE=GK104GLM [GRID IceCube] + + pci:v000010DEd000011B0* +- ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU] ++ ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q / K260Q vGPU] + + pci:v000010DEd000011B0sv000010DEsd0000101A* +- ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU] (GRID K240Q) ++ ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q / K260Q vGPU] (GRID K240Q) + + pci:v000010DEd000011B0sv000010DEsd0000101B* +- ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU] (GRID K260Q) ++ ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q / K260Q vGPU] (GRID K260Q) + + pci:v000010DEd000011B1* + ID_MODEL_FROM_DATABASE=GK104GL [GRID K2 Tesla USM] +@@ -32555,12 +35234,21 @@ pci:v000010DEd00001288* + pci:v000010DEd00001289* + ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710] + ++pci:v000010DEd0000128A* ++ ID_MODEL_FROM_DATABASE=GK208B ++ + pci:v000010DEd0000128B* + ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 710] + + pci:v000010DEd0000128Bsv00001043sd000085F7* + ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 710] (GT710-SL-1GD5) + ++pci:v000010DEd0000128Bsv00001043sd00008770* ++ ID_MODEL_FROM_DATABASE=GK208B [GeForce GT 710] (GT710-4H-SL-2GD5) ++ ++pci:v000010DEd0000128C* ++ ID_MODEL_FROM_DATABASE=GK208B ++ + pci:v000010DEd00001290* + ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] + +@@ -32750,6 +35438,9 @@ pci:v000010DEd00001393* + pci:v000010DEd00001398* + ID_MODEL_FROM_DATABASE=GM107M [GeForce 845M] + ++pci:v000010DEd00001399* ++ ID_MODEL_FROM_DATABASE=GM107M [GeForce 945M] ++ + pci:v000010DEd0000139A* + ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 950M] + +@@ -32774,6 +35465,9 @@ pci:v000010DEd0000139Asv000017AAsd000036B9* + pci:v000010DEd0000139B* + ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 960M] + ++pci:v000010DEd0000139Bsv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 960M] (XPS 15 9550) ++ + pci:v000010DEd0000139Bsv0000103Csd00002B4C* + ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 960M] (GeForce GTX 960A) + +@@ -32903,6 +35597,9 @@ pci:v000010DEd00001401* + pci:v000010DEd00001402* + ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 950] + ++pci:v000010DEd00001404* ++ ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960 FAKE] ++ + pci:v000010DEd00001406* + ID_MODEL_FROM_DATABASE=GM206 [GeForce GTX 960 OEM] + +@@ -32912,6 +35609,9 @@ pci:v000010DEd00001407* + pci:v000010DEd00001427* + ID_MODEL_FROM_DATABASE=GM206M [GeForce GTX 965M] + ++pci:v000010DEd00001427sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=GM206M [GeForce GTX 965M] (OMEN-17-w001nv) ++ + pci:v000010DEd00001430* + ID_MODEL_FROM_DATABASE=GM206GL [Quadro M2000] + +@@ -32969,6 +35669,12 @@ pci:v000010DEd0000174E* + pci:v000010DEd00001789* + ID_MODEL_FROM_DATABASE=GM107GL [GRID M3-3020] + ++pci:v000010DEd0000179C* ++ ID_MODEL_FROM_DATABASE=GM107 [GeForce 940MX] ++ ++pci:v000010DEd0000179Csv00001025sd00001094* ++ ID_MODEL_FROM_DATABASE=GM107 [GeForce 940MX] (Acer Aspire E5-575G) ++ + pci:v000010DEd000017C2* + ID_MODEL_FROM_DATABASE=GM200 [GeForce GTX TITAN X] + +@@ -32978,21 +35684,75 @@ pci:v000010DEd000017C8* + pci:v000010DEd000017F0* + ID_MODEL_FROM_DATABASE=GM200GL [Quadro M6000] + ++pci:v000010DEd000017F0sv000010DEsd00001141* ++ ID_MODEL_FROM_DATABASE=GM200GL [Quadro M6000] (VCA 6000) ++ + pci:v000010DEd000017F1* + ID_MODEL_FROM_DATABASE=GM200GL [Quadro M6000 24GB] + + pci:v000010DEd000017FD* + ID_MODEL_FROM_DATABASE=GM200GL [Tesla M40] + ++pci:v000010DEd00001AD0* ++ ID_MODEL_FROM_DATABASE=Tegra PCIe x8 Endpoint ++ ++pci:v000010DEd00001AD1* ++ ID_MODEL_FROM_DATABASE=Tegra PCIe x4/x8 Endpoint/Root Complex ++ ++pci:v000010DEd00001AD2* ++ ID_MODEL_FROM_DATABASE=Tegra PCIe x1 Root Complex ++ ++pci:v000010DEd00001AD3* ++ ID_MODEL_FROM_DATABASE=Xavier SATA Controller ++ ++pci:v000010DEd00001AD6* ++ ID_MODEL_FROM_DATABASE=TU102 USB 3.1 Host Controller ++ ++pci:v000010DEd00001AD7* ++ ID_MODEL_FROM_DATABASE=TU102 USB Type-C UCSI Controller ++ ++pci:v000010DEd00001AD8* ++ ID_MODEL_FROM_DATABASE=TU104 USB 3.1 Host Controller ++ ++pci:v000010DEd00001AD9* ++ ID_MODEL_FROM_DATABASE=TU104 USB Type-C UCSI Controller ++ ++pci:v000010DEd00001ADA* ++ ID_MODEL_FROM_DATABASE=TU106 USB 3.1 Host Controller ++ ++pci:v000010DEd00001ADAsv00001043sd00008673* ++ ID_MODEL_FROM_DATABASE=TU106 USB 3.1 Host Controller (TURBO-RTX2070-8G) ++ ++pci:v000010DEd00001ADB* ++ ID_MODEL_FROM_DATABASE=TU106 USB Type-C UCSI Controller ++ ++pci:v000010DEd00001ADBsv00001043sd00008673* ++ ID_MODEL_FROM_DATABASE=TU106 USB Type-C UCSI Controller (TURBO-RTX2070-8G) ++ ++pci:v000010DEd00001AEB* ++ ID_MODEL_FROM_DATABASE=TU116 High Definition Audio Controller ++ ++pci:v000010DEd00001AEC* ++ ID_MODEL_FROM_DATABASE=TU116 USB 3.1 Host Controller ++ ++pci:v000010DEd00001AED* ++ ID_MODEL_FROM_DATABASE=TU116 USB Type-C UCSI Controller ++ ++pci:v000010DEd00001AEF* ++ ID_MODEL_FROM_DATABASE=GA102 High Definition Audio Controller ++ + pci:v000010DEd00001B00* + ID_MODEL_FROM_DATABASE=GP102 [TITAN X] + + pci:v000010DEd00001B01* +- ID_MODEL_FROM_DATABASE=GP102 ++ ID_MODEL_FROM_DATABASE=GP102 [GeForce GTX 1080 Ti 10GB] + + pci:v000010DEd00001B02* + ID_MODEL_FROM_DATABASE=GP102 [TITAN Xp] + ++pci:v000010DEd00001B04* ++ ID_MODEL_FROM_DATABASE=GP102 ++ + pci:v000010DEd00001B06* + ID_MODEL_FROM_DATABASE=GP102 [GeForce GTX 1080 Ti] + +@@ -33005,6 +35765,9 @@ pci:v000010DEd00001B30* + pci:v000010DEd00001B38* + ID_MODEL_FROM_DATABASE=GP102GL [Tesla P40] + ++pci:v000010DEd00001B39* ++ ID_MODEL_FROM_DATABASE=GP102GL [Tesla P10] ++ + pci:v000010DEd00001B70* + ID_MODEL_FROM_DATABASE=GP102GL + +@@ -33047,6 +35810,15 @@ pci:v000010DEd00001BA1sv00001462sd000011E9* + pci:v000010DEd00001BA1sv00001558sd00009501* + ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile] (GeForce GTX 1070 Max-Q) + ++pci:v000010DEd00001BA2* ++ ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile] ++ ++pci:v000010DEd00001BA9* ++ ID_MODEL_FROM_DATABASE=GP104M ++ ++pci:v000010DEd00001BAA* ++ ID_MODEL_FROM_DATABASE=GP104M ++ + pci:v000010DEd00001BAD* + ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1070 Engineering Sample] + +@@ -33065,6 +35837,9 @@ pci:v000010DEd00001BB4* + pci:v000010DEd00001BB5* + ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5200 Mobile] + ++pci:v000010DEd00001BB5sv0000103Csd0000842F* ++ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5200 Mobile] (P5200 [Zbook 17 G5 mobile workstation]) ++ + pci:v000010DEd00001BB6* + ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5000 Mobile] + +@@ -33080,23 +35855,29 @@ pci:v000010DEd00001BB8* + pci:v000010DEd00001BB9* + ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P4200 Mobile] + ++pci:v000010DEd00001BB9sv0000103Csd0000842F* ++ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P4200 Mobile] (P4200 [Zbook 17 G5 mobile workstation]) ++ + pci:v000010DEd00001BBB* + ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P3200 Mobile] + ++pci:v000010DEd00001BBBsv0000103Csd0000842F* ++ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P3200 Mobile] (P3200 [Zbook 17 G5 moble workstation]) ++ + pci:v000010DEd00001BC7* + ID_MODEL_FROM_DATABASE=GP104 [P104-101] + + pci:v000010DEd00001BE0* +- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile] ++ ID_MODEL_FROM_DATABASE=GP104BM [GeForce GTX 1080 Mobile] + + pci:v000010DEd00001BE0sv00001028sd000007C0* +- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile] (GeForce GTX 1080 Max-Q) ++ ID_MODEL_FROM_DATABASE=GP104BM [GeForce GTX 1080 Mobile] (GeForce GTX 1080 Max-Q) + + pci:v000010DEd00001BE0sv00001458sd0000355B* +- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile] (GeForce GTX 1080 Max-Q) ++ ID_MODEL_FROM_DATABASE=GP104BM [GeForce GTX 1080 Mobile] (GeForce GTX 1080 Max-Q) + + pci:v000010DEd00001BE1* +- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile] ++ ID_MODEL_FROM_DATABASE=GP104BM [GeForce GTX 1070 Mobile] + + pci:v000010DEd00001C00* + ID_MODEL_FROM_DATABASE=GP106 +@@ -33134,36 +35915,57 @@ pci:v000010DEd00001C21* + pci:v000010DEd00001C22* + ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Mobile] + ++pci:v000010DEd00001C23* ++ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile Rev. 2] ++ ++pci:v000010DEd00001C23sv00001414sd00000020* ++ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile Rev. 2] (GTX 1060 Mobile) ++ ++pci:v000010DEd00001C2D* ++ ID_MODEL_FROM_DATABASE=GP106M ++ + pci:v000010DEd00001C30* + ID_MODEL_FROM_DATABASE=GP106GL [Quadro P2000] + ++pci:v000010DEd00001C31* ++ ID_MODEL_FROM_DATABASE=GP106GL [Quadro P2200] ++ + pci:v000010DEd00001C35* +- ID_MODEL_FROM_DATABASE=GP106 ++ ID_MODEL_FROM_DATABASE=GP106M [Quadro P2000 Mobile] ++ ++pci:v000010DEd00001C36* ++ ID_MODEL_FROM_DATABASE=GP106 [P106M] + + pci:v000010DEd00001C60* +- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile 6GB] ++ ID_MODEL_FROM_DATABASE=GP106BM [GeForce GTX 1060 Mobile 6GB] + + pci:v000010DEd00001C60sv0000103Csd00008390* +- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile 6GB] (GeForce GTX 1060 Max-Q 6GB) ++ ID_MODEL_FROM_DATABASE=GP106BM [GeForce GTX 1060 Mobile 6GB] (GeForce GTX 1060 Max-Q 6GB) + + pci:v000010DEd00001C61* +- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Ti Mobile] ++ ID_MODEL_FROM_DATABASE=GP106BM [GeForce GTX 1050 Ti Mobile] + + pci:v000010DEd00001C62* +- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Mobile] ++ ID_MODEL_FROM_DATABASE=GP106BM [GeForce GTX 1050 Mobile] + + pci:v000010DEd00001C70* + ID_MODEL_FROM_DATABASE=GP106GL + +-pci:v000010DEd00001C80* +- ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 3GB] +- + pci:v000010DEd00001C81* + ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050] + + pci:v000010DEd00001C82* + ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 Ti] + ++pci:v000010DEd00001C82sv00001043sd00008613* ++ ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 Ti] (PH-GTX1050TI-4G) ++ ++pci:v000010DEd00001C82sv00001458sd00003763* ++ ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 Ti] (GV-N105TOC-4GD) ++ ++pci:v000010DEd00001C83* ++ ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 3GB] ++ + pci:v000010DEd00001C8C* + ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 Ti Mobile] + +@@ -33173,6 +35975,24 @@ pci:v000010DEd00001C8D* + pci:v000010DEd00001C8E* + ID_MODEL_FROM_DATABASE=GP107M + ++pci:v000010DEd00001C8F* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 Ti Max-Q] ++ ++pci:v000010DEd00001C90* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce MX150] ++ ++pci:v000010DEd00001C91* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 3 GB Max-Q] ++ ++pci:v000010DEd00001C92* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 Mobile] ++ ++pci:v000010DEd00001C94* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce MX350] ++ ++pci:v000010DEd00001C96* ++ ID_MODEL_FROM_DATABASE=GP107M [GeForce MX350] ++ + pci:v000010DEd00001CA7* + ID_MODEL_FROM_DATABASE=GP107GL + +@@ -33197,33 +36017,90 @@ pci:v000010DEd00001CB6* + pci:v000010DEd00001CBA* + ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P2000 Mobile] + ++pci:v000010DEd00001CBAsv0000103Csd0000842C* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P2000 Mobile] (P2000 [Zbook 15 G5 mobile workstation]) ++ ++pci:v000010DEd00001CBAsv0000103Csd0000842F* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P2000 Mobile] (P2000 [Zbook 17 G5 mobile workstation]) ++ + pci:v000010DEd00001CBB* + ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P1000 Mobile] + ++pci:v000010DEd00001CBBsv0000103Csd00008429* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P1000 Mobile] (P1000 [Zbook Studio G5 mobile workstation]) ++ ++pci:v000010DEd00001CBBsv0000103Csd0000842C* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P1000 Mobile] (P1000 [Zbook 15 G5 mobile workstation]) ++ ++pci:v000010DEd00001CBBsv0000103Csd0000842F* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P1000 Mobile] (P1000 [Zbook 17 G5 mobile workstation]) ++ ++pci:v000010DEd00001CBBsv0000103Csd00008451* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P1000 Mobile] (P1000 [Zbook Studio x360 G5 mobile workstation]) ++ + pci:v000010DEd00001CBC* + ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P600 Mobile] + ++pci:v000010DEd00001CBD* ++ ID_MODEL_FROM_DATABASE=GP107GLM [Quadro P620] ++ ++pci:v000010DEd00001CCC* ++ ID_MODEL_FROM_DATABASE=GP107BM [GeForce GTX 1050 Ti Mobile] ++ ++pci:v000010DEd00001CCD* ++ ID_MODEL_FROM_DATABASE=GP107BM [GeForce GTX 1050 Mobile] ++ ++pci:v000010DEd00001CFA* ++ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P2000] ++ ++pci:v000010DEd00001CFB* ++ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P1000] ++ + pci:v000010DEd00001D01* + ID_MODEL_FROM_DATABASE=GP108 [GeForce GT 1030] + + pci:v000010DEd00001D10* + ID_MODEL_FROM_DATABASE=GP108M [GeForce MX150] + ++pci:v000010DEd00001D10sv000017AAsd0000225E* ++ ID_MODEL_FROM_DATABASE=GP108M [GeForce MX150] (ThinkPad T480) ++ ++pci:v000010DEd00001D11* ++ ID_MODEL_FROM_DATABASE=GP108M [GeForce MX230] ++ + pci:v000010DEd00001D12* + ID_MODEL_FROM_DATABASE=GP108M [GeForce MX150] + + pci:v000010DEd00001D12sv00001D72sd00001701* + ID_MODEL_FROM_DATABASE=GP108M [GeForce MX150] (Mi Notebook Pro [GeForce MX150]) + ++pci:v000010DEd00001D13* ++ ID_MODEL_FROM_DATABASE=GP108M [GeForce MX250] ++ ++pci:v000010DEd00001D16* ++ ID_MODEL_FROM_DATABASE=GP108M [GeForce MX330] ++ + pci:v000010DEd00001D33* + ID_MODEL_FROM_DATABASE=GP108GLM [Quadro P500 Mobile] + ++pci:v000010DEd00001D34* ++ ID_MODEL_FROM_DATABASE=GP108GLM [Quadro P520] ++ ++pci:v000010DEd00001D52* ++ ID_MODEL_FROM_DATABASE=GP108BM [GeForce MX250] ++ ++pci:v000010DEd00001D56* ++ ID_MODEL_FROM_DATABASE=GP108BM [GeForce MX330] ++ + pci:v000010DEd00001D81* + ID_MODEL_FROM_DATABASE=GV100 [TITAN V] + + pci:v000010DEd00001DB1* + ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 SXM2 16GB] + ++pci:v000010DEd00001DB2* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 DGXS 16GB] ++ + pci:v000010DEd00001DB3* + ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 FHHL 16GB] + +@@ -33239,9 +36116,561 @@ pci:v000010DEd00001DB6* + pci:v000010DEd00001DB7* + ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 DGXS 32GB] + ++pci:v000010DEd00001DB8* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 SXM3 32GB] ++ ++pci:v000010DEd00001DB8sv000010DEsd0000131D* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 SXM3 32GB] (Tesla V100-SXM3-32GB-H) ++ + pci:v000010DEd00001DBA* + ID_MODEL_FROM_DATABASE=GV100GL [Quadro GV100] + ++pci:v000010DEd00001DBAsv000010DEsd000012EB* ++ ID_MODEL_FROM_DATABASE=GV100GL [Quadro GV100] (TITAN V CEO Edition) ++ ++pci:v000010DEd00001DF0* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla PG500-216] ++ ++pci:v000010DEd00001DF2* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla PG503-216] ++ ++pci:v000010DEd00001DF5* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100 SXM2 16GB] ++ ++pci:v000010DEd00001DF6* ++ ID_MODEL_FROM_DATABASE=GV100GL [Tesla V100S PCIe 32GB] ++ ++pci:v000010DEd00001E02* ++ ID_MODEL_FROM_DATABASE=TU102 [TITAN RTX] ++ ++pci:v000010DEd00001E04* ++ ID_MODEL_FROM_DATABASE=TU102 [GeForce RTX 2080 Ti] ++ ++pci:v000010DEd00001E07* ++ ID_MODEL_FROM_DATABASE=TU102 [GeForce RTX 2080 Ti Rev. A] ++ ++pci:v000010DEd00001E07sv00001462sd00003715* ++ ID_MODEL_FROM_DATABASE=TU102 [GeForce RTX 2080 Ti Rev. A] (RTX 2080 Ti GAMING X TRIO) ++ ++pci:v000010DEd00001E09* ++ ID_MODEL_FROM_DATABASE=TU102 [CMP 50HX] ++ ++pci:v000010DEd00001E2D* ++ ID_MODEL_FROM_DATABASE=TU102 [GeForce RTX 2080 Ti Engineering Sample] ++ ++pci:v000010DEd00001E2E* ++ ID_MODEL_FROM_DATABASE=TU102 [GeForce RTX 2080 Ti 12GB Engineering Sample] ++ ++pci:v000010DEd00001E30* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] ++ ++pci:v000010DEd00001E30sv000010DEsd0000129E* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] (Quadro RTX 8000) ++ ++pci:v000010DEd00001E30sv000010DEsd000012BA* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] (Quadro RTX 6000) ++ ++pci:v000010DEd00001E36* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000] ++ ++pci:v000010DEd00001E37* ++ ID_MODEL_FROM_DATABASE=TU102GL [GRID RTX T10-4/T10-8/T10-16] ++ ++pci:v000010DEd00001E37sv000010DEsd00001347* ++ ID_MODEL_FROM_DATABASE=TU102GL [GRID RTX T10-4/T10-8/T10-16] (GRID RTX T10-8) ++ ++pci:v000010DEd00001E37sv000010DEsd00001348* ++ ID_MODEL_FROM_DATABASE=TU102GL [GRID RTX T10-4/T10-8/T10-16] (GRID RTX T10-4) ++ ++pci:v000010DEd00001E37sv000010DEsd00001370* ++ ID_MODEL_FROM_DATABASE=TU102GL [GRID RTX T10-4/T10-8/T10-16] (GRID RTX T10-16) ++ ++pci:v000010DEd00001E38* ++ ID_MODEL_FROM_DATABASE=TU102GL ++ ++pci:v000010DEd00001E3C* ++ ID_MODEL_FROM_DATABASE=TU102GL ++ ++pci:v000010DEd00001E3D* ++ ID_MODEL_FROM_DATABASE=TU102GL ++ ++pci:v000010DEd00001E3E* ++ ID_MODEL_FROM_DATABASE=TU102GL ++ ++pci:v000010DEd00001E78* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] ++ ++pci:v000010DEd00001E78sv000010DEsd000013D8* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] (Quadro RTX 8000) ++ ++pci:v000010DEd00001E78sv000010DEsd000013D9* ++ ID_MODEL_FROM_DATABASE=TU102GL [Quadro RTX 6000/8000] (Quadro RTX 6000) ++ ++pci:v000010DEd00001E81* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2080 SUPER] ++ ++pci:v000010DEd00001E82* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2080] ++ ++pci:v000010DEd00001E84* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2070 SUPER] ++ ++pci:v000010DEd00001E87* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2080 Rev. A] ++ ++pci:v000010DEd00001E89* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2060] ++ ++pci:v000010DEd00001E90* ++ ID_MODEL_FROM_DATABASE=TU104M [GeForce RTX 2080 Mobile] ++ ++pci:v000010DEd00001E91* ++ ID_MODEL_FROM_DATABASE=TU104M [GeForce RTX 2070 SUPER Mobile / Max-Q] ++ ++pci:v000010DEd00001E93* ++ ID_MODEL_FROM_DATABASE=TU104M [GeForce RTX 2080 SUPER Mobile / Max-Q] ++ ++pci:v000010DEd00001EAB* ++ ID_MODEL_FROM_DATABASE=TU104M ++ ++pci:v000010DEd00001EAE* ++ ID_MODEL_FROM_DATABASE=TU104M ++ ++pci:v000010DEd00001EB0* ++ ID_MODEL_FROM_DATABASE=TU104GL [Quadro RTX 5000] ++ ++pci:v000010DEd00001EB1* ++ ID_MODEL_FROM_DATABASE=TU104GL [Quadro RTX 4000] ++ ++pci:v000010DEd00001EB5* ++ ID_MODEL_FROM_DATABASE=TU104GLM [Quadro RTX 5000 Mobile / Max-Q] ++ ++pci:v000010DEd00001EB6* ++ ID_MODEL_FROM_DATABASE=TU104GLM [Quadro RTX 4000 Mobile / Max-Q] ++ ++pci:v000010DEd00001EB8* ++ ID_MODEL_FROM_DATABASE=TU104GL [Tesla T4] ++ ++pci:v000010DEd00001EB9* ++ ID_MODEL_FROM_DATABASE=TU104GL ++ ++pci:v000010DEd00001EBE* ++ ID_MODEL_FROM_DATABASE=TU104GL ++ ++pci:v000010DEd00001EC2* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2070 SUPER] ++ ++pci:v000010DEd00001EC7* ++ ID_MODEL_FROM_DATABASE=TU104 [GeForce RTX 2070 SUPER] ++ ++pci:v000010DEd00001ED0* ++ ID_MODEL_FROM_DATABASE=TU104BM [GeForce RTX 2080 Mobile] ++ ++pci:v000010DEd00001ED1* ++ ID_MODEL_FROM_DATABASE=TU104BM [GeForce RTX 2070 SUPER Mobile / Max-Q] ++ ++pci:v000010DEd00001ED3* ++ ID_MODEL_FROM_DATABASE=TU104BM [GeForce RTX 2080 SUPER Mobile / Max-Q] ++ ++pci:v000010DEd00001EF5* ++ ID_MODEL_FROM_DATABASE=TU104GLM [Quadro RTX 5000 Mobile Refresh] ++ ++pci:v000010DEd00001F02* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2070] ++ ++pci:v000010DEd00001F02sv00001043sd00008673* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2070] (TURBO RTX 2070) ++ ++pci:v000010DEd00001F04* ++ ID_MODEL_FROM_DATABASE=TU106 ++ ++pci:v000010DEd00001F06* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2060 SUPER] ++ ++pci:v000010DEd00001F07* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2070 Rev. A] ++ ++pci:v000010DEd00001F08* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2060 Rev. A] ++ ++pci:v000010DEd00001F09* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce GTX 1660 SUPER] ++ ++pci:v000010DEd00001F0A* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce GTX 1650] ++ ++pci:v000010DEd00001F0B* ++ ID_MODEL_FROM_DATABASE=TU106 [CMP 40HX] ++ ++pci:v000010DEd00001F10* ++ ID_MODEL_FROM_DATABASE=TU106M [GeForce RTX 2070 Mobile] ++ ++pci:v000010DEd00001F11* ++ ID_MODEL_FROM_DATABASE=TU106M [GeForce RTX 2060 Mobile] ++ ++pci:v000010DEd00001F12* ++ ID_MODEL_FROM_DATABASE=TU106M [GeForce RTX 2060 Max-Q] ++ ++pci:v000010DEd00001F14* ++ ID_MODEL_FROM_DATABASE=TU106M [GeForce RTX 2070 Mobile / Max-Q Refresh] ++ ++pci:v000010DEd00001F15* ++ ID_MODEL_FROM_DATABASE=TU106M [GeForce RTX 2060 Mobile] ++ ++pci:v000010DEd00001F2E* ++ ID_MODEL_FROM_DATABASE=TU106M ++ ++pci:v000010DEd00001F36* ++ ID_MODEL_FROM_DATABASE=TU106GLM [Quadro RTX 3000 Mobile / Max-Q] ++ ++pci:v000010DEd00001F42* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2060 SUPER] ++ ++pci:v000010DEd00001F47* ++ ID_MODEL_FROM_DATABASE=TU106 [GeForce RTX 2060 SUPER] ++ ++pci:v000010DEd00001F50* ++ ID_MODEL_FROM_DATABASE=TU106BM [GeForce RTX 2070 Mobile / Max-Q] ++ ++pci:v000010DEd00001F51* ++ ID_MODEL_FROM_DATABASE=TU106BM [GeForce RTX 2060 Mobile] ++ ++pci:v000010DEd00001F54* ++ ID_MODEL_FROM_DATABASE=TU106BM [GeForce RTX 2070 Mobile] ++ ++pci:v000010DEd00001F55* ++ ID_MODEL_FROM_DATABASE=TU106BM [GeForce RTX 2060 Mobile] ++ ++pci:v000010DEd00001F76* ++ ID_MODEL_FROM_DATABASE=TU106GLM [Quadro RTX 3000 Mobile Refresh] ++ ++pci:v000010DEd00001F81* ++ ID_MODEL_FROM_DATABASE=TU117 ++ ++pci:v000010DEd00001F82* ++ ID_MODEL_FROM_DATABASE=TU117 [GeForce GTX 1650] ++ ++pci:v000010DEd00001F91* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Mobile / Max-Q] ++ ++pci:v000010DEd00001F92* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Mobile] ++ ++pci:v000010DEd00001F94* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Mobile] ++ ++pci:v000010DEd00001F95* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Ti Mobile] ++ ++pci:v000010DEd00001F96* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Mobile / Max-Q] ++ ++pci:v000010DEd00001F97* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce MX450] ++ ++pci:v000010DEd00001F98* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce MX450] ++ ++pci:v000010DEd00001F99* ++ ID_MODEL_FROM_DATABASE=TU117M ++ ++pci:v000010DEd00001F9C* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce MX450] ++ ++pci:v000010DEd00001F9D* ++ ID_MODEL_FROM_DATABASE=TU117M [GeForce GTX 1650 Mobile / Max-Q] ++ ++pci:v000010DEd00001FAE* ++ ID_MODEL_FROM_DATABASE=TU117GL ++ ++pci:v000010DEd00001FB0* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T1000 Mobile] ++ ++pci:v000010DEd00001FB1* ++ ID_MODEL_FROM_DATABASE=TU117GL [T600] ++ ++pci:v000010DEd00001FB2* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T400 Mobile] ++ ++pci:v000010DEd00001FB8* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T2000 Mobile / Max-Q] ++ ++pci:v000010DEd00001FB9* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T1000 Mobile] ++ ++pci:v000010DEd00001FBA* ++ ID_MODEL_FROM_DATABASE=TU117GLM [T600 Mobile] ++ ++pci:v000010DEd00001FBB* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T500 Mobile] ++ ++pci:v000010DEd00001FBF* ++ ID_MODEL_FROM_DATABASE=TU117GL ++ ++pci:v000010DEd00001FD9* ++ ID_MODEL_FROM_DATABASE=TU117BM [GeForce GTX 1650 Mobile Refresh] ++ ++pci:v000010DEd00001FDD* ++ ID_MODEL_FROM_DATABASE=TU117BM [GeForce GTX 1650 Mobile Refresh] ++ ++pci:v000010DEd00001FF9* ++ ID_MODEL_FROM_DATABASE=TU117GLM [Quadro T1000 Mobile] ++ ++pci:v000010DEd000020B0* ++ ID_MODEL_FROM_DATABASE=GA100 [A100 SXM4 40GB] ++ ++pci:v000010DEd000020B1* ++ ID_MODEL_FROM_DATABASE=GA100 [A100 PCIe 40GB] ++ ++pci:v000010DEd000020B2* ++ ID_MODEL_FROM_DATABASE=GA100 [A100 SXM4 80GB] ++ ++pci:v000010DEd000020B5* ++ ID_MODEL_FROM_DATABASE=GA100 [A100 PCIe 80GB] ++ ++pci:v000010DEd000020B6* ++ ID_MODEL_FROM_DATABASE=GA100GL [PG506-232] ++ ++pci:v000010DEd000020B7* ++ ID_MODEL_FROM_DATABASE=GA100GL [A30 PCIe] ++ ++pci:v000010DEd000020BE* ++ ID_MODEL_FROM_DATABASE=GA100 [GRID A100A] ++ ++pci:v000010DEd000020BF* ++ ID_MODEL_FROM_DATABASE=GA100 [GRID A100B] ++ ++pci:v000010DEd000020F1* ++ ID_MODEL_FROM_DATABASE=GA100 [A100 PCIe 40GB] ++ ++pci:v000010DEd00002182* ++ ID_MODEL_FROM_DATABASE=TU116 [GeForce GTX 1660 Ti] ++ ++pci:v000010DEd00002183* ++ ID_MODEL_FROM_DATABASE=TU116 ++ ++pci:v000010DEd00002184* ++ ID_MODEL_FROM_DATABASE=TU116 [GeForce GTX 1660] ++ ++pci:v000010DEd00002187* ++ ID_MODEL_FROM_DATABASE=TU116 [GeForce GTX 1650 SUPER] ++ ++pci:v000010DEd00002188* ++ ID_MODEL_FROM_DATABASE=TU116 [GeForce GTX 1650] ++ ++pci:v000010DEd00002189* ++ ID_MODEL_FROM_DATABASE=TU116 [CMP 30HX] ++ ++pci:v000010DEd00002191* ++ ID_MODEL_FROM_DATABASE=TU116M [GeForce GTX 1660 Ti Mobile] ++ ++pci:v000010DEd00002192* ++ ID_MODEL_FROM_DATABASE=TU116M [GeForce GTX 1650 Ti Mobile] ++ ++pci:v000010DEd000021AE* ++ ID_MODEL_FROM_DATABASE=TU116GL ++ ++pci:v000010DEd000021BF* ++ ID_MODEL_FROM_DATABASE=TU116GL ++ ++pci:v000010DEd000021C2* ++ ID_MODEL_FROM_DATABASE=TU116 ++ ++pci:v000010DEd000021C4* ++ ID_MODEL_FROM_DATABASE=TU116 [GeForce GTX 1660 SUPER] ++ ++pci:v000010DEd000021D1* ++ ID_MODEL_FROM_DATABASE=TU116BM [GeForce GTX 1660 Ti Mobile] ++ ++pci:v000010DEd00002200* ++ ID_MODEL_FROM_DATABASE=GA102 ++ ++pci:v000010DEd00002204* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3090] ++ ++pci:v000010DEd00002205* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 20GB] ++ ++pci:v000010DEd00002206* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080] ++ ++pci:v000010DEd00002206sv000010DEsd00001467* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080] ++ ++pci:v000010DEd00002206sv000010DEsd0000146D* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080] (GA102 [GeForce RTX 3080 20GB]) ++ ++pci:v000010DEd00002206sv00001462sd00003892* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080] (RTX 3080 10GB GAMING X TRIO) ++ ++pci:v000010DEd00002208* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 Ti] ++ ++pci:v000010DEd0000220D* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 Lite Hash Rate] ++ ++pci:v000010DEd00002216* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 Lite Hash Rate] ++ ++pci:v000010DEd0000222B* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3090 Engineering Sample] ++ ++pci:v000010DEd0000222F* ++ ID_MODEL_FROM_DATABASE=GA102 [GeForce RTX 3080 11GB / 12GB Engineering Sample] ++ ++pci:v000010DEd00002230* ++ ID_MODEL_FROM_DATABASE=GA102GL [RTX A6000] ++ ++pci:v000010DEd00002231* ++ ID_MODEL_FROM_DATABASE=GA102GL [RTX A5000] ++ ++pci:v000010DEd00002235* ++ ID_MODEL_FROM_DATABASE=GA102GL [A40] ++ ++pci:v000010DEd00002236* ++ ID_MODEL_FROM_DATABASE=GA102GL [A10] ++ ++pci:v000010DEd00002237* ++ ID_MODEL_FROM_DATABASE=GA102GL [A10G] ++ ++pci:v000010DEd0000223F* ++ ID_MODEL_FROM_DATABASE=GA102GL ++ ++pci:v000010DEd0000228B* ++ ID_MODEL_FROM_DATABASE=GA104 High Definition Audio Controller ++ ++pci:v000010DEd00002296* ++ ID_MODEL_FROM_DATABASE=Tegra PCIe Endpoint Virtual Network ++ ++pci:v000010DEd00002302* ++ ID_MODEL_FROM_DATABASE=GA103 ++ ++pci:v000010DEd00002321* ++ ID_MODEL_FROM_DATABASE=GA103 ++ ++pci:v000010DEd00002482* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070 Ti] ++ ++pci:v000010DEd00002483* ++ ID_MODEL_FROM_DATABASE=GA104 ++ ++pci:v000010DEd00002484* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070] ++ ++pci:v000010DEd00002484sv000010DEsd0000146B* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070] ++ ++pci:v000010DEd00002484sv000010DEsd000014AE* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070] (GA104 [GeForce RTX 3070 16GB]) ++ ++pci:v000010DEd00002486* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3060 Ti] ++ ++pci:v000010DEd00002488* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070 Lite Hash Rate] ++ ++pci:v000010DEd00002489* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3060 Ti Lite Hash Rate] ++ ++pci:v000010DEd0000249C* ++ ID_MODEL_FROM_DATABASE=GA104M [GeForce RTX 3080 Mobile / Max-Q 8GB/16GB] ++ ++pci:v000010DEd0000249D* ++ ID_MODEL_FROM_DATABASE=GA104M [GeForce RTX 3070 Mobile / Max-Q] ++ ++pci:v000010DEd0000249F* ++ ID_MODEL_FROM_DATABASE=GA104M ++ ++pci:v000010DEd000024AC* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 30x0 Engineering Sample] ++ ++pci:v000010DEd000024AD* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3060 Engineering Sample] ++ ++pci:v000010DEd000024AF* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070 Engineering Sample] ++ ++pci:v000010DEd000024B0* ++ ID_MODEL_FROM_DATABASE=GA104GL [RTX A4000] ++ ++pci:v000010DEd000024B6* ++ ID_MODEL_FROM_DATABASE=GA104GLM [RTX A5000 Mobile] ++ ++pci:v000010DEd000024B7* ++ ID_MODEL_FROM_DATABASE=GA104GLM [RTX A4000 Mobile] ++ ++pci:v000010DEd000024B8* ++ ID_MODEL_FROM_DATABASE=GA104GLM [RTX A3000 Mobile] ++ ++pci:v000010DEd000024BF* ++ ID_MODEL_FROM_DATABASE=GA104 [GeForce RTX 3070 Engineering Sample] ++ ++pci:v000010DEd000024DC* ++ ID_MODEL_FROM_DATABASE=GA104M [GeForce RTX 3080 Mobile / Max-Q 8GB/16GB] ++ ++pci:v000010DEd000024DD* ++ ID_MODEL_FROM_DATABASE=GA104M [GeForce RTX 3070 Mobile / Max-Q] ++ ++pci:v000010DEd00002501* ++ ID_MODEL_FROM_DATABASE=GA106 [GeForce RTX 3060] ++ ++pci:v000010DEd00002503* ++ ID_MODEL_FROM_DATABASE=GA106 [GeForce RTX 3060] ++ ++pci:v000010DEd00002504* ++ ID_MODEL_FROM_DATABASE=GA106 [GeForce RTX 3060 Lite Hash Rate] ++ ++pci:v000010DEd00002505* ++ ID_MODEL_FROM_DATABASE=GA106 ++ ++pci:v000010DEd00002520* ++ ID_MODEL_FROM_DATABASE=GA106M [GeForce RTX 3060 Mobile / Max-Q] ++ ++pci:v000010DEd00002523* ++ ID_MODEL_FROM_DATABASE=GA106M [GeForce RTX 3050 Ti Mobile / Max-Q] ++ ++pci:v000010DEd0000252F* ++ ID_MODEL_FROM_DATABASE=GA106 [GeForce RTX 3060 Engineering Sample] ++ ++pci:v000010DEd00002560* ++ ID_MODEL_FROM_DATABASE=GA106M [GeForce RTX 3060 Mobile / Max-Q] ++ ++pci:v000010DEd00002563* ++ ID_MODEL_FROM_DATABASE=GA106M [GeForce RTX 3050 Ti Mobile / Max-Q] ++ ++pci:v000010DEd00002583* ++ ID_MODEL_FROM_DATABASE=GA107 [GeForce RTX 3050] ++ ++pci:v000010DEd000025A0* ++ ID_MODEL_FROM_DATABASE=GA107M [GeForce RTX 3050 Ti Mobile] ++ ++pci:v000010DEd000025A2* ++ ID_MODEL_FROM_DATABASE=GA107M [GeForce RTX 3050 Mobile] ++ ++pci:v000010DEd000025A4* ++ ID_MODEL_FROM_DATABASE=GA107 ++ ++pci:v000010DEd000025A5* ++ ID_MODEL_FROM_DATABASE=GA107M [GeForce RTX 3050 Mobile] ++ ++pci:v000010DEd000025AF* ++ ID_MODEL_FROM_DATABASE=GA107 [GeForce RTX 3050 Engineering Sample] ++ ++pci:v000010DEd000025B5* ++ ID_MODEL_FROM_DATABASE=GA107GLM [RTX A4 Mobile] ++ ++pci:v000010DEd000025B8* ++ ID_MODEL_FROM_DATABASE=GA107GLM [RTX A2000 Mobile] ++ ++pci:v000010DEd000025E0* ++ ID_MODEL_FROM_DATABASE=GA107BM [GeForce RTX 3050 Ti Mobile] ++ ++pci:v000010DEd000025E2* ++ ID_MODEL_FROM_DATABASE=GA107BM [GeForce RTX 3050 Mobile] ++ ++pci:v000010DEd000025E5* ++ ID_MODEL_FROM_DATABASE=GA107BM [GeForce RTX 3050 Mobile] ++ + pci:v000010DF* + ID_VENDOR_FROM_DATABASE=Emulex Corporation + +@@ -33312,13 +36741,25 @@ pci:v000010DFd0000E180* + ID_MODEL_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter + + pci:v000010DFd0000E200* +- ID_MODEL_FROM_DATABASE=LightPulse LPe16002 ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter + + pci:v000010DFd0000E200sv00001014sd000003F1* +- ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (PCIe2 16 Gb 2-port Fibre Channel Adapter (FC EL5B; CCIN 577F)) ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (PCIe2 2-Port 16Gb Fibre Channel Adapter for POWER (FC EL5B; CCIN 577F)) ++ ++pci:v000010DFd0000E200sv00001014sd000004E3* ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (PCIe3 4-Port 10GbE SR Adapter for POWER (FC EN15/EN16; CCIN 2CE3)) ++ ++pci:v000010DFd0000E200sv00001014sd000004E4* ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (PCIe3 4-Port 10GbE SFP+ Adapter for POWER (FC EN18; CCIN 2CE4)) ++ ++pci:v000010DFd0000E200sv000010DFsd0000E280* ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (LPe16002B-M6 2-Port 16Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E200sv000010DFsd0000E281* ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (LPe16000B-M6 1-Port 16Gb Fibre Channel Adapter) + + pci:v000010DFd0000E200sv000010DFsd0000E282* +- ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (Flex System FC5054 4-port 16Gb FC Adapter) ++ ID_MODEL_FROM_DATABASE=LPe15000/LPe16000 Series 8Gb/16Gb Fibre Channel Adapter (Flex System FC5054 4-port 16Gb FC Adapter) + + pci:v000010DFd0000E208* + ID_MODEL_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF) +@@ -33342,25 +36783,76 @@ pci:v000010DFd0000E268* + ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Converged Network Adapter (Lancer-VF) + + pci:v000010DFd0000E300* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter ++ ++pci:v000010DFd0000E300sv00001014sd00000614* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (PCIe3 4-Port 16Gb Fibre Channel Adapter for POWER (FC EN1C/EN1D; CCIN 578E)) ++ ++pci:v000010DFd0000E300sv00001014sd00000615* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (PCIe3 2-Port 32Gb Fibre Channel Adapter for POWER (FC EN1A/EN1B; CCIN 578F)) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E300* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32002-M2 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E301* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32000-M2 1-Port 32Gb Fibre Channel Adapter) + + pci:v000010DFd0000E300sv000010DFsd0000E310* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31002-M6 2-Port 16Gb Fibre Channel Adapter) + + pci:v000010DFd0000E300sv000010DFsd0000E311* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31000-M6 1-Port 16Gb Fibre Channel Adapter) + + pci:v000010DFd0000E300sv000010DFsd0000E312* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31004-M6 4-Port 16Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E320* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32002-M2-D 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E321* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32000-M2-D 1-Port 32Gb Fibre Channel Adapter) + + pci:v000010DFd0000E300sv000010DFsd0000E322* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31002-M6-D 2-Port 16Gb Fibre Channel Adapter) + + pci:v000010DFd0000E300sv000010DFsd0000E323* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31000-M6-D 1-Port 16Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E324* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPm32002-D 2-Port 32Gb Fibre Channel Mezz Card) + + pci:v000010DFd0000E300sv000010DFsd0000E325* +- ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter) ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPm31002-D 2-Port 16Gb Fibre Channel Mezz Card) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E330* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32002-M2-L 2-Port 32Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E331* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe32000-M2-L 1-Port 32Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E332* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31002-M6-L 2-Port 16Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv000010DFsd0000E333* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (LPe31000-M6-L 1-Port 16Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv00001590sd00000201* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (StoreFabric SN1600E 1-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv00001590sd00000202* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (StoreFabric SN1600E 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv00001590sd00000213* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (StoreFabric SN1200E 1-Port 16Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv00001590sd00000214* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (StoreFabric SN1200E 2-Port 16Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000E300sv00001590sd0000022E* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (Synergy 5330C 2-Port 32Gb Fibre Channel Mezz Card) ++ ++pci:v000010DFd0000E300sv0000193Dsd00001060* ++ ID_MODEL_FROM_DATABASE=LPe31000/LPe32000 Series 16Gb/32Gb Fibre Channel Adapter (NIC-FC730i-Mb-2P) + + pci:v000010DFd0000F011* + ID_MODEL_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter +@@ -33402,13 +36894,19 @@ pci:v000010DFd0000F0F5* + ID_MODEL_FROM_DATABASE=Neptune LightPulse Fibre Channel Host Adapter + + pci:v000010DFd0000F100* +- ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter ++ ID_MODEL_FROM_DATABASE=LPe12000 Series 8Gb Fibre Channel Adapter + + pci:v000010DFd0000F100sv00001014sd0000038A* +- ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb PCI Express Dual Port FC Adapter for POWER) ++ ID_MODEL_FROM_DATABASE=LPe12000 Series 8Gb Fibre Channel Adapter (8Gb PCI Express Dual Port FC Adapter for POWER) + + pci:v000010DFd0000F100sv0000103Csd00003282* +- ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb Dual-port PCI-e FC HBA) ++ ID_MODEL_FROM_DATABASE=LPe12000 Series 8Gb Fibre Channel Adapter (8Gb Dual-port PCI-e FC HBA) ++ ++pci:v000010DFd0000F100sv000010DFsd0000F140* ++ ID_MODEL_FROM_DATABASE=LPe12000 Series 8Gb Fibre Channel Adapter (LPe12000-M8-L 1-Port 8Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000F100sv000010DFsd0000F141* ++ ID_MODEL_FROM_DATABASE=LPe12000 Series 8Gb Fibre Channel Adapter (LPe12002-M8-L 2-Port 8Gb PCIe Fibre Channel Adapter) + + pci:v000010DFd0000F111* + ID_MODEL_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter +@@ -33420,13 +36918,46 @@ pci:v000010DFd0000F180* + ID_MODEL_FROM_DATABASE=LPSe12002 EmulexSecure Fibre Channel Adapter + + pci:v000010DFd0000F400* +- ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism] ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter + + pci:v000010DFd0000F400sv000010DFsd0000F401* +- ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism] (LPe35000 Fibre Channel Host Adapter [Prism]) ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35000-M2 1-Port 32Gb Fibre Channel Adapter) + + pci:v000010DFd0000F400sv000010DFsd0000F402* +- ID_MODEL_FROM_DATABASE=LPe36000 Fibre Channel Host Adapter [Prism] (LPe35000 Fibre Channel Host Adapter [Prism]) ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35002-M2 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F403* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe36000-M64 1-Port 64Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F404* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe36002-M64 2-Port 64Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F405* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35004-M2 4-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F406* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35004-X6 4-Port Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F410* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35002-M2-D 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F411* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35000-M2-D 1-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F418* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35000-M2-L 1-Port 32Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv000010DFsd0000F419* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (LPe35002-M2-L 2-Port 32Gb PCIe Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv00001590sd000002D5* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (StoreFabric SN1610E 1-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F400sv00001590sd000002D6* ++ ID_MODEL_FROM_DATABASE=LPe35000/LPe36000 Series 32Gb/64Gb Fibre Channel Adapter (StoreFabric SN1610E 2-Port 32Gb Fibre Channel Adapter) ++ ++pci:v000010DFd0000F500* ++ ID_MODEL_FROM_DATABASE=LPe37000/LPe38000 Series 32Gb/64Gb Fibre Channel Adapter + + pci:v000010DFd0000F700* + ID_MODEL_FROM_DATABASE=LP7000 Fibre Channel Host Adapter +@@ -33566,6 +37097,9 @@ pci:v000010E3d00000860* + pci:v000010E3d00000862* + ID_MODEL_FROM_DATABASE=CA91C862A [QSpan-II] + ++pci:v000010E3d00008111* ++ ID_MODEL_FROM_DATABASE=Tsi381 PCIe to PCI Bridge ++ + pci:v000010E3d00008260* + ID_MODEL_FROM_DATABASE=CA91L8200B [Dual PCI PowerSpan II] + +@@ -33740,6 +37274,9 @@ pci:v000010EC* + pci:v000010ECd00000139* + ID_MODEL_FROM_DATABASE=RTL-8139/8139C/8139C+ Ethernet Controller + ++pci:v000010ECd00003000* ++ ID_MODEL_FROM_DATABASE=Killer E3000 2.5GbE Controller ++ + pci:v000010ECd00005208* + ID_MODEL_FROM_DATABASE=RTS5208 PCI Express Card Reader + +@@ -33773,6 +37310,15 @@ pci:v000010ECd00005229sv000017AAsd00003832* + pci:v000010ECd0000522A* + ID_MODEL_FROM_DATABASE=RTS522A PCI Express Card Reader + ++pci:v000010ECd0000522Asv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=RTS522A PCI Express Card Reader (EliteBook 840 G3) ++ ++pci:v000010ECd0000522Asv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=RTS522A PCI Express Card Reader (OMEN-17-w001nv) ++ ++pci:v000010ECd0000522Asv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=RTS522A PCI Express Card Reader (ThinkPad E595) ++ + pci:v000010ECd00005249* + ID_MODEL_FROM_DATABASE=RTS5249 PCI Express Card Reader + +@@ -33788,15 +37334,33 @@ pci:v000010ECd00005250* + pci:v000010ECd0000525A* + ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader + ++pci:v000010ECd0000525Asv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (Latitude 7275 tablet) ++ ++pci:v000010ECd0000525Asv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (Latitude E7470) ++ ++pci:v000010ECd0000525Asv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (XPS 15 9550) ++ ++pci:v000010ECd0000525Asv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (Latitude 11 5175 2-in-1) ++ + pci:v000010ECd0000525Asv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (ThinkPad X1 Carbon 5th Gen) + ++pci:v000010ECd00005260* ++ ID_MODEL_FROM_DATABASE=RTS5260 PCI Express Card Reader ++ + pci:v000010ECd00005286* + ID_MODEL_FROM_DATABASE=RTS5286 PCI Express Card Reader + + pci:v000010ECd00005287* + ID_MODEL_FROM_DATABASE=RTL8411B PCI Express Card Reader + ++pci:v000010ECd00005287sv00001025sd00001094* ++ ID_MODEL_FROM_DATABASE=RTL8411B PCI Express Card Reader (Acer Aspire E5-575G) ++ + pci:v000010ECd00005288* + ID_MODEL_FROM_DATABASE=RTS5288 PCI Express Card Reader + +@@ -33806,6 +37370,9 @@ pci:v000010ECd00005289* + pci:v000010ECd00005289sv00001043sd00001457* + ID_MODEL_FROM_DATABASE=RTL8411 PCI Express Card Reader (K55A Laptop) + ++pci:v000010ECd00005762* ++ ID_MODEL_FROM_DATABASE=RTS5763DL NVMe SSD Controller ++ + pci:v000010ECd00008029* + ID_MODEL_FROM_DATABASE=RTL-8029(AS) + +@@ -33827,6 +37394,9 @@ pci:v000010ECd00008029sv00001259sd00002400* + pci:v000010ECd00008029sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=RTL-8029(AS) (QEMU Virtual Machine) + ++pci:v000010ECd00008125* ++ ID_MODEL_FROM_DATABASE=RTL8125 2.5GbE Controller ++ + pci:v000010ECd00008129* + ID_MODEL_FROM_DATABASE=RTL-8129 + +@@ -33891,7 +37461,7 @@ pci:v000010ECd00008139sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Presario C700) + + pci:v000010ECd00008139sv00001043sd00001045* +- ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (L8400B or L3C/S notebook) ++ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (L8400B, L3C/S, X58LE notebook) + + pci:v000010ECd00008139sv00001043sd00008109* + ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (P5P800-MX Mainboard) +@@ -34019,6 +37589,12 @@ pci:v000010ECd00008139sv00008E2Esd00007100* + pci:v000010ECd00008139sv0000A0A0sd00000007* + ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (ALN-325C) + ++pci:v000010ECd00008161* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller ++ ++pci:v000010ECd00008161sv000010ECsd00008168* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (TP-Link TG-3468 v4.0 Gigabit PCI Express Network Adapter) ++ + pci:v000010ECd00008167* + ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet + +@@ -34040,6 +37616,9 @@ pci:v000010ECd00008168* + pci:v000010ECd00008168sv00001019sd00008168* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (RTL8111/8168 PCI Express Gigabit Ethernet controller) + ++pci:v000010ECd00008168sv00001025sd00001094* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Acer Aspire E5-575G) ++ + pci:v000010ECd00008168sv00001028sd00000283* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 220) + +@@ -34049,9 +37628,18 @@ pci:v000010ECd00008168sv00001028sd000004B2* + pci:v000010ECd00008168sv00001028sd000004DA* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 3750) + ++pci:v000010ECd00008168sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Alienware X51 R2) ++ ++pci:v000010ECd00008168sv00001028sd000006F2* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Latitude 3470) ++ + pci:v000010ECd00008168sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Latitude 3570) + ++pci:v000010ECd00008168sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 3470) ++ + pci:v000010ECd00008168sv0000103Csd00001611* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Pavilion DM1Z-3000) + +@@ -34061,6 +37649,15 @@ pci:v000010ECd00008168sv0000103Csd00001950* + pci:v000010ECd00008168sv0000103Csd00002A6F* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Asus IPIBL-LB Motherboard) + ++pci:v000010ECd00008168sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (OMEN-17-w001nv) ++ ++pci:v000010ECd00008168sv0000103Csd00008615* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Pavilion Laptop 15-cw1xxx) ++ ++pci:v000010ECd00008168sv00001043sd000011F5* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Notebook motherboard (one of many models)) ++ + pci:v000010ECd00008168sv00001043sd000016D5* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (U6V/U31J laptop) + +@@ -34079,6 +37676,15 @@ pci:v000010ECd00008168sv00001043sd00008432* + pci:v000010ECd00008168sv00001043sd00008505* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (P8 series motherboard) + ++pci:v000010ECd00008168sv00001043sd00008554* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (H81M-C Motherboard) ++ ++pci:v000010ECd00008168sv00001043sd0000859E* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (AM1I-A Motherboard) ++ ++pci:v000010ECd00008168sv00001043sd00008677* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (PRIME B450M-A Motherboard) ++ + pci:v000010ECd00008168sv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (D270S/D250S Motherboard) + +@@ -34106,9 +37712,24 @@ pci:v000010ECd00008168sv00001462sd00004180* + pci:v000010ECd00008168sv00001462sd00007522* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (X58 Pro-E) + ++pci:v000010ECd00008168sv00001462sd00007C37* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (X570-A PRO motherboard) ++ + pci:v000010ECd00008168sv00001775sd000011CC* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (CC11/CL11) + ++pci:v000010ECd00008168sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (ThinkCentre E73) ++ ++pci:v000010ECd00008168sv000017AAsd00003814* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Z50-75) ++ ++pci:v000010ECd00008168sv000017AAsd00003823* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Lenovo V130-15IGM Laptop - Type 81HL) ++ ++pci:v000010ECd00008168sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (ThinkPad E595) ++ + pci:v000010ECd00008168sv00001849sd00008168* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Motherboard (one of many)) + +@@ -34121,6 +37742,9 @@ pci:v000010ECd00008168sv00008086sd00002055* + pci:v000010ECd00008168sv00008086sd0000D615* + ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Desktop Board D510MO/D525MW) + ++pci:v000010ECd00008168sv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (mCOM10-L1900) ++ + pci:v000010ECd00008169* + ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller + +@@ -34169,6 +37793,33 @@ pci:v000010ECd00008169sv00001734sd00001091* + pci:v000010ECd00008169sv0000A0A0sd00000449* + ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (AK86-L motherboard) + ++pci:v000010ECd0000816A* ++ ID_MODEL_FROM_DATABASE=RTL8111xP UART #1 ++ ++pci:v000010ECd0000816Asv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=RTL8111xP UART #1 (mCOM10-L1900) ++ ++pci:v000010ECd0000816B* ++ ID_MODEL_FROM_DATABASE=RTL8111xP UART #2 ++ ++pci:v000010ECd0000816Bsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=RTL8111xP UART #2 (mCOM10-L1900) ++ ++pci:v000010ECd0000816C* ++ ID_MODEL_FROM_DATABASE=RTL8111xP IPMI interface ++ ++pci:v000010ECd0000816Csv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=RTL8111xP IPMI interface (mCOM10-L1900) ++ ++pci:v000010ECd0000816D* ++ ID_MODEL_FROM_DATABASE=RTL811x EHCI host controller ++ ++pci:v000010ECd0000816Dsv0000EA50sd0000CE19* ++ ID_MODEL_FROM_DATABASE=RTL811x EHCI host controller (mCOM10-L1900) ++ ++pci:v000010ECd0000816E* ++ ID_MODEL_FROM_DATABASE=Realtek RealManage BMC ++ + pci:v000010ECd00008171* + ID_MODEL_FROM_DATABASE=RTL8191SEvA Wireless LAN Controller + +@@ -34259,12 +37910,33 @@ pci:v000010ECd0000B723* + pci:v000010ECd0000B723sv000010ECsd00008739* + ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter (Dell Wireless 1801) + ++pci:v000010ECd0000B723sv000017AAsd0000B736* ++ ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter (Z50-75) ++ + pci:v000010ECd0000B822* + ID_MODEL_FROM_DATABASE=RTL8822BE 802.11a/b/g/n/ac WiFi adapter + ++pci:v000010ECd0000B822sv0000103Csd0000831B* ++ ID_MODEL_FROM_DATABASE=RTL8822BE 802.11a/b/g/n/ac WiFi adapter (Realtek RTL8822BE 802.11ac 2 × 2 Wi-Fi + Bluetooth 4.2 Combo Adapter (MU-MIMO supported)) ++ ++pci:v000010ECd0000B822sv000017AAsd00005124* ++ ID_MODEL_FROM_DATABASE=RTL8822BE 802.11a/b/g/n/ac WiFi adapter (ThinkPad E595) ++ ++pci:v000010ECd0000B822sv000017AAsd0000B023* ++ ID_MODEL_FROM_DATABASE=RTL8822BE 802.11a/b/g/n/ac WiFi adapter (ThinkPad E595) ++ + pci:v000010ECd0000C821* + ID_MODEL_FROM_DATABASE=RTL8821CE 802.11ac PCIe Wireless Network Adapter + ++pci:v000010ECd0000C822* ++ ID_MODEL_FROM_DATABASE=RTL8822CE 802.11ac PCIe Wireless Network Adapter ++ ++pci:v000010ECd0000C82F* ++ ID_MODEL_FROM_DATABASE=RTL8822CE 802.11ac PCIe Wireless Network Adapter ++ ++pci:v000010ECd0000D723* ++ ID_MODEL_FROM_DATABASE=RTL8723DE 802.11b/g/n PCIe Adapter ++ + pci:v000010ED* + ID_VENDOR_FROM_DATABASE=Ascii Corporation + +@@ -34325,12 +37997,18 @@ pci:v000010EEd00003FC5* + pci:v000010EEd00003FC6* + ID_MODEL_FROM_DATABASE=RME Hammerfall DSP MADI + ++pci:v000010EEd00005005* ++ ID_MODEL_FROM_DATABASE=Alveo U250 ++ + pci:v000010EEd00007038* + ID_MODEL_FROM_DATABASE=FPGA Card XC7VX690T + + pci:v000010EEd00007038sv000017AAsd0000402F* + ID_MODEL_FROM_DATABASE=FPGA Card XC7VX690T (FPGA XC7VX690T-3FFG1157E) + ++pci:v000010EEd00008019* ++ ID_MODEL_FROM_DATABASE=Memory controller ++ + pci:v000010EEd00008380* + ID_MODEL_FROM_DATABASE=Ellips ProfiXpress Profibus Master + +@@ -34349,6 +38027,9 @@ pci:v000010EEd0000EBF1* + pci:v000010EEd0000EBF2* + ID_MODEL_FROM_DATABASE=SED Systems Common PCI Interface + ++pci:v000010EEd0000EBF3* ++ ID_MODEL_FROM_DATABASE=SED Systems PCIe-AXI Bridge ++ + pci:v000010EF* + ID_VENDOR_FROM_DATABASE=Racore Computer Products, Inc. + +@@ -34571,6 +38252,15 @@ pci:v00001102d00000002sv00001102sd00008071* + pci:v00001102d00000003* + ID_MODEL_FROM_DATABASE=SB AWE64(D) + ++pci:v00001102d00000003sv00001102sd00000010* ++ ID_MODEL_FROM_DATABASE=SB AWE64(D) (CT4600 AWE64D) ++ ++pci:v00001102d00000003sv00001102sd00000030* ++ ID_MODEL_FROM_DATABASE=SB AWE64(D) (CT4650 AWE64D) ++ ++pci:v00001102d00000003sv00001102sd00000031* ++ ID_MODEL_FROM_DATABASE=SB AWE64(D) (CT4655 AWE64D) ++ + pci:v00001102d00000004* + ID_MODEL_FROM_DATABASE=EMU10k2/CA0100/CA0102/CA10200 [Sound Blaster Audigy Series] + +@@ -34692,7 +38382,16 @@ pci:v00001102d00000005sv00001102sd00001003* + ID_MODEL_FROM_DATABASE=EMU20k1 [Sound Blaster X-Fi Series] (X-Fi XtremeMusic) + + pci:v00001102d00000006* +- ID_MODEL_FROM_DATABASE=EMU10k1X [SB Live! Value/OEM Series] ++ ID_MODEL_FROM_DATABASE=EMU10k1X / CA0103 [SB Live! OEM / SB 5.1 / Ectiva 5.1] ++ ++pci:v00001102d00000006sv00001102sd00001001* ++ ID_MODEL_FROM_DATABASE=EMU10k1X / CA0103 [SB Live! OEM / SB 5.1 / Ectiva 5.1] (SB0680 Sound Blaster 5.1) ++ ++pci:v00001102d00000006sv00001102sd00001003* ++ ID_MODEL_FROM_DATABASE=EMU10k1X / CA0103 [SB Live! OEM / SB 5.1 / Ectiva 5.1] (SB0203 SB Live! 5.1 (Dell)) ++ ++pci:v00001102d00000006sv00001102sd00001004* ++ ID_MODEL_FROM_DATABASE=EMU10k1X / CA0103 [SB Live! OEM / SB 5.1 / Ectiva 5.1] (TP0033 Ectiva Audio 5.1) + + pci:v00001102d00000007* + ID_MODEL_FROM_DATABASE=CA0106/CA0111 [SB Live!/Audigy/X-Fi Series] +@@ -34994,6 +38693,9 @@ pci:v00001103d00003320* + pci:v00001103d00004310* + ID_MODEL_FROM_DATABASE=RocketRaid 4310 + ++pci:v00001103d00007505* ++ ID_MODEL_FROM_DATABASE=SSD7505 PCIe Gen4 x16 4-Port M.2 NVMe RAID Controller ++ + pci:v00001104* + ID_VENDOR_FROM_DATABASE=RasterOps Corp. + +@@ -35133,7 +38835,7 @@ pci:v00001106d00000351* + ID_MODEL_FROM_DATABASE=K8T890CF Host Bridge + + pci:v00001106d00000353* +- ID_MODEL_FROM_DATABASE=VX800 Host Bridge ++ ID_MODEL_FROM_DATABASE=VX800/820-Series Chipset Host-Bridge Controller + + pci:v00001106d00000364* + ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge +@@ -35148,7 +38850,7 @@ pci:v00001106d00000409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Host Bridge: Host Control + + pci:v00001106d00000410* +- ID_MODEL_FROM_DATABASE=VX900 Host Bridge: Host Control ++ ID_MODEL_FROM_DATABASE=VX900 Series Host Bridge: Host Control + + pci:v00001106d00000415* + ID_MODEL_FROM_DATABASE=VT6415 PATA IDE Host Controller +@@ -35223,10 +38925,10 @@ pci:v00001106d00000576* + ID_MODEL_FROM_DATABASE=VT82C576 3V [Apollo Master] + + pci:v00001106d00000581* +- ID_MODEL_FROM_DATABASE=CX700/VX700 RAID Controller ++ ID_MODEL_FROM_DATABASE=CX700/VX700/VX800/820-Series Serial ATA RAID-Controller + + pci:v00001106d00000581sv00001106sd00000581* +- ID_MODEL_FROM_DATABASE=CX700/VX700 RAID Controller (Wrong IDE ID) ++ ID_MODEL_FROM_DATABASE=CX700/VX700/VX800/820-Series Serial ATA RAID-Controller (Wrong IDE ID) + + pci:v00001106d00000585* + ID_MODEL_FROM_DATABASE=VT82C585VP [Apollo VP1/VPX] +@@ -35394,7 +39096,7 @@ pci:v00001106d00001314* + ID_MODEL_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + + pci:v00001106d00001324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 Host Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series Error Reporting + + pci:v00001106d00001327* + ID_MODEL_FROM_DATABASE=P4M890 Host Bridge +@@ -35418,7 +39120,7 @@ pci:v00001106d00001409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Error Reporting + + pci:v00001106d00001410* +- ID_MODEL_FROM_DATABASE=VX900 Error Reporting ++ ID_MODEL_FROM_DATABASE=VX900 Series Error Reporting + + pci:v00001106d00001571* + ID_MODEL_FROM_DATABASE=VT82C576M/VT82C586 +@@ -35469,7 +39171,7 @@ pci:v00001106d00002314* + ID_MODEL_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + + pci:v00001106d00002324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 Host Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series Host Interface Control + + pci:v00001106d00002327* + ID_MODEL_FROM_DATABASE=P4M890 Host Bridge +@@ -35493,7 +39195,7 @@ pci:v00001106d00002409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Host Bus Control + + pci:v00001106d00002410* +- ID_MODEL_FROM_DATABASE=VX900 CPU Bus Controller ++ ID_MODEL_FROM_DATABASE=VX900 Series CPU Bus Controller + + pci:v00001106d0000287A* + ID_MODEL_FROM_DATABASE=VT8251 PCI to PCI Bridge +@@ -35514,64 +39216,67 @@ pci:v00001106d00003022* + ID_MODEL_FROM_DATABASE=CLE266 + + pci:v00001106d00003038* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller + + pci:v00001106d00003038sv00000925sd00001234* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (onboard UHCI USB 1.1 Controller) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (onboard UHCI USB 1.1 Controller) + + pci:v00001106d00003038sv00001019sd00000985* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (P6VXA Motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (P6VXA Motherboard) + + pci:v00001106d00003038sv00001019sd00000A81* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (L7VTA v1.0 Motherboard (KT400-8235)) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (L7VTA v1.0 Motherboard (KT400-8235)) + + pci:v00001106d00003038sv00001043sd00008080* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (A7V333 motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (A7V333 motherboard) + + pci:v00001106d00003038sv00001043sd0000808C* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (VT6202 USB2.0 4 port controller) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (VT62xx USB1.1 4 port controller) + + pci:v00001106d00003038sv00001043sd000080A1* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (A7V8X-X motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (A7V8X-X motherboard) + + pci:v00001106d00003038sv00001043sd000080ED* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (A7V600/K8V-X/A8V Deluxe motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (A7V600/K8V-X/A8V Deluxe motherboard) + + pci:v00001106d00003038sv00001179sd00000001* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (Magnia Z310) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (Magnia Z310) ++ ++pci:v00001106d00003038sv00001234sd00000925* ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (MVP3 USB Controller) + + pci:v00001106d00003038sv00001458sd00005004* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (GA-7VAX Mainboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (GA-7VAX Mainboard) + + pci:v00001106d00003038sv00001462sd00005901* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (KT6 Delta-FIS2R (MS-6590)) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (KT6 Delta-FIS2R (MS-6590)) + + pci:v00001106d00003038sv00001462sd00007020* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (K8T NEO 2 motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (K8T NEO 2 motherboard) + + pci:v00001106d00003038sv00001462sd00007094* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (K8T Neo2-F V2.0) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (K8T Neo2-F V2.0) + + pci:v00001106d00003038sv00001462sd00007120* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (KT4AV motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (KT4AV motherboard) + + pci:v00001106d00003038sv00001462sd00007181* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (K8MM3-V mainboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (K8MM3-V mainboard) + + pci:v00001106d00003038sv0000147Bsd00001407* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (KV8-MAX3 motherboard) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (KV8-MAX3 motherboard) + + pci:v00001106d00003038sv0000182Dsd0000201D* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (CN-029 USB2.0 4 port PCI Card) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (CN-029 USB2.0 4 port PCI Card) + + pci:v00001106d00003038sv00001849sd00003038* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (K7VT series Motherboards) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (K7VT series Motherboards) + + pci:v00001106d00003038sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (ZBOX nano VD01) + + pci:v00001106d00003038sv00001AF4sd00001100* +- ID_MODEL_FROM_DATABASE=VT82xx/62xx UHCI USB 1.1 Controller (QEMU Virtual Machine) ++ ID_MODEL_FROM_DATABASE=VT82xx/62xx/VX700/8x0/900 UHCI USB 1.1 Controller (QEMU Virtual Machine) + + pci:v00001106d00003040* + ID_MODEL_FROM_DATABASE=VT82C586B ACPI +@@ -35880,58 +39585,58 @@ pci:v00001106d00003103* + ID_MODEL_FROM_DATABASE=VT8615 Host Bridge + + pci:v00001106d00003104* +- ID_MODEL_FROM_DATABASE=USB 2.0 ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller + + pci:v00001106d00003104sv00000925sd00001234* +- ID_MODEL_FROM_DATABASE=USB 2.0 (onboard EHCI USB 2.0 Controller) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (onboard EHCI USB 2.0 Controller) + + pci:v00001106d00003104sv00001019sd00000A81* +- ID_MODEL_FROM_DATABASE=USB 2.0 (L7VTA v1.0 Motherboard (KT400-8235)) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (L7VTA v1.0 Motherboard (KT400-8235)) + + pci:v00001106d00003104sv00001043sd0000808C* +- ID_MODEL_FROM_DATABASE=USB 2.0 (A7V8X motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (A7V8X motherboard) + + pci:v00001106d00003104sv00001043sd000080A1* +- ID_MODEL_FROM_DATABASE=USB 2.0 (A7V8X-X motherboard rev 1.01) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (A7V8X-X motherboard rev 1.01) + + pci:v00001106d00003104sv00001043sd000080ED* +- ID_MODEL_FROM_DATABASE=USB 2.0 (A7V600/K8V-X/A8V Deluxe motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (A7V600/K8V-X/A8V Deluxe motherboard) + + pci:v00001106d00003104sv00001106sd00003104* +- ID_MODEL_FROM_DATABASE=USB 2.0 (Controller) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (USB 2.0 Controller) + + pci:v00001106d00003104sv00001297sd0000F641* +- ID_MODEL_FROM_DATABASE=USB 2.0 (FX41 motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (FX41 motherboard) + + pci:v00001106d00003104sv00001458sd00005004* +- ID_MODEL_FROM_DATABASE=USB 2.0 (GA-7VAX Mainboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (GA-7VAX Mainboard) + + pci:v00001106d00003104sv00001462sd00005901* +- ID_MODEL_FROM_DATABASE=USB 2.0 (KT6 Delta-FIS2R (MS-6590)) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (KT6 Delta-FIS2R (MS-6590)) + + pci:v00001106d00003104sv00001462sd00007020* +- ID_MODEL_FROM_DATABASE=USB 2.0 (K8T NEO 2 motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (K8T NEO 2 motherboard) + + pci:v00001106d00003104sv00001462sd00007094* +- ID_MODEL_FROM_DATABASE=USB 2.0 (K8T Neo2-F V2.0) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (K8T Neo2-F V2.0) + + pci:v00001106d00003104sv00001462sd00007120* +- ID_MODEL_FROM_DATABASE=USB 2.0 (KT4AV motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (KT4AV motherboard) + + pci:v00001106d00003104sv00001462sd00007181* +- ID_MODEL_FROM_DATABASE=USB 2.0 (K8MM3-V mainboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (K8MM3-V mainboard) + + pci:v00001106d00003104sv0000147Bsd00001407* +- ID_MODEL_FROM_DATABASE=USB 2.0 (KV8-MAX3 motherboard) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (KV8-MAX3 motherboard) + + pci:v00001106d00003104sv0000182Dsd0000201D* +- ID_MODEL_FROM_DATABASE=USB 2.0 (CN-029 USB 2.0 4 port PCI Card) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (CN-029 USB 2.0 4 port PCI Card) + + pci:v00001106d00003104sv00001849sd00003104* +- ID_MODEL_FROM_DATABASE=USB 2.0 (K7VT series Motherboards) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (K7VT series Motherboards) + + pci:v00001106d00003104sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=USB 2.0 (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=USB 2.0 EHCI-Compliant Host-Controller (ZBOX nano VD01) + + pci:v00001106d00003106* + ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] +@@ -36210,10 +39915,10 @@ pci:v00001106d00003287* + ID_MODEL_FROM_DATABASE=VT8251 PCI to ISA Bridge + + pci:v00001106d00003288* +- ID_MODEL_FROM_DATABASE=VT8237A/VT8251 HDA Controller ++ ID_MODEL_FROM_DATABASE=VX900/VT8xxx High Definition Audio Controller + + pci:v00001106d00003288sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VT8237A/VT8251 HDA Controller (ZBOX VD01) ++ ID_MODEL_FROM_DATABASE=VX900/VT8xxx High Definition Audio Controller (ZBOX VD01) + + pci:v00001106d00003290* + ID_MODEL_FROM_DATABASE=K8M890 Host Bridge +@@ -36222,7 +39927,7 @@ pci:v00001106d00003296* + ID_MODEL_FROM_DATABASE=P4M800 Host Bridge + + pci:v00001106d00003324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 Host Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series DRAM Bus Control + + pci:v00001106d00003327* + ID_MODEL_FROM_DATABASE=P4M890 Host Bridge +@@ -36249,11 +39954,14 @@ pci:v00001106d00003351* + ID_MODEL_FROM_DATABASE=VT3351 Host Bridge + + pci:v00001106d00003353* +- ID_MODEL_FROM_DATABASE=VX800 PCI to PCI Bridge ++ ID_MODEL_FROM_DATABASE=VX800/820 PCI to PCI Bridge + + pci:v00001106d00003364* + ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + ++pci:v00001106d00003365* ++ ID_MODEL_FROM_DATABASE=VT630x IEEE 1394 Host Controller [Fire II/M] ++ + pci:v00001106d00003371* + ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 [Chrome 9 HC] + +@@ -36279,13 +39987,13 @@ pci:v00001106d00003409* + ID_MODEL_FROM_DATABASE=VX855/VX875 DRAM Bus Control + + pci:v00001106d00003410* +- ID_MODEL_FROM_DATABASE=VX900 DRAM Bus Control ++ ID_MODEL_FROM_DATABASE=VX900 Series DRAM Bus Control + + pci:v00001106d00003410sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VX900 DRAM Bus Control (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=VX900 Series DRAM Bus Control (ZBOX nano VD01) + + pci:v00001106d00003432* +- ID_MODEL_FROM_DATABASE=VL80x xHCI USB 3.0 Controller ++ ID_MODEL_FROM_DATABASE=VL800/801 xHCI USB 3.0 Controller + + pci:v00001106d00003456* + ID_MODEL_FROM_DATABASE=VX11 Standard Host Bridge +@@ -36294,7 +40002,7 @@ pci:v00001106d0000345B* + ID_MODEL_FROM_DATABASE=VX11 Miscellaneous Bus + + pci:v00001106d00003483* +- ID_MODEL_FROM_DATABASE=VL805 USB 3.0 Host Controller ++ ID_MODEL_FROM_DATABASE=VL805/806 xHCI USB 3.0 Controller + + pci:v00001106d00003A01* + ID_MODEL_FROM_DATABASE=VX11 Graphics [Chrome 645/640] +@@ -36339,7 +40047,7 @@ pci:v00001106d00004314* + ID_MODEL_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + + pci:v00001106d00004324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 Host Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series Power Management and Testing Control + + pci:v00001106d00004327* + ID_MODEL_FROM_DATABASE=P4M890 Host Bridge +@@ -36363,10 +40071,10 @@ pci:v00001106d00004409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Power Management Control + + pci:v00001106d00004410* +- ID_MODEL_FROM_DATABASE=VX900 Power Management and Chip Testing Control ++ ID_MODEL_FROM_DATABASE=VX900 Series Power Management and Chip Testing Control + + pci:v00001106d00004410sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VX900 Power Management and Chip Testing Control (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=VX900 Series Power Management and Chip Testing Control (ZBOX nano VD01) + + pci:v00001106d00005030* + ID_MODEL_FROM_DATABASE=VT82C596 ACPI [Apollo PRO] +@@ -36390,7 +40098,7 @@ pci:v00001106d00005308* + ID_MODEL_FROM_DATABASE=PT894 I/O APIC Interrupt Controller + + pci:v00001106d00005324* +- ID_MODEL_FROM_DATABASE=VX800 Serial ATA and EIDE Controller ++ ID_MODEL_FROM_DATABASE=CX700M2/VX700/VX800/820-Series Serial ATA & EIDE-Controller + + pci:v00001106d00005327* + ID_MODEL_FROM_DATABASE=P4M890 I/O APIC Interrupt Controller +@@ -36417,7 +40125,7 @@ pci:v00001106d00005409* + ID_MODEL_FROM_DATABASE=VX855/VX875 APIC and Central Traffic Control + + pci:v00001106d00005410* +- ID_MODEL_FROM_DATABASE=VX900 APIC and Central Traffic Control ++ ID_MODEL_FROM_DATABASE=VX900 Series APIC and Central Traffic Control + + pci:v00001106d00006100* + ID_MODEL_FROM_DATABASE=VT85C100A [Rhine II] +@@ -36441,10 +40149,10 @@ pci:v00001106d00006409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Scratch Registers + + pci:v00001106d00006410* +- ID_MODEL_FROM_DATABASE=VX900 Scratch Registers ++ ID_MODEL_FROM_DATABASE=VX900 Series Scratch Registers + + pci:v00001106d00006410sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VX900 Scratch Registers (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=VX900 Series Scratch Registers (ZBOX nano VD01) + + pci:v00001106d00007122* + ID_MODEL_FROM_DATABASE=VX900 Graphics [Chrome9 HD] +@@ -36495,7 +40203,7 @@ pci:v00001106d00007314* + ID_MODEL_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + + pci:v00001106d00007324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 Host Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series North-South Module Interface Control + + pci:v00001106d00007327* + ID_MODEL_FROM_DATABASE=P4M890 Host Bridge +@@ -36519,10 +40227,10 @@ pci:v00001106d00007409* + ID_MODEL_FROM_DATABASE=VX855/VX875 North-South Module Interface Control + + pci:v00001106d00007410* +- ID_MODEL_FROM_DATABASE=VX900 North-South Module Interface Control ++ ID_MODEL_FROM_DATABASE=VX900 Series North-South Module Interface Control + + pci:v00001106d00007410sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VX900 North-South Module Interface Control (ZBOX nano VD01) ++ ID_MODEL_FROM_DATABASE=VX900 Series North-South Module Interface Control (ZBOX nano VD01) + + pci:v00001106d00008231* + ID_MODEL_FROM_DATABASE=VT8231 [PCI-to-ISA Bridge] +@@ -36534,7 +40242,7 @@ pci:v00001106d00008305* + ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133 AGP] + + pci:v00001106d00008324* +- ID_MODEL_FROM_DATABASE=CX700/VX700 PCI to ISA Bridge ++ ID_MODEL_FROM_DATABASE=CX700/VX700-Series Bus Control and Power Management + + pci:v00001106d00008353* + ID_MODEL_FROM_DATABASE=VX800/VX820 Bus Control and Power Management +@@ -36549,10 +40257,10 @@ pci:v00001106d00008409* + ID_MODEL_FROM_DATABASE=VX855/VX875 Bus Control and Power Management + + pci:v00001106d00008410* +- ID_MODEL_FROM_DATABASE=VX900 Bus Control and Power Management ++ ID_MODEL_FROM_DATABASE=VX900 Series Bus Control and Power Management + + pci:v00001106d00008410sv000019DAsd0000A179* +- ID_MODEL_FROM_DATABASE=VX900 Bus Control and Power Management (ZBOX VD01) ++ ID_MODEL_FROM_DATABASE=VX900 Series Bus Control and Power Management (ZBOX VD01) + + pci:v00001106d00008500* + ID_MODEL_FROM_DATABASE=KLE133/PLE133/PLE133T +@@ -36597,7 +40305,7 @@ pci:v00001106d00008D04* + ID_MODEL_FROM_DATABASE=KM266/P4M266/P4M266A/P4N266 [S3 ProSavageDDR] + + pci:v00001106d00009001* +- ID_MODEL_FROM_DATABASE=VX900 Serial ATA Controller ++ ID_MODEL_FROM_DATABASE=VX900 Series Serial-ATA Controller + + pci:v00001106d00009082* + ID_MODEL_FROM_DATABASE=Standard AHCI 1.0 SATA Controller +@@ -36609,10 +40317,10 @@ pci:v00001106d00009201* + ID_MODEL_FROM_DATABASE=USB3.0 Controller + + pci:v00001106d00009530* +- ID_MODEL_FROM_DATABASE=Secure Digital Memory Card Controller ++ ID_MODEL_FROM_DATABASE=VX800/820/900 Series Secure Digital Memory Card Controller + + pci:v00001106d000095D0* +- ID_MODEL_FROM_DATABASE=SDIO Host Controller ++ ID_MODEL_FROM_DATABASE=VX800/820/900 Series SDIO Host Controller + + pci:v00001106d0000A208* + ID_MODEL_FROM_DATABASE=PT890 PCI to PCI Bridge Controller +@@ -36624,16 +40332,16 @@ pci:v00001106d0000A327* + ID_MODEL_FROM_DATABASE=P4M890 PCI to PCI Bridge Controller + + pci:v00001106d0000A353* +- ID_MODEL_FROM_DATABASE=VX8xx South-North Module Interface Control ++ ID_MODEL_FROM_DATABASE=VX8xx/900 Series South-North Module Interface Control + + pci:v00001106d0000A364* + ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller + + pci:v00001106d0000A409* +- ID_MODEL_FROM_DATABASE=VX855/VX875 USB Device Controller ++ ID_MODEL_FROM_DATABASE=VX855/VX875/VX900 Series USB Device Controller + + pci:v00001106d0000A410* +- ID_MODEL_FROM_DATABASE=VX900 PCI Express Root Port 0 ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI Express Root Port 0 + + pci:v00001106d0000B091* + ID_MODEL_FROM_DATABASE=VT8633 [Apollo Pro266 AGP] +@@ -36669,7 +40377,7 @@ pci:v00001106d0000B188sv0000147Bsd00001407* + ID_MODEL_FROM_DATABASE=VT8237/8251 PCI bridge [K8M890/K8T800/K8T890 South] (KV8-MAX3 motherboard) + + pci:v00001106d0000B198* +- ID_MODEL_FROM_DATABASE=VT8237/VX700 PCI Bridge ++ ID_MODEL_FROM_DATABASE=VT8237/CX700/VX700-Series PCI to PCI Bridge + + pci:v00001106d0000B213* + ID_MODEL_FROM_DATABASE=VPX/VPX2 I/O APIC Interrupt Controller +@@ -36678,7 +40386,7 @@ pci:v00001106d0000B353* + ID_MODEL_FROM_DATABASE=VX855/VX875/VX900 PCI to PCI Bridge + + pci:v00001106d0000B410* +- ID_MODEL_FROM_DATABASE=VX900 PCI Express Root Port 1 ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI Express Root Port 1 + + pci:v00001106d0000B999* + ID_MODEL_FROM_DATABASE=[K8T890 North / VT8237 South] PCI Bridge +@@ -36696,7 +40404,7 @@ pci:v00001106d0000C340* + ID_MODEL_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + + pci:v00001106d0000C353* +- ID_MODEL_FROM_DATABASE=VX800/VX820 PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=VX800/820-Series PCI-Express Root (PCI-to-PCI Virtual Bridge) + + pci:v00001106d0000C364* + ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller +@@ -36705,7 +40413,7 @@ pci:v00001106d0000C409* + ID_MODEL_FROM_DATABASE=VX855/VX875 EIDE Controller + + pci:v00001106d0000C410* +- ID_MODEL_FROM_DATABASE=VX900 PCI Express Root Port 2 ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI Express Root Port 2 + + pci:v00001106d0000D104* + ID_MODEL_FROM_DATABASE=VT8237R USB UDCI Controller +@@ -36723,7 +40431,7 @@ pci:v00001106d0000D340* + ID_MODEL_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + + pci:v00001106d0000D410* +- ID_MODEL_FROM_DATABASE=VX900 PCI Express Root Port 3 ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI Express Root Port 3 + + pci:v00001106d0000E208* + ID_MODEL_FROM_DATABASE=PT890 PCI to PCI Bridge Controller +@@ -36735,10 +40443,10 @@ pci:v00001106d0000E340* + ID_MODEL_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + + pci:v00001106d0000E353* +- ID_MODEL_FROM_DATABASE=VX800/VX820 PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=VX800/820-Series PCI-Express Root Port 0 + + pci:v00001106d0000E410* +- ID_MODEL_FROM_DATABASE=VX900 PCI Express Physical Layer Electrical Sub-block ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI Express Physical Layer Electrical Sub-block + + pci:v00001106d0000F208* + ID_MODEL_FROM_DATABASE=PT890 PCI to PCI Bridge Controller +@@ -36750,7 +40458,10 @@ pci:v00001106d0000F340* + ID_MODEL_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + + pci:v00001106d0000F353* +- ID_MODEL_FROM_DATABASE=VX800/VX820 PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=VX800/820-Series PCI-Express Root Port 1 ++ ++pci:v00001106d0000F410* ++ ID_MODEL_FROM_DATABASE=VX900 Series PCI UART Port 0-3 + + pci:v00001107* + ID_VENDOR_FROM_DATABASE=Stratus Computers +@@ -37457,6 +41168,9 @@ pci:v0000111Dd0000806E* + pci:v0000111Dd0000806F* + ID_MODEL_FROM_DATABASE=HIO524G2 PCI Express Gen2 Switch + ++pci:v0000111Dd00008077* ++ ID_MODEL_FROM_DATABASE=89HPES64H16G2 64-Lane 16-Port PCIe Gen2 System Interconnect Switch ++ + pci:v0000111Dd00008088* + ID_MODEL_FROM_DATABASE=PES32NT8BG2 PCI Express Switch + +@@ -37581,7 +41295,7 @@ pci:v0000112A* + ID_VENDOR_FROM_DATABASE=Hermes Electronics Company, Ltd. + + pci:v0000112B* +- ID_VENDOR_FROM_DATABASE=Linotype - Hell AG ++ ID_VENDOR_FROM_DATABASE=Heidelberger Druckmaschinen AGHeidelberger Druckmaschinen AG + + pci:v0000112C* + ID_VENDOR_FROM_DATABASE=Zenith Data Systems +@@ -37601,6 +41315,9 @@ pci:v0000112Fd00000000* + pci:v0000112Fd00000001* + ID_MODEL_FROM_DATABASE=MVC IM-PCI Video frame grabber/processor + ++pci:v0000112Fd00000004* ++ ID_MODEL_FROM_DATABASE=PCDig Digital Image Capture ++ + pci:v0000112Fd00000008* + ID_MODEL_FROM_DATABASE=PC-CamLink PCI framegrabber + +@@ -38625,7 +42342,7 @@ pci:v00001134d0000000D* + ID_MODEL_FROM_DATABASE=POET PSDMS Device + + pci:v00001135* +- ID_VENDOR_FROM_DATABASE=Fuji Xerox Co Ltd ++ ID_VENDOR_FROM_DATABASE=FUJIFILM Business Innovation Corp. + + pci:v00001135d00000001* + ID_MODEL_FROM_DATABASE=Printer controller +@@ -38699,6 +42416,12 @@ pci:v00001137d00000042sv00001137sd0000012E* + pci:v00001137d00000042sv00001137sd0000014D* + ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1385 PCIe Management Controller) + ++pci:v00001137d00000042sv00001137sd00000217* ++ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1455 PCIe Management Controller) ++ ++pci:v00001137d00000042sv00001137sd00000218* ++ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1457 PCIe Management Controller) ++ + pci:v00001137d00000043* + ID_MODEL_FROM_DATABASE=VIC Ethernet NIC + +@@ -38738,6 +42461,33 @@ pci:v00001137d00000043sv00001137sd00000137* + pci:v00001137d00000043sv00001137sd0000014D* + ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1385 PCIe Ethernet NIC) + ++pci:v00001137d00000043sv00001137sd0000015D* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1387 MLOM Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd00000215* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1440 Mezzanine Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd00000216* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1480 MLOM Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd00000217* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1455 PCIe Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd00000218* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1457 MLOM Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd00000219* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1485 PCIe Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd0000021A* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1487 MLOM Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd0000024A* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1495 PCIe Ethernet NIC) ++ ++pci:v00001137d00000043sv00001137sd0000024B* ++ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1497 MLOM Ethernet NIC) ++ + pci:v00001137d00000044* + ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic + +@@ -38873,6 +42623,9 @@ pci:v00001137d000000CFsv00001137sd0000012E* + pci:v00001137d000000CFsv00001137sd00000137* + ID_MODEL_FROM_DATABASE=VIC Userspace NIC (VIC 1380 Mezzanine Userspace NIC) + ++pci:v00001137d0000023E* ++ ID_MODEL_FROM_DATABASE=1GigE I350 LOM ++ + pci:v00001138* + ID_VENDOR_FROM_DATABASE=Ziatech Corporation + +@@ -39126,61 +42879,64 @@ pci:v00001148d00004300sv00001259sd00002977* + ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970TX/2TX Gigabit Ethernet Adapter) + + pci:v00001148d00004320* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] + + pci:v00001148d00004320sv00001148sd00000121* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8001 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8001 Adapter) + + pci:v00001148d00004320sv00001148sd00000221* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8002 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8002 Adapter) + + pci:v00001148d00004320sv00001148sd00000321* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8003 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8003 Adapter) + + pci:v00001148d00004320sv00001148sd00000421* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8004 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8004 Adapter) + + pci:v00001148d00004320sv00001148sd00000621* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8006 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8006 Adapter) + + pci:v00001148d00004320sv00001148sd00000721* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8007 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8007 Adapter) + + pci:v00001148d00004320sv00001148sd00000821* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8008 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8008 Adapter) + + pci:v00001148d00004320sv00001148sd00000921* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8009 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8009 Adapter) + + pci:v00001148d00004320sv00001148sd00001121* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8011 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8011 Adapter) + + pci:v00001148d00004320sv00001148sd00001221* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8012 Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (Marvell RDK-8012 Adapter) + + pci:v00001148d00004320sv00001148sd00003221* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9521 V2.0 10/100/1000Base-T Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9521 V2.0 10/100/1000Base-T Adapter) + + pci:v00001148d00004320sv00001148sd00005021* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter) + + pci:v00001148d00004320sv00001148sd00005041* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter) + + pci:v00001148d00004320sv00001148sd00005043* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter) + + pci:v00001148d00004320sv00001148sd00005051* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter) + + pci:v00001148d00004320sv00001148sd00005061* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter) + + pci:v00001148d00004320sv00001148sd00005071* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter) + + pci:v00001148d00004320sv00001148sd00009521* +- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9521 10/100/1000Base-T Adapter) ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (SK-9521 10/100/1000Base-T Adapter) ++ ++pci:v00001148d00004320sv00001259sd00002916* ++ ID_MODEL_FROM_DATABASE=SK-98xx V2.0 Gigabit Ethernet Adapter [Marvell 88E8001] (AT-2916T) + + pci:v00001148d00004400* + ID_MODEL_FROM_DATABASE=SK-9Dxx Gigabit Ethernet Adapter +@@ -39189,7 +42945,46 @@ pci:v00001148d00004500* + ID_MODEL_FROM_DATABASE=SK-9Mxx Gigabit Ethernet Adapter + + pci:v00001148d00009000* +- ID_MODEL_FROM_DATABASE=SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45 ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] ++ ++pci:v00001148d00009000sv00001148sd00002100* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45) ++ ++pci:v00001148d00009000sv00001148sd00002200* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S22 10/100/1000Base-T Dual Port Server Adapter, PCI-X, 2 Copper RJ-45) ++ ++pci:v00001148d00009000sv00001148sd00002210* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9P22 10/100/1000 Base-T Dual Port PMC card) ++ ++pci:v00001148d00009000sv00001148sd00002220* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (TPMC-GBE-CO) ++ ++pci:v00001148d00009000sv00001148sd00008100* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S81 1000Base-SX Server Adapter,PCI-X, Fiber SX/LC) ++ ++pci:v00001148d00009000sv00001148sd00008200* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S82 1000Base-SX Dual Port Server Adapter, PCI-X, 2 Fiber SX/LC) ++ ++pci:v00001148d00009000sv00001148sd00008210* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9P82 1000 Base-SX Dual Port PMC card) ++ ++pci:v00001148d00009000sv00001148sd00008220* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (TPMC-GBE-FI) ++ ++pci:v00001148d00009000sv00001148sd00009100* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S91 1000Base-LX Server Adapter,PCI-X, Fiber LX/LC) ++ ++pci:v00001148d00009000sv00001148sd00009200* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (SK-9S92 1000Base-LX Dual Port Server Adapter, PCI-X, 2 Fiber LX/LC) ++ ++pci:v00001148d00009000sv00001259sd00002973* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (AT-2971SX v2 Gigabit Adapter) ++ ++pci:v00001148d00009000sv00001259sd00002974* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (AT-2971T v2 Gigabit Adapter) ++ ++pci:v00001148d00009000sv00001259sd00002978* ++ ID_MODEL_FROM_DATABASE=SK-9Sxx Gigabit Ethernet Server Adapter PCI-X [Marvell 88E8022] (AT-2971LX Gigabit Adapter) + + pci:v00001148d00009843* + ID_MODEL_FROM_DATABASE=[Fujitsu] Gigabit Ethernet +@@ -39953,6 +43748,9 @@ pci:v00001172d000000A7* + pci:v00001172d00000530* + ID_MODEL_FROM_DATABASE=Stratix IV + ++pci:v00001172d0000646C* ++ ID_MODEL_FROM_DATABASE=KT-500/KT-521 board ++ + pci:v00001173* + ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc + +@@ -39975,7 +43773,7 @@ pci:v00001178d0000AFA1* + ID_MODEL_FROM_DATABASE=Fast Ethernet Adapter + + pci:v00001179* +- ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems ++ ID_VENDOR_FROM_DATABASE=Toshiba Corporation + + pci:v00001179d00000102* + ID_MODEL_FROM_DATABASE=Extended IDE Controller +@@ -39983,12 +43781,51 @@ pci:v00001179d00000102* + pci:v00001179d00000103* + ID_MODEL_FROM_DATABASE=EX-IDE Type-B + ++pci:v00001179d0000010E* ++ ID_MODEL_FROM_DATABASE=PXP04 NVMe SSD ++ + pci:v00001179d0000010F* + ID_MODEL_FROM_DATABASE=NVMe Controller + ++pci:v00001179d00000110* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 ++ ++pci:v00001179d00000110sv00001028sd00001FFB* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Express Flash NVMe 960G (RI) U.2 (CD5)) ++ ++pci:v00001179d00000110sv00001028sd00001FFC* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Express Flash NVMe 1.92T (RI) U.2 (CD5)) ++ ++pci:v00001179d00000110sv00001028sd00001FFD* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Express Flash NVMe 3.84T (RI) U.2 (CD5)) ++ ++pci:v00001179d00000110sv00001028sd00001FFE* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Express Flash NVMe 7.68T (RI) U.2 (CD5)) ++ ++pci:v00001179d00000110sv00001179sd00000001* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (KIOXIA CM5-R series SSD) ++ ++pci:v00001179d00000110sv00001179sd00000021* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (KIOXIA CD5 series SSD) ++ ++pci:v00001179d00000110sv00001D49sd00004039* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Thinksystem U.2 CM5 NVMe SSD) ++ ++pci:v00001179d00000110sv00001D49sd0000403A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx5 (Thinksystem AIC CM5 NVMe SSD) ++ ++pci:v00001179d00000113* ++ ID_MODEL_FROM_DATABASE=BG3 NVMe SSD Controller ++ ++pci:v00001179d00000113sv00001179sd00000001* ++ ID_MODEL_FROM_DATABASE=BG3 NVMe SSD Controller (Toshiba KBG30ZMS128G 128GB NVMe SSD) ++ + pci:v00001179d00000115* + ID_MODEL_FROM_DATABASE=XG4 NVMe SSD Controller + ++pci:v00001179d0000011A* ++ ID_MODEL_FROM_DATABASE=XG6 NVMe SSD Controller ++ + pci:v00001179d00000404* + ID_MODEL_FROM_DATABASE=DVD Decoder card + +@@ -40175,6 +44012,45 @@ pci:v0000117Cd00000094sv0000117Csd000000A3* + pci:v0000117Cd00000094sv0000117Csd000000AC* + ID_MODEL_FROM_DATABASE=Celerity FC 16/32Gb/s Gen 6 Fibre Channel HBA (Celerity FC-324E) + ++pci:v0000117Cd000000BB* ++ ID_MODEL_FROM_DATABASE=Celerity FC 32/64Gb/s Gen 7 Fibre Channel HBA ++ ++pci:v0000117Cd000000BBsv0000117Csd000000BC* ++ ID_MODEL_FROM_DATABASE=Celerity FC 32/64Gb/s Gen 7 Fibre Channel HBA (Celerity FC-321P) ++ ++pci:v0000117Cd000000BBsv0000117Csd000000BD* ++ ID_MODEL_FROM_DATABASE=Celerity FC 32/64Gb/s Gen 7 Fibre Channel HBA (Celerity FC-322P) ++ ++pci:v0000117Cd000000BBsv0000117Csd000000BE* ++ ID_MODEL_FROM_DATABASE=Celerity FC 32/64Gb/s Gen 7 Fibre Channel HBA (Celerity FC-324P) ++ ++pci:v0000117Cd000000C5* ++ ID_MODEL_FROM_DATABASE=ExpressNVM PCIe Gen4 Switch ++ ++pci:v0000117Cd000000C5sv0000117Csd000000C6* ++ ID_MODEL_FROM_DATABASE=ExpressNVM PCIe Gen4 Switch (ExpressNVM S48F PCIe Gen4) ++ ++pci:v0000117Cd000000C5sv0000117Csd000000C7* ++ ID_MODEL_FROM_DATABASE=ExpressNVM PCIe Gen4 Switch (ExpressNVM S468 PCIe Gen4) ++ ++pci:v0000117Cd000000E6* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA ++ ++pci:v0000117Cd000000E6sv0000117Csd000000C0* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA (ExpressSAS H1280 GT) ++ ++pci:v0000117Cd000000E6sv0000117Csd000000C1* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA (ExpressSAS H1208 GT) ++ ++pci:v0000117Cd000000E6sv0000117Csd000000C2* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA (ExpressSAS H1244 GT) ++ ++pci:v0000117Cd000000E6sv0000117Csd000000C3* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA (ExpressSAS H12F0 GT) ++ ++pci:v0000117Cd000000E6sv0000117Csd000000C4* ++ ID_MODEL_FROM_DATABASE=ExpressSAS GT 12Gb/s SAS/SATA HBA (ExpressSAS H120F GT) ++ + pci:v0000117Cd00008013* + ID_MODEL_FROM_DATABASE=ExpressPCI UL4D + +@@ -40256,6 +44132,9 @@ pci:v00001180d00000476sv0000103Csd000030C0* + pci:v00001180d00000476sv0000103Csd000030C1* + ID_MODEL_FROM_DATABASE=RL5c476 II (Compaq 6910p) + ++pci:v00001180d00000476sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=RL5c476 II (X58LE) ++ + pci:v00001180d00000476sv00001043sd00001237* + ID_MODEL_FROM_DATABASE=RL5c476 II (A6J-Q008) + +@@ -40293,7 +44172,7 @@ pci:v00001180d00000476sv000017AAsd000020C4* + ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61/R61) + + pci:v00001180d00000476sv000017AAsd000020C6* +- ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad R61) ++ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad R61/T400) + + pci:v00001180d00000477* + ID_MODEL_FROM_DATABASE=RL5c477 +@@ -40388,17 +44267,23 @@ pci:v00001180d00000592sv0000103Csd000030CC* + pci:v00001180d00000592sv0000103Csd000030CF* + ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Pavilion dv95xx/96xx/97xx/98xx series) + ++pci:v00001180d00000592sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (X58LE) ++ + pci:v00001180d00000592sv00001043sd00001237* + ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (A6J-Q008) + + pci:v00001180d00000592sv00001043sd00001967* + ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (V6800V) + ++pci:v00001180d00000592sv0000104Dsd00009035* ++ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (VAIO VGN-FW11ZRU) ++ + pci:v00001180d00000592sv0000144Dsd0000C018* + ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (X20 IV) + + pci:v00001180d00000592sv000017AAsd000020CA* +- ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (ThinkPad T61) ++ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (ThinkPad T61/T400) + + pci:v00001180d00000811* + ID_MODEL_FROM_DATABASE=R5C811 +@@ -40445,6 +44330,9 @@ pci:v00001180d00000822sv0000103Csd000030CC* + pci:v00001180d00000822sv0000103Csd000030CF* + ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Pavilion dv9668eg Laptop) + ++pci:v00001180d00000822sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (X58LE) ++ + pci:v00001180d00000822sv00001043sd00001237* + ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (A6J-Q008) + +@@ -40464,7 +44352,7 @@ pci:v00001180d00000822sv000017AAsd000020C7* + ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad T61) + + pci:v00001180d00000822sv000017AAsd000020C8* +- ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad W500) ++ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad T400/W500) + + pci:v00001180d00000832* + ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller +@@ -40538,6 +44426,9 @@ pci:v00001180d00000843sv0000103Csd000030B7* + pci:v00001180d00000843sv0000103Csd000030CF* + ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Pavilion dv9500/9600/9700 series) + ++pci:v00001180d00000843sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (X58LE) ++ + pci:v00001180d00000843sv00001183sd00000843* + ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Alienware Aurora m9700) + +@@ -40574,6 +44465,9 @@ pci:v00001180d00000852sv00001180sd00000852* + pci:v00001180d00000852sv00001324sd000010CF* + ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (P7120) + ++pci:v00001180d00000852sv000017AAsd000020CB* ++ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (ThinkPad T400) ++ + pci:v00001180d0000E230* + ID_MODEL_FROM_DATABASE=R5U2xx (R5U230 / R5U231 / R5U241) [Memory Stick Host Controller] + +@@ -40595,6 +44489,9 @@ pci:v00001180d0000E822sv00001028sd0000040A* + pci:v00001180d0000E822sv00001028sd0000040B* + ID_MODEL_FROM_DATABASE=MMC/SD Host Controller (Latitude E6510) + ++pci:v00001180d0000E822sv000017AAsd000021CF* ++ ID_MODEL_FROM_DATABASE=MMC/SD Host Controller (ThinkPad T520) ++ + pci:v00001180d0000E823* + ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller + +@@ -40811,6 +44708,9 @@ pci:v0000118Dd00000324* + pci:v0000118Dd00000344* + ID_MODEL_FROM_DATABASE=Model 44 Road Runner Frame Grabber + ++pci:v0000118Dd0000B04E* ++ ID_MODEL_FROM_DATABASE=Claxon CXP4 CoaXPress frame grabber ++ + pci:v0000118E* + ID_VENDOR_FROM_DATABASE=Hermstedt GmbH + +@@ -40955,6 +44855,12 @@ pci:v0000119F* + pci:v0000119Fd00001081* + ID_MODEL_FROM_DATABASE=BXI Host Channel Adapter + ++pci:v0000119Fd00001101* ++ ID_MODEL_FROM_DATABASE=BXI Host Channel Adapter v1.2 ++ ++pci:v0000119Fd00001121* ++ ID_MODEL_FROM_DATABASE=BXI Host Channel Adapter v1.3 ++ + pci:v000011A0* + ID_VENDOR_FROM_DATABASE=Convex Computer Corporation + +@@ -40994,6 +44900,12 @@ pci:v000011AA* + pci:v000011AB* + ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. + ++pci:v000011ABd00000100* ++ ID_MODEL_FROM_DATABASE=88F3700 [Armada 3700 Family] ARM SoC ++ ++pci:v000011ABd00000110* ++ ID_MODEL_FROM_DATABASE=88F8040 PCI Express controller ++ + pci:v000011ABd00000146* + ID_MODEL_FROM_DATABASE=GT-64010/64010A System Controller + +@@ -41537,6 +45449,12 @@ pci:v000011ABd00004380* + pci:v000011ABd00004381* + ID_MODEL_FROM_DATABASE=Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB] + ++pci:v000011ABd00004381sv00001259sd00002803* ++ ID_MODEL_FROM_DATABASE=Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB] (AT-2814FX) ++ ++pci:v000011ABd00004381sv00001259sd00002804* ++ ID_MODEL_FROM_DATABASE=Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB] (AT-2874xx) ++ + pci:v000011ABd00004611* + ID_MODEL_FROM_DATABASE=GT-64115 System Controller + +@@ -41627,6 +45545,12 @@ pci:v000011ABd00006480sv00001775sd0000C200* + pci:v000011ABd00006485* + ID_MODEL_FROM_DATABASE=MV64460/64461/64462 System Controller, Revision B + ++pci:v000011ABd00006820* ++ ID_MODEL_FROM_DATABASE=88F6820 [Armada 385] ARM SoC ++ ++pci:v000011ABd00006828* ++ ID_MODEL_FROM_DATABASE=88F6828 [Armada 388] ARM SoC ++ + pci:v000011ABd00007042* + ID_MODEL_FROM_DATABASE=88SX7042 PCI-e 4-port SATA-II + +@@ -41645,6 +45569,9 @@ pci:v000011ABd00007823* + pci:v000011ABd00007846* + ID_MODEL_FROM_DATABASE=88F6820 [Armada 385] ARM SoC + ++pci:v000011ABd0000D40F* ++ ID_MODEL_FROM_DATABASE=Bobcat3 Ethernet Switch ++ + pci:v000011ABd0000F003* + ID_MODEL_FROM_DATABASE=GT-64010 Primary Image Piranha Image Generator + +@@ -41670,7 +45597,7 @@ pci:v000011ADd00000002sv000011ADsd0000FFFF* + ID_MODEL_FROM_DATABASE=LNE100TX + + pci:v000011ADd00000002sv00001385sd0000F004* +- ID_MODEL_FROM_DATABASE=LNE100TX (FA310TX) ++ ID_MODEL_FROM_DATABASE=LNE100TX (FA310/TX LAN 10/100 PCI Ethernet Adapter) + + pci:v000011ADd00000002sv00002646sd0000F002* + ID_MODEL_FROM_DATABASE=LNE100TX (KNE110TX EtheRx Fast Ethernet) +@@ -42158,9 +46085,15 @@ pci:v000011C1d00005811sv0000103Csd00002A9E* + pci:v000011C1d00005811sv00001043sd00008294* + ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (LSI FW322/323 IEEE 1394a FireWire Controller) + ++pci:v000011C1d00005811sv000011BDsd0000000E* ++ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (LSI FW323) ++ + pci:v000011C1d00005811sv00008086sd0000524C* + ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (D865PERL mainboard) + ++pci:v000011C1d00005811sv00009005sd00000033* ++ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (Adaptec AFW-2100 (HP) 2102900-R) ++ + pci:v000011C1d00005811sv0000DEADsd00000800* + ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (FireWire Host Bus Adapter) + +@@ -42551,6 +46484,9 @@ pci:v000011F8d00008000* + pci:v000011F8d00008009* + ID_MODEL_FROM_DATABASE=PM8009 SPCve 8x6G + ++pci:v000011F8d00008018* ++ ID_MODEL_FROM_DATABASE=PM8018 Adaptec SAS Adaptor ASA-70165H PCIe Gen3 x8 6 Gbps 16-lane 4x SFF-8644 ++ + pci:v000011F8d00008032* + ID_MODEL_FROM_DATABASE=PM8032 Tachyon QE8 + +@@ -42597,11 +46533,29 @@ pci:v000011F8d00008073* + ID_MODEL_FROM_DATABASE=PM8073 Tachyon SPCve 12G 16-port SAS/SATA controller + + pci:v000011F8d00008531* +- ID_MODEL_FROM_DATABASE=PM8531 PFX 24xG3 Fanout PCIe Switches ++ ID_MODEL_FROM_DATABASE=PM8531 PFX 24xG3 PCIe Fanout Switch ++ ++pci:v000011F8d00008532* ++ ID_MODEL_FROM_DATABASE=PM8532 PFX 32xG3 PCIe Fanout Switch ++ ++pci:v000011F8d00008533* ++ ID_MODEL_FROM_DATABASE=PM8533 PFX 48xG3 PCIe Fanout Switch ++ ++pci:v000011F8d00008534* ++ ID_MODEL_FROM_DATABASE=PM8534 PFX 64xG3 PCIe Fanout Switch ++ ++pci:v000011F8d00008535* ++ ID_MODEL_FROM_DATABASE=PM8535 PFX 80xG3 PCIe Fanout Switch ++ ++pci:v000011F8d00008536* ++ ID_MODEL_FROM_DATABASE=PM8536 PFX 96xG3 PCIe Fanout Switch + + pci:v000011F8d00008546* + ID_MODEL_FROM_DATABASE=PM8546 B-FEIP PSX 96xG3 PCIe Storage Switch + ++pci:v000011F8d00008562* ++ ID_MODEL_FROM_DATABASE=PM8562 Switchtec PFX-L 32xG3 Fanout-Lite PCIe Gen3 Switch ++ + pci:v000011F9* + ID_VENDOR_FROM_DATABASE=I-Cube Inc + +@@ -42618,7 +46572,7 @@ pci:v000011FD* + ID_VENDOR_FROM_DATABASE=High Street Consultants + + pci:v000011FE* +- ID_VENDOR_FROM_DATABASE=Comtrol Corporation ++ ID_VENDOR_FROM_DATABASE=Pepperl+Fuchs + + pci:v000011FEd00000001* + ID_MODEL_FROM_DATABASE=RocketPort PCI 32-port w/external I/F +@@ -43344,7 +47298,7 @@ pci:v00001225* + ID_VENDOR_FROM_DATABASE=Power I/O, Inc. + + pci:v00001227* +- ID_VENDOR_FROM_DATABASE=Tech-Source ++ ID_VENDOR_FROM_DATABASE=EIZO Rugged Solutions + + pci:v00001227d00000006* + ID_MODEL_FROM_DATABASE=Raptor GFX 8P +@@ -43733,6 +47687,24 @@ pci:v0000125Bd00001400* + pci:v0000125Bd00001400sv00001186sd00001100* + ID_MODEL_FROM_DATABASE=AX88141 Fast Ethernet Controller (AX8814X Based PCI Fast Ethernet Adapter) + ++pci:v0000125Bd00009100* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller ++ ++pci:v0000125Bd00009100sv0000A000sd00001000* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller (Serial Port) ++ ++pci:v0000125Bd00009100sv0000A000sd00002000* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller (Parallel Port) ++ ++pci:v0000125Bd00009100sv0000A000sd00006000* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller (SPI) ++ ++pci:v0000125Bd00009100sv0000A000sd00007000* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller (Local Bus) ++ ++pci:v0000125Bd00009100sv0000EA50sd00001C10* ++ ID_MODEL_FROM_DATABASE=AX99100 PCIe to Multi I/O Controller (RXi2-BP) ++ + pci:v0000125C* + ID_VENDOR_FROM_DATABASE=Aurora Technologies, Inc. + +@@ -44051,6 +48023,9 @@ pci:v00001268* + pci:v00001269* + ID_VENDOR_FROM_DATABASE=Thomson-CSF/TTM + ++pci:v00001269d000000B3* ++ ID_MODEL_FROM_DATABASE=5G Data Card [Cinterion MV31-W] ++ + pci:v0000126A* + ID_VENDOR_FROM_DATABASE=Lexmark International, Inc. + +@@ -44111,6 +48086,12 @@ pci:v0000126Fd00000820* + pci:v0000126Fd00000910* + ID_MODEL_FROM_DATABASE=SM910 + ++pci:v0000126Fd00002262* ++ ID_MODEL_FROM_DATABASE=SM2262/SM2262EN SSD Controller ++ ++pci:v0000126Fd00002263* ++ ID_MODEL_FROM_DATABASE=SM2263EN/SM2263XT SSD Controller ++ + pci:v00001270* + ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd. + +@@ -44763,16 +48744,16 @@ pci:v00001282d00006585* + ID_MODEL_FROM_DATABASE=DM562P V90 Modem + + pci:v00001282d00009009* +- ID_MODEL_FROM_DATABASE=Ethernet 100/10 MBit ++ ID_MODEL_FROM_DATABASE=DM9009 Ethernet Controller + + pci:v00001282d00009100* + ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + + pci:v00001282d00009102* +- ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet ++ ID_MODEL_FROM_DATABASE=DM9102 Fast Ethernet Controller + + pci:v00001282d00009102sv00000291sd00008212* +- ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet (DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit) ++ ID_MODEL_FROM_DATABASE=DM9102 Fast Ethernet Controller (DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit) + + pci:v00001282d00009132* + ID_MODEL_FROM_DATABASE=Ethernet 100/10 MBit +@@ -44819,6 +48800,9 @@ pci:v00001283d00008889* + pci:v00001283d00008892* + ID_MODEL_FROM_DATABASE=IT8892E PCIe to PCI Bridge + ++pci:v00001283d00008892sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=IT8892E PCIe to PCI Bridge (DH61CR motherboard) ++ + pci:v00001283d00008893* + ID_MODEL_FROM_DATABASE=IT8893E PCIe to PCI Bridge + +@@ -45081,7 +49065,7 @@ pci:v000012B6* + ID_VENDOR_FROM_DATABASE=Natural Microsystems + + pci:v000012B7* +- ID_VENDOR_FROM_DATABASE=Cognex Modular Vision Systems Div. - Acumen Inc. ++ ID_VENDOR_FROM_DATABASE=Cognex Corporation + + pci:v000012B8* + ID_VENDOR_FROM_DATABASE=Korg +@@ -45470,9 +49454,24 @@ pci:v000012D8* + pci:v000012D8d000001A7* + ID_MODEL_FROM_DATABASE=7C21P100 2-port PCI-X to PCI-X Bridge + ++pci:v000012D8d00000303* ++ ID_MODEL_FROM_DATABASE=PCI Express Switch 3-3 ++ ++pci:v000012D8d00000508* ++ ID_MODEL_FROM_DATABASE=PI7C9X20508GP PCI Express Switch 5Port-8Lane ++ ++pci:v000012D8d00002304* ++ ID_MODEL_FROM_DATABASE=PI7C9X2G304 EL/SL PCIe2 3-Port/4-Lane Packet Switch ++ ++pci:v000012D8d00002404* ++ ID_MODEL_FROM_DATABASE=PI7C9X2G404 EL/SL PCIe2 4-Port/4-Lane Packet Switch ++ + pci:v000012D8d00002608* + ID_MODEL_FROM_DATABASE=PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch + ++pci:v000012D8d00002608sv0000EA50sd0000CC10* ++ ID_MODEL_FROM_DATABASE=PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch (RXi2-BP) ++ + pci:v000012D8d0000400A* + ID_MODEL_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port + +@@ -45503,6 +49502,9 @@ pci:v000012D8d00008152* + pci:v000012D8d00008154* + ID_MODEL_FROM_DATABASE=PI7C8154A/PI7C8154B/PI7C8154BI PCI-to-PCI Bridge + ++pci:v000012D8d00008619* ++ ID_MODEL_FROM_DATABASE=PI7C9X2G1616PR PCIe2 16-Port/16-Lane Packet Switch ++ + pci:v000012D8d0000E110* + ID_MODEL_FROM_DATABASE=PI7C9X110 PCI Express to PCI bridge + +@@ -45605,6 +49607,9 @@ pci:v000012EB* + pci:v000012EBd00000001* + ID_MODEL_FROM_DATABASE=Vortex 1 + ++pci:v000012EBd00000001sv00000000sd00000300* ++ ID_MODEL_FROM_DATABASE=Vortex 1 (Terasound A3D PCI) ++ + pci:v000012EBd00000001sv0000104Dsd00008036* + ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor) + +@@ -45621,7 +49626,7 @@ pci:v000012EBd00000001sv00001092sd00002200* + ID_MODEL_FROM_DATABASE=Vortex 1 (Sonic Impact A3D) + + pci:v000012EBd00000001sv0000122Dsd00001002* +- ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor) ++ ID_MODEL_FROM_DATABASE=Vortex 1 (SC 338-A3D) + + pci:v000012EBd00000001sv000012EBsd00000001* + ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor) +@@ -46479,7 +50484,7 @@ pci:v00001351* + ID_VENDOR_FROM_DATABASE=Sonix Inc + + pci:v00001353* +- ID_VENDOR_FROM_DATABASE=Vierling Communication SAS ++ ID_VENDOR_FROM_DATABASE=dbeeSet Technology + + pci:v00001353d00000002* + ID_MODEL_FROM_DATABASE=Proserver +@@ -46493,6 +50498,12 @@ pci:v00001353d00000004* + pci:v00001353d00000005* + ID_MODEL_FROM_DATABASE=PCI-FUT-S0 + ++pci:v00001353d00000006* ++ ID_MODEL_FROM_DATABASE=OTDU-1U (FPGA Zynq-7000) ++ ++pci:v00001353d00000007* ++ ID_MODEL_FROM_DATABASE=OTDU-EX ++ + pci:v00001354* + ID_VENDOR_FROM_DATABASE=Dwave System Inc + +@@ -47643,7 +51654,7 @@ pci:v000013CB* + ID_VENDOR_FROM_DATABASE=Yano Electric Co Ltd + + pci:v000013CC* +- ID_VENDOR_FROM_DATABASE=Metheus Corporation ++ ID_VENDOR_FROM_DATABASE=BARCO + + pci:v000013CD* + ID_VENDOR_FROM_DATABASE=Compatible Systems Corporation +@@ -47948,6 +51959,9 @@ pci:v000013F6d00008788sv00001043sd00008467* + pci:v000013F6d00008788sv00001043sd00008521* + ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CMI8786 (Xonar DGX)) + ++pci:v000013F6d00008788sv00001043sd00008522* ++ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Xonar DSX) ++ + pci:v000013F6d00008788sv00001043sd000085F4* + ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar Essence STX II)) + +@@ -48035,6 +52049,9 @@ pci:v000013FEd00001603* + pci:v000013FEd00001604* + ID_MODEL_FROM_DATABASE=PCI-1604 2-port RS-232 + ++pci:v000013FEd00001680* ++ ID_MODEL_FROM_DATABASE=PCI-1680 Rev.A1 2-port CAN-bus with isolation protection ++ + pci:v000013FEd000016FF* + ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD) + +@@ -48050,17 +52067,26 @@ pci:v000013FEd000016FFsv00001612sd00000000* + pci:v000013FEd00001711* + ID_MODEL_FROM_DATABASE=PCI-1711 16-channel data acquisition card 12-bit, 100kS/s + ++pci:v000013FEd00001713* ++ ID_MODEL_FROM_DATABASE=PCI-1713 32-channel isolated analog input card ++ + pci:v000013FEd00001733* + ID_MODEL_FROM_DATABASE=PCI-1733 32-channel isolated digital input card + ++pci:v000013FEd00001734* ++ ID_MODEL_FROM_DATABASE=PCI-1734 32-channel isolated digital output card ++ + pci:v000013FEd00001752* +- ID_MODEL_FROM_DATABASE=PCI-1752 ++ ID_MODEL_FROM_DATABASE=PCI-1752 64-channel Isolated Digital Output Card + + pci:v000013FEd00001754* +- ID_MODEL_FROM_DATABASE=PCI-1754 ++ ID_MODEL_FROM_DATABASE=PCI-1754 64-channel Isolated Digital Input Card + + pci:v000013FEd00001756* +- ID_MODEL_FROM_DATABASE=PCI-1756 ++ ID_MODEL_FROM_DATABASE=PCI-1756 64-ch Isolated Digital I/O PCI Card ++ ++pci:v000013FEd0000A004* ++ ID_MODEL_FROM_DATABASE=PCI-1612 4-port RS-232/422/485 + + pci:v000013FEd0000C302* + ID_MODEL_FROM_DATABASE=MIOe-3680 2-Port CAN-Bus MIOe Module with Isolation Protection +@@ -48578,6 +52604,9 @@ pci:v00001414d00000001* + pci:v00001414d00000002* + ID_MODEL_FROM_DATABASE=MN-130 (ADMtek Centaur-P based) + ++pci:v00001414d0000008C* ++ ID_MODEL_FROM_DATABASE=Basic Render Driver ++ + pci:v00001414d00005353* + ID_MODEL_FROM_DATABASE=Hyper-V virtual VGA + +@@ -48692,17 +52721,425 @@ pci:v00001415d00009521* + pci:v00001415d00009523* + ID_MODEL_FROM_DATABASE=OX16PCI952 Integrated Parallel Port + ++pci:v00001415d0000C000* ++ ID_MODEL_FROM_DATABASE=OXPCIe840 Parallel Port ++ ++pci:v00001415d0000C004* ++ ID_MODEL_FROM_DATABASE=OXPCIe840 Parallel Port ++ ++pci:v00001415d0000C006* ++ ID_MODEL_FROM_DATABASE=OXPCIe840 GPIO ++ ++pci:v00001415d0000C100* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C101* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C104* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C105* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C106* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C108* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C109* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C10C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C10D* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C10E* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C110* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C114* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C118* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C11B* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Native 950 UART ++ ++pci:v00001415d0000C11C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Parallel Port ++ ++pci:v00001415d0000C11E* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C11F* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Native 950 UART ++ ++pci:v00001415d0000C120* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C124* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C126* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C128* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C12C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART ++ ++pci:v00001415d0000C12E* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C134* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C138* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Native 950 UART ++ ++pci:v00001415d0000C13C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C13D* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Native 950 UART ++ ++pci:v00001415d0000C140* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #1 ++ ++pci:v00001415d0000C141* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #2 ++ ++pci:v00001415d0000C144* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #1 ++ ++pci:v00001415d0000C145* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #2 ++ ++pci:v00001415d0000C146* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C148* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #1 ++ ++pci:v00001415d0000C149* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #2 ++ ++pci:v00001415d0000C14C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #1 ++ ++pci:v00001415d0000C14D* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Legacy 950 UART #2 ++ ++pci:v00001415d0000C14E* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C154* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ + pci:v00001415d0000C158* +- ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual Native 950 UART + + pci:v00001415d0000C158sv0000E4BFsd0000C504* +- ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART (CP4-SCAT Wireless Technologies Carrier Board) ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual Native 950 UART (CP4-SCAT Wireless Technologies Carrier Board) + + pci:v00001415d0000C158sv0000E4BFsd0000D551* +- ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART (DU1-MUSTANG Dual-Port RS-485 Interface) ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual Native 950 UART (DU1-MUSTANG Dual-Port RS-485 Interface) ++ ++pci:v00001415d0000C15C* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 GPIO ++ ++pci:v00001415d0000C15D* ++ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual Native 950 UART ++ ++pci:v00001415d0000C204* ++ ID_MODEL_FROM_DATABASE=OXPCIe954 GPIO ++ ++pci:v00001415d0000C208* ++ ID_MODEL_FROM_DATABASE=OXPCIe954 Quad Native 950 UART ++ ++pci:v00001415d0000C20C* ++ ID_MODEL_FROM_DATABASE=OXPCIe954 GPIO ++ ++pci:v00001415d0000C20D* ++ ID_MODEL_FROM_DATABASE=OXPCIe954 Quad Native 950 UART ++ ++pci:v00001415d0000C304* ++ ID_MODEL_FROM_DATABASE=OXPCIe958 GPIO + + pci:v00001415d0000C308* +- ID_MODEL_FROM_DATABASE=EX-44016 16-port serial ++ ID_MODEL_FROM_DATABASE=OXPCIe958 Quad Native 950 UART ++ ++pci:v00001415d0000C30C* ++ ID_MODEL_FROM_DATABASE=OXPCIe958 GPIO ++ ++pci:v00001415d0000C30D* ++ ID_MODEL_FROM_DATABASE=OXPCIe958 Quad Native 950 UART ++ ++pci:v00001415d0000C530* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C531* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C534* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C535* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C536* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C538* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C539* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C53B* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C53C* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C53D* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (ULPI/R-ULPI) ++ ++pci:v00001415d0000C53E* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C53F* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C540* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C541* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C544* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C545* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C546* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C548* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C549* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C54B* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C54C* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C54D* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C54E* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual GPIO ++ ++pci:v00001415d0000C54F* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C560* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/analog) ++ ++pci:v00001415d0000C561* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C564* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/analog) ++ ++pci:v00001415d0000C565* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C566* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C568* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/analog) ++ ++pci:v00001415d0000C569* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C56B* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C56C* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (ULPI/analog) ++ ++pci:v00001415d0000C56D* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C56E* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C56F* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C570* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI/analog) ++ ++pci:v00001415d0000C571* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C574* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI/analog) ++ ++pci:v00001415d0000C575* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C576* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C578* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI/analog) ++ ++pci:v00001415d0000C579* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C57B* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C57C* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Dual OHCI USB Controller (R-ULPI/analog) ++ ++pci:v00001415d0000C57D* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C57E* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 GPIO ++ ++pci:v00001415d0000C57F* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5A0* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5A1* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5A2* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5A4* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5A5* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5A6* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5A8* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5A9* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5AA* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5AB* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5AC* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5AD* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (ULPI) ++ ++pci:v00001415d0000C5AE* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5AF* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5B0* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5B1* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5B2* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5B4* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5B5* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5B6* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5B8* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5B9* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5BA* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5BB* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5BC* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5BD* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 EHCI USB Controller (R-ULPI) ++ ++pci:v00001415d0000C5BE* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5BF* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5C0* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (analog) ++ ++pci:v00001415d0000C5C2* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5C4* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (analog) ++ ++pci:v00001415d0000C5C6* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5C8* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (analog) ++ ++pci:v00001415d0000C5CA* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface ++ ++pci:v00001415d0000C5CB* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART ++ ++pci:v00001415d0000C5CC* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 OHCI USB Controller (analog) ++ ++pci:v00001415d0000C5CE* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Programmable Memory Interface & GPIO ++ ++pci:v00001415d0000C5CF* ++ ID_MODEL_FROM_DATABASE=OXPCIe200 Native 950 UART + + pci:v00001416* + ID_VENDOR_FROM_DATABASE=Multiwave Innovation pte Ltd +@@ -49427,6 +53864,15 @@ pci:v00001425d000050AC* + pci:v00001425d000050AD* + ID_MODEL_FROM_DATABASE=T520-50AD Unified Wire Ethernet Controller + ++pci:v00001425d000050AE* ++ ID_MODEL_FROM_DATABASE=T540-50AE Unified Wire Ethernet Controller ++ ++pci:v00001425d000050AF* ++ ID_MODEL_FROM_DATABASE=T580-50AF Unified Wire Ethernet Controller ++ ++pci:v00001425d000050B0* ++ ID_MODEL_FROM_DATABASE=T520-50B0 Unified Wire Ethernet Controller ++ + pci:v00001425d00005401* + ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller + +@@ -49628,6 +54074,15 @@ pci:v00001425d000054AC* + pci:v00001425d000054AD* + ID_MODEL_FROM_DATABASE=T520-50AD Unified Wire Ethernet Controller + ++pci:v00001425d000054AE* ++ ID_MODEL_FROM_DATABASE=T540-50AE Unified Wire Ethernet Controller ++ ++pci:v00001425d000054AF* ++ ID_MODEL_FROM_DATABASE=T580-50AF Unified Wire Ethernet Controller ++ ++pci:v00001425d000054B0* ++ ID_MODEL_FROM_DATABASE=T520-50B0 Unified Wire Ethernet Controller ++ + pci:v00001425d00005501* + ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller + +@@ -49829,6 +54284,15 @@ pci:v00001425d000055AC* + pci:v00001425d000055AD* + ID_MODEL_FROM_DATABASE=T520-50AD Unified Wire Storage Controller + ++pci:v00001425d000055AE* ++ ID_MODEL_FROM_DATABASE=T540-50AE Unified Wire Storage Controller ++ ++pci:v00001425d000055AF* ++ ID_MODEL_FROM_DATABASE=T580-50AF Unified Wire Storage Controller ++ ++pci:v00001425d000055B0* ++ ID_MODEL_FROM_DATABASE=T520-50B0 Unified Wire Storage Controller ++ + pci:v00001425d00005601* + ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller + +@@ -50030,6 +54494,15 @@ pci:v00001425d000056AC* + pci:v00001425d000056AD* + ID_MODEL_FROM_DATABASE=T520-50AD Unified Wire Storage Controller + ++pci:v00001425d000056AE* ++ ID_MODEL_FROM_DATABASE=T540-50AE Unified Wire Storage Controller ++ ++pci:v00001425d000056AF* ++ ID_MODEL_FROM_DATABASE=T580-50AF Unified Wire Storage Controller ++ ++pci:v00001425d000056B0* ++ ID_MODEL_FROM_DATABASE=T520-50B0 Unified Wire Storage Controller ++ + pci:v00001425d00005701* + ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller + +@@ -50348,6 +54821,15 @@ pci:v00001425d000058AC* + pci:v00001425d000058AD* + ID_MODEL_FROM_DATABASE=T520-50AD Unified Wire Ethernet Controller [VF] + ++pci:v00001425d000058AE* ++ ID_MODEL_FROM_DATABASE=T540-50AE Unified Wire Ethernet Controller [VF] ++ ++pci:v00001425d000058AF* ++ ID_MODEL_FROM_DATABASE=T580-50AF Unified Wire Ethernet Controller [VF] ++ ++pci:v00001425d000058B0* ++ ID_MODEL_FROM_DATABASE=T520-50B0 Unified Wire Ethernet Controller [VF] ++ + pci:v00001425d00006001* + ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller + +@@ -50417,6 +54899,9 @@ pci:v00001425d00006088* + pci:v00001425d00006089* + ID_MODEL_FROM_DATABASE=T62100-6089 Unified Wire Ethernet Controller + ++pci:v00001425d0000608A* ++ ID_MODEL_FROM_DATABASE=T62100-608a Unified Wire Ethernet Controller ++ + pci:v00001425d00006401* + ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller + +@@ -50486,6 +54971,9 @@ pci:v00001425d00006488* + pci:v00001425d00006489* + ID_MODEL_FROM_DATABASE=T62100-6089 Unified Wire Ethernet Controller + ++pci:v00001425d0000648A* ++ ID_MODEL_FROM_DATABASE=T62100-608a Unified Wire Ethernet Controller ++ + pci:v00001425d00006501* + ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller + +@@ -50555,6 +55043,9 @@ pci:v00001425d00006588* + pci:v00001425d00006589* + ID_MODEL_FROM_DATABASE=T62100-6089 Unified Wire Storage Controller + ++pci:v00001425d0000658A* ++ ID_MODEL_FROM_DATABASE=T62100-608a Unified Wire Storage Controller ++ + pci:v00001425d00006601* + ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller + +@@ -50624,6 +55115,9 @@ pci:v00001425d00006688* + pci:v00001425d00006689* + ID_MODEL_FROM_DATABASE=T62100-6089 Unified Wire Storage Controller + ++pci:v00001425d0000668A* ++ ID_MODEL_FROM_DATABASE=T62100-608a Unified Wire Storage Controller ++ + pci:v00001425d00006801* + ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF] + +@@ -50693,6 +55187,9 @@ pci:v00001425d00006888* + pci:v00001425d00006889* + ID_MODEL_FROM_DATABASE=T62100-6089 Unified Wire Ethernet Controller [VF] + ++pci:v00001425d0000688A* ++ ID_MODEL_FROM_DATABASE=T62100-608a Unified Wire Ethernet Controller [VF] ++ + pci:v00001425d0000A000* + ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller + +@@ -50894,17 +55391,56 @@ pci:v0000144D* + pci:v0000144Dd00001600* + ID_MODEL_FROM_DATABASE=Apple PCIe SSD + ++pci:v0000144Dd0000A544* ++ ID_MODEL_FROM_DATABASE=Exynos 8890 PCIe Root Complex ++ + pci:v0000144Dd0000A800* + ID_MODEL_FROM_DATABASE=XP941 PCIe SSD + + pci:v0000144Dd0000A802* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM951/PM951 + ++pci:v0000144Dd0000A802sv0000144Dsd0000A801* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM951/PM951 (PM963 2.5" NVMe PCIe SSD) ++ + pci:v0000144Dd0000A804* +- ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM961/PM961 ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM961/PM961/SM963 ++ ++pci:v0000144Dd0000A804sv0000144Dsd0000A801* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM961/PM961/SM963 (SM963 2.5" NVMe PCIe SSD) + + pci:v0000144Dd0000A808* +- ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM981/PM981 ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM981/PM981/PM983 ++ ++pci:v0000144Dd0000A808sv00001D49sd0000403B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM981/PM981/PM983 (Thinksystem U.2 PM983 NVMe SSD) ++ ++pci:v0000144Dd0000A80A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO ++ ++pci:v0000144Dd0000A80Asv00000128sd0000215A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI U.2 960GB) ++ ++pci:v0000144Dd0000A80Asv00000128sd0000215B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI U.2 1.92TB) ++ ++pci:v0000144Dd0000A80Asv00000128sd0000215C* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI U.2 3.84TB) ++ ++pci:v0000144Dd0000A80Asv00000128sd0000215D* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI U.2 7.68TB) ++ ++pci:v0000144Dd0000A80Asv00000128sd00002166* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI 110M.2 960GB) ++ ++pci:v0000144Dd0000A80Asv00000128sd00002167* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI 110M.2 1.92TB) ++ ++pci:v0000144Dd0000A80Asv00000128sd00002168* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI 80M.2 480GB) ++ ++pci:v0000144Dd0000A80Asv00000128sd00002169* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM9A1/PM9A3/980PRO (DC NVMe PM9A3 RI 80M.2 960GB) + + pci:v0000144Dd0000A820* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X +@@ -50966,6 +55502,15 @@ pci:v0000144Dd0000A822sv00001014sd00000622* + pci:v0000144Dd0000A822sv00001014sd00000629* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (PCIe3 6.4TB NVMe Flash Adapter II x8) + ++pci:v0000144Dd0000A822sv00001014sd0000064A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (PCIe3 1.6TB NVMe Flash Adapter III x8) ++ ++pci:v0000144Dd0000A822sv00001014sd0000064B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (PCIe3 3.2TB NVMe Flash Adapter III x8) ++ ++pci:v0000144Dd0000A822sv00001014sd0000064C* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (PCIe3 6.4TB NVMe Flash Adapter III x8) ++ + pci:v0000144Dd0000A822sv00001028sd00001FD9* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (Express Flash PM1725a 800GB SFF) + +@@ -51011,6 +55556,138 @@ pci:v0000144Dd0000A822sv00001028sd00001FF9* + pci:v0000144Dd0000A822sv00001028sd00001FFA* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa/172Xb (Express Flash PM1725b 12.8TB AIC) + ++pci:v0000144Dd0000A824* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X ++ ++pci:v0000144Dd0000A824sv00001028sd00002040* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU U.2 Gen4 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002041* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU U.2 Gen4 3.2TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002042* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU U.2 Gen4 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002043* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU U.2 Gen4 12.8TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002044* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU AIC Gen4 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002045* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU AIC Gen4 3.2TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002046* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN MU AIC Gen4 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002070* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI U.2 Gen4 1.92TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002071* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI U.2 Gen4 3.84TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002072* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI U.2 Gen4 7.68TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002073* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI U.2 Gen4 15.36TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002074* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI AIC Gen4 1.92TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002075* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI AIC Gen4 3.84TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002076* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN RI AIC Gen4 7.68TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002090* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU U.2 Gen4 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002091* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU U.2 Gen4 3.2TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002092* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU U.2 Gen4 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002093* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU U.2 Gen4 12.8TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002094* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU AIC Gen4 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002095* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU AIC Gen4 3.2TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002096* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED MU AIC Gen4 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002097* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED RI U.2 Gen4 1.92TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002098* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED RI U.2 Gen4 3.84TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002099* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (EMC PowerEdge Express Flash Ent NVMe AGN SED RI U.2 Gen4 7.68TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002118* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS MU U.2 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002119* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN MU U.2 1.6TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002120* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS MU U.2 3.2T) ++ ++pci:v0000144Dd0000A824sv00001028sd00002121* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN MU U.2 3.2TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002122* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS MU U.2 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002123* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN MU U.2 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002124* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS MU U.2 6.4TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002125* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN MU U.2 12.8TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002126* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS RI U.2 1.92TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002127* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN RI U.2 1.92TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002128* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS RI U.2 3.84TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002129* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN RI U.2 3.84TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002130* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS RI U.2 7.68TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002131* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN RI U.2 7.68TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002132* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN FIPS RI U.2 15.36TB) ++ ++pci:v0000144Dd0000A824sv00001028sd00002133* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173X (Ent NVMe v2 AGN RI U.2 15.36TB) ++ ++pci:v0000144Dd0000A825* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM173Xa ++ ++pci:v0000144Dd0000A826* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller PM174X ++ ++pci:v0000144Dd0000ECEC* ++ ID_MODEL_FROM_DATABASE=Exynos 8895 PCIe Root Complex ++ + pci:v0000144E* + ID_VENDOR_FROM_DATABASE=OLITEC + +@@ -51041,6 +55718,9 @@ pci:v00001457* + pci:v00001458* + ID_VENDOR_FROM_DATABASE=Gigabyte Technology Co., Ltd + ++pci:v00001458d00003483* ++ ID_MODEL_FROM_DATABASE=USB 3.0 Controller (VIA VL80x-based xHCI Controller) ++ + pci:v00001459* + ID_VENDOR_FROM_DATABASE=DOOIN Electronics + +@@ -51089,6 +55769,12 @@ pci:v00001461d0000F436* + pci:v00001462* + ID_VENDOR_FROM_DATABASE=Micro-Star International Co., Ltd. [MSI] + ++pci:v00001462d00003483* ++ ID_MODEL_FROM_DATABASE=MSI USB 3.0 (VIA VL80x-based xHCI USB Controller) ++ ++pci:v00001462d00007C56* ++ ID_MODEL_FROM_DATABASE=Realtek Ethernet controller RTL8111H ++ + pci:v00001462d0000AAF0* + ID_MODEL_FROM_DATABASE=Radeon RX 580 Gaming X 8G + +@@ -51230,6 +55916,9 @@ pci:v0000148B* + pci:v0000148C* + ID_VENDOR_FROM_DATABASE=Tul Corporation / PowerColor + ++pci:v0000148Cd00002391* ++ ID_MODEL_FROM_DATABASE=Radeon RX 590 [Red Devil] ++ + pci:v0000148D* + ID_VENDOR_FROM_DATABASE=DIGICOM Systems, Inc. + +@@ -51363,7 +56052,7 @@ pci:v000014AA* + ID_VENDOR_FROM_DATABASE=Advanced MOS Technology Inc + + pci:v000014AB* +- ID_VENDOR_FROM_DATABASE=Mentor Graphics Corp. ++ ID_VENDOR_FROM_DATABASE=Siemens Industry Software Inc. + + pci:v000014AC* + ID_VENDOR_FROM_DATABASE=Novaweb Technologies Inc +@@ -51524,12 +56213,18 @@ pci:v000014C2* + pci:v000014C3* + ID_VENDOR_FROM_DATABASE=MEDIATEK Corp. + ++pci:v000014C3d00007612* ++ ID_MODEL_FROM_DATABASE=MT7612E 802.11acbgn PCI Express Wireless Network Adapter ++ + pci:v000014C3d00007630* + ID_MODEL_FROM_DATABASE=MT7630e 802.11bgn Wireless Network Adapter + + pci:v000014C3d00007662* + ID_MODEL_FROM_DATABASE=MT7662E 802.11ac PCI Express Wireless Network Adapter + ++pci:v000014C3d00007915* ++ ID_MODEL_FROM_DATABASE=MT7915E 802.11ax PCI Express Wireless Network Adapter ++ + pci:v000014C4* + ID_VENDOR_FROM_DATABASE=IWASAKI Information Systems Co Ltd + +@@ -51656,6 +56351,15 @@ pci:v000014D2d0000E020* + pci:v000014D3* + ID_VENDOR_FROM_DATABASE=CIRTECH (UK) Ltd + ++pci:v000014D3d00000002* ++ ID_MODEL_FROM_DATABASE=DTL-T14000 Rev. 1 [PS2 TOOL CD/DVD Emulator] ++ ++pci:v000014D3d00000003* ++ ID_MODEL_FROM_DATABASE=DTL-T14000 Rev. 2 [PS2 TOOL CD/DVD Emulator] ++ ++pci:v000014D3d00000004* ++ ID_MODEL_FROM_DATABASE=DTL-T14000 Rev. 3 [PS2 TOOL CD/DVD Emulator] ++ + pci:v000014D4* + ID_VENDOR_FROM_DATABASE=Panacom Technology Corp + +@@ -51756,7 +56460,7 @@ pci:v000014E3* + ID_VENDOR_FROM_DATABASE=AMTELCO + + pci:v000014E4* +- ID_VENDOR_FROM_DATABASE=Broadcom Limited ++ ID_VENDOR_FROM_DATABASE=Broadcom Inc. and subsidiaries + + pci:v000014E4d00000576* + ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n +@@ -52322,6 +57026,36 @@ pci:v000014E4d0000165Esv000010CFsd00001279* + pci:v000014E4d0000165F* + ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe + ++pci:v000014E4d0000165Fsv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge R320 server) ++ ++pci:v000014E4d0000165Fsv00001028sd000008FD* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge R6515/R7515 LOM) ++ ++pci:v000014E4d0000165Fsv00001028sd000008FF* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge Rx5xx LOM Board) ++ ++pci:v000014E4d0000165Fsv00001028sd00000900* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge C6525 LOM) ++ ++pci:v000014E4d0000165Fsv00001028sd00000917* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (PowerEdge C6520 LOM) ++ ++pci:v000014E4d0000165Fsv0000103Csd00001786* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332T Adapter) ++ ++pci:v000014E4d0000165Fsv0000103Csd0000193D* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter) ++ ++pci:v000014E4d0000165Fsv0000103Csd00002133* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter) ++ ++pci:v000014E4d0000165Fsv0000103Csd000022E8* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter) ++ ++pci:v000014E4d0000165Fsv0000103Csd000022EB* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe (NC332i Adapter) ++ + pci:v000014E4d00001662* + ID_MODEL_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet + +@@ -52382,6 +57116,9 @@ pci:v000014E4d00001677sv00001028sd00000182* + pci:v000014E4d00001677sv00001028sd00000187* + ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Precision M70) + ++pci:v000014E4d00001677sv00001028sd000001A3* ++ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Latitude X1) ++ + pci:v000014E4d00001677sv00001028sd000001A8* + ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Precision 380) + +@@ -52556,6 +57293,9 @@ pci:v000014E4d0000168Esv0000193Dsd00001003* + pci:v000014E4d0000168Esv0000193Dsd00001006* + ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (530F-L) + ++pci:v000014E4d0000168Esv0000193Dsd0000100F* ++ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (NIC-ETH522i-Mb-2x10G) ++ + pci:v000014E4d00001690* + ID_MODEL_FROM_DATABASE=NetXtreme BCM57760 Gigabit Ethernet PCIe + +@@ -52634,6 +57374,9 @@ pci:v000014E4d000016A1* + pci:v000014E4d000016A1sv00001043sd0000866E* + ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet (PEB-10G/57840-2T 10GBase-T Network Adapter) + ++pci:v000014E4d000016A1sv0000193Dsd0000100B* ++ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet (NIC-ETH521i-Mb-4x10G) ++ + pci:v000014E4d000016A2* + ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet + +@@ -52985,30 +57728,60 @@ pci:v000014E4d000016D5* + pci:v000014E4d000016D6* + ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller + ++pci:v000014E4d000016D6sv000014E4sd00001202* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (BCM957412M4122C OCP 1x25G Type1 wRoCE) ++ ++pci:v000014E4d000016D6sv000014E4sd00004120* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (NetXtreme E-Series Advanced Dual-port 10Gb SFP+ Ethernet Network Daughter Card) ++ ++pci:v000014E4d000016D6sv000014E4sd00004126* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (NetXtreme-E Dual-port 10G SFP+ Ethernet OCP 3.0 Adapter (BCM957412N4120C)) ++ ++pci:v000014E4d000016D6sv0000152Dsd00008B20* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller ++ ++pci:v000014E4d000016D6sv0000152Dsd00008B22* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller (BCM57412 NetXtreme-E 25Gb RDMA Ethernet Controller) ++ + pci:v000014E4d000016D7* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller + +-pci:v000014E4d000016D7sv000014E4sd00001202* +- ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957412M4122C OCP 1x25G Type1 wRoCE) +- + pci:v000014E4d000016D7sv000014E4sd00001402* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957414A4142CC 10Gb/25Gb Ethernet PCIe) + + pci:v000014E4d000016D7sv000014E4sd00001404* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957414M4142C OCP 2x25G Type1 wRoCE) + ++pci:v000014E4d000016D7sv000014E4sd00004140* ++ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (NetXtreme E-Series Advanced Dual-port 25Gb SFP28 Network Daughter Card) ++ ++pci:v000014E4d000016D7sv000014E4sd00004143* ++ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (NetXtreme-E Single-port 40Gb/50Gb Ethernet OCP 2.0 Adapter (BCM957414M4143C)) ++ ++pci:v000014E4d000016D7sv000014E4sd00004146* ++ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (NetXtreme-E Dual-port 25G SFP28 Ethernet OCP 3.0 Adapter (BCM957414N4140C)) ++ + pci:v000014E4d000016D7sv00001590sd0000020E* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (Ethernet 25Gb 2-port 631SFP28 Adapter) + + pci:v000014E4d000016D7sv00001590sd00000211* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (Ethernet 25Gb 2-port 631FLR-SFP28 Adapter) + ++pci:v000014E4d000016D7sv00001EECsd00000101* ++ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (VSE250231S Dual-port 10Gb/25Gb Ethernet PCIe) ++ + pci:v000014E4d000016D8* + ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller + + pci:v000014E4d000016D8sv00001028sd00001FEB* + ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (NetXtreme-E 10Gb SFP+ Adapter) + ++pci:v000014E4d000016D8sv000014E4sd00004163* ++ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (NetXtreme-E Dual-port 10GBASE-T Ethernet OCP 2.0 Adapter (BCM957416M4163C)) ++ ++pci:v000014E4d000016D8sv000014E4sd00004166* ++ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (NetXtreme-E Dual-port 10GBASE-T Ethernet OCP 3.0 Adapter (BCM957416N4160C)) ++ + pci:v000014E4d000016D8sv00001590sd0000020C* + ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller (Ethernet 10Gb 2-port 535T Adapter) + +@@ -53057,6 +57830,9 @@ pci:v000014E4d000016E8* + pci:v000014E4d000016E9* + ID_MODEL_FROM_DATABASE=BCM57407 NetXtreme-E 25Gb Ethernet Controller + ++pci:v000014E4d000016EB* ++ ID_MODEL_FROM_DATABASE=BCM57412 NetXtreme-E RDMA Partition ++ + pci:v000014E4d000016EC* + ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E Ethernet Partition + +@@ -53150,6 +57926,90 @@ pci:v000014E4d00001713sv0000103Csd000030C0* + pci:v000014E4d00001713sv000017AAsd00003A23* + ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express (IdeaPad S10e) + ++pci:v000014E4d00001750* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet ++ ++pci:v000014E4d00001750sv000014E4sd00002100* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E Dual-port 100G QSFP56 Ethernet PCIe4.0 x16 Adapter (BCM957508-P2100G)) ++ ++pci:v000014E4d00001750sv000014E4sd00005208* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E Dual-port 100G QSFP56 Ethernet OCP 3.0 Adapter (BCM957508-N2100G)) ++ ++pci:v000014E4d00001750sv000014E4sd0000D124* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E P2100D BCM57508 2x100G QSFP PCIE) ++ ++pci:v000014E4d00001750sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz Ethernet) ++ ++pci:v000014E4d00001751* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet ++ ++pci:v000014E4d00001751sv00001028sd000009D4* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (PowerEdge XR11/XR12 LOM) ++ ++pci:v000014E4d00001751sv000014E4sd00005045* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E BCM57504 4x25G OCP3.0) ++ ++pci:v000014E4d00001751sv000014E4sd00005250* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E BCM57504 4x25G KR Mezz) ++ ++pci:v000014E4d00001751sv000014E4sd0000D142* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (NetXtreme-E P425D BCM57504 4x25G SFP28 PCIE) ++ ++pci:v000014E4d00001752* ++ ID_MODEL_FROM_DATABASE=BCM57502 NetXtreme-E 10Gb/25Gb/40Gb/50Gb Ethernet ++ ++pci:v000014E4d00001800* ++ ID_MODEL_FROM_DATABASE=BCM57502 NetXtreme-E Ethernet Partition ++ ++pci:v000014E4d00001801* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E Ethernet Partition ++ ++pci:v000014E4d00001802* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E Ethernet Partition ++ ++pci:v000014E4d00001802sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E Ethernet Partition (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz Ethernet Partition) ++ ++pci:v000014E4d00001803* ++ ID_MODEL_FROM_DATABASE=BCM57502 NetXtreme-E RDMA Partition ++ ++pci:v000014E4d00001804* ++ ID_MODEL_FROM_DATABASE=BCM57504 NetXtreme-E RDMA Partition ++ ++pci:v000014E4d00001805* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E RDMA Partition ++ ++pci:v000014E4d00001805sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM57508 NetXtreme-E RDMA Partition (NetXtreme-E NGM2100D BCM57508 2x100G KR Mezz RDMA Partition) ++ ++pci:v000014E4d00001806* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E Ethernet Virtual Function ++ ++pci:v000014E4d00001806sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E Ethernet Virtual Function (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz Ethernet Virtual Function) ++ ++pci:v000014E4d00001807* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E RDMA Virtual Function ++ ++pci:v000014E4d00001807sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E RDMA Virtual Function (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz RDMA Virtual Function) ++ ++pci:v000014E4d00001808* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E Ethernet Virtual Function ++ ++pci:v000014E4d00001808sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E Ethernet Virtual Function (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz Ethernet Virtual Function) ++ ++pci:v000014E4d00001809* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E RDMA Virtual Function ++ ++pci:v000014E4d00001809sv000014E4sd0000DF24* ++ ID_MODEL_FROM_DATABASE=BCM5750X NetXtreme-E RDMA Virtual Function (BCM57508 NetXtreme-E NGM2100D 2x100G KR Mezz RDMA Virtual Function) ++ ++pci:v000014E4d00002711* ++ ID_MODEL_FROM_DATABASE=BCM2711 PCIe Bridge ++ + pci:v000014E4d00003352* + ID_MODEL_FROM_DATABASE=BCM3352 + +@@ -53675,6 +58535,9 @@ pci:v000014E4d000043A2* + pci:v000014E4d000043A3* + ID_MODEL_FROM_DATABASE=BCM4350 802.11ac Wireless Network Adapter + ++pci:v000014E4d000043A3sv000017AAsd0000075A* ++ ID_MODEL_FROM_DATABASE=BCM4350 802.11ac Wireless Network Adapter (00JT494) ++ + pci:v000014E4d000043A9* + ID_MODEL_FROM_DATABASE=BCM43217 802.11b/g/n + +@@ -53702,6 +58565,9 @@ pci:v000014E4d000043D3* + pci:v000014E4d000043D9* + ID_MODEL_FROM_DATABASE=BCM43570 802.11ac Wireless Network Adapter + ++pci:v000014E4d000043DC* ++ ID_MODEL_FROM_DATABASE=BCM4355 802.11ac Wireless LAN SoC ++ + pci:v000014E4d000043DF* + ID_MODEL_FROM_DATABASE=BCM4354 802.11ac Wireless LAN SoC + +@@ -53744,12 +58610,30 @@ pci:v000014E4d00004411* + pci:v000014E4d00004412* + ID_MODEL_FROM_DATABASE=BCM4412 10/100BaseT + ++pci:v000014E4d00004415* ++ ID_MODEL_FROM_DATABASE=BCM4359 802.11ac Dual-Band Wireless Network Controller ++ ++pci:v000014E4d0000441F* ++ ID_MODEL_FROM_DATABASE=BCM4361 802.11ac Dual-Band Wireless Network Controller ++ ++pci:v000014E4d00004420* ++ ID_MODEL_FROM_DATABASE=BCM4361 802.11ac 2.4 GHz Wireless Network Controller ++ ++pci:v000014E4d00004421* ++ ID_MODEL_FROM_DATABASE=BCM4361 802.11ac 5 GHz Wireless Network Controller ++ + pci:v000014E4d00004430* + ID_MODEL_FROM_DATABASE=BCM44xx CardBus iLine32 HomePNA 2.0 + + pci:v000014E4d00004432* + ID_MODEL_FROM_DATABASE=BCM4432 CardBus 10/100BaseT + ++pci:v000014E4d00004464* ++ ID_MODEL_FROM_DATABASE=BCM4364 802.11ac Wireless Network Adapter ++ ++pci:v000014E4d00004488* ++ ID_MODEL_FROM_DATABASE=BCM4377b Wireless Network Adapter ++ + pci:v000014E4d00004610* + ID_MODEL_FROM_DATABASE=BCM4610 Sentry5 PCI to SB Bridge + +@@ -53885,9 +58769,21 @@ pci:v000014E4d00005841* + pci:v000014E4d00005850* + ID_MODEL_FROM_DATABASE=BCM5850 Crypto Accelerator + ++pci:v000014E4d00005E87* ++ ID_MODEL_FROM_DATABASE=Valkyrie offload engine ++ ++pci:v000014E4d00005E88* ++ ID_MODEL_FROM_DATABASE=Viper Offload Engine ++ + pci:v000014E4d00008602* + ID_MODEL_FROM_DATABASE=BCM7400/BCM7405 Serial ATA Controller + ++pci:v000014E4d00009026* ++ ID_MODEL_FROM_DATABASE=CN99xx [ThunderX2] Integrated USB 3.0 xHCI Host Controller ++ ++pci:v000014E4d00009027* ++ ID_MODEL_FROM_DATABASE=CN99xx [ThunderX2] Integrated AHCI/SATA 3 Host Controller ++ + pci:v000014E4d0000A8D8* + ID_MODEL_FROM_DATABASE=BCM43224/5 Wireless Network Adapter + +@@ -53921,6 +58817,15 @@ pci:v000014E4d0000B377* + pci:v000014E4d0000B379* + ID_MODEL_FROM_DATABASE=Broadcom BCM56379 Switch ASIC + ++pci:v000014E4d0000B470* ++ ID_MODEL_FROM_DATABASE=BCM56470 SWITCH ASIC ++ ++pci:v000014E4d0000B471* ++ ID_MODEL_FROM_DATABASE=BCM56471 SWITCH ASIC ++ ++pci:v000014E4d0000B472* ++ ID_MODEL_FROM_DATABASE=BCM56472 SWITCH ASIC ++ + pci:v000014E4d0000B800* + ID_MODEL_FROM_DATABASE=BCM56800 StrataXGS 10GE Switch Controller + +@@ -53930,9 +58835,36 @@ pci:v000014E4d0000B842* + pci:v000014E4d0000B850* + ID_MODEL_FROM_DATABASE=Broadcom BCM56850 Switch ASIC + ++pci:v000014E4d0000B880* ++ ID_MODEL_FROM_DATABASE=BCM56880 Switch ASIC ++ + pci:v000014E4d0000B960* + ID_MODEL_FROM_DATABASE=Broadcom BCM56960 Switch ASIC + ++pci:v000014E4d0000B990* ++ ID_MODEL_FROM_DATABASE=BCM56990 Switch ASIC ++ ++pci:v000014E4d0000D802* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC ++ ++pci:v000014E4d0000D802sv000014E4sd00008021* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC (Stingray Dual-Port 25Gb Ethernet PCIe SmartNIC w16GB DRAM (Part No BCM958802A8046C)) ++ ++pci:v000014E4d0000D802sv000014E4sd00008023* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC (PS410T-H04 NetXtreme-S 4x10G 10GBaseT PCIe SmartNIC) ++ ++pci:v000014E4d0000D802sv000014E4sd00008024* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC (Stingray Dual-Port 25Gb Ethernet PCIe SmartNIC w4GB DRAM (Part No BCM958802A8044C)) ++ ++pci:v000014E4d0000D802sv000014E4sd00008028* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC (Stingray Dual-Port 25Gb Ethernet PCIe SmartNIC w8GB DRAM (Part No BCM958802A8048C)) ++ ++pci:v000014E4d0000D802sv00001BB0sd00000021* ++ ID_MODEL_FROM_DATABASE=BCM58802 Stingray 50Gb Ethernet SoC (HPE SimpliVity Accelerator) ++ ++pci:v000014E4d0000D804* ++ ID_MODEL_FROM_DATABASE=BCM58804 Stingray 100Gb Ethernet SoC ++ + pci:v000014E5* + ID_VENDOR_FROM_DATABASE=Pixelfusion Ltd + +@@ -54473,6 +59405,9 @@ pci:v000014F1d00008800sv00000070sd00007801* + pci:v000014F1d00008800sv00000070sd00009001* + ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-T DVB-T) + ++pci:v000014F1d00008800sv00000070sd00009002* ++ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-T DVB-T Model 909) ++ + pci:v000014F1d00008800sv00000070sd00009200* + ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-SE2 DVB-S) + +@@ -54782,6 +59717,9 @@ pci:v000014F1d00008880sv00000070sd00006A18* + pci:v000014F1d00008880sv00000070sd0000C108* + ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (WinTV-HVR-4400-HD model 1278) + ++pci:v000014F1d00008880sv00001461sd00003100* ++ ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (CE310B SD PCIe Video Capture Card) ++ + pci:v000014F1d00008880sv00005654sd00002389* + ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (GoTView X5 DVD Hybrid PCI-E) + +@@ -55221,7 +60159,7 @@ pci:v00001528* + ID_VENDOR_FROM_DATABASE=ACKSYS + + pci:v00001529* +- ID_VENDOR_FROM_DATABASE=AMERICAN MICROSystems Inc ++ ID_VENDOR_FROM_DATABASE=ON Semiconductor + + pci:v0000152A* + ID_VENDOR_FROM_DATABASE=QUICKTURN DESIGN Systems +@@ -55325,6 +60263,9 @@ pci:v00001542d00009271* + pci:v00001542d00009272* + ID_MODEL_FROM_DATABASE=Pulse Width Modulator Card + ++pci:v00001542d00009273* ++ ID_MODEL_FROM_DATABASE=RCIM-IV Real-Time Clock & Interrupt Module (PCIe) ++ + pci:v00001542d00009277* + ID_MODEL_FROM_DATABASE=5 Volt Delta Sigma Converter Card + +@@ -55337,6 +60278,15 @@ pci:v00001542d00009287* + pci:v00001542d00009290* + ID_MODEL_FROM_DATABASE=FPGA Card + ++pci:v00001542d00009300* ++ ID_MODEL_FROM_DATABASE=Universal Exhaust Gas Oxygen Sensor Simulator ++ ++pci:v00001542d00009310* ++ ID_MODEL_FROM_DATABASE=Digital Programmable Resistor ++ ++pci:v00001542d00009350* ++ ID_MODEL_FROM_DATABASE=Analog Input Card ++ + pci:v00001543* + ID_VENDOR_FROM_DATABASE=SILICON Laboratories + +@@ -55412,9 +60362,27 @@ pci:v00001556d0000110F* + pci:v00001556d00001110* + ID_MODEL_FROM_DATABASE=XpressRich Reference Design + ++pci:v00001556d00001111* ++ ID_MODEL_FROM_DATABASE=XpressRich-AXI Ref Design ++ ++pci:v00001556d00001112* ++ ID_MODEL_FROM_DATABASE=QuickPCIe ++ + pci:v00001556d00001113* + ID_MODEL_FROM_DATABASE=XpressSwitch + ++pci:v00001556d00001114* ++ ID_MODEL_FROM_DATABASE=Inspector ++ ++pci:v00001556d00001115* ++ ID_MODEL_FROM_DATABASE=XpressLINK Ref Design ++ ++pci:v00001556d00001116* ++ ID_MODEL_FROM_DATABASE=XpressLINK-SOC Ref Design ++ ++pci:v00001556d0000BE00* ++ ID_MODEL_FROM_DATABASE=PCI Express Bridge ++ + pci:v00001557* + ID_VENDOR_FROM_DATABASE=MEDIASTAR Co Ltd + +@@ -55883,12 +60851,75 @@ pci:v000015B3d00000210* + pci:v000015B3d00000211* + ID_MODEL_FROM_DATABASE=MT416842 Family [BlueField SoC Flash Recovery] + ++pci:v000015B3d00000212* ++ ID_MODEL_FROM_DATABASE=MT2892 Family [ConnectX-6 Dx Flash Recovery] ++ ++pci:v000015B3d00000213* ++ ID_MODEL_FROM_DATABASE=MT2892 Family [ConnectX-6 Dx Secure Flash Recovery] ++ ++pci:v000015B3d00000214* ++ ID_MODEL_FROM_DATABASE=MT42822 Family [BlueField-2 SoC Flash Recovery] ++ ++pci:v000015B3d00000215* ++ ID_MODEL_FROM_DATABASE=MT42822 Family [BlueField-2 Secure Flash Recovery] ++ ++pci:v000015B3d00000216* ++ ID_MODEL_FROM_DATABASE=MT2894 Family [ConnectX-6 Lx Flash Recovery] ++ ++pci:v000015B3d00000217* ++ ID_MODEL_FROM_DATABASE=MT2894 Family [ConnectX-6 Lx Secure Flash Recovery] ++ ++pci:v000015B3d00000218* ++ ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7 Flash Recovery] ++ ++pci:v000015B3d00000219* ++ ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7 Secure Flash Recovery] ++ ++pci:v000015B3d0000021A* ++ ID_MODEL_FROM_DATABASE=MT43162 Family [BlueField-3 Lx SoC Flash Recovery] ++ ++pci:v000015B3d0000021B* ++ ID_MODEL_FROM_DATABASE=MT43162 Family [BlueField-3 Lx Secure Flash Recovery] ++ ++pci:v000015B3d0000021C* ++ ID_MODEL_FROM_DATABASE=MT43244 Family [BlueField-3 SoC Flash Recovery] ++ ++pci:v000015B3d0000021D* ++ ID_MODEL_FROM_DATABASE=MT43244 Family [BlueField-3 Secure Flash Recovery] ++ + pci:v000015B3d0000024E* + ID_MODEL_FROM_DATABASE=MT53100 [Spectrum-2, Flash recovery mode] + + pci:v000015B3d0000024F* + ID_MODEL_FROM_DATABASE=MT53100 [Spectrum-2, Secure Flash recovery mode] + ++pci:v000015B3d00000250* ++ ID_MODEL_FROM_DATABASE=Spectrum-3, Flash recovery mode ++ ++pci:v000015B3d00000251* ++ ID_MODEL_FROM_DATABASE=Spectrum-3, Secure Flash recovery mode ++ ++pci:v000015B3d00000252* ++ ID_MODEL_FROM_DATABASE=Amos chiplet ++ ++pci:v000015B3d00000253* ++ ID_MODEL_FROM_DATABASE=Amos GearBox Manager ++ ++pci:v000015B3d00000254* ++ ID_MODEL_FROM_DATABASE=Spectrum-4, Flash recovery mode ++ ++pci:v000015B3d00000255* ++ ID_MODEL_FROM_DATABASE=Spectrum-4 RMA ++ ++pci:v000015B3d00000256* ++ ID_MODEL_FROM_DATABASE=Abir GearBox ++ ++pci:v000015B3d00000257* ++ ID_MODEL_FROM_DATABASE=Quantum-2 in Flash Recovery Mode ++ ++pci:v000015B3d00000258* ++ ID_MODEL_FROM_DATABASE=Quantum-2 RMA ++ + pci:v000015B3d00000262* + ID_MODEL_FROM_DATABASE=MT27710 [ConnectX-4 Lx Programmable] EN + +@@ -55901,6 +60932,12 @@ pci:v000015B3d00000264* + pci:v000015B3d00000281* + ID_MODEL_FROM_DATABASE=NPS-600 Flash Recovery + ++pci:v000015B3d00000357* ++ ID_MODEL_FROM_DATABASE=Abir GearBox in Flash Recovery Mode ++ ++pci:v000015B3d00000358* ++ ID_MODEL_FROM_DATABASE=Abir GearBox in RMA ++ + pci:v000015B3d00001002* + ID_MODEL_FROM_DATABASE=MT25400 Family [ConnectX-2 Virtual Function] + +@@ -56057,6 +61094,9 @@ pci:v000015B3d00001013sv000015B3sd00000005* + pci:v000015B3d00001013sv000015B3sd00000006* + ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (MCX416A-BCAT, ConnectX-4 EN, 40/56GbE 2P, PCIe3.0 x16) + ++pci:v000015B3d00001013sv000015B3sd00000007* ++ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 EN network interface card, 40/56GbE dual-port QSFP28, PCIe3.0 x16, tall bracket) ++ + pci:v000015B3d00001013sv000015B3sd00000008* + ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 Stand-up dual-port 100GbE MCX416A-CCAT) + +@@ -56099,18 +61139,51 @@ pci:v000015B3d00001015sv000015B3sd00000025* + pci:v000015B3d00001015sv0000193Dsd0000100A* + ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (620F-B) + ++pci:v000015B3d00001015sv0000193Dsd00001023* ++ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH540F-LP-2P) ++ ++pci:v000015B3d00001015sv0000193Dsd00001031* ++ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH640i-Mb-2x25G) ++ ++pci:v000015B3d00001015sv0000193Dsd00001083* ++ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH640F-3S-2P) ++ ++pci:v000015B3d00001015sv0000193Dsd00001084* ++ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (NIC-ETH540F-3S-2P) ++ + pci:v000015B3d00001016* + ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx Virtual Function] + + pci:v000015B3d00001017* + ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] + ++pci:v000015B3d00001017sv000015B3sd00000006* ++ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] (ConnectX®-5 EN network interface card, 100GbE single-port QSFP28, PCIe3.0 x16, tall bracket; MCX515A-CCAT) ++ ++pci:v000015B3d00001017sv000015B3sd00000007* ++ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] (Mellanox ConnectX®-5 MCX516A-CCAT) ++ ++pci:v000015B3d00001017sv000015B3sd00000020* ++ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] (ConnectX®-5 EN network interface card, 10/25GbE dual-port SFP28, PCIe3.0 x8, tall bracket ; MCX512A-ACAT) ++ ++pci:v000015B3d00001017sv000015B3sd00000068* ++ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] (ConnectX®-5 EN network interface card for OCP2.0, Type 1, with host management, 25GbE dual-port SFP28, PCIe3.0 x8, no bracket Halogen free ; MCX542B-ACAN) ++ ++pci:v000015B3d00001017sv0000193Dsd00001051* ++ ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5] (NIC-IB1040i-Mb-2P) ++ + pci:v000015B3d00001018* + ID_MODEL_FROM_DATABASE=MT27800 Family [ConnectX-5 Virtual Function] + + pci:v000015B3d00001019* + ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Ex] + ++pci:v000015B3d00001019sv000015B3sd00000008* ++ ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Ex] (ConnectX-5 Ex EN network interface card, 100GbE dual-port QSFP28, PCIe4.0 x16, tall bracket; MCX516A-CDAT) ++ ++pci:v000015B3d00001019sv000015B3sd00000125* ++ ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Ex] (Tencent ConnectX-5 EN Ex network interface card for OCP 3.0, with host management, 50GbE Dual-port QSFP28, PCIe4.0 x16, Thumbscrew (pull-tab) bracket) ++ + pci:v000015B3d0000101A* + ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Ex Virtual Function] + +@@ -56121,19 +61194,19 @@ pci:v000015B3d0000101C* + ID_MODEL_FROM_DATABASE=MT28908 Family [ConnectX-6 Virtual Function] + + pci:v000015B3d0000101D* +- ID_MODEL_FROM_DATABASE=MT28841 ++ ID_MODEL_FROM_DATABASE=MT2892 Family [ConnectX-6 Dx] + + pci:v000015B3d0000101E* +- ID_MODEL_FROM_DATABASE=MT28850 ++ ID_MODEL_FROM_DATABASE=ConnectX Family mlx5Gen Virtual Function + + pci:v000015B3d0000101F* +- ID_MODEL_FROM_DATABASE=MT28851 ++ ID_MODEL_FROM_DATABASE=MT2894 Family [ConnectX-6 Lx] + + pci:v000015B3d00001020* + ID_MODEL_FROM_DATABASE=MT28860 + + pci:v000015B3d00001021* +- ID_MODEL_FROM_DATABASE=MT28861 ++ ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7] + + pci:v000015B3d00001974* + ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 PCIe Bridge] +@@ -56141,6 +61214,48 @@ pci:v000015B3d00001974* + pci:v000015B3d00001975* + ID_MODEL_FROM_DATABASE=MT416842 Family [BlueField SoC PCIe Bridge] + ++pci:v000015B3d00001976* ++ ID_MODEL_FROM_DATABASE=MT28908 Family [ConnectX-6 PCIe Bridge] ++ ++pci:v000015B3d00001977* ++ ID_MODEL_FROM_DATABASE=MT2892 Family [ConnectX-6 Dx PCIe Bridge] ++ ++pci:v000015B3d00001978* ++ ID_MODEL_FROM_DATABASE=MT42822 Family [BlueField-2 SoC PCIe Bridge] ++ ++pci:v000015B3d00001979* ++ ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7 PCIe Bridge] ++ ++pci:v000015B3d0000197A* ++ ID_MODEL_FROM_DATABASE=MT43162 Family [BlueField-3 Lx SoC PCIe Bridge] ++ ++pci:v000015B3d0000197B* ++ ID_MODEL_FROM_DATABASE=MT43244 Family [BlueField-3 SoC PCIe Bridge] ++ ++pci:v000015B3d00002020* ++ ID_MODEL_FROM_DATABASE=MT2892 Family [ConnectX-6 Dx Emulated PCIe Bridge] ++ ++pci:v000015B3d00002021* ++ ID_MODEL_FROM_DATABASE=MT42822 Family [BlueField-2 SoC Emulated PCIe Bridge] ++ ++pci:v000015B3d00002023* ++ ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7 Emulated PCIe Bridge] ++ ++pci:v000015B3d00002024* ++ ID_MODEL_FROM_DATABASE=MT43244 Family [BlueField-3 SoC Emulated PCIe Bridge] ++ ++pci:v000015B3d00004117* ++ ID_MODEL_FROM_DATABASE=MT27712A0-FDCF-AE ++ ++pci:v000015B3d00004117sv00001BD4sd00000039* ++ ID_MODEL_FROM_DATABASE=MT27712A0-FDCF-AE (SN10XMP2P25) ++ ++pci:v000015B3d00004117sv00001BD4sd0000003A* ++ ID_MODEL_FROM_DATABASE=MT27712A0-FDCF-AE (25G SFP28 SP EO251FM9 Adapter) ++ ++pci:v000015B3d00004117sv00001BD4sd0000004D* ++ ID_MODEL_FROM_DATABASE=MT27712A0-FDCF-AE (SN10XMP2P25,YZPC-01191-101) ++ + pci:v000015B3d00005274* + ID_MODEL_FROM_DATABASE=MT21108 InfiniBridge + +@@ -56159,6 +61274,9 @@ pci:v000015B3d00005E8C* + pci:v000015B3d00005E8D* + ID_MODEL_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA Flash Recovery] + ++pci:v000015B3d00006001* ++ ID_MODEL_FROM_DATABASE=NVMe SNAP Controller ++ + pci:v000015B3d00006274* + ID_MODEL_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA] + +@@ -56276,6 +61394,45 @@ pci:v000015B3d0000A2D2* + pci:v000015B3d0000A2D3* + ID_MODEL_FROM_DATABASE=MT416842 BlueField multicore SoC family VF + ++pci:v000015B3d0000A2D4* ++ ID_MODEL_FROM_DATABASE=MT42822 BlueField-2 SoC Crypto enabled ++ ++pci:v000015B3d0000A2D5* ++ ID_MODEL_FROM_DATABASE=MT42822 BlueField-2 SoC Crypto disabled ++ ++pci:v000015B3d0000A2D6* ++ ID_MODEL_FROM_DATABASE=MT42822 BlueField-2 integrated ConnectX-6 Dx network controller ++ ++pci:v000015B3d0000A2D7* ++ ID_MODEL_FROM_DATABASE=MT43162 BlueField-3 Lx SoC Crypto enabled ++ ++pci:v000015B3d0000A2D8* ++ ID_MODEL_FROM_DATABASE=MT43162 BlueField-3 Lx SoC Crypto disabled ++ ++pci:v000015B3d0000A2D9* ++ ID_MODEL_FROM_DATABASE=MT43162 BlueField-3 Lx integrated ConnectX-7 network controller ++ ++pci:v000015B3d0000A2DA* ++ ID_MODEL_FROM_DATABASE=MT43244 BlueField-3 SoC Crypto enabled ++ ++pci:v000015B3d0000A2DB* ++ ID_MODEL_FROM_DATABASE=MT43244 BlueField-3 SoC Crypto disabled ++ ++pci:v000015B3d0000A2DC* ++ ID_MODEL_FROM_DATABASE=MT43244 BlueField-3 integrated ConnectX-7 network controller ++ ++pci:v000015B3d0000C2D2* ++ ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC management interfac ++ ++pci:v000015B3d0000C2D3* ++ ID_MODEL_FROM_DATABASE=MT42822 BlueField-2 SoC Management Interface ++ ++pci:v000015B3d0000C2D4* ++ ID_MODEL_FROM_DATABASE=MT43162 BlueField-3 Lx SoC Management Interface ++ ++pci:v000015B3d0000C2D5* ++ ID_MODEL_FROM_DATABASE=MT43244 BlueField-3 SoC Management Interface ++ + pci:v000015B3d0000C738* + ID_MODEL_FROM_DATABASE=MT51136 + +@@ -56295,13 +61452,22 @@ pci:v000015B3d0000CB84* + ID_MODEL_FROM_DATABASE=MT52100 + + pci:v000015B3d0000CF08* +- ID_MODEL_FROM_DATABASE=MT53236 ++ ID_MODEL_FROM_DATABASE=Switch-IB2 + + pci:v000015B3d0000CF6C* + ID_MODEL_FROM_DATABASE=MT53100 [Spectrum-2] + ++pci:v000015B3d0000CF70* ++ ID_MODEL_FROM_DATABASE=Spectrum-3 ++ ++pci:v000015B3d0000CF80* ++ ID_MODEL_FROM_DATABASE=Spectrum-4 ++ + pci:v000015B3d0000D2F0* +- ID_MODEL_FROM_DATABASE=Switch-IB 3 HDR (200Gbps) switch ++ ID_MODEL_FROM_DATABASE=Quantum HDR (200Gbps) switch ++ ++pci:v000015B3d0000D2F2* ++ ID_MODEL_FROM_DATABASE=Quantum-2 NDR (400Gbps) switch + + pci:v000015B4* + ID_VENDOR_FROM_DATABASE=CCI/TRIAD +@@ -56369,6 +61535,39 @@ pci:v000015B7d00002001* + pci:v000015B7d00005001* + ID_MODEL_FROM_DATABASE=WD Black NVMe SSD + ++pci:v000015B7d00005002* ++ ID_MODEL_FROM_DATABASE=WD Black 2018/SN750 / PC SN720 NVMe SSD ++ ++pci:v000015B7d00005003* ++ ID_MODEL_FROM_DATABASE=WD Blue SN500 / PC SN520 NVMe SSD ++ ++pci:v000015B7d00005004* ++ ID_MODEL_FROM_DATABASE=PC SN520 NVMe SSD ++ ++pci:v000015B7d00005005* ++ ID_MODEL_FROM_DATABASE=PC SN520 NVMe SSD ++ ++pci:v000015B7d00005006* ++ ID_MODEL_FROM_DATABASE=WD Black SN750 / PC SN730 NVMe SSD ++ ++pci:v000015B7d00005009* ++ ID_MODEL_FROM_DATABASE=WD Blue SN550 NVMe SSD ++ ++pci:v000015B7d00005009sv000015B7sd00005009* ++ ID_MODEL_FROM_DATABASE=WD Blue SN550 NVMe SSD ++ ++pci:v000015B7d0000500B* ++ ID_MODEL_FROM_DATABASE=PC SN530 NVMe SSD ++ ++pci:v000015B7d0000500Bsv00001414sd0000500B* ++ ID_MODEL_FROM_DATABASE=PC SN530 NVMe SSD (Xbox Series X) ++ ++pci:v000015B7d0000500D* ++ ID_MODEL_FROM_DATABASE=WD Ultrastar DC SN340 NVMe SSD ++ ++pci:v000015B7d00005011* ++ ID_MODEL_FROM_DATABASE=WD Black SN850 ++ + pci:v000015B8* + ID_VENDOR_FROM_DATABASE=ADDI-DATA GmbH + +@@ -57152,6 +62351,12 @@ pci:v0000165Cd000071A1* + pci:v0000165Cd000071B1* + ID_MODEL_FROM_DATABASE=Proc10A + ++pci:v0000165Cd000072B1* ++ ID_MODEL_FROM_DATABASE=HawkEye ++ ++pci:v0000165Cd000073B1* ++ ID_MODEL_FROM_DATABASE=Proc10s ++ + pci:v0000165D* + ID_VENDOR_FROM_DATABASE=Hsing Tech. Enterprise Co., Ltd. + +@@ -57239,12 +62444,39 @@ pci:v00001681* + pci:v00001682* + ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc. + ++pci:v00001682d00005701* ++ ID_MODEL_FROM_DATABASE=Radeon 5700 XT Thicc III Ultra ++ ++pci:v00001682d0000C580* ++ ID_MODEL_FROM_DATABASE=Radeon RX 580 ++ + pci:v00001688* + ID_VENDOR_FROM_DATABASE=CastleNet Technology Inc. + + pci:v00001688d00001170* + ID_MODEL_FROM_DATABASE=WLAN 802.11b card + ++pci:v0000168A* ++ ID_VENDOR_FROM_DATABASE=Utimaco IS GmbH ++ ++pci:v0000168Ad00002086* ++ ID_MODEL_FROM_DATABASE=CryptoServer Se-Series Hardware Security Module ++ ++pci:v0000168Ad0000C040* ++ ID_MODEL_FROM_DATABASE=CryptoServer CSe-Series Hardware Security Module ++ ++pci:v0000168Ad0000C051* ++ ID_MODEL_FROM_DATABASE=CryptoServer Se-Series Gen2 Hardware Security Module ++ ++pci:v0000168Ad0000C070* ++ ID_MODEL_FROM_DATABASE=u.trust Anchor Hardware Security Module cs7.2 Series ++ ++pci:v0000168Ad0000C071* ++ ID_MODEL_FROM_DATABASE=u.trust Anchor Hardware Security Module cs7.3 Series ++ ++pci:v0000168Ad0000C072* ++ ID_MODEL_FROM_DATABASE=u.trust Anchor Hardware Security Module cs7.3 Series Virtual Function ++ + pci:v0000168C* + ID_VENDOR_FROM_DATABASE=Qualcomm Atheros + +@@ -57791,6 +63023,9 @@ pci:v0000168Cd0000002Asv00001A32sd00000306* + pci:v0000168Cd0000002Asv00001A3Bsd00001067* + ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281]) + ++pci:v0000168Cd0000002Asv00001A3Bsd00001071* ++ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AW-NE772 802.11abgn Wireless Mini PCIe Card [AR9280]) ++ + pci:v0000168Cd0000002Asv00001A3Bsd00001081* + ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280]) + +@@ -57908,6 +63143,9 @@ pci:v0000168Cd00000034sv00001A56sd00002003* + pci:v0000168Cd00000036* + ID_MODEL_FROM_DATABASE=QCA9565 / AR9565 Wireless Network Adapter + ++pci:v0000168Cd00000036sv00001028sd0000020E* ++ ID_MODEL_FROM_DATABASE=QCA9565 / AR9565 Wireless Network Adapter (Vostro 3470) ++ + pci:v0000168Cd00000037* + ID_MODEL_FROM_DATABASE=AR9485 Wireless Network Adapter + +@@ -57920,6 +63158,9 @@ pci:v0000168Cd0000003C* + pci:v0000168Cd0000003E* + ID_MODEL_FROM_DATABASE=QCA6174 802.11ac Wireless Network Adapter + ++pci:v0000168Cd0000003Esv00001A56sd0000143A* ++ ID_MODEL_FROM_DATABASE=QCA6174 802.11ac Wireless Network Adapter (Killer 1435 Wireless-AC) ++ + pci:v0000168Cd0000003Esv00001A56sd00001525* + ID_MODEL_FROM_DATABASE=QCA6174 802.11ac Wireless Network Adapter (Killer N1525 Wireless-AC) + +@@ -57932,6 +63173,12 @@ pci:v0000168Cd00000041* + pci:v0000168Cd00000042* + ID_MODEL_FROM_DATABASE=QCA9377 802.11ac Wireless Network Adapter + ++pci:v0000168Cd00000042sv000011ADsd000008A6* ++ ID_MODEL_FROM_DATABASE=QCA9377 802.11ac Wireless Network Adapter (Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter) ++ ++pci:v0000168Cd00000042sv000017AAsd00000901* ++ ID_MODEL_FROM_DATABASE=QCA9377 802.11ac Wireless Network Adapter (Qualcomm Atheros QCA9377 Wireless Network Adapter) ++ + pci:v0000168Cd00000046* + ID_MODEL_FROM_DATABASE=QCA9984 802.11ac Wave 2 Wireless Network Adapter + +@@ -58028,6 +63275,15 @@ pci:v000016BE* + pci:v000016C3* + ID_VENDOR_FROM_DATABASE=Synopsys, Inc. + ++pci:v000016C3d0000ABCD* ++ ID_MODEL_FROM_DATABASE=DWC_usb3 / PCIe bridge ++ ++pci:v000016C3d0000ABCE* ++ ID_MODEL_FROM_DATABASE=DWC_usb3 ++ ++pci:v000016C3d0000ABCF* ++ ID_MODEL_FROM_DATABASE=DWC_usb31 ++ + pci:v000016C3d0000EDDA* + ID_MODEL_FROM_DATABASE=EPMockUp + +@@ -58160,6 +63416,12 @@ pci:v000016D5d00004357* + pci:v000016D5d00004457* + ID_MODEL_FROM_DATABASE=PMC730, APC730, AcPC730 Multifunction Module + ++pci:v000016D5d00004471* ++ ID_MODEL_FROM_DATABASE=XMC730 Multi-function I/O module with front I/O ++ ++pci:v000016D5d00004473* ++ ID_MODEL_FROM_DATABASE=XMC730CC Multi-function I/O module with rear I/O Conduction-cooled ++ + pci:v000016D5d0000464D* + ID_MODEL_FROM_DATABASE=PMC408 32-Channel Digital Input/Output Module + +@@ -58343,6 +63605,9 @@ pci:v000016D5d0000702A* + pci:v000016D5d0000702B* + ID_MODEL_FROM_DATABASE=AP236 16-Bit, 8-Channel Isolated Analog Output Module + ++pci:v000016D5d0000702C* ++ ID_MODEL_FROM_DATABASE=AP560A Module 4 Independent isolated CAN bus channels ++ + pci:v000016D5d00007031* + ID_MODEL_FROM_DATABASE=AP441-1: 32-Channel Isolated Digital Input Module + +@@ -58361,6 +63626,21 @@ pci:v000016D5d00007043* + pci:v000016D5d00007044* + ID_MODEL_FROM_DATABASE=AP484 Counter Timer Module with RS422 Input/Output + ++pci:v000016D5d00007051* ++ ID_MODEL_FROM_DATABASE=APA7-501 Reconfigurable Artix-7 52,160 Cell FPGA module 48 TTL channels ++ ++pci:v000016D5d00007052* ++ ID_MODEL_FROM_DATABASE=APA7-502 Reconfigurable Artix-7 52,160 Cell FPGA module 24 RS485 channels ++ ++pci:v000016D5d00007053* ++ ID_MODEL_FROM_DATABASE=APA7-503 Reconfigurable Artix-7 52,160 Cell FPGA module 24 TTL & 12 RS485 channels ++ ++pci:v000016D5d00007054* ++ ID_MODEL_FROM_DATABASE=APA7-504 Reconfigurable Artix-7 52,160 Cell FPGA module 24 LVDS channels ++ ++pci:v000016D5d00007073* ++ ID_MODEL_FROM_DATABASE=AP730 Multi-function I/O Module 16 Digital I/O 8 Differential Analog In 4 Analog Out ++ + pci:v000016DA* + ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd. + +@@ -58505,6 +63785,9 @@ pci:v00001737d0000AB09* + pci:v0000173B* + ID_VENDOR_FROM_DATABASE=Altima (nee Broadcom) + ++pci:v0000173Bd00000001* ++ ID_MODEL_FROM_DATABASE=AC1002 PCI Gigabit Ethernet controller ++ + pci:v0000173Bd000003E8* + ID_MODEL_FROM_DATABASE=AC1000 Gigabit Ethernet + +@@ -58559,9 +63842,108 @@ pci:v00001760d00000101* + pci:v00001760d00000102* + ID_MODEL_FROM_DATABASE=PCD-7104 Digital Input & Output PCI Card + ++pci:v00001760d00000121* ++ ID_MODEL_FROM_DATABASE=PCT-7303A PC card with IRC counters ++ ++pci:v00001760d00000122* ++ ID_MODEL_FROM_DATABASE=PCT-7408A PC card with counters and timers ++ ++pci:v00001760d00000123* ++ ID_MODEL_FROM_DATABASE=PCT-7424 PCI card with standard counters ++ ++pci:v00001760d00000141* ++ ID_MODEL_FROM_DATABASE=PCA7208AL - Analog Inputs/Outputs ++ ++pci:v00001760d00000142* ++ ID_MODEL_FROM_DATABASE=PCA7208AS - Analog inputs/Outputs ++ ++pci:v00001760d00000143* ++ ID_MODEL_FROM_DATABASE=PCA7408AL - Analog Inputs/Outputs ++ ++pci:v00001760d00000144* ++ ID_MODEL_FROM_DATABASE=PCA7408AS - Analog Inputs/Outputs ++ ++pci:v00001760d00000145* ++ ID_MODEL_FROM_DATABASE=PCA-7228AL Multifunction PCI IO card ++ ++pci:v00001760d00000146* ++ ID_MODEL_FROM_DATABASE=PCA-7228AS Multifunction PCI IO card ++ ++pci:v00001760d00000147* ++ ID_MODEL_FROM_DATABASE=PCA7428AL Multifunction PCI IO card ++ ++pci:v00001760d00000148* ++ ID_MODEL_FROM_DATABASE=PCA7428AS Multifunction PCI IO card ++ ++pci:v00001760d00000149* ++ ID_MODEL_FROM_DATABASE=PCA7228EL Multifunction PCI IO card with isolated analog inputs ++ ++pci:v00001760d00000150* ++ ID_MODEL_FROM_DATABASE=PCA7428EL Multifunction PCI IO card with isolated analog inputs ++ ++pci:v00001760d00000151* ++ ID_MODEL_FROM_DATABASE=PCA7628AL - PCI card with analog inputs, counters and DIO ++ ++pci:v00001760d00000152* ++ ID_MODEL_FROM_DATABASE=PCA7628AS PCI card with analog inputs, outputs, counters and DIO ++ ++pci:v00001760d00000161* ++ ID_MODEL_FROM_DATABASE=PCA7288A PCI card with analog outputs, counters and DIO ++ ++pci:v00001760d00000180* ++ ID_MODEL_FROM_DATABASE=PCI1052 Communication card for MicroUnit network ++ ++pci:v00001760d00000214* ++ ID_MODEL_FROM_DATABASE=PCT-7424C (F0) PC card with standard counters ++ ++pci:v00001760d00000215* ++ ID_MODEL_FROM_DATABASE=PCT-7424C (F1) PC card with standard counters ++ ++pci:v00001760d00000216* ++ ID_MODEL_FROM_DATABASE=PCT-7424E (F0) PC card with standard counters ++ ++pci:v00001760d00000217* ++ ID_MODEL_FROM_DATABASE=PCT-7424E (F1) PC card with standard counters ++ ++pci:v00001760d00000240* ++ ID_MODEL_FROM_DATABASE=PCA7428CL_F0 - analog Inputs ++ ++pci:v00001760d00000241* ++ ID_MODEL_FROM_DATABASE=PCA7428CL_F1 - analog Inputs ++ ++pci:v00001760d00000242* ++ ID_MODEL_FROM_DATABASE=PCA7428CS_F0 - Analog Inputs/Outputs non isolated ++ ++pci:v00001760d00000243* ++ ID_MODEL_FROM_DATABASE=PCA7428CS_F1 - Analog Inputs/Outputs non isolated ++ ++pci:v00001760d00000244* ++ ID_MODEL_FROM_DATABASE=PCA7428CE_F0 - Analog Inputs isolated ++ ++pci:v00001760d00000245* ++ ID_MODEL_FROM_DATABASE=PCA7428CE_F1 - Analog Inputs isolated ++ + pci:v00001760d00000303* + ID_MODEL_FROM_DATABASE=PCD-7006C Digital Input & Output PCI Card + ++pci:v00001760d00000800* ++ ID_MODEL_FROM_DATABASE=PCD8006 - PCIe digital Inputs/Outputs ++ ++pci:v00001760d00000840* ++ ID_MODEL_FROM_DATABASE=PCA-8428 General-purpose multifunctional PCIe card with 8 analog inputs and 2 analog outputs ++ ++pci:v00001760d00000841* ++ ID_MODEL_FROM_DATABASE=PCA-8429 General-purpose multifunctional PCIe card with 8 analog inputs ++ ++pci:v00001760d00000842* ++ ID_MODEL_FROM_DATABASE=PCA-8438 General-purpose multifunctional PCIe card with 16 analog inputs and 2 analog outputs ++ ++pci:v00001760d00000843* ++ ID_MODEL_FROM_DATABASE=PCA-8439 General-purpose multifunctional PCIe card with 16 analog inputs ++ ++pci:v00001760d0000FF00* ++ ID_MODEL_FROM_DATABASE=CTU CAN FD PCIe Card ++ + pci:v00001761* + ID_VENDOR_FROM_DATABASE=Pickering Interfaces Ltd + +@@ -58569,7 +63951,7 @@ pci:v00001771* + ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia Ltd. + + pci:v00001775* +- ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms ++ ID_VENDOR_FROM_DATABASE=General Electric + + pci:v0000177D* + ID_VENDOR_FROM_DATABASE=Cavium, Inc. +@@ -58590,7 +63972,13 @@ pci:v0000177Dd00000006* + ID_MODEL_FROM_DATABASE=RoHS + + pci:v0000177Dd00000010* +- ID_MODEL_FROM_DATABASE=Nitrox XL NPX ++ ID_MODEL_FROM_DATABASE=CN15XX/CN16XX [Nitrox PX] ++ ++pci:v0000177Dd00000011* ++ ID_MODEL_FROM_DATABASE=CNN35XX [Nitrox III] ++ ++pci:v0000177Dd00000012* ++ ID_MODEL_FROM_DATABASE=CNN55XX [Nitrox V] + + pci:v0000177Dd00000020* + ID_MODEL_FROM_DATABASE=Octeon CN31XX Network Processor +@@ -58859,6 +64247,12 @@ pci:v0000177Dd0000A200* + pci:v0000177Dd0000A300* + ID_MODEL_FROM_DATABASE=OCTEON TX CN83XX + ++pci:v0000177Dd0000AF00* ++ ID_MODEL_FROM_DATABASE=CN99xx [ThunderX2] Integrated PCI Host bridge ++ ++pci:v0000177Dd0000AF84* ++ ID_MODEL_FROM_DATABASE=CN99xx [ThunderX2] Integrated PCI Express RP Bridge ++ + pci:v00001787* + ID_VENDOR_FROM_DATABASE=Hightech Information System Ltd. + +@@ -58886,6 +64280,21 @@ pci:v00001796d00000005* + pci:v00001796d00000006* + ID_MODEL_FROM_DATABASE=AMCC HOTlink + ++pci:v00001796d00000007* ++ ID_MODEL_FROM_DATABASE=LVD Cable Bus ++ ++pci:v00001796d00000008* ++ ID_MODEL_FROM_DATABASE=100MHz, 64bit Sequence Generator based on VirtexII ++ ++pci:v00001796d00000009* ++ ID_MODEL_FROM_DATABASE=double 14bit-ADC ++ ++pci:v00001796d0000000A* ++ ID_MODEL_FROM_DATABASE=SIS1100 with N110 TDC ++ ++pci:v00001796d0000000B* ++ ID_MODEL_FROM_DATABASE=double 14bit-ADC with memory ++ + pci:v00001796d0000000D* + ID_MODEL_FROM_DATABASE=Synchronisation Slave + +@@ -58904,9 +64313,39 @@ pci:v00001796d00000011* + pci:v00001796d00000012* + ID_MODEL_FROM_DATABASE=SIS1100-e quad link + ++pci:v00001796d00000013* ++ ID_MODEL_FROM_DATABASE=4x2.5GHz SFP to 4 lane PCIe bridge ++ ++pci:v00001796d00000014* ++ ID_MODEL_FROM_DATABASE=SIS1100 with GPX piggy back ++ + pci:v00001796d00000015* + ID_MODEL_FROM_DATABASE=SIS8100 [Gigabit link, MicroTCA] + ++pci:v00001796d00000016* ++ ID_MODEL_FROM_DATABASE=SIS1100e with 4 lanes ++ ++pci:v00001796d00000017* ++ ID_MODEL_FROM_DATABASE=Quad 14bit, 50MHz ADC with 2.5GHz SFP ++ ++pci:v00001796d00000018* ++ ID_MODEL_FROM_DATABASE=SIS8300 4-lane PCI Express, Micro TCA for Physics ADC ++ ++pci:v00001796d00000019* ++ ID_MODEL_FROM_DATABASE=SIS SIS8300-Lx MTCA.4 Digitizer ++ ++pci:v00001796d0000001A* ++ ID_MODEL_FROM_DATABASE=100MHz, 64bit Sequence Generator based on VirtexII ++ ++pci:v00001796d0000001C* ++ ID_MODEL_FROM_DATABASE=Quad 16bit, 150MHz ADC with 2.5GHz SFP ++ ++pci:v00001796d00000030* ++ ID_MODEL_FROM_DATABASE=100MHz, 64bit Sequence Generator based on Spartan6 ++ ++pci:v00001796d00000031* ++ ID_MODEL_FROM_DATABASE=200MHz 64bit Sequence Generator based on Spartan7 ++ + pci:v00001797* + ID_VENDOR_FROM_DATABASE=Intersil Techwell + +@@ -59009,9 +64448,21 @@ pci:v000017A0d00008083* + pci:v000017A0d00008084* + ID_MODEL_FROM_DATABASE=GL880 USB 2.0 EHCI controller + ++pci:v000017A0d00009750* ++ ID_MODEL_FROM_DATABASE=GL9750 SD Host Controller ++ ++pci:v000017A0d00009755* ++ ID_MODEL_FROM_DATABASE=GL9755 SD Host Controller ++ ++pci:v000017A0d0000E763* ++ ID_MODEL_FROM_DATABASE=GL9763E eMMC Controller ++ + pci:v000017AA* + ID_VENDOR_FROM_DATABASE=Lenovo + ++pci:v000017AAd00003181* ++ ID_MODEL_FROM_DATABASE=ThinkCentre M75n IoT ++ + pci:v000017AAd0000402B* + ID_MODEL_FROM_DATABASE=Intel 82599ES 10Gb 2-port Server Adapter X520-2 + +@@ -59072,12 +64523,36 @@ pci:v000017CBd00000002sv00001385sd00006D00* + pci:v000017CBd00000002sv00001737sd00000054* + ID_MODEL_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card (WPC54GX4 v1 802.11g Wireless-G Notebook Adapter with SRX400) + ++pci:v000017CBd00000105* ++ ID_MODEL_FROM_DATABASE=MSM8998 PCIe Root Complex ++ ++pci:v000017CBd00000108* ++ ID_MODEL_FROM_DATABASE=SM8150 PCIe Root Complex ++ ++pci:v000017CBd00000109* ++ ID_MODEL_FROM_DATABASE=SA8195P PCIe Root Complex ++ ++pci:v000017CBd00000300* ++ ID_MODEL_FROM_DATABASE=MDM9x35 LTE Modem [Snapdragon X7] ++ ++pci:v000017CBd00000301* ++ ID_MODEL_FROM_DATABASE=MDM9x45 LTE Modem [Snapdragon X12] ++ ++pci:v000017CBd00000302* ++ ID_MODEL_FROM_DATABASE=MDM9x55 LTE Modem [Snapdragon X16] ++ + pci:v000017CBd00000400* + ID_MODEL_FROM_DATABASE=Datacenter Technologies QDF2432 PCI Express Root Port + + pci:v000017CBd00000401* + ID_MODEL_FROM_DATABASE=Datacenter Technologies QDF2400 PCI Express Root Port + ++pci:v000017CBd00001000* ++ ID_MODEL_FROM_DATABASE=QCS405 PCIe Root Complex ++ ++pci:v000017CBd00001101* ++ ID_MODEL_FROM_DATABASE=QCA6390 Wireless Network Adapter [AX500-DBS (2x2)] ++ + pci:v000017CC* + ID_VENDOR_FROM_DATABASE=NetChip Technology, Inc + +@@ -59204,6 +64679,9 @@ pci:v000017D3d00001880sv000017D3sd00001883* + pci:v000017D3d00001884* + ID_MODEL_FROM_DATABASE=ARC-1884 series PCIe 3.0 to SAS/SATA 12/6Gb RAID Controller + ++pci:v000017D3d0000188A* ++ ID_MODEL_FROM_DATABASE=ARC-1886 series PCIe 4.0 to NVMe/SAS/SATA 16/12/6Gb RAID Controller ++ + pci:v000017D5* + ID_VENDOR_FROM_DATABASE=Exar Corp. + +@@ -59393,6 +64871,12 @@ pci:v000017DFd00001916* + pci:v000017DFd00001917* + ID_MODEL_FROM_DATABASE=UltrascalePlus PCIe Accelerator Board [DNPCIe_400G_VU_LL] + ++pci:v000017DFd00001918* ++ ID_MODEL_FROM_DATABASE=VirtexUS+ ASIC Emulation Board [DNVUPF4A] ++ ++pci:v000017DFd00001919* ++ ID_MODEL_FROM_DATABASE=UltrascalePlus PCIe Accelerator Board [DNPCIe_400G_VUP_HBM_LL] ++ + pci:v000017DFd00001A00* + ID_MODEL_FROM_DATABASE=Virtex6 PCIe DMA Netlist Design + +@@ -59429,6 +64913,12 @@ pci:v000017DFd00001A0B* + pci:v000017DFd00001A0C* + ID_MODEL_FROM_DATABASE=KintexUS PCIe DRAM Packet Capture Design [DNPCIe_40G_KU_LL] + ++pci:v000017DFd00001A0D* ++ ID_MODEL_FROM_DATABASE=KintexUS PCIe DRAM Packet Capture Design [DNPCIe_40G_KU_LL_2QSFP] ++ ++pci:v000017DFd00001A0E* ++ ID_MODEL_FROM_DATABASE=UltrascalePlus PCIe Darklite Design [DNPCIe_400G_VUP_HBM_LL] ++ + pci:v000017E4* + ID_VENDOR_FROM_DATABASE=Sectra AB + +@@ -59474,21 +64964,66 @@ pci:v000017F3* + pci:v000017F3d00001010* + ID_MODEL_FROM_DATABASE=R1010 IDE Controller + ++pci:v000017F3d00001011* ++ ID_MODEL_FROM_DATABASE=R1011 IDE Controller ++ ++pci:v000017F3d00001012* ++ ID_MODEL_FROM_DATABASE=R1012 IDE Controller ++ ++pci:v000017F3d00001031* ++ ID_MODEL_FROM_DATABASE=PCI/PCI-X to PCI-E Bridge ++ ++pci:v000017F3d00001070* ++ ID_MODEL_FROM_DATABASE=CAN Bus Controller ++ ++pci:v000017F3d00001331* ++ ID_MODEL_FROM_DATABASE=Motion Control Interface ++ ++pci:v000017F3d00001930* ++ ID_MODEL_FROM_DATABASE=Hybrid Function Control Register ++ ++pci:v000017F3d00002010* ++ ID_MODEL_FROM_DATABASE=RDC M2010 VGA-compatible graphics adapter ++ + pci:v000017F3d00002012* + ID_MODEL_FROM_DATABASE=M2012/R3308 VGA-compatible graphics adapter + ++pci:v000017F3d00002015* ++ ID_MODEL_FROM_DATABASE=RDC M2015 VGA-compatible graphics adapter ++ ++pci:v000017F3d00006011* ++ ID_MODEL_FROM_DATABASE=R6011 ISA Bridge ++ ++pci:v000017F3d00006013* ++ ID_MODEL_FROM_DATABASE=R6013 ISA Bridge ++ + pci:v000017F3d00006020* + ID_MODEL_FROM_DATABASE=R6020 North Bridge + + pci:v000017F3d00006021* + ID_MODEL_FROM_DATABASE=R6021 Host Bridge + ++pci:v000017F3d00006023* ++ ID_MODEL_FROM_DATABASE=R6023 Host Bridge ++ ++pci:v000017F3d00006025* ++ ID_MODEL_FROM_DATABASE=R6025 Host Bridge ++ ++pci:v000017F3d00006026* ++ ID_MODEL_FROM_DATABASE=R6026 Host Bridge ++ + pci:v000017F3d00006030* + ID_MODEL_FROM_DATABASE=R6030 ISA Bridge + + pci:v000017F3d00006031* + ID_MODEL_FROM_DATABASE=R6031 ISA Bridge + ++pci:v000017F3d00006035* ++ ID_MODEL_FROM_DATABASE=R6035 ISA Bridge ++ ++pci:v000017F3d00006036* ++ ID_MODEL_FROM_DATABASE=R6036 ISA Bridge ++ + pci:v000017F3d00006040* + ID_MODEL_FROM_DATABASE=R6040 MAC Controller + +@@ -59537,6 +65072,12 @@ pci:v00001800d00001100* + pci:v00001803* + ID_VENDOR_FROM_DATABASE=ProdaSafe GmbH + ++pci:v00001804* ++ ID_VENDOR_FROM_DATABASE=Ralink corp. (wrong ID) ++ ++pci:v00001804d00003060* ++ ID_MODEL_FROM_DATABASE=RT3060 Wireless 802.11n 1T/1R ++ + pci:v00001805* + ID_VENDOR_FROM_DATABASE=Euresys S.A. + +@@ -59846,6 +65387,18 @@ pci:v0000182Fd0000000B* + pci:v00001830* + ID_VENDOR_FROM_DATABASE=Credence Systems Corporation + ++pci:v00001830d00008000* ++ ID_MODEL_FROM_DATABASE=CPIn ++ ++pci:v00001830d00008001* ++ ID_MODEL_FROM_DATABASE=CPId ++ ++pci:v00001830d00008002* ++ ID_MODEL_FROM_DATABASE=CPIx ++ ++pci:v00001830d00008003* ++ ID_MODEL_FROM_DATABASE=CPIq ++ + pci:v0000183B* + ID_VENDOR_FROM_DATABASE=MikroM GmbH + +@@ -59945,6 +65498,9 @@ pci:v0000186Cd00000625* + pci:v0000186Cd00000634* + ID_MODEL_FROM_DATABASE=MF634 Multifunction I/O PCIe Card + ++pci:v0000186Cd00000644* ++ ID_MODEL_FROM_DATABASE=MF644 Multifunction I/O Thb Card ++ + pci:v0000186F* + ID_VENDOR_FROM_DATABASE=WiNRADiO Communications + +@@ -60281,6 +65837,9 @@ pci:v000018ECd0000C232sv000018ECsd0000FF00* + pci:v000018ECd0000C232sv000018ECsd0000FF01* + ID_MODEL_FROM_DATABASE=COMBO-FXT100 (Boot design) + ++pci:v000018ECd0000C400* ++ ID_MODEL_FROM_DATABASE=COMBO-400G1 ++ + pci:v000018EE* + ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp. + +@@ -60365,6 +65924,15 @@ pci:v000018F4d00000185* + pci:v000018F4d000001A5* + ID_MODEL_FROM_DATABASE=NT200A01 Network Adapter + ++pci:v000018F4d000001C5* ++ ID_MODEL_FROM_DATABASE=NT200A02 Network Adapter ++ ++pci:v000018F4d000001D5* ++ ID_MODEL_FROM_DATABASE=NT50B01 Network Adapter ++ ++pci:v000018F4d000001E5* ++ ID_MODEL_FROM_DATABASE=NT100A01 Network Adapter ++ + pci:v000018F6* + ID_VENDOR_FROM_DATABASE=NextIO + +@@ -60827,17 +66395,44 @@ pci:v00001924d00000A03sv00001924sd0000801A* + pci:v00001924d00000A03sv00001924sd0000801B* + ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R3 8000 Series 10G Adapter) + ++pci:v00001924d00000A03sv00001924sd0000801C* ++ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R3 8000 Series 10/40G Adapter) ++ ++pci:v00001924d00000A03sv00001924sd00008021* ++ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8041-R1 8000 Series 10/40G Adapter) ++ + pci:v00001924d00000B03* +- ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller + + pci:v00001924d00000B03sv00001924sd0000801D* +- ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (x2522-R1 2000 Series 10/25G Adapter) ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (x2522-R1 2000 Series 10/25G Adapter) + + pci:v00001924d00000B03sv00001924sd0000801E* +- ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (x2542-R1 2000 Series 40/100G Adapter) ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (x2542-R1 2000 Series 40/100G Adapter) + + pci:v00001924d00000B03sv00001924sd00008022* +- ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (x2522-R2 2000 Series 10/25G Adapter) ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2522 10G Network Adapter) ++ ++pci:v00001924d00000B03sv00001924sd00008024* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2562 OCP 3.0 Dual Port SFP28) ++ ++pci:v00001924d00000B03sv00001924sd00008027* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2541 PCIe Single Port QSFP28) ++ ++pci:v00001924d00000B03sv00001924sd00008028* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2522-25G Network Adapter) ++ ++pci:v00001924d00000B03sv00001924sd0000802A* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2542 PCIe Dual Port QSFP28) ++ ++pci:v00001924d00000B03sv00001924sd0000802B* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2552 OCP 2.0 Dual Port SFP28) ++ ++pci:v00001924d00000B03sv00001924sd0000802C* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2522-25G PCIe Dual Port SFP28) ++ ++pci:v00001924d00000B03sv00001924sd0000802D* ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (XtremeScale X2562 OCP 3.0 Dual Port SFP28) + + pci:v00001924d00001803* + ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function) +@@ -60855,7 +66450,7 @@ pci:v00001924d00001A03* + ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (Virtual Function) + + pci:v00001924d00001B03* +- ID_MODEL_FROM_DATABASE=SFC9250 10/25/40/50/100G Ethernet Controller (Virtual Function) ++ ID_MODEL_FROM_DATABASE=XtremeScale SFC9250 10/25/40/50/100G Ethernet Controller (Virtual Function) + + pci:v00001924d00006703* + ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] +@@ -60902,6 +66497,9 @@ pci:v00001924d0000C101* + pci:v0000192A* + ID_VENDOR_FROM_DATABASE=BiTMICRO Networks Inc. + ++pci:v0000192Ad00000008* ++ ID_MODEL_FROM_DATABASE=RAMPART ++ + pci:v0000192E* + ID_VENDOR_FROM_DATABASE=TransDimension + +@@ -61131,7 +66729,7 @@ pci:v00001957d000000B6* + ID_MODEL_FROM_DATABASE=MPC8314E + + pci:v00001957d000000B6sv00001A56sd00001101* +- ID_MODEL_FROM_DATABASE=MPC8314E (Killer Xeno Pro Gigabit Ethernet Controller) ++ ID_MODEL_FROM_DATABASE=MPC8314E (Bigfoot Killer Xeno Pro Gigabit Ethernet Controller) + + pci:v00001957d000000C2* + ID_MODEL_FROM_DATABASE=MPC8379E +@@ -61248,7 +66846,7 @@ pci:v00001957d0000C006* + ID_MODEL_FROM_DATABASE=MPC8308 + + pci:v00001957d0000C006sv00001A56sd00001201* +- ID_MODEL_FROM_DATABASE=MPC8308 (Killer E2100 Gigabit Ethernet Controller) ++ ID_MODEL_FROM_DATABASE=MPC8308 (Bigfoot Killer E2100 Gigabit Ethernet Controller) + + pci:v00001957d0000FC02* + ID_MODEL_FROM_DATABASE=RedStone +@@ -61313,6 +66911,21 @@ pci:v00001966d00001975* + pci:v00001966d00001977* + ID_MODEL_FROM_DATABASE=DVG128 family + ++pci:v00001966d00001979* ++ ID_MODEL_FROM_DATABASE=3DVG/UHD3 ++ ++pci:v00001966d00001980* ++ ID_MODEL_FROM_DATABASE=HDV2/UHD2 ++ ++pci:v00001966d00001980sv00001234sd00003160* ++ ID_MODEL_FROM_DATABASE=HDV2/UHD2 (UHD2LC) ++ ++pci:v00001966d00001980sv00001234sd00003300* ++ ID_MODEL_FROM_DATABASE=HDV2/UHD2 (Legacy UHD2) ++ ++pci:v00001966d00001980sv00001234sd00003410* ++ ID_MODEL_FROM_DATABASE=HDV2/UHD2 (UHD2) ++ + pci:v00001969* + ID_VENDOR_FROM_DATABASE=Qualcomm Atheros + +@@ -61326,7 +66939,7 @@ pci:v00001969d00001048* + ID_MODEL_FROM_DATABASE=Attansic L1 Gigabit Ethernet + + pci:v00001969d00001048sv00001043sd00008226* +- ID_MODEL_FROM_DATABASE=Attansic L1 Gigabit Ethernet (P5KPL-VM Motherboard) ++ ID_MODEL_FROM_DATABASE=Attansic L1 Gigabit Ethernet (P5B-MX/WiFi-AP, P5KPL-VM Motherboard) + + pci:v00001969d00001062* + ID_MODEL_FROM_DATABASE=AR8132 Fast Ethernet +@@ -61379,6 +66992,9 @@ pci:v00001969d00002060* + pci:v00001969d00002062* + ID_MODEL_FROM_DATABASE=AR8152 v2.0 Fast Ethernet + ++pci:v00001969d00002062sv00001043sd00008468* ++ ID_MODEL_FROM_DATABASE=AR8152 v2.0 Fast Ethernet (Eee PC 1015PX) ++ + pci:v00001969d0000E091* + ID_MODEL_FROM_DATABASE=Killer E220x Gigabit Ethernet Controller + +@@ -61403,6 +67019,9 @@ pci:v0000196Ad00000105* + pci:v0000196D* + ID_VENDOR_FROM_DATABASE=Club-3D BV + ++pci:v0000196E* ++ ID_VENDOR_FROM_DATABASE=PNY ++ + pci:v00001971* + ID_VENDOR_FROM_DATABASE=AGEIA Technologies, Inc. + +@@ -61413,7 +67032,19 @@ pci:v00001971d00001011sv00001043sd00000001* + ID_MODEL_FROM_DATABASE=Physics Processing Unit [PhysX] (PhysX P1) + + pci:v00001974* +- ID_VENDOR_FROM_DATABASE=Eberspaecher Electronics ++ ID_VENDOR_FROM_DATABASE=Star Electronics GmbH & Co. KG ++ ++pci:v00001974d00000009* ++ ID_MODEL_FROM_DATABASE=FlexCard PMC-II ++ ++pci:v00001974d00000011* ++ ID_MODEL_FROM_DATABASE=FlexCard PMC-II Ethernet ++ ++pci:v00001974d00000018* ++ ID_MODEL_FROM_DATABASE=FlexCard PXIe3 ++ ++pci:v00001974d00000019* ++ ID_MODEL_FROM_DATABASE=FlexCard PCIe3 + + pci:v00001976* + ID_VENDOR_FROM_DATABASE=TRENDnet +@@ -61433,6 +67064,9 @@ pci:v0000197Bd00000260* + pci:v0000197Bd00000368* + ID_MODEL_FROM_DATABASE=JMB368 IDE controller + ++pci:v0000197Bd00000585* ++ ID_MODEL_FROM_DATABASE=JMB58x AHCI SATA controller ++ + pci:v0000197Bd00002360* + ID_MODEL_FROM_DATABASE=JMB360 AHCI Controller + +@@ -61523,6 +67157,24 @@ pci:v00001982d00001600* + pci:v00001982d000016FF* + ID_MODEL_FROM_DATABASE=OX16C954 HOST-B + ++pci:v00001987* ++ ID_VENDOR_FROM_DATABASE=Phison Electronics Corporation ++ ++pci:v00001987d00005007* ++ ID_MODEL_FROM_DATABASE=E7 NVMe Controller ++ ++pci:v00001987d00005012* ++ ID_MODEL_FROM_DATABASE=E12 NVMe Controller ++ ++pci:v00001987d00005013* ++ ID_MODEL_FROM_DATABASE=PS5013 E13 NVMe Controller ++ ++pci:v00001987d00005016* ++ ID_MODEL_FROM_DATABASE=E16 PCIe4 NVMe Controller ++ ++pci:v00001987d00005018* ++ ID_MODEL_FROM_DATABASE=E18 PCIe4 NVMe Controller ++ + pci:v00001989* + ID_VENDOR_FROM_DATABASE=Montilio Inc. + +@@ -61752,23 +67404,152 @@ pci:v000019E5d00000123sv000019E5sd00003036* + ID_MODEL_FROM_DATABASE=ES3000 V3 NVMe PCIe SSD (NVMe SSD ES3600C V3 3200GB HHHL AIC) + + pci:v000019E5d00000200* +- ID_MODEL_FROM_DATABASE=Hi1822 Family (2*25GE) ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) ++ ++pci:v000019E5d00000200sv000019E5sd0000D139* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) (Hi1822 SP572 (2*100GE)) ++ ++pci:v000019E5d00000200sv000019E5sd0000D13D* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) (Hi1822 SC371 (2*100GE)) ++ ++pci:v000019E5d00000200sv000019E5sd0000D147* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) (Hi1822 SP573 (2*100GE)) ++ ++pci:v000019E5d00000202* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*32G FC) ++ ++pci:v000019E5d00000202sv000019E5sd0000D149* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*32G FC) (Hi1822 SP528 (2*32G FC)) ++ ++pci:v000019E5d00000202sv000019E5sd0000D302* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*32G FC) (Hi1822 SP521 (2*32G FC)) + +-pci:v000019E5d00000201* ++pci:v000019E5d00000202sv000019E5sd0000D304* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*32G FC) (Hi1822 SP526 (2*32G FC)) ++ ++pci:v000019E5d00000203* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*16G FC) ++ ++pci:v000019E5d00000203sv000019E5sd0000D148* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*16G FC) (Hi1822 SP527 (2*16G FC)) ++ ++pci:v000019E5d00000203sv000019E5sd0000D301* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*16G FC) (Hi1822 SP520 (2*16G FC)) ++ ++pci:v000019E5d00000203sv000019E5sd0000D305* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*16G FC) (Hi1822 SP525 (2*16G FC)) ++ ++pci:v000019E5d00000205* + ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) + ++pci:v000019E5d00000205sv000019E5sd0000DF27* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*100GE) (Hi1822 MZ731 MEZZ (2*100GE)) ++ ++pci:v000019E5d00000206* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*25GE) ++ ++pci:v000019E5d00000206sv000019E5sd0000D138* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*25GE) (Hi1822 SP582 (2*25GE)) ++ ++pci:v000019E5d00000206sv000019E5sd0000D13A* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*25GE) (Hi1822 SC381 (2*25GE)) ++ ++pci:v000019E5d00000206sv000019E5sd0000D145* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*25GE) (Hi1822 SP586 (2*25GE)) ++ ++pci:v000019E5d00000210* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) ++ ++pci:v000019E5d00000210sv000019E5sd0000DF2E* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 MZ532 MEZZ (4*25GE)) ++ ++pci:v000019E5d00000211* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) ++ ++pci:v000019E5d00000211sv000019E5sd0000D12F* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP571 (4*25GE)) ++ ++pci:v000019E5d00000211sv000019E5sd0000D137* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP581 (4*25GE)) ++ ++pci:v000019E5d00000211sv000019E5sd0000D142* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP583 (4*25GE)) ++ ++pci:v000019E5d00000212* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*8G FC) ++ ++pci:v000019E5d00000212sv000019E5sd0000D303* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*8G FC) (Hi1822 SP522 (2*8G FC)) ++ ++pci:v000019E5d00000212sv000019E5sd0000D306* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (2*8G FC) (Hi1822 SP523 (2*8G FC)) ++ + pci:v000019E5d00001710* + ID_MODEL_FROM_DATABASE=iBMA Virtual Network Adapter + + pci:v000019E5d00001711* +- ID_MODEL_FROM_DATABASE=Hi1710 [iBMC Intelligent Management system chip w/VGA support] ++ ID_MODEL_FROM_DATABASE=Hi171x Series [iBMC Intelligent Management system chip w/VGA support] + + pci:v000019E5d00001822* + ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) + ++pci:v000019E5d00001822sv000019E5sd0000D129* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP570 (4*25GE)) ++ ++pci:v000019E5d00001822sv000019E5sd0000D136* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP580 (4*25GE)) ++ ++pci:v000019E5d00001822sv000019E5sd0000D141* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP583 (4*25GE)) ++ ++pci:v000019E5d00001822sv000019E5sd0000D146* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family (4*25GE) (Hi1822 SP585 (4*25GE)) ++ ++pci:v000019E5d00003714* ++ ID_MODEL_FROM_DATABASE=ES3000 V5 NVMe PCIe SSD ++ ++pci:v000019E5d00003714sv000019E5sd00005312* ++ ID_MODEL_FROM_DATABASE=ES3000 V5 NVMe PCIe SSD (NVMe SSD ES3500P V5 2000GB 2.5" U.2) ++ + pci:v000019E5d0000371E* + ID_MODEL_FROM_DATABASE=Hi1822 Family Virtual Bridge + ++pci:v000019E5d00003754* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD ++ ++pci:v000019E5d00003754sv000019E5sd00006122* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3600P V6 1600GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006123* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3600P V6 3200GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006124* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3600P V6 6400GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006141* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3800P V6 800GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006142* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3800P V6 1600GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006212* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3500P V6 1920GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006213* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3500P V6 3840GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006214* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3500P V6 7680GB 2.5" U.2) ++ ++pci:v000019E5d00003754sv000019E5sd00006215* ++ ID_MODEL_FROM_DATABASE=ES3000 V6 NVMe PCIe SSD (NVMe SSD ES3500P V6 15360GB 2.5" U.2) ++ ++pci:v000019E5d0000375E* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family Virtual Function ++ ++pci:v000019E5d0000379E* ++ ID_MODEL_FROM_DATABASE=Hi1822 Family Virtual Function ++ + pci:v000019E5d0000A120* + ID_MODEL_FROM_DATABASE=HiSilicon PCIe Root Port with Gen4 + +@@ -61799,6 +67580,18 @@ pci:v000019E5d0000A220* + pci:v000019E5d0000A221* + ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE Network Controller + ++pci:v000019E5d0000A221sv000019E5sd00000454* ++ ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE Network Controller (TM280) ++ ++pci:v000019E5d0000A221sv000019E5sd000004CC* ++ ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE Network Controller (TM210) ++ ++pci:v000019E5d0000A221sv000019E5sd0000D14A* ++ ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE Network Controller (TM280 4*25G) ++ ++pci:v000019E5d0000A221sv000019E5sd0000D14B* ++ ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE Network Controller (TM210 4*GE) ++ + pci:v000019E5d0000A222* + ID_MODEL_FROM_DATABASE=HNS GE/10GE/25GE RDMA Network Controller + +@@ -61832,6 +67625,9 @@ pci:v000019E5d0000A239* + pci:v000019E5d0000A23A* + ID_MODEL_FROM_DATABASE=HiSilicon USB 2.0 Host Controller + ++pci:v000019E5d0000A23B* ++ ID_MODEL_FROM_DATABASE=HiSilicon USB 1.1 Host Controller ++ + pci:v000019E5d0000A250* + ID_MODEL_FROM_DATABASE=HiSilicon ZIP Engine + +@@ -61892,6 +67688,12 @@ pci:v00001A03d00001150* + pci:v00001A03d00002000* + ID_MODEL_FROM_DATABASE=ASPEED Graphics Family + ++pci:v00001A03d00002000sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=ASPEED Graphics Family (X10SRL-F) ++ ++pci:v00001A05* ++ ID_VENDOR_FROM_DATABASE=deltaww ++ + pci:v00001A07* + ID_VENDOR_FROM_DATABASE=Kvaser AB + +@@ -61913,6 +67715,9 @@ pci:v00001A08* + pci:v00001A08d00000000* + ID_MODEL_FROM_DATABASE=SC15064 + ++pci:v00001A0D* ++ ID_VENDOR_FROM_DATABASE=SEAKR Engineering ++ + pci:v00001A0E* + ID_VENDOR_FROM_DATABASE=DekTec Digital Video B.V. + +@@ -61946,6 +67751,9 @@ pci:v00001A29d00004338* + pci:v00001A29d00004E36* + ID_MODEL_FROM_DATABASE=NP6 Network Processor + ++pci:v00001A29d00004E37* ++ ID_MODEL_FROM_DATABASE=NP7 Network Processor ++ + pci:v00001A2B* + ID_VENDOR_FROM_DATABASE=Ascom AG + +@@ -62016,7 +67824,10 @@ pci:v00001A4Ad00001010* + ID_MODEL_FROM_DATABASE=AMC EVR - Stockholm Timing Board + + pci:v00001A4Ad00001020* +- ID_MODEL_FROM_DATABASE=Cluster On Board (COB) Ethernet Switch ++ ID_MODEL_FROM_DATABASE=PGPCard - Gen3 Cameralink Interface ++ ++pci:v00001A4Ad00001030* ++ ID_MODEL_FROM_DATABASE=PGPCard - Gen3 GIGe Interface + + pci:v00001A4Ad00002000* + ID_MODEL_FROM_DATABASE=PGPCard - 4 Lane +@@ -62027,12 +67838,24 @@ pci:v00001A4Ad00002001* + pci:v00001A4Ad00002010* + ID_MODEL_FROM_DATABASE=PCI-Express EVR + ++pci:v00001A4Ad00002011* ++ ID_MODEL_FROM_DATABASE=PCI-Express EVR - TPR Version ++ + pci:v00001A4Ad00002020* +- ID_MODEL_FROM_DATABASE=PGP-GEN3 PCIe ++ ID_MODEL_FROM_DATABASE=PGP-GEN3 PCIe - 8 Lane Plus EVR + + pci:v00001A4Ad00002030* + ID_MODEL_FROM_DATABASE=AXI Stream DAQ PCIe card + ++pci:v00001A4Ad00002040* ++ ID_MODEL_FROM_DATABASE=EXO PCIe TEM ++ ++pci:v00001A4Ad00003000* ++ ID_MODEL_FROM_DATABASE=COB DTM V1 ++ ++pci:v00001A4Ad00003001* ++ ID_MODEL_FROM_DATABASE=COB DTM V2 ++ + pci:v00001A51* + ID_VENDOR_FROM_DATABASE=Hectronic AB + +@@ -62088,7 +67911,7 @@ pci:v00001A55d00000090* + ID_MODEL_FROM_DATABASE=CinePlay + + pci:v00001A56* +- ID_VENDOR_FROM_DATABASE=Bigfoot Networks, Inc. ++ ID_VENDOR_FROM_DATABASE=Rivet Networks + + pci:v00001A57* + ID_VENDOR_FROM_DATABASE=Highly Reliable Systems +@@ -62193,7 +68016,7 @@ pci:v00001AAE* + ID_VENDOR_FROM_DATABASE=Global Velocity, Inc. + + pci:v00001AB4* +- ID_VENDOR_FROM_DATABASE=FFEI Ltd ++ ID_VENDOR_FROM_DATABASE=Distributed Management Task Force, Inc. (DMTF) + + pci:v00001AB6* + ID_VENDOR_FROM_DATABASE=CalDigit, Inc. +@@ -62216,6 +68039,12 @@ pci:v00001AB8d00004006* + pci:v00001AB9* + ID_VENDOR_FROM_DATABASE=Espia Srl + ++pci:v00001AC1* ++ ID_VENDOR_FROM_DATABASE=Global Unichip Corp. ++ ++pci:v00001AC1d0000089A* ++ ID_MODEL_FROM_DATABASE=Coral Edge TPU ++ + pci:v00001AC8* + ID_VENDOR_FROM_DATABASE=Aeroflex Gaisler + +@@ -62249,6 +68078,15 @@ pci:v00001ADEd00003038sv00004254sd00000552* + pci:v00001AE0* + ID_VENDOR_FROM_DATABASE=Google, Inc. + ++pci:v00001AE0d00000042* ++ ID_MODEL_FROM_DATABASE=Compute Engine Virtual Ethernet [gVNIC] ++ ++pci:v00001AE0d0000ABCD* ++ ID_MODEL_FROM_DATABASE=Airbrush Combined Paintbox IPU/Oscar Edge TPU [Pixel Neural Core] ++ ++pci:v00001AE3* ++ ID_VENDOR_FROM_DATABASE=SANBlaze Technology, Inc. ++ + pci:v00001AE7* + ID_VENDOR_FROM_DATABASE=First Wise Media GmbH + +@@ -62258,23 +68096,89 @@ pci:v00001AE7d00000520* + pci:v00001AE8* + ID_VENDOR_FROM_DATABASE=Silicon Software GmbH + ++pci:v00001AE8d00000751* ++ ID_MODEL_FROM_DATABASE=mE5 marathon VCL ++ ++pci:v00001AE8d00000752* ++ ID_MODEL_FROM_DATABASE=mE5 marathon AF2 ++ ++pci:v00001AE8d00000753* ++ ID_MODEL_FROM_DATABASE=mE5 marathon ACX QP ++ ++pci:v00001AE8d00000754* ++ ID_MODEL_FROM_DATABASE=mE5 marathon ACL ++ ++pci:v00001AE8d00000755* ++ ID_MODEL_FROM_DATABASE=mE5 marathon ACX SP ++ ++pci:v00001AE8d00000756* ++ ID_MODEL_FROM_DATABASE=mE5 marathon ACX DP ++ ++pci:v00001AE8d00000757* ++ ID_MODEL_FROM_DATABASE=mE5 marathon VCX QP ++ ++pci:v00001AE8d00000758* ++ ID_MODEL_FROM_DATABASE=mE5 marathon VF2 ++ ++pci:v00001AE8d00000759* ++ ID_MODEL_FROM_DATABASE=mE5 marathon VCLx ++ + pci:v00001AE8d00000A40* +- ID_MODEL_FROM_DATABASE=microEnable IV-BASE x1 ++ ID_MODEL_FROM_DATABASE=microEnable IV AD1-CL + + pci:v00001AE8d00000A41* +- ID_MODEL_FROM_DATABASE=microEnable IV-FULL x1 ++ ID_MODEL_FROM_DATABASE=microEnable IV VD1-CL ++ ++pci:v00001AE8d00000A42* ++ ID_MODEL_FROM_DATABASE=microEnable IV AD4-CL + + pci:v00001AE8d00000A44* +- ID_MODEL_FROM_DATABASE=microEnable IV-FULL x4 ++ ID_MODEL_FROM_DATABASE=microEnable IV VD4-CL ++ ++pci:v00001AE8d00000A45* ++ ID_MODEL_FROM_DATABASE=microEnable IV AS1-CL ++ ++pci:v00001AE8d00000A53* ++ ID_MODEL_FROM_DATABASE=microEnable 5 AQ8-CXP6B ++ ++pci:v00001AE8d00000A54* ++ ID_MODEL_FROM_DATABASE=microEnable 5 VQ8-CXP6B ++ ++pci:v00001AE8d00000A56* ++ ID_MODEL_FROM_DATABASE=microEnable 5 VQ8-CXP6D ++ ++pci:v00001AE8d00000A57* ++ ID_MODEL_FROM_DATABASE=microEnable 5 AQ8-CXP6D ++ ++pci:v00001AE8d00000A58* ++ ID_MODEL_FROM_DATABASE=microEnable 5 VD8-CL ++ ++pci:v00001AE8d00000A5A* ++ ID_MODEL_FROM_DATABASE=microEnable 5 AD8-CL ++ ++pci:v00001AE8d00000B52* ++ ID_MODEL_FROM_DATABASE=mE5 Abacus 4G Base ++ ++pci:v00001AE8d00000B53* ++ ID_MODEL_FROM_DATABASE=mE5 Abacus 4G Base II ++ ++pci:v00001AE8d00000B61* ++ ID_MODEL_FROM_DATABASE=mE6 Abacus 4TG ++ ++pci:v00001AE8d00000B63* ++ ID_MODEL_FROM_DATABASE=CXP-12 Interface Card 1C ++ ++pci:v00001AE8d00000E42* ++ ID_MODEL_FROM_DATABASE=microEnable IV AQ4-GE + + pci:v00001AE8d00000E44* +- ID_MODEL_FROM_DATABASE=microEnable IV-GigE x4 ++ ID_MODEL_FROM_DATABASE=microEnable IV VQ4-GE + + pci:v00001AE9* + ID_VENDOR_FROM_DATABASE=Wilocity Ltd. + + pci:v00001AE9d00000101* +- ID_MODEL_FROM_DATABASE=Wil6200 PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=Wil6200 PCI Express Upstream Port + + pci:v00001AE9d00000200* + ID_MODEL_FROM_DATABASE=Wil6200 PCI Express Port +@@ -62297,6 +68201,12 @@ pci:v00001AEA* + pci:v00001AEAd00006601* + ID_MODEL_FROM_DATABASE=AU6601 PCI-E Flash card reader controller + ++pci:v00001AEAd00006621* ++ ID_MODEL_FROM_DATABASE=AU6621 PCI-E Flash card reader controller ++ ++pci:v00001AEAd00006625* ++ ID_MODEL_FROM_DATABASE=AU6625 PCI-E Flash card reader controller ++ + pci:v00001AEC* + ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics + +@@ -62405,6 +68315,12 @@ pci:v00001AF4d00001050* + pci:v00001AF4d00001052* + ID_MODEL_FROM_DATABASE=Virtio input + ++pci:v00001AF4d00001053* ++ ID_MODEL_FROM_DATABASE=Virtio socket ++ ++pci:v00001AF4d0000105A* ++ ID_MODEL_FROM_DATABASE=Virtio file system ++ + pci:v00001AF4d00001110* + ID_MODEL_FROM_DATABASE=Inter-VM shared memory + +@@ -62441,6 +68357,9 @@ pci:v00001B1A* + pci:v00001B1Ad00000E70* + ID_MODEL_FROM_DATABASE=GRAPE + ++pci:v00001B1C* ++ ID_VENDOR_FROM_DATABASE=Corsair ++ + pci:v00001B21* + ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc. + +@@ -62453,9 +68372,15 @@ pci:v00001B21d00000612* + pci:v00001B21d00000612sv00001849sd00000612* + ID_MODEL_FROM_DATABASE=ASM1062 Serial ATA Controller (Motherboard) + ++pci:v00001B21d00001040* ++ ID_MODEL_FROM_DATABASE=ASM1040 XHCI Controller ++ + pci:v00001B21d00001042* + ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller + ++pci:v00001B21d00001042sv00001043sd00001059* ++ ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller (K53SM motherboard) ++ + pci:v00001B21d00001042sv00001043sd00008488* + ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller (P8B WS Motherboard) + +@@ -62471,12 +68396,69 @@ pci:v00001B21d00001080sv00001849sd00001080* + pci:v00001B21d00001142* + ID_MODEL_FROM_DATABASE=ASM1042A USB 3.0 Host Controller + ++pci:v00001B21d00001182* ++ ID_MODEL_FROM_DATABASE=ASM1182e 2-Port PCIe x1 Gen2 Packet Switch ++ ++pci:v00001B21d00001182sv00001B21sd0000118F* ++ ID_MODEL_FROM_DATABASE=ASM1182e 2-Port PCIe x1 Gen2 Packet Switch ++ ++pci:v00001B21d00001184* ++ ID_MODEL_FROM_DATABASE=ASM1184e 4-Port PCIe x1 Gen2 Packet Switch ++ ++pci:v00001B21d00001184sv00001849sd00001184* ++ ID_MODEL_FROM_DATABASE=ASM1184e 4-Port PCIe x1 Gen2 Packet Switch ++ + pci:v00001B21d00001242* + ID_MODEL_FROM_DATABASE=ASM1142 USB 3.1 Host Controller + + pci:v00001B21d00001343* + ID_MODEL_FROM_DATABASE=ASM1143 USB 3.1 Host Controller + ++pci:v00001B21d00002142* ++ ID_MODEL_FROM_DATABASE=ASM2142 USB 3.1 Host Controller ++ ++pci:v00001B21d00002142sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=ASM2142 USB 3.1 Host Controller (H270 PC MATE) ++ ++pci:v00001B21d00002824* ++ ID_MODEL_FROM_DATABASE=ASM2824 PCIe Gen3 Packet Switch ++ ++pci:v00001B21d00003242* ++ ID_MODEL_FROM_DATABASE=ASM3242 USB 3.2 Host Controller ++ ++pci:v00001B26* ++ ID_VENDOR_FROM_DATABASE=Netcope Technologies, a.s. ++ ++pci:v00001B26d0000C132* ++ ID_MODEL_FROM_DATABASE=COMBO-LXT155 ++ ++pci:v00001B26d0000C1C0* ++ ID_MODEL_FROM_DATABASE=NFB-100G1-e0 ++ ++pci:v00001B26d0000C1C1* ++ ID_MODEL_FROM_DATABASE=NFB-100G1-e1 ++ ++pci:v00001B26d0000C250* ++ ID_MODEL_FROM_DATABASE=NFB-200G2-master ++ ++pci:v00001B26d0000C251* ++ ID_MODEL_FROM_DATABASE=NFB-200G2-slave ++ ++pci:v00001B26d0000C2C0* ++ ID_MODEL_FROM_DATABASE=NFB-100G2-e0 ++ ++pci:v00001B26d0000C2C1* ++ ID_MODEL_FROM_DATABASE=NFB-100G2-e1 ++ ++pci:v00001B26d0000CB20* ++ ID_MODEL_FROM_DATABASE=COMBO-20G ++ ++pci:v00001B26d0000CB40* ++ ID_MODEL_FROM_DATABASE=COMBO-40G ++ ++pci:v00001B26d0000CB80* ++ ID_MODEL_FROM_DATABASE=NFB-40G2 ++ + pci:v00001B2C* + ID_VENDOR_FROM_DATABASE=Opal-RT Technologies Inc. + +@@ -62534,6 +68516,9 @@ pci:v00001B36d0000000C* + pci:v00001B36d0000000D* + ID_MODEL_FROM_DATABASE=QEMU XHCI Host Controller + ++pci:v00001B36d00000010* ++ ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller ++ + pci:v00001B36d00000100* + ID_MODEL_FROM_DATABASE=QXL paravirtual graphic card + +@@ -62582,6 +68567,9 @@ pci:v00001B37d00000020* + pci:v00001B37d00000023* + ID_MODEL_FROM_DATABASE=ADQ7 + ++pci:v00001B37d00000026* ++ ID_MODEL_FROM_DATABASE=ADQ8 ++ + pci:v00001B37d00002014* + ID_MODEL_FROM_DATABASE=TX320 + +@@ -62627,9 +68615,27 @@ pci:v00001B47d00000602* + pci:v00001B4B* + ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. + ++pci:v00001B4Bd00000100* ++ ID_MODEL_FROM_DATABASE=88F3700 [Armada 3700 Family] ARM SoC ++ + pci:v00001B4Bd00000640* + ID_MODEL_FROM_DATABASE=88SE9128 SATA III 6Gb/s RAID Controller + ++pci:v00001B4Bd00002241* ++ ID_MODEL_FROM_DATABASE=88NR2241 Non-Volatile memory controller ++ ++pci:v00001B4Bd00002241sv00001028sd00002112* ++ ID_MODEL_FROM_DATABASE=88NR2241 Non-Volatile memory controller (BOSS-N1 Monolithic) ++ ++pci:v00001B4Bd00002241sv00001028sd00002113* ++ ID_MODEL_FROM_DATABASE=88NR2241 Non-Volatile memory controller (BOSS-N1 Modular) ++ ++pci:v00001B4Bd00002241sv00001D49sd00000306* ++ ID_MODEL_FROM_DATABASE=88NR2241 Non-Volatile memory controller (ThinkSystem M.2 NVMe 2-Bay RAID Enablement Kit) ++ ++pci:v00001B4Bd00002241sv00001D49sd00000307* ++ ID_MODEL_FROM_DATABASE=88NR2241 Non-Volatile memory controller (ThinkSystem 7mm NVMe 2-Bay Rear RAID Enablement Kit) ++ + pci:v00001B4Bd00009120* + ID_MODEL_FROM_DATABASE=88SE9120 SATA 6Gb/s Controller + +@@ -62660,6 +68666,9 @@ pci:v00001B4Bd00009178* + pci:v00001B4Bd0000917A* + ID_MODEL_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller + ++pci:v00001B4Bd00009182* ++ ID_MODEL_FROM_DATABASE=88SE9182 PCIe 2.0 x2 2-port SATA 6 Gb/s Controller ++ + pci:v00001B4Bd00009183* + ID_MODEL_FROM_DATABASE=88SS9183 PCIe SSD Controller + +@@ -62672,23 +68681,44 @@ pci:v00001B4Bd000091A0* + pci:v00001B4Bd000091A4* + ID_MODEL_FROM_DATABASE=88SE912x IDE Controller + ++pci:v00001B4Bd00009215* ++ ID_MODEL_FROM_DATABASE=88SE9215 PCIe 2.0 x1 4-port SATA 6 Gb/s Controller ++ + pci:v00001B4Bd00009220* + ID_MODEL_FROM_DATABASE=88SE9220 PCIe 2.0 x2 2-port SATA 6 Gb/s RAID Controller + + pci:v00001B4Bd00009230* +- ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller + + pci:v00001B4Bd00009230sv00001028sd00001FD6* +- ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller (BOSS-S1 Adapter) ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (BOSS-S1 Adapter) + + pci:v00001B4Bd00009230sv00001028sd00001FDF* +- ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller (BOSS-S1 Modular) ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (BOSS-S1 Modular) + + pci:v00001B4Bd00009230sv00001028sd00001FE2* +- ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller (BOSS-S1 Adapter) ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (BOSS-S1 Adapter) ++ ++pci:v00001B4Bd00009230sv00001028sd00002010* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (BOSS-S2 Adapter) + + pci:v00001B4Bd00009230sv00001D49sd00000300* +- ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller (ThinkSystem M.2 with Mirroring Enablement Kit) ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem M.2 with Mirroring Enablement Kit) ++ ++pci:v00001B4Bd00009230sv00001D49sd00000301* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem SR630 x16 PCIE with 4 SATA ports Riser) ++ ++pci:v00001B4Bd00009230sv00001D49sd00000302* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem SE350 M.2 SATA 4-Bay Data RAID Mirroring Enablement Kit) ++ ++pci:v00001B4Bd00009230sv00001D49sd00000303* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem SE350 M.2 SATA 4-Bay Data RAID Mirroring Enablement Kit) ++ ++pci:v00001B4Bd00009230sv00001D49sd00000304* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem M.2 SATA 2-Bay RAID Enablement Kit) ++ ++pci:v00001B4Bd00009230sv00001D49sd00000305* ++ ID_MODEL_FROM_DATABASE=88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (ThinkSystem 7mm SATA 2-Bay Rear RAID Enablement Kit) + + pci:v00001B4Bd00009235* + ID_MODEL_FROM_DATABASE=88SE9235 PCIe 2.0 x2 4-port SATA 6 Gb/s Controller +@@ -62702,6 +68732,9 @@ pci:v00001B4Bd00009480* + pci:v00001B4Bd00009485* + ID_MODEL_FROM_DATABASE=88SE9485 SAS/SATA 6Gb/s controller + ++pci:v00001B4C* ++ ID_VENDOR_FROM_DATABASE=GALAX ++ + pci:v00001B55* + ID_VENDOR_FROM_DATABASE=NetUP Inc. + +@@ -62735,9 +68768,15 @@ pci:v00001B6F* + pci:v00001B6Fd00007023* + ID_MODEL_FROM_DATABASE=EJ168 USB 3.0 Host Controller + ++pci:v00001B6Fd00007023sv00001458sd00005007* ++ ID_MODEL_FROM_DATABASE=EJ168 USB 3.0 Host Controller (GA-880GMA-USB3) ++ + pci:v00001B6Fd00007052* + ID_MODEL_FROM_DATABASE=EJ188/EJ198 USB 3.0 Host Controller + ++pci:v00001B6Fd00007052sv00001849sd00007052* ++ ID_MODEL_FROM_DATABASE=EJ188/EJ198 USB 3.0 Host Controller (QC5000-ITX/PH) ++ + pci:v00001B73* + ID_VENDOR_FROM_DATABASE=Fresco Logic + +@@ -62753,6 +68792,9 @@ pci:v00001B73d00001009* + pci:v00001B73d00001100* + ID_MODEL_FROM_DATABASE=FL1100 USB 3.0 Host Controller + ++pci:v00001B73d00001100sv000016B8sd00006E31* ++ ID_MODEL_FROM_DATABASE=FL1100 USB 3.0 Host Controller (Allegro Pro USB 3.0 PCIe) ++ + pci:v00001B74* + ID_VENDOR_FROM_DATABASE=OpenVox Communication Co. Ltd. + +@@ -62798,12 +68840,54 @@ pci:v00001B94d0000E400* + pci:v00001B96* + ID_VENDOR_FROM_DATABASE=Western Digital + ++pci:v00001B96d00002200* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN630 NVMe SSD ++ ++pci:v00001B96d00002201* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN630 NVMe SSD ++ ++pci:v00001B96d00002300* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN840 NVMe SSD ++ ++pci:v00001B96d00002400* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN640 NVMe SSD ++ ++pci:v00001B96d00002401* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN640 NVMe SSD ++ ++pci:v00001B96d00002402* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN640 NVMe SSD ++ ++pci:v00001B96d00002404* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN640 NVMe SSD ++ ++pci:v00001B96d00002500* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC SN840 NVMe SSD ++ ++pci:v00001B96d00002600* ++ ID_MODEL_FROM_DATABASE=Ultrastar DC ZN540 ZNS NVMe SSD ++ ++pci:v00001B96d00003714* ++ ID_MODEL_FROM_DATABASE=PC SN730 NVMe SSD ++ ++pci:v00001B96d00003734* ++ ID_MODEL_FROM_DATABASE=PC SN730 NVMe SSD ++ + pci:v00001B9A* + ID_VENDOR_FROM_DATABASE=XAVi Technologies Corp. + ++pci:v00001BAA* ++ ID_VENDOR_FROM_DATABASE=QNAP Systems, Inc. ++ + pci:v00001BAD* + ID_VENDOR_FROM_DATABASE=ReFLEX CES + ++pci:v00001BADd0000C001* ++ ID_MODEL_FROM_DATABASE=XpressGXA10-LP1150 ++ ++pci:v00001BADd0000C002* ++ ID_MODEL_FROM_DATABASE=XpressGXA10-LP1151 ++ + pci:v00001BB0* + ID_VENDOR_FROM_DATABASE=SimpliVity Corporation + +@@ -62852,15 +68936,63 @@ pci:v00001BB1d00000100sv00001BB1sd00000101* + pci:v00001BB1d00000100sv00001BB1sd00000103* + ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5000) + ++pci:v00001BB1d00000100sv00001BB1sd00000105* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5020) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000106* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5020 TCG) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000107* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000108* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 TCG) ++ + pci:v00001BB1d00000100sv00001BB1sd00000121* + ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro XM1440) + + pci:v00001BB1d00000100sv00001BB1sd00000123* + ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5000) + ++pci:v00001BB1d00000100sv00001BB1sd00000125* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5020) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000126* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5020) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000127* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 M.2) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000128* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 M.2 TCG) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000131* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 M.2) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000132* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 M.2 TCG) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000141* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 E1.S) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000142* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5320 E1.S TCG) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000151* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5520) ++ ++pci:v00001BB1d00000100sv00001BB1sd00000152* ++ ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro 5520 TCG) ++ + pci:v00001BB1d00000100sv00001BB1sd000001A1* + ID_MODEL_FROM_DATABASE=Nytro Flash Storage (Nytro XP7102) + ++pci:v00001BB1d00005012* ++ ID_MODEL_FROM_DATABASE=FireCuda 510 SSD ++ ++pci:v00001BB1d00005016* ++ ID_MODEL_FROM_DATABASE=FireCuda 520 SSD ++ + pci:v00001BB3* + ID_VENDOR_FROM_DATABASE=Bluecherry + +@@ -62903,6 +69035,36 @@ pci:v00001BBFd00000003* + pci:v00001BBFd00000004* + ID_MODEL_FROM_DATABASE=MAX4 + ++pci:v00001BC0* ++ ID_VENDOR_FROM_DATABASE=Innodisk Corporation ++ ++pci:v00001BC0d00001001* ++ ID_MODEL_FROM_DATABASE=PCIe 3TG6-P Controller ++ ++pci:v00001BC0d00001002* ++ ID_MODEL_FROM_DATABASE=PCIe 3TE6 Controller ++ ++pci:v00001BC0d00001160* ++ ID_MODEL_FROM_DATABASE=PCIe 3TE2 Controller ++ ++pci:v00001BC0d00001321* ++ ID_MODEL_FROM_DATABASE=PCIe 4TG-P Controller ++ ++pci:v00001BC0d00001322* ++ ID_MODEL_FROM_DATABASE=PCIe 4TE Controller ++ ++pci:v00001BC0d00002262* ++ ID_MODEL_FROM_DATABASE=PCIe 3TG3-P Controller ++ ++pci:v00001BC0d00005208* ++ ID_MODEL_FROM_DATABASE=PCIe 3TE7 Controller ++ ++pci:v00001BC0d00005216* ++ ID_MODEL_FROM_DATABASE=PCIe 3TE8 Controller ++ ++pci:v00001BC0d00005236* ++ ID_MODEL_FROM_DATABASE=PCIe 4TG2-P Controller ++ + pci:v00001BCF* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +@@ -62924,6 +69086,18 @@ pci:v00001BD0d00001004* + pci:v00001BD0d00001005* + ID_MODEL_FROM_DATABASE=PE1000 (Multi-Protocol PCIe/104 Interface Card) + ++pci:v00001BD0d00001006* ++ ID_MODEL_FROM_DATABASE=webCS Wireless Aircraft Communications Server ++ ++pci:v00001BD0d00001007* ++ ID_MODEL_FROM_DATABASE=AB3000 Series Rugged Computer (Series N) ++ ++pci:v00001BD0d00001008* ++ ID_MODEL_FROM_DATABASE=ME1000 mPCIe Avionics Interface Card ++ ++pci:v00001BD0d0000100A* ++ ID_MODEL_FROM_DATABASE=NG1 Series Avionics Converter ++ + pci:v00001BD0d00001101* + ID_MODEL_FROM_DATABASE=OmniBus II PCIe Multi-Protocol Interface Card + +@@ -62933,9 +69107,24 @@ pci:v00001BD0d00001102* + pci:v00001BD0d00001103* + ID_MODEL_FROM_DATABASE=OmniBus II cPCIe/PXIe Multi-Protocol Interface Card + ++pci:v00001BD0d00001200* ++ ID_MODEL_FROM_DATABASE=NG3 Series Mil-Std-1553 Interface ++ ++pci:v00001BD0d00001201* ++ ID_MODEL_FROM_DATABASE=NG3 Series ARINC 429 Interface ++ ++pci:v00001BD0d00001202* ++ ID_MODEL_FROM_DATABASE=NG3 Series Avionics Discrete & Serial Interface ++ ++pci:v00001BD0d00001203* ++ ID_MODEL_FROM_DATABASE=NG3 Series Avionics Discrete Interface ++ + pci:v00001BD4* + ID_VENDOR_FROM_DATABASE=Inspur Electronic Information Industry Co., Ltd. + ++pci:v00001BD4d00000911* ++ ID_MODEL_FROM_DATABASE=Arria10_PCIe_F10A1150 ++ + pci:v00001BEE* + ID_VENDOR_FROM_DATABASE=IXXAT Automation GmbH + +@@ -62954,6 +69143,9 @@ pci:v00001BF4* + pci:v00001BF4d00000001* + ID_MODEL_FROM_DATABASE=SentinelEX + ++pci:v00001BF4d00007011* ++ ID_MODEL_FROM_DATABASE=RX0xxx ++ + pci:v00001BFD* + ID_VENDOR_FROM_DATABASE=EeeTOP + +@@ -62990,12 +69182,42 @@ pci:v00001C09d00004264* + pci:v00001C09d00004265* + ID_MODEL_FROM_DATABASE=10G-PCIE3-8E-2S Network Adapter + ++pci:v00001C09d00005000* ++ ID_MODEL_FROM_DATABASE=25G-PCIE3-8A-2S Security Intelligent Adapter ++ ++pci:v00001C09d00005001* ++ ID_MODEL_FROM_DATABASE=25G-PCIE3-8B-2S Security Intelligent Adapter ++ + pci:v00001C1C* + ID_VENDOR_FROM_DATABASE=Symphony + + pci:v00001C1Cd00000001* + ID_MODEL_FROM_DATABASE=82C101 + ++pci:v00001C1F* ++ ID_VENDOR_FROM_DATABASE=SoftLab-NSK ++ ++pci:v00001C1Fd00000015* ++ ID_MODEL_FROM_DATABASE=FD842 ++ ++pci:v00001C1Fd00000019* ++ ID_MODEL_FROM_DATABASE=FD722 ++ ++pci:v00001C1Fd0000001A* ++ ID_MODEL_FROM_DATABASE=FD788 ++ ++pci:v00001C1Fd0000001B* ++ ID_MODEL_FROM_DATABASE=FD720 ++ ++pci:v00001C1Fd0000001C* ++ ID_MODEL_FROM_DATABASE=FD922 ++ ++pci:v00001C1Fd0000001D* ++ ID_MODEL_FROM_DATABASE=Vega ++ ++pci:v00001C1Fd0000001F* ++ ID_MODEL_FROM_DATABASE=FD940 ++ + pci:v00001C28* + ID_VENDOR_FROM_DATABASE=Lite-On IT Corp. / Plextor + +@@ -63003,7 +69225,7 @@ pci:v00001C28d00000122* + ID_MODEL_FROM_DATABASE=M6e PCI Express SSD [Marvell 88SS9183] + + pci:v00001C2C* +- ID_VENDOR_FROM_DATABASE=Fiberblaze ++ ID_VENDOR_FROM_DATABASE=Silicom Denmark + + pci:v00001C2Cd0000000A* + ID_MODEL_FROM_DATABASE=Capture +@@ -63012,37 +69234,97 @@ pci:v00001C2Cd0000000F* + ID_MODEL_FROM_DATABASE=SmartNIC + + pci:v00001C2Cd000000A0* +- ID_MODEL_FROM_DATABASE=FBC4G Capture 4x1Gb ++ ID_MODEL_FROM_DATABASE=FBC4G Capture 4x1Gb [Herculaneum] + + pci:v00001C2Cd000000A1* +- ID_MODEL_FROM_DATABASE=FBC4XG Capture 4x10Gb ++ ID_MODEL_FROM_DATABASE=FBC4XG Capture 4x10Gb [Ancona] + + pci:v00001C2Cd000000A2* +- ID_MODEL_FROM_DATABASE=FBC8XG Capture 8x10Gb ++ ID_MODEL_FROM_DATABASE=FBC8XG Capture 8x10Gb [Livorno] + + pci:v00001C2Cd000000A3* +- ID_MODEL_FROM_DATABASE=FBC2XG Capture 2x10Gb ++ ID_MODEL_FROM_DATABASE=FBC2XG Capture 2x10Gb [Genoa] + + pci:v00001C2Cd000000A4* +- ID_MODEL_FROM_DATABASE=FBC4XGG3 Capture 4x10Gb ++ ID_MODEL_FROM_DATABASE=FBC4XGG3 Capture 4x10Gb [Livigno] + + pci:v00001C2Cd000000A5* +- ID_MODEL_FROM_DATABASE=FBC2XLG Capture 2x40Gb ++ ID_MODEL_FROM_DATABASE=FBC2XLG Capture 2x40Gb [Livorno] + + pci:v00001C2Cd000000A6* + ID_MODEL_FROM_DATABASE=FBC1CG Capture 1x100Gb + + pci:v00001C2Cd000000A9* +- ID_MODEL_FROM_DATABASE=FBC2XGHH Capture 2x10Gb ++ ID_MODEL_FROM_DATABASE=FBC2XGHH Capture 2x10Gb [Latina] + + pci:v00001C2Cd000000AD* +- ID_MODEL_FROM_DATABASE=FBC2CGG3HL Capture 2x200Gb ++ ID_MODEL_FROM_DATABASE=FBC2CGG3HL Capture 2x100Gb [Padua] + + pci:v00001C2Cd000000AF* + ID_MODEL_FROM_DATABASE=Capture slave device + ++pci:v00001C2Cd000000E0* ++ ID_MODEL_FROM_DATABASE=PacketMover 2x100Gb [Savona] ++ ++pci:v00001C2Cd000000E1* ++ ID_MODEL_FROM_DATABASE=PacketMover 2x100Gb [Tivoli] ++ ++pci:v00001C2Cd000000E3* ++ ID_MODEL_FROM_DATABASE=PacketMover 2x10Gb [Tivoli] ++ ++pci:v00001C2Cd000000E5* ++ ID_MODEL_FROM_DATABASE=PacketMover 2x10Gb [Corfu] ++ ++pci:v00001C2Cd00001000* ++ ID_MODEL_FROM_DATABASE=SmartNIC N5010 4x100Gb ++ ++pci:v00001C2Cd00001001* ++ ID_MODEL_FROM_DATABASE=SmartNIC N5011 w/2xE810 4x100Gb ++ ++pci:v00001C2Cd0000A000* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x40Gb [Mango_02] ++ + pci:v00001C2Cd0000A001* +- ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x200Gb ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x100Gb [Mango_02] ++ ++pci:v00001C2Cd0000A003* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 16x10Gb [Mango] ++ ++pci:v00001C2Cd0000A007* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x40Gb [Mango] ++ ++pci:v00001C2Cd0000A008* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x25Gb [Mango] ++ ++pci:v00001C2Cd0000A009* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 16x10Gb [Mango] ++ ++pci:v00001C2Cd0000A00A* ++ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 8x10Gb [Mango] ++ ++pci:v00001C2Cd0000A00E* ++ ID_MODEL_FROM_DATABASE=FB2CG Capture 2x100Gb [Savona] ++ ++pci:v00001C2Cd0000A00F* ++ ID_MODEL_FROM_DATABASE=FB2CG Capture 2x40Gb [Savona] ++ ++pci:v00001C2Cd0000A010* ++ ID_MODEL_FROM_DATABASE=FB2CGHH Capture 2x40Gb [Tivoli] ++ ++pci:v00001C2Cd0000A011* ++ ID_MODEL_FROM_DATABASE=FB2CG Capture 2x25Gb [Savona] ++ ++pci:v00001C2Cd0000A012* ++ ID_MODEL_FROM_DATABASE=FB2CG Capture 8x10Gb [Savona] ++ ++pci:v00001C2Cd0000A013* ++ ID_MODEL_FROM_DATABASE=FB2CGHH Capture 2x25Gb [Tivoli] ++ ++pci:v00001C2Cd0000A014* ++ ID_MODEL_FROM_DATABASE=FB2CGHH Capture 8x10Gb [Tivoli] ++ ++pci:v00001C2Cd0000A015* ++ ID_MODEL_FROM_DATABASE=FB2CGHH Capture 2x100Gb [Tivoli] + + pci:v00001C32* + ID_VENDOR_FROM_DATABASE=Highland Technology, Inc. +@@ -63086,21 +69368,87 @@ pci:v00001C58d00000003sv00001014sd000004F5* + pci:v00001C58d00000003sv00001014sd000004F6* + ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 3.2TB NVMe Flash Adapter) + ++pci:v00001C58d00000003sv00001C58sd00000003* ++ ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (Ultrastar SN100/SN150 NVMe SSD) ++ + pci:v00001C58d00000023* + ID_MODEL_FROM_DATABASE=Ultrastar SN200 Series NVMe SSD + ++pci:v00001C58d00000023sv00001C58sd00008823* ++ ID_MODEL_FROM_DATABASE=Ultrastar SN200 Series NVMe SSD (Ultrastar Memory (ME200)) ++ + pci:v00001C5C* + ID_VENDOR_FROM_DATABASE=SK hynix + + pci:v00001C5Cd00001283* +- ID_MODEL_FROM_DATABASE=PC300 NVMe Solid State Drive ++ ID_MODEL_FROM_DATABASE=PC300 NVMe Solid State Drive 256GB ++ ++pci:v00001C5Cd00001284* ++ ID_MODEL_FROM_DATABASE=PC300 NVMe Solid State Drive 512GB ++ ++pci:v00001C5Cd00001285* ++ ID_MODEL_FROM_DATABASE=PC300 NVMe Solid State Drive 1TB ++ ++pci:v00001C5Cd00001327* ++ ID_MODEL_FROM_DATABASE=BC501 NVMe Solid State Drive ++ ++pci:v00001C5Cd00001339* ++ ID_MODEL_FROM_DATABASE=BC511 ++ ++pci:v00001C5Cd00001504* ++ ID_MODEL_FROM_DATABASE=SC300 512GB M.2 2280 SATA Solid State Drive ++ ++pci:v00001C5Cd00001527* ++ ID_MODEL_FROM_DATABASE=PC401 NVMe Solid State Drive 256GB ++ ++pci:v00001C5Cd0000243B* ++ ID_MODEL_FROM_DATABASE=PE6110 NVMe Solid State Drive ++ ++pci:v00001C5Cd0000243Bsv00001C5Csd00000100* ++ ID_MODEL_FROM_DATABASE=PE6110 NVMe Solid State Drive ++ ++pci:v00001C5Cd00002839* ++ ID_MODEL_FROM_DATABASE=PE8000 Series NVMe Solid State Drive ++ ++pci:v00001C5Cd00002839sv00001C5Csd00000100* ++ ID_MODEL_FROM_DATABASE=PE8000 Series NVMe Solid State Drive + + pci:v00001C5F* + ID_VENDOR_FROM_DATABASE=Beijing Memblaze Technology Co. Ltd. + ++pci:v00001C5Fd0000000D* ++ ID_MODEL_FROM_DATABASE=PBlaze5 520/526 ++ ++pci:v00001C5Fd0000003D* ++ ID_MODEL_FROM_DATABASE=PBlaze5 920/926 ++ ++pci:v00001C5Fd0000003E* ++ ID_MODEL_FROM_DATABASE=PBlaze6 6920 ++ ++pci:v00001C5Fd0000003Esv00001C5Fsd00000A31* ++ ID_MODEL_FROM_DATABASE=PBlaze6 6920 (NVMe SSD PBlaze6 6920 3840GB 2.5" U.2) ++ ++pci:v00001C5Fd0000003Esv00001C5Fsd00000A41* ++ ID_MODEL_FROM_DATABASE=PBlaze6 6920 (NVMe SSD PBlaze6 6920 7680GB 2.5" U.2) ++ ++pci:v00001C5Fd0000003Esv00001C5Fsd00004A31* ++ ID_MODEL_FROM_DATABASE=PBlaze6 6920 (NVMe SSD PBlaze6 6920 3200GB 2.5" U.2) ++ ++pci:v00001C5Fd0000003Esv00001C5Fsd00004A41* ++ ID_MODEL_FROM_DATABASE=PBlaze6 6920 (NVMe SSD PBlaze6 6920 6400GB 2.5" U.2) ++ + pci:v00001C5Fd00000540* + ID_MODEL_FROM_DATABASE=PBlaze4 NVMe SSD + ++pci:v00001C5Fd00000550* ++ ID_MODEL_FROM_DATABASE=PBlaze5 700/900 ++ ++pci:v00001C5Fd00000555* ++ ID_MODEL_FROM_DATABASE=PBlaze5 510/516 ++ ++pci:v00001C5Fd00000557* ++ ID_MODEL_FROM_DATABASE=PBlaze5 910/916 ++ + pci:v00001C63* + ID_VENDOR_FROM_DATABASE=Science and Research Centre of Computer Technology (JSC "NICEVT") + +@@ -63128,12 +69476,78 @@ pci:v00001C8Ad00000001* + pci:v00001C8C* + ID_VENDOR_FROM_DATABASE=Mobiveil, Inc. + ++pci:v00001CB0* ++ ID_VENDOR_FROM_DATABASE=Shannon Systems ++ ++pci:v00001CB0d00008266* ++ ID_MODEL_FROM_DATABASE=Andalusia Series SSD ++ ++pci:v00001CB0d00008266sv00001CB0sd00002021* ++ ID_MODEL_FROM_DATABASE=Andalusia Series SSD (Andalusia Series OCS U.2 SSD) ++ ++pci:v00001CB0d00008266sv00001CB0sd00002121* ++ ID_MODEL_FROM_DATABASE=Andalusia Series SSD (Andalusia Series ZNS U.2 SSD) ++ ++pci:v00001CB0d00008266sv00001CB0sd00002F21* ++ ID_MODEL_FROM_DATABASE=Andalusia Series SSD (Andalusia Series NVMe U.2 SSD) ++ ++pci:v00001CB0d0000D000* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002010* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-E Series OCS U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002011* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice Series OCS U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002012* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-X Series OCS U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002F10* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-E Series NVMe U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002F11* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice Series NVMe U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd00002F12* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-X Series NVMe U.2) ++ ++pci:v00001CB0d0000D000sv00001CB0sd0000A010* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-E Series OCS AIC) ++ ++pci:v00001CB0d0000D000sv00001CB0sd0000A012* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-X Series OCS AIC) ++ ++pci:v00001CB0d0000D000sv00001CB0sd0000AF10* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-E Series NVMe AIC) ++ ++pci:v00001CB0d0000D000sv00001CB0sd0000AF12* ++ ID_MODEL_FROM_DATABASE=Venice NVMe SSD (Venice-X Series NVMe AIC) ++ + pci:v00001CB1* + ID_VENDOR_FROM_DATABASE=Collion UG & Co.KG + ++pci:v00001CB5* ++ ID_VENDOR_FROM_DATABASE=Focusrite Audio Engineering Ltd ++ ++pci:v00001CB5d00000002* ++ ID_MODEL_FROM_DATABASE=Clarett ++ + pci:v00001CB8* + ID_VENDOR_FROM_DATABASE=Dawning Information Industry Co., Ltd. + ++pci:v00001CC1* ++ ID_VENDOR_FROM_DATABASE=ADATA Technology Co., Ltd. ++ ++pci:v00001CC1d00008201* ++ ID_MODEL_FROM_DATABASE=XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive ++ ++pci:v00001CC4* ++ ID_VENDOR_FROM_DATABASE=Union Memory (Shenzhen) ++ ++pci:v00001CC4d000017AB* ++ ID_MODEL_FROM_DATABASE=NVMe 256G SSD device ++ + pci:v00001CC5* + ID_VENDOR_FROM_DATABASE=Embedded Intelligence, Inc. + +@@ -63173,12 +69587,36 @@ pci:v00001CD2d00000304* + pci:v00001CD2d00000305* + ID_MODEL_FROM_DATABASE=Simulyzer-RT CompactPCI Serial CAN-1 card + ++pci:v00001CD2d00000306* ++ ID_MODEL_FROM_DATABASE=Simulyzer-RT CompactPCI Serial CAN-2 card (CAN-FD) ++ ++pci:v00001CD2d00000307* ++ ID_MODEL_FROM_DATABASE=Simulyzer-RT CompactPCI Serial DIO-2 card [Xilinx Zynq UltraScale+] ++ + pci:v00001CD7* + ID_VENDOR_FROM_DATABASE=Nanjing Magewell Electronics Co., Ltd. + + pci:v00001CD7d00000010* + ID_MODEL_FROM_DATABASE=Pro Capture Endpoint + ++pci:v00001CD7d00000014* ++ ID_MODEL_FROM_DATABASE=PRO CAPTURE AIO 4K PLUS ++ ++pci:v00001CD7d00000017* ++ ID_MODEL_FROM_DATABASE=PRO CAPTURE AIO 4K ++ ++pci:v00001CD7d00000051* ++ ID_MODEL_FROM_DATABASE=Eco Capture Dual HDMI M.2 ++ ++pci:v00001CD7d00000052* ++ ID_MODEL_FROM_DATABASE=Eco Capture HDMI 4K M.2 ++ ++pci:v00001CD7d00000053* ++ ID_MODEL_FROM_DATABASE=Eco Capture Dual SDI M.2 ++ ++pci:v00001CD7d00000054* ++ ID_MODEL_FROM_DATABASE=Eco Capture Quad SDI M.2 ++ + pci:v00001CDD* + ID_VENDOR_FROM_DATABASE=secunet Security Networks AG + +@@ -63209,21 +69647,51 @@ pci:v00001CE4d00000007* + pci:v00001CE4d00000008* + ID_MODEL_FROM_DATABASE=ExaNIC V5P + ++pci:v00001CE4d00000009* ++ ID_MODEL_FROM_DATABASE=ExaNIC X25 ++ ++pci:v00001CE4d0000000A* ++ ID_MODEL_FROM_DATABASE=ExaNIC X100 ++ ++pci:v00001CE4d0000000B* ++ ID_MODEL_FROM_DATABASE=ExaNIC V9P ++ ++pci:v00001CE4d0000000C* ++ ID_MODEL_FROM_DATABASE=ExaNIC V9P-3 ++ ++pci:v00001CE4d00000100* ++ ID_MODEL_FROM_DATABASE=ExaDISK FX1 ++ ++pci:v00001CF0* ++ ID_VENDOR_FROM_DATABASE=Akitio ++ + pci:v00001CF7* + ID_VENDOR_FROM_DATABASE=Subspace Dynamics + + pci:v00001D00* + ID_VENDOR_FROM_DATABASE=Pure Storage + ++pci:v00001D05* ++ ID_VENDOR_FROM_DATABASE=Tongfang Hongkong Limited ++ + pci:v00001D0F* + ID_VENDOR_FROM_DATABASE=Amazon.com, Inc. + ++pci:v00001D0Fd00008061* ++ ID_MODEL_FROM_DATABASE=NVMe EBS Controller ++ + pci:v00001D0Fd0000CD01* + ID_MODEL_FROM_DATABASE=NVMe SSD Controller + + pci:v00001D0Fd0000EC20* + ID_MODEL_FROM_DATABASE=Elastic Network Adapter (ENA) + ++pci:v00001D0Fd0000EFA0* ++ ID_MODEL_FROM_DATABASE=Elastic Fabric Adapter (EFA) ++ ++pci:v00001D0Fd0000EFA1* ++ ID_MODEL_FROM_DATABASE=Elastic Fabric Adapter (EFA) ++ + pci:v00001D17* + ID_VENDOR_FROM_DATABASE=Zhaoxin + +@@ -63252,28 +69720,28 @@ pci:v00001D17d00000716* + ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port + + pci:v00001D17d00000717* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d00000718* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d00000719* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071A* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071B* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071C* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071D* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071E* +- ID_MODEL_FROM_DATABASE=ZX-D PCI Express Root Port ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E PCI Express Root Port + + pci:v00001D17d0000071F* + ID_MODEL_FROM_DATABASE=ZX-200 Upstream Port of PCI Express Switch +@@ -63291,7 +69759,10 @@ pci:v00001D17d00001000* + ID_MODEL_FROM_DATABASE=ZX-D Standard Host Bridge + + pci:v00001D17d00001001* +- ID_MODEL_FROM_DATABASE=ZX-D Miscellaneous Bus ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E Miscellaneous Bus ++ ++pci:v00001D17d00001003* ++ ID_MODEL_FROM_DATABASE=ZX-E Standard Host Bridge + + pci:v00001D17d00003001* + ID_MODEL_FROM_DATABASE=ZX-100 Standard Host Bridge +@@ -63300,10 +69771,10 @@ pci:v00001D17d0000300A* + ID_MODEL_FROM_DATABASE=ZX-100 Miscellaneous Bus + + pci:v00001D17d00003038* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-200 Standard Universal PCI to USB Host Controller ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-200/ZX-E Standard Universal PCI to USB Host Controller + + pci:v00001D17d00003104* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-200 Standard Enhanced PCI to USB Host Controller ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-200/ZX-E Standard Enhanced PCI to USB Host Controller + + pci:v00001D17d000031B0* + ID_MODEL_FROM_DATABASE=ZX-100/ZX-D Standard Host Bridge +@@ -63324,16 +69795,16 @@ pci:v00001D17d000031B5* + ID_MODEL_FROM_DATABASE=ZX-100/ZX-D Scratch Device + + pci:v00001D17d000031B7* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-D Standard Host Bridge ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-D/ZX-E Standard Host Bridge + + pci:v00001D17d000031B8* + ID_MODEL_FROM_DATABASE=ZX-100/ZX-D PCI to PCI Bridge + + pci:v00001D17d00003288* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-D High Definition Audio Controller ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-D/ZX-E High Definition Audio Controller + + pci:v00001D17d0000345B* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-D Miscellaneous Bus ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-D/ZX-E Miscellaneous Bus + + pci:v00001D17d00003A02* + ID_MODEL_FROM_DATABASE=ZX-100 C-320 GPU +@@ -63341,20 +69812,23 @@ pci:v00001D17d00003A02* + pci:v00001D17d00003A03* + ID_MODEL_FROM_DATABASE=ZX-D C-860 GPU + ++pci:v00001D17d00003A04* ++ ID_MODEL_FROM_DATABASE=ZX-E C-960 GPU ++ + pci:v00001D17d00009002* + ID_MODEL_FROM_DATABASE=ZX-100/ZX-200 EIDE Controller + + pci:v00001D17d00009003* +- ID_MODEL_FROM_DATABASE=ZX-100 EIDE Controller ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-E EIDE Controller + + pci:v00001D17d00009045* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-D RAID Accelerator ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-D/ZX-E RAID Accelerator 0 + + pci:v00001D17d00009046* +- ID_MODEL_FROM_DATABASE=ZX-D RAID Accelerator ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E RAID Accelerator 1 + + pci:v00001D17d00009083* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-200 StorX AHCI Controller ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-200/ZX-E StorX AHCI Controller + + pci:v00001D17d00009084* + ID_MODEL_FROM_DATABASE=ZX-100 StorX AHCI Controller +@@ -63371,6 +69845,9 @@ pci:v00001D17d00009141* + pci:v00001D17d00009142* + ID_MODEL_FROM_DATABASE=ZX-D High Definition Audio Controller + ++pci:v00001D17d00009144* ++ ID_MODEL_FROM_DATABASE=ZX-E High Definition Audio Controller ++ + pci:v00001D17d00009180* + ID_MODEL_FROM_DATABASE=ZX-200 Networking Gigabit Ethernet Adapter + +@@ -63380,17 +69857,20 @@ pci:v00001D17d00009202* + pci:v00001D17d00009203* + ID_MODEL_FROM_DATABASE=ZX-200 USB eXtensible Host Controller + ++pci:v00001D17d00009204* ++ ID_MODEL_FROM_DATABASE=ZX-E USB eXtensible Host Controller ++ + pci:v00001D17d00009286* + ID_MODEL_FROM_DATABASE=ZX-D eMMC Host Controller + + pci:v00001D17d00009300* +- ID_MODEL_FROM_DATABASE=ZX-D eSPI Host Controller ++ ID_MODEL_FROM_DATABASE=ZX-D/ZX-E eSPI Host Controller + + pci:v00001D17d000095D0* + ID_MODEL_FROM_DATABASE=ZX-100 Universal SD Host Controller + + pci:v00001D17d0000F410* +- ID_MODEL_FROM_DATABASE=ZX-100/ZX-D PCI Com Port ++ ID_MODEL_FROM_DATABASE=ZX-100/ZX-D/ZX-E PCI Com Port + + pci:v00001D18* + ID_VENDOR_FROM_DATABASE=RME +@@ -63410,6 +69890,12 @@ pci:v00001D1Dd00002807* + pci:v00001D21* + ID_VENDOR_FROM_DATABASE=Allo + ++pci:v00001D22* ++ ID_VENDOR_FROM_DATABASE=Baidu Technology ++ ++pci:v00001D22d00001380* ++ ID_MODEL_FROM_DATABASE=Cloud Storage Device ++ + pci:v00001D26* + ID_VENDOR_FROM_DATABASE=Kalray Inc. + +@@ -63422,9 +69908,27 @@ pci:v00001D26d00000080* + pci:v00001D26d000000C0* + ID_MODEL_FROM_DATABASE=Turbocard3 Accelerator + ++pci:v00001D26d00000140* ++ ID_MODEL_FROM_DATABASE=Open Network Interface Card 40G ++ + pci:v00001D26d0000E004* + ID_MODEL_FROM_DATABASE=AB01/EMB01 Development Board + ++pci:v00001D37* ++ ID_VENDOR_FROM_DATABASE=NovaSparks ++ ++pci:v00001D37d00000013* ++ ID_MODEL_FROM_DATABASE=PM3 ++ ++pci:v00001D37d00000014* ++ ID_MODEL_FROM_DATABASE=PM4 ++ ++pci:v00001D37d00000015* ++ ID_MODEL_FROM_DATABASE=PM4edge ++ ++pci:v00001D37d00000016* ++ ID_MODEL_FROM_DATABASE=PM4edge User Device ++ + pci:v00001D40* + ID_VENDOR_FROM_DATABASE=Techman Electronics (Changshu) Co., Ltd. + +@@ -63461,6 +69965,9 @@ pci:v00001D6A* + pci:v00001D6Ad00000001* + ID_MODEL_FROM_DATABASE=AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + ++pci:v00001D6Ad000000B1* ++ ID_MODEL_FROM_DATABASE=AQC100 10G Ethernet MAC controller [AQtion] ++ + pci:v00001D6Ad000007B1* + ID_MODEL_FROM_DATABASE=AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] + +@@ -63536,6 +70043,48 @@ pci:v00001D6Cd0000100E* + pci:v00001D6Cd0000100Esv00001D6Csd00002001* + ID_MODEL_FROM_DATABASE=AR-ARKA-FX1 [Arkville 64B DPDK Data Mover] (DPDK-Aware Virtual Function [Arkville VF]) + ++pci:v00001D6Cd0000100F* ++ ID_MODEL_FROM_DATABASE=AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal] ++ ++pci:v00001D6Cd00001010* ++ ID_MODEL_FROM_DATABASE=AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex] ++ ++pci:v00001D6Cd00001011* ++ ID_MODEL_FROM_DATABASE=AR-MAN-U50 [Manitou Class Accelerator for U50] ++ ++pci:v00001D6Cd00001012* ++ ID_MODEL_FROM_DATABASE=AR-MAN-U200 [Manitou Class Accelerator for U200] ++ ++pci:v00001D6Cd00001013* ++ ID_MODEL_FROM_DATABASE=AR-MAN-U250 [Manitou Class Accelerator for U250] ++ ++pci:v00001D6Cd00001014* ++ ID_MODEL_FROM_DATABASE=AR-MAN-U280 [Manitou Class Accelerator for U280] ++ ++pci:v00001D6Cd00001015* ++ ID_MODEL_FROM_DATABASE=AR-ARK-BBDEV-FX0 [Arkville 32B DPDK Baseband Device] ++ ++pci:v00001D6Cd00001016* ++ ID_MODEL_FROM_DATABASE=AR-ARK-BBDEV-FX1 [Arkville 64B DPDK Baseband Device] ++ ++pci:v00001D6Cd00001017* ++ ID_MODEL_FROM_DATABASE=AR-ARK-FX1 [Arkville 64B Multi-Homed Primary Endpoint] ++ ++pci:v00001D6Cd00001018* ++ ID_MODEL_FROM_DATABASE=AR-ARK-FX1 [Arkville 64B Multi-Homed Secondary Endpoint] ++ ++pci:v00001D6Cd00001019* ++ ID_MODEL_FROM_DATABASE=AR-ARK-FX1 [Arkville 64B Multi-Homed Tertiary Endpoint] ++ ++pci:v00001D6Cd0000101A* ++ ID_MODEL_FROM_DATABASE=AR-ARK-SRIOV-FX0 [Arkville 32B Primary Physical Function] ++ ++pci:v00001D6Cd0000101B* ++ ID_MODEL_FROM_DATABASE=AR-ARK-SRIOV-FX1 [Arkville 64B Primary Physical Function] ++ ++pci:v00001D6Cd0000101C* ++ ID_MODEL_FROM_DATABASE=AR-ARK-SRIOV-VF [Arkville Virtual Function] ++ + pci:v00001D6Cd00004200* + ID_MODEL_FROM_DATABASE=A5PL-E1-10GETI [10 GbE Ethernet Traffic Instrument] + +@@ -63543,19 +70092,88 @@ pci:v00001D72* + ID_VENDOR_FROM_DATABASE=Xiaomi + + pci:v00001D78* +- ID_VENDOR_FROM_DATABASE=DERA ++ ID_VENDOR_FROM_DATABASE=DERA Storage ++ ++pci:v00001D78d00001512* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller ++ ++pci:v00001D78d00001512sv00001D78sd00002004* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 HHHL 2TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00002006* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 HHHL 4TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00002008* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 HHHL 8TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00002104* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 U.2 2TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00002106* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 U.2 4TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00002108* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5437 U.2 8TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003003* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 HHHL 1.6TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003005* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 HHHL 3.2TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003007* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 HHHL 6.4TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003103* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 U.2 1.6TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003105* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 U.2 3.2TB NVMe SSD) ++ ++pci:v00001D78d00001512sv00001D78sd00003107* ++ ID_MODEL_FROM_DATABASE=TAI NVMe Controller (D5457 U.2 6.4TB NVMe SSD) + + pci:v00001D7C* + ID_VENDOR_FROM_DATABASE=Aerotech, Inc. + ++pci:v00001D7Cd00000001* ++ ID_MODEL_FROM_DATABASE=HyperWire Adapter ++ ++pci:v00001D82* ++ ID_VENDOR_FROM_DATABASE=NETINT Technologies Inc. ++ ++pci:v00001D82d00000101* ++ ID_MODEL_FROM_DATABASE=Codensity D400 SSD ++ ++pci:v00001D82d00000102* ++ ID_MODEL_FROM_DATABASE=Codensity D408 PCIe Gen4 NVMe SSD ++ ++pci:v00001D82d00000202* ++ ID_MODEL_FROM_DATABASE=Codensity T408 Video Encoding-Decoding Accelerator ++ + pci:v00001D87* +- ID_VENDOR_FROM_DATABASE=Fuzhou Rockchip Electronics Co., Ltd ++ ID_VENDOR_FROM_DATABASE=Rockchip Electronics Co., Ltd ++ ++pci:v00001D87d00000100* ++ ID_MODEL_FROM_DATABASE=RK3399 PCI Express Root Port ++ ++pci:v00001D87d00001808* ++ ID_MODEL_FROM_DATABASE=RK1808 Neural Network Processor Card ++ ++pci:v00001D87d00003566* ++ ID_MODEL_FROM_DATABASE=RK3568 Remote Signal Processor + + pci:v00001D8F* + ID_VENDOR_FROM_DATABASE=Enyx + ++pci:v00001D92* ++ ID_VENDOR_FROM_DATABASE=Abaco Systems Inc. ++ ++pci:v00001D93* ++ ID_VENDOR_FROM_DATABASE=YADRO ++ + pci:v00001D94* +- ID_VENDOR_FROM_DATABASE=Chengdu Higon IC Design Co.Ltd ++ ID_VENDOR_FROM_DATABASE=Chengdu Haiguang IC Design Co., Ltd. + + pci:v00001D94d00001450* + ID_MODEL_FROM_DATABASE=Root Complex +@@ -63647,15 +70265,294 @@ pci:v00001D94d0000790E* + pci:v00001D95* + ID_VENDOR_FROM_DATABASE=Graphcore Ltd + ++pci:v00001D95d00000001* ++ ID_MODEL_FROM_DATABASE=Colossus GC2 [C2] ++ ++pci:v00001D95d00000002* ++ ID_MODEL_FROM_DATABASE=Colossus GC1 [S1] ++ ++pci:v00001D97* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Longsys Electronics Co., Ltd. ++ ++pci:v00001D97d00002263* ++ ID_MODEL_FROM_DATABASE=SM2263EN/SM2263XT-based OEM SSD ++ ++pci:v00001D9B* ++ ID_VENDOR_FROM_DATABASE=Facebook, Inc. ++ ++pci:v00001D9Bd00000010* ++ ID_MODEL_FROM_DATABASE=Networking DOM Engine ++ ++pci:v00001D9Bd00000011* ++ ID_MODEL_FROM_DATABASE=IO Bridge ++ + pci:v00001DA1* + ID_VENDOR_FROM_DATABASE=Teko Telecom S.r.l. + + pci:v00001DA2* + ID_VENDOR_FROM_DATABASE=Sapphire Technology Limited + ++pci:v00001DA2d0000E26A* ++ ID_MODEL_FROM_DATABASE=Radeon R7 250 ++ ++pci:v00001DA3* ++ ID_VENDOR_FROM_DATABASE=Habana Labs Ltd. ++ ++pci:v00001DA3d00000001* ++ ID_MODEL_FROM_DATABASE=HL-1000 AI Inference Accelerator [Goya] ++ ++pci:v00001DA3d00001000* ++ ID_MODEL_FROM_DATABASE=HL-2000 AI Training Accelerator [Gaudi] ++ ++pci:v00001DA3d00001010* ++ ID_MODEL_FROM_DATABASE=HL-2000 AI Training Accelerator [Gaudi secured] ++ ++pci:v00001DB2* ++ ID_VENDOR_FROM_DATABASE=ATP ELECTRONICS INC ++ + pci:v00001DBB* + ID_VENDOR_FROM_DATABASE=NGD Systems, Inc. + ++pci:v00001DBF* ++ ID_VENDOR_FROM_DATABASE=Guizhou Huaxintong Semiconductor Technology Co., Ltd ++ ++pci:v00001DBFd00000401* ++ ID_MODEL_FROM_DATABASE=StarDragon4800 PCI Express Root Port ++ ++pci:v00001DC5* ++ ID_VENDOR_FROM_DATABASE=FADU Inc. ++ ++pci:v00001DCD* ++ ID_VENDOR_FROM_DATABASE=Liqid Inc. ++ ++pci:v00001DD8* ++ ID_VENDOR_FROM_DATABASE=Pensando Systems ++ ++pci:v00001DD8d00000002* ++ ID_MODEL_FROM_DATABASE=DSC2 Elba Upstream Port ++ ++pci:v00001DD8d00000002sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC2 Elba Upstream Port (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DD8d00001000* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port ++ ++pci:v00001DD8d00001000sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001000sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001000sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001000sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001000sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Capri Upstream Port (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001001* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port ++ ++pci:v00001DD8d00001001sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001001sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001001sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001001sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001001sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC Virtual Downstream Port (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DD8d00001002* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller ++ ++pci:v00001DD8d00001002sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001002sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001002sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001002sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001002sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DD8d00001003* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF ++ ++pci:v00001DD8d00001003sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001003sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001003sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001003sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001003sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC Ethernet Controller VF (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DD8d00001004* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller ++ ++pci:v00001DD8d00001004sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001004sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001004sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001004sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001004sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC Management Controller (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DD8d00001007* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator ++ ++pci:v00001DD8d00001007sv00001DD8sd00004000* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (Naples 100Gb 2-port QSFP28 x16 8GB) ++ ++pci:v00001DD8d00001007sv00001DD8sd00004001* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (Naples 100Gb 2-port QSFP28 x16 4GB) ++ ++pci:v00001DD8d00001007sv00001DD8sd00004002* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (Naples 25Gb 2-port SFP28 x8 4GB) ++ ++pci:v00001DD8d00001007sv00001DD8sd00004007* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSP DSC-25 Ent 10/25G OCP3 Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd00004008* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSP DSC-25 10/25G 2p SFP28 Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd0000400A* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd0000400C* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd0000400D* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSP DSC-100 Ent 100Gb Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd0000400E* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSC-25 10/25G 2-port 4G RAM 8G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd00004014* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card) ++ ++pci:v00001DD8d00001007sv00001DD8sd00005001* ++ ID_MODEL_FROM_DATABASE=DSC Storage Accelerator (DSC2-200 50/100/200G 2-port 32G RAM 64G eMMC G2 Services Card) ++ ++pci:v00001DE0* ++ ID_VENDOR_FROM_DATABASE=Groq ++ ++pci:v00001DE0d00000000* ++ ID_MODEL_FROM_DATABASE=TSP100 Tensor Streaming Processor ++ + pci:v00001DE1* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd. + +@@ -63663,7 +70560,7 @@ pci:v00001DE1d00000391* + ID_MODEL_FROM_DATABASE=TRM-S1040 [DC-315 / DC-395 series] + + pci:v00001DE1d00002020* +- ID_MODEL_FROM_DATABASE=DC-390 ++ ID_MODEL_FROM_DATABASE=DC-390 Series SCSI Adapter [AMD Am53C974] + + pci:v00001DE1d0000690C* + ID_MODEL_FROM_DATABASE=690c +@@ -63680,32 +70577,179 @@ pci:v00001DE5d00001000* + pci:v00001DE5d00002000* + ID_MODEL_FROM_DATABASE=NoLoad Hardware Development Kit + ++pci:v00001DE5d00003000* ++ ID_MODEL_FROM_DATABASE=eBPF-based PCIe Accelerator ++ ++pci:v00001DEE* ++ ID_VENDOR_FROM_DATABASE=Biwin Storage Technology Co., Ltd. ++ + pci:v00001DEF* + ID_VENDOR_FROM_DATABASE=Ampere Computing, LLC + + pci:v00001DEFd0000E005* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 0 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 0 + + pci:v00001DEFd0000E006* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 1 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 1 + + pci:v00001DEFd0000E007* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 2 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 2 + + pci:v00001DEFd0000E008* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 3 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 3 + + pci:v00001DEFd0000E009* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 4 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 4 + + pci:v00001DEFd0000E00A* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 5 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 5 + + pci:v00001DEFd0000E00B* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 6 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 6 + + pci:v00001DEFd0000E00C* +- ID_MODEL_FROM_DATABASE=Skylark PCI Express Root Port 7 [X-Gene 3] ++ ID_MODEL_FROM_DATABASE=eMAG PCI Express Root Port 7 ++ ++pci:v00001DEFd0000E100* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Complex A ++ ++pci:v00001DEFd0000E101* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a0 ++ ++pci:v00001DEFd0000E102* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a1 ++ ++pci:v00001DEFd0000E103* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a2 ++ ++pci:v00001DEFd0000E104* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a3 ++ ++pci:v00001DEFd0000E105* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a4 ++ ++pci:v00001DEFd0000E106* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a5 ++ ++pci:v00001DEFd0000E107* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a6 ++ ++pci:v00001DEFd0000E108* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port a7 ++ ++pci:v00001DEFd0000E110* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Complex B ++ ++pci:v00001DEFd0000E111* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b0 ++ ++pci:v00001DEFd0000E112* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b1 ++ ++pci:v00001DEFd0000E113* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b2 ++ ++pci:v00001DEFd0000E114* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b3 ++ ++pci:v00001DEFd0000E115* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b4 ++ ++pci:v00001DEFd0000E116* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b5 ++ ++pci:v00001DEFd0000E117* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b6 ++ ++pci:v00001DEFd0000E118* ++ ID_MODEL_FROM_DATABASE=Altra PCI Express Root Port b7 ++ ++pci:v00001DF3* ++ ID_VENDOR_FROM_DATABASE=Ethernity Networks ++ ++pci:v00001DF3d00000201* ++ ID_MODEL_FROM_DATABASE=ACE-NIC40 Programmable Network Accelerator ++ ++pci:v00001DF3d00000201sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC40 Programmable Network Accelerator (ENA1040) ++ ++pci:v00001DF3d00000201sv00001DF3sd00000002* ++ ID_MODEL_FROM_DATABASE=ACE-NIC40 Programmable Network Accelerator (ENA1044) ++ ++pci:v00001DF3d00000201sv00001DF3sd00000003* ++ ID_MODEL_FROM_DATABASE=ACE-NIC40 Programmable Network Accelerator (ENA1044S) ++ ++pci:v00001DF3d00000202* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50 Programmable Network Accelerator ++ ++pci:v00001DF3d00000202sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50 Programmable Network Accelerator (ENA2050F) ++ ++pci:v00001DF3d00000202sv00001DF3sd00000002* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50 Programmable Network Accelerator (ENA2050FS) ++ ++pci:v00001DF3d00000203* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator ++ ++pci:v00001DF3d00000203sv00001DF3sd00000000* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator (Maintenance Mode) ++ ++pci:v00001DF3d00000203sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator (ENA2080F) ++ ++pci:v00001DF3d00000203sv00001DF3sd00000002* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator (ENA2080FS) ++ ++pci:v00001DF3d00000203sv00001DF3sd00000003* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator (ENA2100F) ++ ++pci:v00001DF3d00000203sv00001DF3sd00000004* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100 Programmable Network Accelerator (ENA2040F) ++ ++pci:v00001DF3d00000204* ++ ID_MODEL_FROM_DATABASE=ACE-NIC-NID Programmable Network Accelerator ++ ++pci:v00001DF3d00000204sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC-NID Programmable Network Accelerator (ENA1020Z) ++ ++pci:v00001DF3d00000204sv00001DF3sd00000002* ++ ID_MODEL_FROM_DATABASE=ACE-NIC-NID Programmable Network Accelerator (ENA1020ZS) ++ ++pci:v00001DF3d00000205* ++ ID_MODEL_FROM_DATABASE=ACE-NIC250 Programmable Network Accelerator ++ ++pci:v00001DF3d00000205sv00001DF3sd00000000* ++ ID_MODEL_FROM_DATABASE=ACE-NIC250 Programmable Network Accelerator (Maintenance Mode) ++ ++pci:v00001DF3d00000205sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC250 Programmable Network Accelerator (ENA2250F) ++ ++pci:v00001DF3d00000206* ++ ID_MODEL_FROM_DATABASE=ACE-NIC200 Programmable Network Accelerator ++ ++pci:v00001DF3d00000206sv00001DF3sd00000000* ++ ID_MODEL_FROM_DATABASE=ACE-NIC200 Programmable Network Accelerator (Maintenance Mode) ++ ++pci:v00001DF3d00000206sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC200 Programmable Network Accelerator (ENA2200F) ++ ++pci:v00001DF3d00000207* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50RN Programmable Network Accelerator ++ ++pci:v00001DF3d00000207sv00001DF3sd00000000* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50RN Programmable Network Accelerator (Maintenance Mode) ++ ++pci:v00001DF3d00000207sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC50RN Programmable Network Accelerator (ENA2050RN) ++ ++pci:v00001DF3d00000208* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100RN Programmable Network Accelerator ++ ++pci:v00001DF3d00000208sv00001DF3sd00000000* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100RN Programmable Network Accelerator (Maintenance Mode) ++ ++pci:v00001DF3d00000208sv00001DF3sd00000001* ++ ID_MODEL_FROM_DATABASE=ACE-NIC100RN Programmable Network Accelerator (ENA2100RN) + + pci:v00001DF7* + ID_VENDOR_FROM_DATABASE=opencpi.org +@@ -63725,6 +70769,378 @@ pci:v00001DFC* + pci:v00001DFCd00001181* + ID_MODEL_FROM_DATABASE=TDM 8 Port E1/T1/J1 Adapter + ++pci:v00001E0F* ++ ID_VENDOR_FROM_DATABASE=KIOXIA Corporation ++ ++pci:v00001E0Fd00000007* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 ++ ++pci:v00001E0Fd00000007sv00001028sd00002078* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (DC NVMe CD6 RI 960GB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002079* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (DC NVMe CD6 RI 1.92TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000207A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (DC NVMe CD6 RI 3.84TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000207B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (DC NVMe CD6 RI 7.68TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000207C* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (DC NVMe CD6 RI 15.36TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000207E* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 RI 1.92TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000207F* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 RI 3.84TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002080* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 RI 7.68TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002081* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 RI 15.36TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002084* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 MU 1.6TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002085* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 MU 3.2TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002086* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe CM6 MU 6.4TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 RI 1.92TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 RI 3.84TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210C* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 RI 7.68TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210D* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 RI15.36TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210E* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 MU 1.6TB) ++ ++pci:v00001E0Fd00000007sv00001028sd0000210F* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 MU 3.2TB) ++ ++pci:v00001E0Fd00000007sv00001028sd00002110* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Dell Ent NVMe FIPS CM6 MU 6.4TB) ++ ++pci:v00001E0Fd00000007sv00001E0Fsd00000001* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller Cx6 (Generic NVMe CM6 RI 3.84TB) ++ ++pci:v00001E0Fd00000009* ++ ID_MODEL_FROM_DATABASE=NVMe SSD ++ ++pci:v00001E0Fd00000009sv00001E0Fsd00000001* ++ ID_MODEL_FROM_DATABASE=NVMe SSD (Toshiba RC500 NVMe SSD 500GB) ++ ++pci:v00001E17* ++ ID_VENDOR_FROM_DATABASE=Arnold & Richter Cine Technik GmbH & Co. Betriebs KG ++ ++pci:v00001E24* ++ ID_VENDOR_FROM_DATABASE=Squirrels Research Labs ++ ++pci:v00001E24d00000101* ++ ID_MODEL_FROM_DATABASE=Acorn CLE-101 ++ ++pci:v00001E24d00000215* ++ ID_MODEL_FROM_DATABASE=Acorn CLE-215 ++ ++pci:v00001E24d0000021F* ++ ID_MODEL_FROM_DATABASE=Acorn CLE-215+ ++ ++pci:v00001E24d00001525* ++ ID_MODEL_FROM_DATABASE=Xilinx BCU-1525 ++ ++pci:v00001E24d00001533* ++ ID_MODEL_FROM_DATABASE=ForestKitten 33 ++ ++pci:v00001E24d00001633* ++ ID_MODEL_FROM_DATABASE=JCM33 ++ ++pci:v00001E24d00001635* ++ ID_MODEL_FROM_DATABASE=JCM35 ++ ++pci:v00001E26* ++ ID_VENDOR_FROM_DATABASE=Fujitsu Client Computing Limited ++ ++pci:v00001E36* ++ ID_VENDOR_FROM_DATABASE=Shanghai Enflame Technology Co. Ltd ++ ++pci:v00001E36d00000001* ++ ID_MODEL_FROM_DATABASE=T10 [CloudBlazer] ++ ++pci:v00001E36d00000002* ++ ID_MODEL_FROM_DATABASE=T11 [CloudBlazer] ++ ++pci:v00001E36d00000003* ++ ID_MODEL_FROM_DATABASE=T10(QSFP-DD) [CloudBlazer] ++ ++pci:v00001E36d00008011* ++ ID_MODEL_FROM_DATABASE=I10 [CloudBlazer] ++ ++pci:v00001E36d00008012* ++ ID_MODEL_FROM_DATABASE=I10L [CloudBlazer] ++ ++pci:v00001E38* ++ ID_VENDOR_FROM_DATABASE=Blaize, Inc ++ ++pci:v00001E38d00000102* ++ ID_MODEL_FROM_DATABASE=Xplorer X1600 ++ ++pci:v00001E3B* ++ ID_VENDOR_FROM_DATABASE=Shenzhen DAPU Microelectronics Co., Ltd ++ ++pci:v00001E3Bd00001098* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000001* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.8TB (H2100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000002* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.96TB (H2200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000004* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 1.6TB (H2100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000005* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 1.92TB (H2200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000009* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.8TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000000A* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.96TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000000C* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 1.6TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000000D* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 1.92TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000014* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 3.2TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000015* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 3.84TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000021* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 6.4TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000022* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 7.68TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000052* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.8TB (H3900)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000053* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 1.6TB (H3900)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000059* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD U.2 0.75TB (H3900)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000061* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.8TB (H2100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000062* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.96TB (H2200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000064* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 1.6TB (H2100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000065* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 1.92TB (H2200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000006C* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.8TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000006D* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.96TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000006F* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 1.6TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000070* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 1.92TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000007C* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 3.2TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000007D* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 3.84TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000007F* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 6.4TB (H3100)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000080* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 7.68TB (H3200)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000008A* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.8TB (H3900)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd0000008B* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 1.6TB (H3900)) ++ ++pci:v00001E3Bd00001098sv00001E3Bsd00000091* ++ ID_MODEL_FROM_DATABASE=Haishen NVMe SSD (Enterprise NVMe SSD HHHL 0.75TB (H3900)) ++ ++pci:v00001E3D* ++ ID_VENDOR_FROM_DATABASE=Burlywood, Inc ++ ++pci:v00001E49* ++ ID_VENDOR_FROM_DATABASE=Yangtze Memory Technologies Co.,Ltd ++ ++pci:v00001E49d00001013* ++ ID_MODEL_FROM_DATABASE=PC210 ++ ++pci:v00001E4B* ++ ID_VENDOR_FROM_DATABASE=MAXIO Technology (Hangzhou) Ltd. ++ ++pci:v00001E4Bd00001001* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1001 ++ ++pci:v00001E4Bd00001002* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1002 ++ ++pci:v00001E4Bd00001003* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1003 ++ ++pci:v00001E4Bd00001201* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1201 ++ ++pci:v00001E4Bd00001202* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1202 ++ ++pci:v00001E4Bd00001601* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller MAP1601 ++ ++pci:v00001E4C* ++ ID_VENDOR_FROM_DATABASE=GSI Technology ++ ++pci:v00001E4Cd00000010* ++ ID_MODEL_FROM_DATABASE=APU [Leda] ++ ++pci:v00001E4Cd00000010sv00001E4Csd00000120* ++ ID_MODEL_FROM_DATABASE=APU [Leda] (SE120) ++ ++pci:v00001E57* ++ ID_VENDOR_FROM_DATABASE=Beijing Panyi Technology Co., Ltd ++ ++pci:v00001E57d00000100* ++ ID_MODEL_FROM_DATABASE=The device has already been deleted. ++ ++pci:v00001E57d00000100sv00000000sd00000100* ++ ID_MODEL_FROM_DATABASE=The device has already been deleted. (PY8800 64GB Accelerator) ++ ++pci:v00001E59* ++ ID_VENDOR_FROM_DATABASE=Oxford Nanopore Technologies ++ ++pci:v00001E59d00000001* ++ ID_MODEL_FROM_DATABASE=MinION Mk1C ++ ++pci:v00001E60* ++ ID_VENDOR_FROM_DATABASE=Hailo Technologies Ltd. ++ ++pci:v00001E60d00002864* ++ ID_MODEL_FROM_DATABASE=Hailo-8 AI Processor ++ ++pci:v00001E6B* ++ ID_VENDOR_FROM_DATABASE=Axiado Corp. ++ ++pci:v00001E7B* ++ ID_VENDOR_FROM_DATABASE=Dataland ++ ++pci:v00001E7C* ++ ID_VENDOR_FROM_DATABASE=Brainchip Inc ++ ++pci:v00001E7Cd0000BCA1* ++ ID_MODEL_FROM_DATABASE=AKD1000 Neural Network Coprocessor [Akida] ++ ++pci:v00001E81* ++ ID_VENDOR_FROM_DATABASE=Ramaxel Technology(Shenzhen) Limited ++ ++pci:v00001E85* ++ ID_VENDOR_FROM_DATABASE=Heitec AG ++ ++pci:v00001E89* ++ ID_VENDOR_FROM_DATABASE=ID Quantique SA ++ ++pci:v00001E89d00000002* ++ ID_MODEL_FROM_DATABASE=Quantis-PCIe-40M ++ ++pci:v00001E89d00000003* ++ ID_MODEL_FROM_DATABASE=Quantis-PCIe-240M ++ ++pci:v00001E94* ++ ID_VENDOR_FROM_DATABASE=Calian SED ++ ++pci:v00001E95* ++ ID_VENDOR_FROM_DATABASE=Solid State Storage Technology Corporation ++ ++pci:v00001EA0* ++ ID_VENDOR_FROM_DATABASE=Tencent Technology (Shenzhen) Company Limited ++ ++pci:v00001EA0d00002A16* ++ ID_MODEL_FROM_DATABASE=Cloud Intelligent Inference Controller ++ ++pci:v00001EA7* ++ ID_VENDOR_FROM_DATABASE=Intelliprop, Inc ++ ++pci:v00001EA7d0000223A* ++ ID_MODEL_FROM_DATABASE=Typhon+ PCIe to Gen-Z Bridge ++ ++pci:v00001EAB* ++ ID_VENDOR_FROM_DATABASE=Hefei DATANG Storage Technology Co.,LTD. ++ ++pci:v00001EABd0000300A* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 300A ++ ++pci:v00001EABd0000300B* ++ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 300B ++ ++pci:v00001EAE* ++ ID_VENDOR_FROM_DATABASE=XFX Limited ++ ++pci:v00001EB1* ++ ID_VENDOR_FROM_DATABASE=VeriSilicon Inc ++ ++pci:v00001EB1d00001001* ++ ID_MODEL_FROM_DATABASE=Video Accelerator ++ ++pci:v00001EBD* ++ ID_VENDOR_FROM_DATABASE=EMERGETECH Company Ltd. ++ ++pci:v00001EBDd00000101* ++ ID_MODEL_FROM_DATABASE=Seirios 2063 Video Codec ++ ++pci:v00001ED3* ++ ID_VENDOR_FROM_DATABASE=Yeston ++ ++pci:v00001ED8* ++ ID_VENDOR_FROM_DATABASE=Digiteq Automotive ++ ++pci:v00001ED8d00000101* ++ ID_MODEL_FROM_DATABASE=FG4 PCIe Frame Grabber ++ ++pci:v00001ED9* ++ ID_VENDOR_FROM_DATABASE=Myrtle.ai ++ ++pci:v00001EE9* ++ ID_VENDOR_FROM_DATABASE=SUSE LLC ++ ++pci:v00001EEC* ++ ID_VENDOR_FROM_DATABASE=Viscore Technologies Ltd ++ ++pci:v00001EFB* ++ ID_VENDOR_FROM_DATABASE=Flexxon Pte Ltd ++ + pci:v00001FC0* + ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy + +@@ -63860,6 +71276,9 @@ pci:v00001FC9d00004025sv00001FC9sd00003015* + pci:v00001FC9d00004026* + ID_MODEL_FROM_DATABASE=TN9610 10GbE SFP+ Ethernet Adapter + ++pci:v00001FC9d00004026sv00004C52sd00001000* ++ ID_MODEL_FROM_DATABASE=TN9610 10GbE SFP+ Ethernet Adapter (LREC6860AF 10 Gigabit Ethernet Adapter) ++ + pci:v00001FC9d00004027* + ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter + +@@ -63872,9 +71291,15 @@ pci:v00001FC9d00004027sv00001432sd00008104* + pci:v00001FC9d00004027sv00001546sd00004027* + ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (GE10-PCIE4XG202P 10Gbase-T/NBASE-T Ethernet Adapter) + ++pci:v00001FC9d00004027sv00001BAAsd00003310* ++ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (PCIe Expansion Card) ++ + pci:v00001FC9d00004027sv00001FC9sd00003015* + ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (Ethernet Adapter) + ++pci:v00001FC9d00004027sv00004C52sd00001001* ++ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (LREC6860BT 10 Gigabit Ethernet Adapter) ++ + pci:v00001FC9d00004527* + ID_MODEL_FROM_DATABASE=TN9710Q 5GBase-T/NBASE-T Ethernet Adapter + +@@ -63920,6 +71345,9 @@ pci:v00002003d00008800* + pci:v00002004* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + ++pci:v00002048* ++ ID_VENDOR_FROM_DATABASE=Beijing SpaceControl Technology Co.Ltd ++ + pci:v000020F4* + ID_VENDOR_FROM_DATABASE=TRENDnet + +@@ -63929,6 +71357,12 @@ pci:v00002116* + pci:v000021C3* + ID_VENDOR_FROM_DATABASE=21st Century Computer Corp. + ++pci:v000022B8* ++ ID_VENDOR_FROM_DATABASE=Flex-Logix Technologies ++ ++pci:v000022B8d000022A0* ++ ID_MODEL_FROM_DATABASE=Flex Logix InferX X1 Inference Accelerator ++ + pci:v000022DB* + ID_VENDOR_FROM_DATABASE=Missing Link Electronics, Inc. + +@@ -63944,6 +71378,21 @@ pci:v00002348d00002010* + pci:v00002646* + ID_VENDOR_FROM_DATABASE=Kingston Technology Company, Inc. + ++pci:v00002646d00000010* ++ ID_MODEL_FROM_DATABASE=HyperX Predator PCIe AHCI SSD ++ ++pci:v00002646d00002262* ++ ID_MODEL_FROM_DATABASE=KC2000 NVMe SSD ++ ++pci:v00002646d00002263* ++ ID_MODEL_FROM_DATABASE=A2000 NVMe SSD ++ ++pci:v00002646d00005008* ++ ID_MODEL_FROM_DATABASE=U-SNS8154P3 NVMe SSD ++ ++pci:v00002646d0000500D* ++ ID_MODEL_FROM_DATABASE=OM3PDP3 NVMe SSD ++ + pci:v0000270B* + ID_VENDOR_FROM_DATABASE=Xantel Corporation + +@@ -64080,7 +71529,7 @@ pci:v00003442d00001922* + ID_MODEL_FROM_DATABASE=AS-i 3.0 PCI Master + + pci:v00003475* +- ID_VENDOR_FROM_DATABASE=Arastra Inc. ++ ID_VENDOR_FROM_DATABASE=Arista Networks, Inc. + + pci:v00003513* + ID_VENDOR_FROM_DATABASE=ARCOM Control Systems Ltd +@@ -64238,6 +71687,9 @@ pci:v00003D3Dd000007A1* + pci:v00003D3Dd000007A2* + ID_MODEL_FROM_DATABASE=Sun XVR-500 Graphics Accelerator + ++pci:v00003D3Dd000007A2sv00003D3Dsd00001047* ++ ID_MODEL_FROM_DATABASE=Sun XVR-500 Graphics Accelerator (Sun XVR-600 Graphics Accelerator) ++ + pci:v00003D3Dd000007A3* + ID_MODEL_FROM_DATABASE=Wildcat IV 7210 + +@@ -64428,7 +71880,10 @@ pci:v00004348d00007173* + ID_MODEL_FROM_DATABASE=CH355 PCI Quad Serial Port Controller + + pci:v0000434E* +- ID_VENDOR_FROM_DATABASE=CAST Navigation LLC ++ ID_VENDOR_FROM_DATABASE=Cornelis Networks ++ ++pci:v000043BC* ++ ID_VENDOR_FROM_DATABASE=Tiger Lake-H PCIe Root Port #5 + + pci:v00004444* + ID_VENDOR_FROM_DATABASE=Internext Compression Inc +@@ -65048,6 +72503,9 @@ pci:v00004B10* + pci:v00004C48* + ID_VENDOR_FROM_DATABASE=LUNG HWA Electronics + ++pci:v00004C52* ++ ID_VENDOR_FROM_DATABASE=LR-Link ++ + pci:v00004C53* + ID_VENDOR_FROM_DATABASE=SBS Technologies + +@@ -65102,6 +72560,21 @@ pci:v00004DDC* + pci:v00004DDCd00000100* + ID_MODEL_FROM_DATABASE=DD-42924I5-300 (ARINC 429 Data Bus) + ++pci:v00004DDCd00000300* ++ ID_MODEL_FROM_DATABASE=SB-3620 Motion Feedback Device ++ ++pci:v00004DDCd00000340* ++ ID_MODEL_FROM_DATABASE=SB-3623 Motion Feedback Device ++ ++pci:v00004DDCd00000400* ++ ID_MODEL_FROM_DATABASE=SB-3622 Motion Feedback Device ++ ++pci:v00004DDCd00000500* ++ ID_MODEL_FROM_DATABASE=SB-3621 Motion Feedback Device ++ ++pci:v00004DDCd00000510* ++ ID_MODEL_FROM_DATABASE=SB-3624 Motion Feedback Device ++ + pci:v00004DDCd00000801* + ID_MODEL_FROM_DATABASE=BU-65570I1 MIL-STD-1553 Test and Simulation + +@@ -65150,6 +72623,18 @@ pci:v00004DDCd00000B03* + pci:v00004DDCd00000B04* + ID_MODEL_FROM_DATABASE=BU-65569I4 MIL-STD-1553 Data Bus + ++pci:v00004DDCd00000D01* ++ ID_MODEL_FROM_DATABASE=SB-3641 Motion Feedback Device ++ ++pci:v00004DDCd00000D10* ++ ID_MODEL_FROM_DATABASE=SB-365x Motion Feedback Device ++ ++pci:v00004DDCd00002F00* ++ ID_MODEL_FROM_DATABASE=SB-3642 Motion Feedback Device ++ ++pci:v00004DDCd00003000* ++ ID_MODEL_FROM_DATABASE=SB-3644 Motion Feedback Device ++ + pci:v00005045* + ID_VENDOR_FROM_DATABASE=University of Toronto + +@@ -65646,19 +73131,19 @@ pci:v0000544D* + ID_VENDOR_FROM_DATABASE=TBS Technologies + + pci:v0000544Dd00006178* +- ID_MODEL_FROM_DATABASE=DVB-S2 4 Tuner PCIe Card ++ ID_MODEL_FROM_DATABASE=DVB Tuner PCIe Card + + pci:v0000544Dd00006178sv0000544Dsd00006904* +- ID_MODEL_FROM_DATABASE=DVB-S2 4 Tuner PCIe Card (TBS6904 DVB-S2 Quad Tuner PCIe Card) ++ ID_MODEL_FROM_DATABASE=DVB Tuner PCIe Card (TBS6904 DVB-S2 Quad Tuner PCIe Card) + + pci:v0000544Dd00006178sv0000544Dsd00006905* +- ID_MODEL_FROM_DATABASE=DVB-S2 4 Tuner PCIe Card (TBS6905 DVB-S2 Quad Tuner PCIe Card) ++ ID_MODEL_FROM_DATABASE=DVB Tuner PCIe Card (TBS6905 DVB-S2 Quad Tuner PCIe Card) + + pci:v0000544Dd00006178sv00006205sd00000001* +- ID_MODEL_FROM_DATABASE=DVB-S2 4 Tuner PCIe Card (TBS6205 DVB-T2/T/C Quad TV Tuner PCIe Card) ++ ID_MODEL_FROM_DATABASE=DVB Tuner PCIe Card (TBS6205 DVB-T2/T/C Quad TV Tuner PCIe Card) + + pci:v0000544Dd00006178sv00006209sd00000001* +- ID_MODEL_FROM_DATABASE=DVB-S2 4 Tuner PCIe Card (TBS6209 DVB-T2/C2/T/C/ISDB-T OctaTV Tuner) ++ ID_MODEL_FROM_DATABASE=DVB Tuner PCIe Card (TBS6209 DVB-T2/C2/T/C/ISDB-T OctaTV Tuner) + + pci:v00005452* + ID_VENDOR_FROM_DATABASE=SCANLAB AG +@@ -65667,7 +73152,7 @@ pci:v00005452d00003443* + ID_MODEL_FROM_DATABASE=RTC4 + + pci:v00005455* +- ID_VENDOR_FROM_DATABASE=Technische University Berlin ++ ID_VENDOR_FROM_DATABASE=Technische Universitaet Berlin + + pci:v00005455d00004458* + ID_MODEL_FROM_DATABASE=S5933 +@@ -65738,6 +73223,9 @@ pci:v00005853d0000C110* + pci:v00005853d0000C147* + ID_MODEL_FROM_DATABASE=Virtualized Graphics Device + ++pci:v00005853d0000C200* ++ ID_MODEL_FROM_DATABASE=XCP-ng Project PCI Device for Windows Update ++ + pci:v00005854* + ID_VENDOR_FROM_DATABASE=GoTView + +@@ -66134,6 +73622,9 @@ pci:v00008086d00000100sv00001028sd000004AA* + pci:v00008086d00000100sv00001043sd0000844D* + ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (P8P67/P8H67 Series Motherboard) + ++pci:v00008086d00000100sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (DH61CR motherboard) ++ + pci:v00008086d00000101* + ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port + +@@ -66227,6 +73718,9 @@ pci:v00008086d00000126* + pci:v00008086d00000126sv00001028sd000004CC* + ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (Vostro 3350) + ++pci:v00008086d00000126sv000017AAsd000021CE* ++ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (ThinkPad T420) ++ + pci:v00008086d00000126sv000017AAsd000021CF* + ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (ThinkPad T520) + +@@ -66293,6 +73787,9 @@ pci:v00008086d00000154sv00001043sd00001477* + pci:v00008086d00000154sv00001043sd00001517* + ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (Zenbook Prime UX31A) + ++pci:v00008086d00000154sv000010CFsd000016BF* ++ ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (LIFEBOOK E752) ++ + pci:v00008086d00000155* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port + +@@ -66312,7 +73809,7 @@ pci:v00008086d00000158sv00001043sd0000844D* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller (P8 series motherboard) + + pci:v00008086d00000158sv00008086sd00002010* +- ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller (Server Board S1200BTS) ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller (Server Board S1200BT Family) + + pci:v00008086d00000159* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port +@@ -66350,6 +73847,9 @@ pci:v00008086d00000166sv00001043sd00001517* + pci:v00008086d00000166sv00001043sd00002103* + ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller (N56VZ) + ++pci:v00008086d00000166sv000010CFsd000016C1* ++ ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller (LIFEBOOK E752) ++ + pci:v00008086d0000016A* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +@@ -66362,6 +73862,90 @@ pci:v00008086d00000172* + pci:v00008086d00000176* + ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller + ++pci:v00008086d00000201* ++ ID_MODEL_FROM_DATABASE=Arctic Sound ++ ++pci:v00008086d00000284* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP LPC Premium Controller/eSPI Controller ++ ++pci:v00008086d000002A3* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP SMBus Host Controller ++ ++pci:v00008086d000002A4* ++ ID_MODEL_FROM_DATABASE=Comet Lake SPI (flash) Controller ++ ++pci:v00008086d000002A6* ++ ID_MODEL_FROM_DATABASE=Comet Lake North Peak ++ ++pci:v00008086d000002B0* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #9 ++ ++pci:v00008086d000002B1* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #10 ++ ++pci:v00008086d000002B3* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #12 ++ ++pci:v00008086d000002B4* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #13 ++ ++pci:v00008086d000002B8* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #1 ++ ++pci:v00008086d000002BC* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #5 ++ ++pci:v00008086d000002C5* ++ ID_MODEL_FROM_DATABASE=Comet Lake Serial IO I2C Host Controller ++ ++pci:v00008086d000002C8* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP cAVS ++ ++pci:v00008086d000002D3* ++ ID_MODEL_FROM_DATABASE=Comet Lake SATA AHCI Controller ++ ++pci:v00008086d000002E0* ++ ID_MODEL_FROM_DATABASE=Comet Lake Management Engine Interface ++ ++pci:v00008086d000002E8* ++ ID_MODEL_FROM_DATABASE=Serial IO I2C Host Controller ++ ++pci:v00008086d000002E9* ++ ID_MODEL_FROM_DATABASE=Comet Lake Serial IO I2C Host Controller ++ ++pci:v00008086d000002EA* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP LPSS: I2C Controller #2 ++ ++pci:v00008086d000002ED* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP USB 3.1 xHCI Host Controller ++ ++pci:v00008086d000002EF* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP Shared SRAM ++ ++pci:v00008086d000002F0* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP CNVi WiFi ++ ++pci:v00008086d000002F0sv00008086sd00000034* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP CNVi WiFi (Wireless-AC 9560 160MHz) ++ ++pci:v00008086d000002F0sv00008086sd00000070* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP CNVi WiFi (Wi-Fi 6 AX201 160MHz) ++ ++pci:v00008086d000002F0sv00008086sd00000074* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP CNVi WiFi (Wi-Fi 6 AX201 160MHz) ++ ++pci:v00008086d000002F0sv00008086sd00004070* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP CNVi WiFi (Wi-Fi 6 AX201 160MHz) ++ ++pci:v00008086d000002F5* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-LP SCS3 ++ ++pci:v00008086d000002F9* ++ ID_MODEL_FROM_DATABASE=Comet Lake Thermal Subsytem ++ ++pci:v00008086d000002FC* ++ ID_MODEL_FROM_DATABASE=Comet Lake Integrated Sensor Solution ++ + pci:v00008086d00000309* + ID_MODEL_FROM_DATABASE=80303 I/O Processor PCI-to-PCI Bridge + +@@ -66441,7 +74025,7 @@ pci:v00008086d00000402* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller + + pci:v00008086d00000406* +- ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller ++ ID_MODEL_FROM_DATABASE=Haswell Integrated Graphics Controller + + pci:v00008086d0000040A* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3 Processor Integrated Graphics Controller +@@ -66449,6 +74033,18 @@ pci:v00008086d0000040A* + pci:v00008086d00000412* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller + ++pci:v00008086d00000412sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (Alienware X51 R2) ++ ++pci:v00008086d00000412sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (EliteDesk 800 G1) ++ ++pci:v00008086d00000412sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (ThinkCentre E73) ++ ++pci:v00008086d00000412sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (ThinkCentre M83) ++ + pci:v00008086d00000416* + ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller + +@@ -66581,6 +74177,87 @@ pci:v00008086d00000600sv00008086sd000001F7* + pci:v00008086d0000061F* + ID_MODEL_FROM_DATABASE=80303 I/O Processor + ++pci:v00008086d0000068D* ++ ID_MODEL_FROM_DATABASE=Comet Lake LPC Controller ++ ++pci:v00008086d000006A3* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH SMBus Controller ++ ++pci:v00008086d000006A4* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH SPI Controller ++ ++pci:v00008086d000006A8* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO UART Host Controller #0 ++ ++pci:v00008086d000006A9* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO UART Host Controller #1 ++ ++pci:v00008086d000006AA* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO SPI Controller #0 ++ ++pci:v00008086d000006AB* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO SPI Controller #1 ++ ++pci:v00008086d000006AC* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #21 ++ ++pci:v00008086d000006B0* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #9 ++ ++pci:v00008086d000006BD* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCIe Port #6 ++ ++pci:v00008086d000006C0* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCI Express Root Port #17 ++ ++pci:v00008086d000006C8* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH cAVS ++ ++pci:v00008086d000006D2* ++ ID_MODEL_FROM_DATABASE=Comet Lake SATA AHCI Controller ++ ++pci:v00008086d000006E0* ++ ID_MODEL_FROM_DATABASE=Comet Lake HECI Controller ++ ++pci:v00008086d000006E3* ++ ID_MODEL_FROM_DATABASE=Comet Lake Keyboard and Text (KT) Redirection ++ ++pci:v00008086d000006E8* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO I2C Controller #0 ++ ++pci:v00008086d000006E9* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO I2C Controller #1 ++ ++pci:v00008086d000006EA* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO I2C Controller #2 ++ ++pci:v00008086d000006EB* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO I2C Controller #3 ++ ++pci:v00008086d000006ED* ++ ID_MODEL_FROM_DATABASE=Comet Lake USB 3.1 xHCI Host Controller ++ ++pci:v00008086d000006EF* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Shared SRAM ++ ++pci:v00008086d000006F0* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH CNVi WiFi ++ ++pci:v00008086d000006F0sv00008086sd00000034* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH CNVi WiFi (Wireless-AC 9560) ++ ++pci:v00008086d000006F0sv00008086sd00000074* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH CNVi WiFi (Wi-Fi 6 AX201 160MHz) ++ ++pci:v00008086d000006F0sv00008086sd000002A4* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH CNVi WiFi (Wireless-AC 9462) ++ ++pci:v00008086d000006F9* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Thermal Controller ++ ++pci:v00008086d000006FB* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH Serial IO SPI Controller #2 ++ + pci:v00008086d00000700* + ID_MODEL_FROM_DATABASE=CE Media Processor A/V Bridge + +@@ -67407,37 +75084,241 @@ pci:v00008086d00000A53* + ID_MODEL_FROM_DATABASE=DC P3520 SSD + + pci:v00008086d00000A54* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500/P4600 ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] + + pci:v00008086d00000A54sv00001028sd00001FE1* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500/P4600 (Express Flash NVMe 1TB 2.5" U.2 (P4500)) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 1TB 2.5" U.2 (P4500)) + + pci:v00008086d00000A54sv00001028sd00001FE2* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500/P4600 (Express Flash NVMe 2TB 2.5" U.2 (P4500)) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 2TB 2.5" U.2 (P4500)) + + pci:v00008086d00000A54sv00001028sd00001FE3* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500/P4600 (Express Flash NVMe 4TB 2.5" U.2 (P4500)) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 4TB 2.5" U.2 (P4500)) + + pci:v00008086d00000A54sv00001028sd00001FE4* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4500/P4600 (Express Flash NVMe 4TB HHHL AIC (P4500)) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 4TB HHHL AIC (P4500)) ++ ++pci:v00008086d00000A54sv00001028sd00001FEE* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 1.6TB 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00001028sd00001FEF* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 3.2TB 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00001028sd00001FF0* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 6.4TB 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00001028sd00001FFF* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 8.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001028sd00002003* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 1.0 TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001028sd00002004* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 2.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001028sd00002005* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 4.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv0000108Esd00004870* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe PCIe 3.0 SSD 6.4TB AIC (P4608)) ++ ++pci:v00008086d00000A54sv0000108Esd00004871* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe PCIe 3.0 SSD 6.4TB 2.5-inch (P4600)) ++ ++pci:v00008086d00000A54sv0000108Esd00004879* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe PCIe 3.0 SSD v2 6.4TB AIC (P4618)) ++ ++pci:v00008086d00000A54sv0000108Esd0000487A* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe PCIe 3.0 SSD v2 6.4TB 2.5-inch (P4610)) ++ ++pci:v00008086d00000A54sv00001137sd00000227* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.6TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001137sd00000228* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 2.0TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001137sd00000229* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 3.2TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001137sd0000022B* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001137sd0000022C* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 2.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001137sd0000022D* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 4.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001137sd00000231* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 0.5TB 2.5" U.2 (P4501)) ++ ++pci:v00008086d00000A54sv00001137sd00000232* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.0TB 2.5" U.2 (P4501)) ++ ++pci:v00008086d00000A54sv00001137sd00000233* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 2.0TB 2.5" U.2 (P4501)) ++ ++pci:v00008086d00000A54sv00001137sd00000258* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.6TB 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00001137sd0000025A* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 3.2TB 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00001137sd0000025B* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001137sd0000025C* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 2.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001137sd0000025D* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 4.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001137sd0000025E* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 8.0TB 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00001590sd0000025D* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001590sd0000025E* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 2.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001590sd0000025F* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 4.0TB 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00001590sd00000262* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 1.6TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001590sd00000264* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 3.2TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001590sd00000265* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 6.4TB 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00001590sd0000026C* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] 4.0TB AIC (P4500)) ++ ++pci:v00008086d00000A54sv00001D49sd00004702* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem Intel P4500 NVMe U.2) ++ ++pci:v00008086d00000A54sv00001D49sd00004704* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem Intel P4500 NVMe AIC) ++ ++pci:v00008086d00000A54sv00001D49sd00004712* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem Intel P4600 NVMe U.2) ++ ++pci:v00008086d00000A54sv00001D49sd00004714* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem Intel P4600 NVMe AIC) ++ ++pci:v00008086d00000A54sv00001D49sd00004802* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem U.2 P4510 NVMe SSD) ++ ++pci:v00008086d00000A54sv00001D49sd00004812* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (Thinksystem U.2 P4610 NVMe SSD) ++ ++pci:v00008086d00000A54sv00008086sd00004308* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (SSD D5-P4320 and D5-P4326) ++ ++pci:v00008086d00000A54sv00008086sd00004702* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] SE 2.5" U.2 (P4500)) ++ ++pci:v00008086d00000A54sv00008086sd00004704* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] SE AIC (P4500)) ++ ++pci:v00008086d00000A54sv00008086sd00004712* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] ME 2.5" U.2 (P4600)) ++ ++pci:v00008086d00000A54sv00008086sd00004714* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] ME AIC (P4600)) ++ ++pci:v00008086d00000A54sv00008086sd00004802* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] SE 2.5" U.2 (P4510)) ++ ++pci:v00008086d00000A54sv00008086sd00004804* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] SE AIC (P4510)) ++ ++pci:v00008086d00000A54sv00008086sd00004805* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] SE M.2 (P4511)) ++ ++pci:v00008086d00000A54sv00008086sd00004812* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] ME 2.5" U.2 (P4610)) ++ ++pci:v00008086d00000A54sv00008086sd00004814* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [3DNAND, Beta Rock Controller] (NVMe Datacenter SSD [3DNAND] ME AIC (P4610)) + + pci:v00008086d00000A55* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] + + pci:v00008086d00000A55sv00001028sd00001FE5* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 1.6TB 2.5" U.2 (P4600)) ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 1.6TB 2.5" U.2 (P4600)) + + pci:v00008086d00000A55sv00001028sd00001FE6* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 2TB 2.5" U.2 (P4600)) ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 2TB 2.5" U.2 (P4600)) + + pci:v00008086d00000A55sv00001028sd00001FE7* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 3.2TB 2.5" U.2 (P4600)) ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 3.2TB 2.5" U.2 (P4600)) + + pci:v00008086d00000A55sv00001028sd00001FE8* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 2.0TB HHHL AIC (P4600)) ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 2.0TB HHHL AIC (P4600)) + + pci:v00008086d00000A55sv00001028sd00001FE9* +- ID_MODEL_FROM_DATABASE=Express Flash NVMe P4600 (Express Flash NVMe 4.0TB HHHL AIC (P4600)) ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Beta Rock Controller] (Express Flash NVMe 4.0TB HHHL AIC (P4600)) ++ ++pci:v00008086d00000B26* ++ ID_MODEL_FROM_DATABASE=Thunderbolt 4 Bridge [Goshen Ridge 2020] ++ ++pci:v00008086d00000B27* ++ ID_MODEL_FROM_DATABASE=Thunderbolt 4 USB Controller [Goshen Ridge 2020] ++ ++pci:v00008086d00000B60* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] ++ ++pci:v00008086d00000B60sv00001028sd00002060* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED MU U.2 1.6TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd00002061* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED MU U.2 3.2TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd00002062* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED MU U.2 6.4TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd00002064* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED RI U.2 1.92TB (P5500)) ++ ++pci:v00008086d00000B60sv00001028sd00002065* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED RI U.2 3.84TB (P5500)) ++ ++pci:v00008086d00000B60sv00001028sd00002066* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe SED RI U.2 7.68TB (P5500)) ++ ++pci:v00008086d00000B60sv00001028sd0000209E* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe MU U.2 1.6TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd0000209F* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe MU U.2 3.2TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd00002100* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe MU U.2 6.4TB (P5600)) ++ ++pci:v00008086d00000B60sv00001028sd00002102* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe RI U.2 1.92TB (P5500)) ++ ++pci:v00008086d00000B60sv00001028sd00002103* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe RI U.2 3.84TB (P5500)) ++ ++pci:v00008086d00000B60sv00001028sd00002104* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe RI U.2 7.68TB (P5500)) ++ ++pci:v00008086d00000B60sv00008086sd00008008* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] SE 2.5" U.2 (P5510)) ++ ++pci:v00008086d00000B60sv00008086sd00008D08* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] VE 2.5" U.2 (P5316)) ++ ++pci:v00008086d00000B60sv00008086sd00008D1D* ++ ID_MODEL_FROM_DATABASE=NVMe DC SSD [3DNAND, Sentinel Rock Controller] (NVMe Datacenter SSD [3DNAND] VE E1.L 9.5/18mm (P5316)) ++ ++pci:v00008086d00000BD0* ++ ID_MODEL_FROM_DATABASE=Ponte Vecchio 2T + + pci:v00008086d00000BE0* + ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller +@@ -67520,6 +75401,18 @@ pci:v00008086d00000BF7* + pci:v00008086d00000C00* + ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller + ++pci:v00008086d00000C00sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller (Alienware X51 R2) ++ ++pci:v00008086d00000C00sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller (EliteDesk 800 G1) ++ ++pci:v00008086d00000C00sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller (ThinkCentre E73) ++ ++pci:v00008086d00000C00sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=4th Gen Core Processor DRAM Controller (ThinkCentre M83) ++ + pci:v00008086d00000C01* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor PCI Express x16 Controller + +@@ -67544,9 +75437,15 @@ pci:v00008086d00000C09* + pci:v00008086d00000C0C* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller + ++pci:v00008086d00000C0Csv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (EliteDesk 800 G1) ++ + pci:v00008086d00000C0Csv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (ThinkPad T440p) + ++pci:v00008086d00000C0Csv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (ThinkCentre M83) ++ + pci:v00008086d00000C46* + ID_MODEL_FROM_DATABASE=Atom Processor S1200 PCI Express Root Port 1 + +@@ -67655,6 +75554,15 @@ pci:v00008086d00000C7E* + pci:v00008086d00000C7F* + ID_MODEL_FROM_DATABASE=Atom Processor S1200 Internal + ++pci:v00008086d00000CF8* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ ++pci:v00008086d00000CF8sv00008086sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ ++pci:v00008086d00000CF8sv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ + pci:v00008086d00000D00* + ID_MODEL_FROM_DATABASE=Crystal Well DRAM Controller + +@@ -67682,15 +75590,54 @@ pci:v00008086d00000D26* + pci:v00008086d00000D36* + ID_MODEL_FROM_DATABASE=Crystal Well Integrated Graphics Controller + ++pci:v00008086d00000D4C* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (11) I219-LM ++ ++pci:v00008086d00000D4D* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (11) I219-V ++ ++pci:v00008086d00000D4E* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (10) I219-LM ++ ++pci:v00008086d00000D4F* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (10) I219-V ++ ++pci:v00008086d00000D53* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (12) I219-LM ++ ++pci:v00008086d00000D55* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (12) I219-V ++ ++pci:v00008086d00000D58* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ ++pci:v00008086d00000D58sv00008086sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ ++pci:v00008086d00000D58sv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 Intel(R) FPGA Programmable Acceleration Card N3000 for Networking ++ ++pci:v00008086d00000D9F* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller (2) I225-IT ++ + pci:v00008086d00000E00* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DMI2 + ++pci:v00008086d00000E00sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DMI2 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E00sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DMI2 (X9SRL-F) ++ + pci:v00008086d00000E01* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port in DMI2 Mode + + pci:v00008086d00000E02* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 1a + ++pci:v00008086d00000E02sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 1a (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E03* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 1b + +@@ -67709,6 +75656,9 @@ pci:v00008086d00000E07* + pci:v00008086d00000E08* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3a + ++pci:v00008086d00000E08sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3a (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E09* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3b + +@@ -67745,39 +75695,102 @@ pci:v00008086d00000E1F* + pci:v00008086d00000E20* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0 + ++pci:v00008086d00000E20sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E20sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0 (X9SRL-F) ++ + pci:v00008086d00000E21* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1 + ++pci:v00008086d00000E21sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E21sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1 (X9SRL-F) ++ + pci:v00008086d00000E22* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2 + ++pci:v00008086d00000E22sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E22sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2 (X9SRL-F) ++ + pci:v00008086d00000E23* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3 + ++pci:v00008086d00000E23sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E23sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3 (X9SRL-F) ++ + pci:v00008086d00000E24* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4 + ++pci:v00008086d00000E24sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E24sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4 (X9SRL-F) ++ + pci:v00008086d00000E25* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5 + ++pci:v00008086d00000E25sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E25sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5 (X9SRL-F) ++ + pci:v00008086d00000E26* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6 + ++pci:v00008086d00000E26sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E26sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6 (X9SRL-F) ++ + pci:v00008086d00000E27* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7 + ++pci:v00008086d00000E27sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7 (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E27sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7 (X9SRL-F) ++ + pci:v00008086d00000E28* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 VTd/Memory Map/Misc + ++pci:v00008086d00000E28sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 VTd/Memory Map/Misc (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E28sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 VTd/Memory Map/Misc (X9SRL-F) ++ + pci:v00008086d00000E29* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Memory Hotplug + + pci:v00008086d00000E2A* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO RAS + ++pci:v00008086d00000E2Asv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO RAS (Xeon E5 v2 on PowerEdge R320 server) ++ ++pci:v00008086d00000E2Asv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO RAS (X9SRL-F) ++ + pci:v00008086d00000E2C* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IOAPIC + ++pci:v00008086d00000E2Csv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IOAPIC (X9SRL-F) ++ + pci:v00008086d00000E2E* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 CBDMA + +@@ -67787,6 +75800,9 @@ pci:v00008086d00000E2F* + pci:v00008086d00000E30* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0 + ++pci:v00008086d00000E30sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0 (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E32* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 0 + +@@ -67796,9 +75812,15 @@ pci:v00008086d00000E33* + pci:v00008086d00000E34* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe + ++pci:v00008086d00000E34sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E36* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring + ++pci:v00008086d00000E36sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E37* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring + +@@ -67877,6 +75899,9 @@ pci:v00008086d00000E80* + pci:v00008086d00000E81* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers + ++pci:v00008086d00000E81sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000E83* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 0 + +@@ -67904,6 +75929,9 @@ pci:v00008086d00000E95* + pci:v00008086d00000EA0* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0 + ++pci:v00008086d00000EA0sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0 (Xeon E5 v2 on PowerEdge R320 server) ++ + pci:v00008086d00000EA8* + ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Target Address/Thermal Registers + +@@ -68540,6 +76568,9 @@ pci:v00008086d0000101Esv00001179sd00000001* + pci:v00008086d0000101Esv00008086sd0000101E* + ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection) + ++pci:v00008086d0000101F* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller V710 for 5GBASE-T ++ + pci:v00008086d00001026* + ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller + +@@ -68735,9 +76766,18 @@ pci:v00008086d0000104C* + pci:v00008086d0000104D* + ID_MODEL_FROM_DATABASE=82566MC Gigabit Network Connection + ++pci:v00008086d0000104E* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10 Gigabit SFP+ ++ ++pci:v00008086d0000104F* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10 Gigabit backplane ++ + pci:v00008086d00001050* + ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller + ++pci:v00008086d00001050sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (ThinkCentre S50) ++ + pci:v00008086d00001050sv00001028sd0000019D* + ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (Dimension 3000) + +@@ -69377,6 +77417,9 @@ pci:v00008086d000010D3sv00001093sd000076E9* + pci:v00008086d000010D3sv000010A9sd00008029* + ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Prism XL Single Port Gigabit Ethernet) + ++pci:v00008086d000010D3sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (X8SIL) ++ + pci:v00008086d000010D3sv000015D9sd0000060A* + ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (X7SPA-H/X7SPA-HF Motherboard) + +@@ -69386,6 +77429,9 @@ pci:v00008086d000010D3sv000015D9sd0000060D* + pci:v00008086d000010D3sv00008086sd00000001* + ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Gigabit CT2 Desktop Adapter) + ++pci:v00008086d000010D3sv00008086sd00003578* ++ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Server Board S1200BTLR) ++ + pci:v00008086d000010D3sv00008086sd0000357A* + ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Server Board S1200BTS) + +@@ -69542,6 +77588,9 @@ pci:v00008086d000010F4sv00008086sd0000A06F* + pci:v00008086d000010F5* + ID_MODEL_FROM_DATABASE=82567LM Gigabit Network Connection + ++pci:v00008086d000010F5sv000017AAsd000020EE* ++ ID_MODEL_FROM_DATABASE=82567LM Gigabit Network Connection (ThinkPad T400) ++ + pci:v00008086d000010F6* + ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection + +@@ -69608,6 +77657,9 @@ pci:v00008086d000010FBsv0000108Esd00007B11* + pci:v00008086d000010FBsv00001170sd0000004C* + ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (82599 DP 10G Mezzanine Adapter) + ++pci:v00008086d000010FBsv000015D9sd00000611* ++ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (AOC-STGN-i2S) ++ + pci:v00008086d000010FBsv00001734sd000011A9* + ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (10 Gigabit Dual Port Network Connection) + +@@ -69638,6 +77690,9 @@ pci:v00008086d000010FBsv00001BD4sd0000002F* + pci:v00008086d000010FBsv00001BD4sd00000032* + ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (10G SFP+ DP EP102Fi4 Adapter) + ++pci:v00008086d000010FBsv00001BD4sd00000067* ++ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (F102I82599) ++ + pci:v00008086d000010FBsv00008086sd00000002* + ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-DA2) + +@@ -69716,6 +77771,15 @@ pci:v00008086d00001132sv00008086sd00004541* + pci:v00008086d00001132sv00008086sd00004557* + ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (D815EGEW Mainboard) + ++pci:v00008086d00001136* ++ ID_MODEL_FROM_DATABASE=Thunderbolt 4 Bridge [Maple Ridge 4C 2020] ++ ++pci:v00008086d00001137* ++ ID_MODEL_FROM_DATABASE=Thunderbolt 4 NHI [Maple Ridge 4C 2020] ++ ++pci:v00008086d00001138* ++ ID_MODEL_FROM_DATABASE=Thunderbolt 4 USB Controller [Maple Ridge 4C 2020] ++ + pci:v00008086d00001161* + ID_MODEL_FROM_DATABASE=82806AA PCI64 Hub Advanced Programmable Interrupt Controller + +@@ -70346,6 +78410,18 @@ pci:v00008086d00001240* + pci:v00008086d0000124B* + ID_MODEL_FROM_DATABASE=82380FB (MPCI2) Mobile Docking Controller + ++pci:v00008086d0000124C* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E823-L for backplane ++ ++pci:v00008086d0000124D* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E823-L for SFP ++ ++pci:v00008086d0000124E* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E823-L/X557-AT 10GBASE-T ++ ++pci:v00008086d0000124F* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E823-L 1GbE ++ + pci:v00008086d00001250* + ID_MODEL_FROM_DATABASE=430HX - 82439HX TXC [Triton II] + +@@ -70388,6 +78464,9 @@ pci:v00008086d00001502sv00001028sd000004A3* + pci:v00008086d00001502sv000017AAsd000021CE* + ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (ThinkPad T520) + ++pci:v00008086d00001502sv00008086sd00003578* ++ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Server Board S1200BTLR) ++ + pci:v00008086d00001502sv00008086sd0000357A* + ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Server Board S1200BTS) + +@@ -70397,12 +78476,21 @@ pci:v00008086d00001503* + pci:v00008086d00001503sv00001043sd0000849C* + ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection (P8P67 Deluxe Motherboard) + ++pci:v00008086d00001503sv000010CFsd0000161C* ++ ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection (LIFEBOOK E752) ++ ++pci:v00008086d00001503sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection (DH61CR motherboard) ++ + pci:v00008086d00001507* + ID_MODEL_FROM_DATABASE=Ethernet Express Module X520-P2 + + pci:v00008086d00001508* + ID_MODEL_FROM_DATABASE=82598EB Gigabit BX Network Connection + ++pci:v00008086d00001509* ++ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection ++ + pci:v00008086d0000150A* + ID_MODEL_FROM_DATABASE=82576NS Gigabit Network Connection + +@@ -70490,6 +78578,9 @@ pci:v00008086d0000151C* + pci:v00008086d0000151Csv0000108Esd00007B13* + ID_MODEL_FROM_DATABASE=82599 10 Gigabit TN Network Connection (Dual 10GBASE-T LP) + ++pci:v00008086d0000151D* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E823-L for QSFP ++ + pci:v00008086d00001520* + ID_MODEL_FROM_DATABASE=I350 Ethernet Controller Virtual Function + +@@ -70571,6 +78662,12 @@ pci:v00008086d00001521sv00001093sd0000775B* + pci:v00008086d00001521sv000010A9sd0000802A* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (UV2-BaseIO dual-port GbE) + ++pci:v00008086d00001521sv00001137sd0000023E* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (1GigE I350 LOM) ++ ++pci:v00008086d00001521sv000015D9sd00000000* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (AOC-SGP-i4) ++ + pci:v00008086d00001521sv000015D9sd00000652* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Dual Port i350 GbE MicroLP [AOC-CGP-i2]) + +@@ -70589,30 +78686,48 @@ pci:v00008086d00001521sv0000193Dsd00001005* + pci:v00008086d00001521sv0000193Dsd00001007* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (360T-L) + ++pci:v00008086d00001521sv0000193Dsd00001080* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (NIC-ETH360T-3S-4P) ++ + pci:v00008086d00001521sv00001BD4sd0000001D* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (1G base-T QP EP014Ti1 Adapter) + + pci:v00008086d00001521sv00001BD4sd00000035* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (1G base-T QP EP014Ti1 Adapter) + ++pci:v00008086d00001521sv00001BD4sd00000066* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (F014I350) ++ + pci:v00008086d00001521sv00008086sd00000001* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4) + + pci:v00008086d00001521sv00008086sd00000002* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2) + ++pci:v00008086d00001521sv00008086sd00000003* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Network Adapter I350-T4 for OCP NIC 3.0) ++ + pci:v00008086d00001521sv00008086sd000000A1* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4) + + pci:v00008086d00001521sv00008086sd000000A2* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2) + ++pci:v00008086d00001521sv00008086sd000000A3* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Network Adapter I350-T4 for OCP NIC 3.0) ++ ++pci:v00008086d00001521sv00008086sd000000AA* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Network Adapter I350-T4 for OCP NIC 3.0) ++ + pci:v00008086d00001521sv00008086sd00005001* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4) + + pci:v00008086d00001521sv00008086sd00005002* + ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2) + ++pci:v00008086d00001521sv00008086sd00005003* ++ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1G 4P I350-t OCP) ++ + pci:v00008086d00001522* + ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection + +@@ -70721,6 +78836,9 @@ pci:v00008086d00001528sv00001137sd000000BF* + pci:v00008086d00001528sv00001170sd00000052* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 + ++pci:v00008086d00001528sv000015D9sd00000734* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (AOC-STG-I2T) ++ + pci:v00008086d00001528sv000017AAsd00001073* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (ThinkServer X540-T2 AnyFabric) + +@@ -70772,12 +78890,18 @@ pci:v00008086d0000152F* + pci:v00008086d00001530* + ID_MODEL_FROM_DATABASE=X540 Virtual Function + ++pci:v00008086d00001531* ++ ID_MODEL_FROM_DATABASE=I210 Gigabit Unprogrammed ++ + pci:v00008086d00001533* + ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection + + pci:v00008086d00001533sv0000103Csd00000003* + ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (Ethernet I210-T1 GbE NIC) + ++pci:v00008086d00001533sv00001059sd00000180* ++ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (RD10019 1GbE interface) ++ + pci:v00008086d00001533sv00001093sd00007706* + ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (Compact Vision System Ethernet Adapter) + +@@ -70820,6 +78944,9 @@ pci:v00008086d00001537sv00001059sd00000140* + pci:v00008086d00001537sv00001059sd00000150* + ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (RD-01068 1GbE interface) + ++pci:v00008086d00001537sv00001059sd00000170* ++ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (RD-01213 10GbE interface) ++ + pci:v00008086d00001538* + ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection + +@@ -70832,9 +78959,15 @@ pci:v00008086d0000153A* + pci:v00008086d0000153Asv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (ZBook 15) + ++pci:v00008086d0000153Asv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (EliteDesk 800 G1) ++ + pci:v00008086d0000153Asv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (ThinkPad T440p) + ++pci:v00008086d0000153Asv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (ThinkCentre M83) ++ + pci:v00008086d0000153B* + ID_MODEL_FROM_DATABASE=Ethernet Connection I217-V + +@@ -70928,6 +79061,12 @@ pci:v00008086d00001563sv00001028sd00001FA8* + pci:v00008086d00001563sv00001028sd00001FA9* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet 10G 4P X550 rNDC) + ++pci:v00008086d00001563sv00001137sd000002B2* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (X550-TX 10 Gig LOM) ++ ++pci:v00008086d00001563sv00001137sd000002B3* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (X550-TX 10 Gig LOM) ++ + pci:v00008086d00001563sv00001170sd00000001* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Intel Ethernet Controller X550-T2 OCP card) + +@@ -70952,6 +79091,9 @@ pci:v00008086d00001563sv0000193Dsd00001008* + pci:v00008086d00001563sv0000193Dsd00001009* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (560T-L) + ++pci:v00008086d00001563sv0000193Dsd00001011* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (UN-NIC-ETH563T-sL-2P) ++ + pci:v00008086d00001563sv00008086sd00000001* + ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2) + +@@ -71000,6 +79142,15 @@ pci:v00008086d0000156D* + pci:v00008086d0000156F* + ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM + ++pci:v00008086d0000156Fsv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM (Latitude E7470) ++ ++pci:v00008086d0000156Fsv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM (EliteBook 840 G3) ++ ++pci:v00008086d0000156Fsv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM (ThinkPad T570) ++ + pci:v00008086d00001570* + ID_MODEL_FROM_DATABASE=Ethernet Connection I219-V + +@@ -71054,9 +79205,27 @@ pci:v00008086d00001572sv000017AAsd00004001* + pci:v00008086d00001572sv000017AAsd00004002* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (ThinkServer X710-2 AnyFabric for 10GbE SFP+) + ++pci:v00008086d00001572sv0000193Dsd00001020* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (NIC-ETH561F-sL-4x10G) ++ ++pci:v00008086d00001572sv0000193Dsd00001021* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (NIC-ETH561F-sL-2x10G) ++ ++pci:v00008086d00001572sv0000193Dsd00001081* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (NIC-ETH561F-3S-2P) ++ + pci:v00008086d00001572sv000019E5sd0000D11C* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 2-port X710 10Gb SFP+ Adapter SP330) + ++pci:v00008086d00001572sv00001BD4sd00000042* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (10G SFP+ DP EP102Fi4 Adapter) ++ ++pci:v00008086d00001572sv00001BD4sd00000056* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Network Adapter X710-BM2 for OCP NIC 3.0) ++ ++pci:v00008086d00001572sv00001BD4sd00000065* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (F102IX710) ++ + pci:v00008086d00001572sv00008086sd00000000* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710) + +@@ -71102,6 +79271,27 @@ pci:v00008086d00001572sv00008086sd0000000F* + pci:v00008086d00001572sv00008086sd00000010* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710) + ++pci:v00008086d00001572sv00008086sd00000011* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Network Adapter X710-2 for OCP NIC 3.0) ++ ++pci:v00008086d00001572sv00008086sd00000012* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Network Adapter X710-4 for OCP NIC 3.0) ++ ++pci:v00008086d00001572sv00008086sd00000013* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10G 2P X710 OCP) ++ ++pci:v00008086d00001572sv00008086sd00000014* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10G 4P X710 OCP) ++ ++pci:v00008086d00001572sv00008086sd00000015* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Server Adapter X710-DA2 for OCP) ++ ++pci:v00008086d00001572sv00008086sd000000A1* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Network Adapter X710-2 for OCP NIC 3.0) ++ ++pci:v00008086d00001572sv00008086sd000000A2* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Network Adapter X710-4 for OCP NIC 3.0) ++ + pci:v00008086d00001572sv00008086sd00004005* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ + +@@ -71111,6 +79301,9 @@ pci:v00008086d00001572sv00008086sd00004006* + pci:v00008086d00001572sv00008086sd00004007* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ + ++pci:v00008086d00001574* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 Emulation ++ + pci:v00008086d00001575* + ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 NHI [Alpine Ridge 2C 2015] + +@@ -71126,6 +79319,9 @@ pci:v00008086d00001578* + pci:v00008086d0000157B* + ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection + ++pci:v00008086d0000157Bsv0000EA50sd0000CC10* ++ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (RXi2-BP) ++ + pci:v00008086d0000157C* + ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection + +@@ -71153,12 +79349,18 @@ pci:v00008086d00001581sv00001028sd00001F9E* + pci:v00008086d00001581sv00001059sd00000150* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (RD-01068 10GbE-KR interface) + ++pci:v00008086d00001581sv00001059sd00000170* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (RD-01213 10GbE interface) ++ + pci:v00008086d00001581sv00001590sd00000000* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter) + + pci:v00008086d00001581sv00001590sd000000F8* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter) + ++pci:v00008086d00001581sv0000193Dsd0000100E* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (NIC-ETH561i-Mb-4x10G) ++ + pci:v00008086d00001581sv00008086sd00000000* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet Converged Network Adapter XL710-Q2) + +@@ -71177,6 +79379,9 @@ pci:v00008086d00001583sv0000108Esd00000000* + pci:v00008086d00001583sv0000108Esd00007B1B* + ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (10 Gb/40 Gb Ethernet Adapter) + ++pci:v00008086d00001583sv0000108Esd00007B1D* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (10Gb/40Gb Ethernet Adapter) ++ + pci:v00008086d00001583sv00001137sd00000000* + ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged NIC XL710-QDA2) + +@@ -71249,6 +79454,12 @@ pci:v00008086d00001588sv0000103Csd00000000* + pci:v00008086d00001588sv0000103Csd000022FF* + ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660M Adapter) + ++pci:v00008086d00001588sv00001137sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet Network Adapter XXV710) ++ ++pci:v00008086d00001588sv00001137sd000002B4* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet Network Adapter XXV710 OCP 2.0) ++ + pci:v00008086d00001589* + ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T + +@@ -71279,12 +79490,60 @@ pci:v00008086d00001589sv00008086sd00001003* + pci:v00008086d0000158A* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE backplane + ++pci:v00008086d0000158Asv00001590sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE backplane (10/25Gb Ethernet Adapter) ++ ++pci:v00008086d0000158Asv00001590sd00000286* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE backplane (Synergy 4610C 10/25Gb Ethernet Adapter) ++ ++pci:v00008086d0000158Asv00008086sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE backplane ++ + pci:v00008086d0000158Asv00008086sd0000000A* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE backplane (Ethernet 25G 2P XXV710 Mezz) + + pci:v00008086d0000158B* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 + ++pci:v00008086d0000158Bsv00001137sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710) ++ ++pci:v00008086d0000158Bsv00001137sd00000225* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710) ++ ++pci:v00008086d0000158Bsv00001137sd000002B4* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710 OCP 2.0) ++ ++pci:v00008086d0000158Bsv00001374sd00000230* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Single Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G1I71)) ++ ++pci:v00008086d0000158Bsv00001374sd00000231* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Single Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G1I71EU)) ++ ++pci:v00008086d0000158Bsv00001374sd00000234* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Dual Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G2I71)) ++ ++pci:v00008086d0000158Bsv00001374sd00000235* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Dual Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G2I71EU)) ++ ++pci:v00008086d0000158Bsv00001374sd00000238* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G4I71L)) ++ ++pci:v00008086d0000158Bsv00001374sd00000239* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE325G4I71LEU)) ++ ++pci:v00008086d0000158Bsv00001374sd0000023A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE31625G4I71L)) ++ ++pci:v00008086d0000158Bsv00001374sd0000023B* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Quad Port 25 Gigabit Ethernet PCI Express Server Adapter (PE31625G4I71LEU)) ++ ++pci:v00008086d0000158Bsv00001590sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710-2) ++ ++pci:v00008086d0000158Bsv00001590sd00000253* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet 10/25/Gb 2-port 661SFP28 Adapter) ++ + pci:v00008086d0000158Bsv00008086sd00000000* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710) + +@@ -71315,9 +79574,126 @@ pci:v00008086d0000158Bsv00008086sd00000008* + pci:v00008086d0000158Bsv00008086sd00000009* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet 25G 2P XXV710 Adapter) + ++pci:v00008086d0000158Bsv00008086sd0000000A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet 25G 2P XXV710 OCP) ++ + pci:v00008086d0000158Bsv00008086sd00004001* + ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710-2) + ++pci:v00008086d00001591* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for backplane ++ ++pci:v00008086d00001592* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP ++ ++pci:v00008086d00001592sv00001137sd000002BF* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (E810CQDA2 2x100 GbE QSFP28 PCIe NIC) ++ ++pci:v00008086d00001592sv0000193Dsd00001050* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (NIC-ETH1060F-LP-2P 2x100GbE Ethernet PCIe Card) ++ ++pci:v00008086d00001592sv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q1) ++ ++pci:v00008086d00001592sv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q2) ++ ++pci:v00008086d00001592sv00008086sd00000004* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q2) ++ ++pci:v00008086d00001592sv00008086sd00000005* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q1 for OCP3.0) ++ ++pci:v00008086d00001592sv00008086sd00000006* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q2 for OCP3.0) ++ ++pci:v00008086d00001592sv00008086sd00000009* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q1) ++ ++pci:v00008086d00001592sv00008086sd0000000A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-C-Q1 for OCP) ++ ++pci:v00008086d00001592sv00008086sd0000000B* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet 100G 2P E810-C Adapter) ++ ++pci:v00008086d00001592sv00008086sd0000000C* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet 100G 2P E810-C OCP) ++ ++pci:v00008086d00001592sv00008086sd0000000D* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-L-Q2 for OCP 3.0) ++ ++pci:v00008086d00001592sv00008086sd0000000E* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for QSFP (Ethernet Network Adapter E810-2C-Q2) ++ ++pci:v00008086d00001593* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP ++ ++pci:v00008086d00001593sv00001137sd000002C3* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (E810XXVDA4 4x25/10 GbE SFP28 PCIe NIC) ++ ++pci:v00008086d00001593sv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-L-2) ++ ++pci:v00008086d00001593sv00008086sd00000005* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-4) ++ ++pci:v00008086d00001593sv00008086sd00000006* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-4) ++ ++pci:v00008086d00001593sv00008086sd00000007* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-4) ++ ++pci:v00008086d00001593sv00008086sd00000008* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-2) ++ ++pci:v00008086d00001593sv00008086sd00000009* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-2 for OCP 2.0) ++ ++pci:v00008086d00001593sv00008086sd0000000A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet 25G 4P E810-XXV Adapter) ++ ++pci:v00008086d00001593sv00008086sd0000000C* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-C for SFP (Ethernet Network Adapter E810-XXV-4 for OCP 3.0) ++ ++pci:v00008086d00001599* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for backplane ++ ++pci:v00008086d0000159A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for QSFP ++ ++pci:v00008086d0000159B* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP ++ ++pci:v00008086d0000159Bsv00001137sd000002BE* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (E810XXVDA2 2x25/10 GbE SFP28 PCIe NIC) ++ ++pci:v00008086d0000159Bsv00001BD4sd00000057* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXVAM2) ++ ++pci:v00008086d0000159Bsv00001BD4sd00000058* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXVAM2 for OCP 3.0) ++ ++pci:v00008086d0000159Bsv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet 25G 2P E810-XXV OCP) ++ ++pci:v00008086d0000159Bsv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet 25G 2P E810-XXV Adapter) ++ ++pci:v00008086d0000159Bsv00008086sd00000003* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXV-2) ++ ++pci:v00008086d0000159Bsv00008086sd00000005* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXV-2 for OCP 3.0) ++ ++pci:v00008086d0000159Bsv00008086sd00004001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXV-2) ++ ++pci:v00008086d0000159Bsv00008086sd00004002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXV-2 for OCP 3.0) ++ ++pci:v00008086d0000159Bsv00008086sd00004003* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller E810-XXV for SFP (Ethernet Network Adapter E810-XXV-2) ++ + pci:v00008086d000015A0* + ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-LM + +@@ -71348,12 +79724,15 @@ pci:v00008086d000015AA* + pci:v00008086d000015AAsv00001059sd00000120* + ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (T4008 10GbE interface) + +-pci:v00008086d000015AAsv00001059sd00000150* +- ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (RD-01068 10GbE interface) +- + pci:v00008086d000015AB* + ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane + ++pci:v00008086d000015ABsv00001059sd00000150* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (RD-01068 10GbE interface) ++ ++pci:v00008086d000015ABsv00001059sd00000170* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (RD-01213 10GbE interface) ++ + pci:v00008086d000015AC* + ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE SFP+ + +@@ -71384,6 +79763,9 @@ pci:v00008086d000015B7* + pci:v00008086d000015B8* + ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I219-V + ++pci:v00008086d000015B8sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I219-V (H270 PC MATE) ++ + pci:v00008086d000015B9* + ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I219-LM + +@@ -71405,6 +79787,9 @@ pci:v00008086d000015BF* + pci:v00008086d000015C0* + ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 Bridge (Low Power) [Alpine Ridge LP 2016] + ++pci:v00008086d000015C1* ++ ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 USB 3.1 Controller (Low Power) [Alpine Ridge LP 2016] ++ + pci:v00008086d000015C2* + ID_MODEL_FROM_DATABASE=Ethernet Connection X553 Backplane + +@@ -71466,7 +79851,7 @@ pci:v00008086d000015D5* + ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2 + + pci:v00008086d000015D5sv00008086sd00000001* +- ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2 (Intel(R) Ethernet SDI Adapter FM10420-25GbE-DA2) ++ ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2 + + pci:v00008086d000015D6* + ID_MODEL_FROM_DATABASE=Ethernet Connection (5) I219-V +@@ -71483,12 +79868,18 @@ pci:v00008086d000015D8sv000017AAsd00002247* + pci:v00008086d000015D8sv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d000015D8sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V (ThinkPad T480) ++ + pci:v00008086d000015D9* + ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 NHI (C step) [Alpine Ridge 2C 2016] + + pci:v00008086d000015DA* + ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 Bridge (C step) [Alpine Ridge 2C 2016] + ++pci:v00008086d000015DB* ++ ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 USB 3.1 Controller (C step) [Alpine Ridge 2C 2016] ++ + pci:v00008086d000015DF* + ID_MODEL_FROM_DATABASE=Ethernet Connection (8) I219-LM + +@@ -71534,6 +79925,105 @@ pci:v00008086d000015EF* + pci:v00008086d000015F0* + ID_MODEL_FROM_DATABASE=JHL7540 Thunderbolt 3 USB Controller [Titan Ridge DD 2018] + ++pci:v00008086d000015F2* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I225-LM ++ ++pci:v00008086d000015F2sv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I225-LM (Ethernet Network Adapter I225-T1) ++ ++pci:v00008086d000015F2sv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I225-LM (Ethernet Network Adapter I225-T1) ++ ++pci:v00008086d000015F3* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I225-V ++ ++pci:v00008086d000015F3sv00008086sd00000003* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I225-V (Intel(R) Ethernet Controller (3) I225-V) ++ ++pci:v00008086d000015F4* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (15) I219-LM ++ ++pci:v00008086d000015F5* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (15) I219-V ++ ++pci:v00008086d000015F6* ++ ID_MODEL_FROM_DATABASE=I210 Gigabit Ethernet Connection ++ ++pci:v00008086d000015F9* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (14) I219-LM ++ ++pci:v00008086d000015FA* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (14) I219-V ++ ++pci:v00008086d000015FB* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (13) I219-LM ++ ++pci:v00008086d000015FC* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (13) I219-V ++ ++pci:v00008086d000015FF* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T ++ ++pci:v00008086d000015FFsv00001137sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (X710TLG GbE RJ45 PCIe NIC) ++ ++pci:v00008086d000015FFsv00001137sd000002C1* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (X710T2LG 2x10 GbE RJ45 PCIe NIC) ++ ++pci:v00008086d000015FFsv00001137sd000002C2* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (X710T4LG 4x10 GbE RJ45 PCIe NIC) ++ ++pci:v00008086d000015FFsv00001137sd000002D9* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L OCP 3.0) ++ ++pci:v00008086d000015FFsv00001137sd000002DA* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L OCP 3.0) ++ ++pci:v00008086d000015FFsv0000193Dsd00001082* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (NIC-ETH565T-3S-2P) ++ ++pci:v00008086d000015FFsv00008086sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-TL) ++ ++pci:v00008086d000015FFsv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L) ++ ++pci:v00008086d000015FFsv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L) ++ ++pci:v00008086d000015FFsv00008086sd00000003* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L) ++ ++pci:v00008086d000015FFsv00008086sd00000004* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L) ++ ++pci:v00008086d000015FFsv00008086sd00000005* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet 10G 2P X710-T2L-t Adapter) ++ ++pci:v00008086d000015FFsv00008086sd00000006* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet 10G 4P X710-T4L-t Adapter) ++ ++pci:v00008086d000015FFsv00008086sd00000007* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet 10G 2P X710-T2L-t OCP) ++ ++pci:v00008086d000015FFsv00008086sd00000008* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet 10G 4P X710-T4L-t OCP) ++ ++pci:v00008086d000015FFsv00008086sd00000009* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L for OCP 3.0) ++ ++pci:v00008086d000015FFsv00008086sd0000000A* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T4L for OCP 3.0) ++ ++pci:v00008086d000015FFsv00008086sd0000000B* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L for OCP 3.0) ++ ++pci:v00008086d000015FFsv00008086sd0000000C* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L for OCP 3.0) ++ ++pci:v00008086d000015FFsv00008086sd0000000F* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GBASE-T (Ethernet Network Adapter X710-T2L for OCP 3.0) ++ + pci:v00008086d00001600* + ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI + +@@ -71651,11 +80141,50 @@ pci:v00008086d0000163E* + pci:v00008086d00001889* + ID_MODEL_FROM_DATABASE=Ethernet Adaptive Virtual Function + ++pci:v00008086d00001890* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-C for backplane ++ ++pci:v00008086d00001891* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-C for QSFP ++ ++pci:v00008086d00001892* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-C for SFP ++ ++pci:v00008086d00001893* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-C/X557-AT 10GBASE-T ++ ++pci:v00008086d00001894* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-C 1GbE ++ ++pci:v00008086d00001897* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-L for backplane ++ ++pci:v00008086d00001898* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-L for SFP ++ ++pci:v00008086d00001899* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-L/X557-AT 10GBASE-T ++ ++pci:v00008086d0000189A* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection E822-L 1GbE ++ ++pci:v00008086d000018A0* ++ ID_MODEL_FROM_DATABASE=C4xxx Series QAT ++ ++pci:v00008086d000018A1* ++ ID_MODEL_FROM_DATABASE=C4XXX Series QAT Virtual Function ++ ++pci:v00008086d000018EE* ++ ID_MODEL_FROM_DATABASE=200xx Series QAT ++ ++pci:v00008086d000018EF* ++ ID_MODEL_FROM_DATABASE=200xx Series QAT Virtual Function ++ + pci:v00008086d00001900* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + + pci:v00008086d00001901* +- ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x16) ++ ID_MODEL_FROM_DATABASE=6th-10th Gen Core Processor PCIe Controller (x16) + + pci:v00008086d00001902* + ID_MODEL_FROM_DATABASE=HD Graphics 510 +@@ -71663,12 +80192,39 @@ pci:v00008086d00001902* + pci:v00008086d00001903* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem + ++pci:v00008086d00001903sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (Latitude 7275 tablet) ++ ++pci:v00008086d00001903sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (Latitude E7470) ++ ++pci:v00008086d00001903sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (XPS 15 9550) ++ ++pci:v00008086d00001903sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (Latitude 11 5175 2-in-1) ++ ++pci:v00008086d00001903sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (OMEN-17-w001nv) ++ ++pci:v00008086d00001903sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Thermal Subsystem (ThinkPad T480) ++ + pci:v00008086d00001904* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00001904sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (Latitude E7470) ++ + pci:v00008086d00001904sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (Latitude 3570) + ++pci:v00008086d00001904sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (EliteBook 840 G3) ++ ++pci:v00008086d00001904sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad T570) ++ + pci:v00008086d00001904sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (B51-80 Laptop) + +@@ -71690,20 +80246,41 @@ pci:v00008086d00001909* + pci:v00008086d0000190C* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d0000190Csv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (Latitude 7275 tablet) ++ ++pci:v00008086d0000190Csv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (Latitude 11 5175 2-in-1) ++ + pci:v00008086d0000190F* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + + pci:v00008086d00001910* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00001910sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (XPS 15 9550) ++ ++pci:v00008086d00001910sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (OMEN-17-w001nv) ++ + pci:v00008086d00001911* +- ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th Gen Core Processor Gaussian Mixture Model ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model ++ ++pci:v00008086d00001911sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model (Vostro 3470) ++ ++pci:v00008086d00001911sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model (H270 PC MATE) + + pci:v00008086d00001911sv000017AAsd00002247* +- ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th Gen Core Processor Gaussian Mixture Model (ThinkPad T570) ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model (ThinkPad T570) + + pci:v00008086d00001911sv000017AAsd0000224F* +- ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th Gen Core Processor Gaussian Mixture Model (ThinkPad X1 Carbon 5th Gen) ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model (ThinkPad X1 Carbon 5th Gen) ++ ++pci:v00008086d00001911sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model (ThinkPad T480) + + pci:v00008086d00001912* + ID_MODEL_FROM_DATABASE=HD Graphics 530 +@@ -71711,24 +80288,51 @@ pci:v00008086d00001912* + pci:v00008086d00001916* + ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] + ++pci:v00008086d00001916sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] (Latitude E7470) ++ + pci:v00008086d00001916sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] (Latitude 3570) + ++pci:v00008086d00001916sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] (EliteBook 840 G3) ++ ++pci:v00008086d00001916sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Skylake GT2 [HD Graphics 520] (ThinkPad T570) ++ + pci:v00008086d00001918* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + + pci:v00008086d00001919* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Imaging Unit + ++pci:v00008086d00001919sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Imaging Unit (Latitude 7275 tablet) ++ ++pci:v00008086d00001919sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Imaging Unit (Latitude 11 5175 2-in-1) ++ + pci:v00008086d0000191B* + ID_MODEL_FROM_DATABASE=HD Graphics 530 + ++pci:v00008086d0000191Bsv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=HD Graphics 530 (XPS 15 9550) ++ ++pci:v00008086d0000191Bsv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=HD Graphics 530 (OMEN-17-w001nv) ++ + pci:v00008086d0000191D* + ID_MODEL_FROM_DATABASE=HD Graphics P530 + + pci:v00008086d0000191E* + ID_MODEL_FROM_DATABASE=HD Graphics 515 + ++pci:v00008086d0000191Esv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=HD Graphics 515 (Latitude 7275 tablet) ++ ++pci:v00008086d0000191Esv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=HD Graphics 515 (Latitude 11 5175 2-in-1) ++ + pci:v00008086d0000191F* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers + +@@ -71840,6 +80444,45 @@ pci:v00008086d00001962* + pci:v00008086d00001962sv0000105Asd00000000* + ID_MODEL_FROM_DATABASE=80960RM (i960RM) Microprocessor (SuperTrak SX6000 I2O CPU) + ++pci:v00008086d00001964* ++ ID_MODEL_FROM_DATABASE=80960RN (i960RN) Microprocessor ++ ++pci:v00008086d00001980* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series System Agent ++ ++pci:v00008086d000019A1* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Error Registers ++ ++pci:v00008086d000019A2* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Root Complex Event Collector ++ ++pci:v00008086d000019A3* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Integrated QAT Root Port ++ ++pci:v00008086d000019A4* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #0 ++ ++pci:v00008086d000019A5* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #1 ++ ++pci:v00008086d000019A6* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #2 ++ ++pci:v00008086d000019A7* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #3 ++ ++pci:v00008086d000019A8* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #4 ++ ++pci:v00008086d000019A9* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #5 ++ ++pci:v00008086d000019AA* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #6 ++ ++pci:v00008086d000019AB* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series PCI Express Root Port #7 ++ + pci:v00008086d000019AC* + ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series SMBus Contoller - Host + +@@ -71906,9 +80549,36 @@ pci:v00008086d000019CF* + pci:v00008086d000019D0* + ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series USB 3.0 xHCI Controller + ++pci:v00008086d000019D1* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Integrated LAN Root Port #0 ++ ++pci:v00008086d000019D2* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Integrated LAN Root Port #1 ++ ++pci:v00008086d000019D3* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series ME HECI 1 ++ ++pci:v00008086d000019D4* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series ME HECI 2 ++ ++pci:v00008086d000019D5* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series ME KT Controller ++ ++pci:v00008086d000019D6* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series ME HECI 3 ++ ++pci:v00008086d000019D8* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series HSUART Controller ++ + pci:v00008086d000019DC* + ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series LPC or eSPI + ++pci:v00008086d000019DD* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Primary to Side Band (P2SB) Bridge ++ ++pci:v00008086d000019DE* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series Power Management Controller ++ + pci:v00008086d000019DF* + ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series SMBus controller + +@@ -71918,6 +80588,21 @@ pci:v00008086d000019E0* + pci:v00008086d000019E2* + ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series QuickAssist Technology + ++pci:v00008086d000019E3* ++ ID_MODEL_FROM_DATABASE=Atom Processor C3000 Series QuickAssist Technology Virtual Function ++ ++pci:v00008086d00001A1C* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (17) I219-LM ++ ++pci:v00008086d00001A1D* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (17) I219-V ++ ++pci:v00008086d00001A1E* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (16) I219-LM ++ ++pci:v00008086d00001A1F* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection (16) I219-V ++ + pci:v00008086d00001A21* + ID_MODEL_FROM_DATABASE=82840 840 [Carmel] Chipset Host Bridge (Hub A) + +@@ -71984,8 +80669,11 @@ pci:v00008086d00001C02sv00001028sd000004AA* + pci:v00008086d00001C02sv00001043sd0000844D* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (P8 series motherboard) + ++pci:v00008086d00001C02sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (DH61CR motherboard) ++ + pci:v00008086d00001C02sv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (Server Board S1200BTS) ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (Server Board S1200BT Family) + + pci:v00008086d00001C03* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller +@@ -72119,6 +80807,9 @@ pci:v00008086d00001C20sv00001028sd000004B2* + pci:v00008086d00001C20sv00001028sd000004DA* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Vostro 3750) + ++pci:v00008086d00001C20sv0000103Csd00002ABF* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (HP Pavilion p6-2100 Desktop PC Series) ++ + pci:v00008086d00001C20sv00001043sd00008418* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (P8P67 Deluxe Motherboard) + +@@ -72131,6 +80822,9 @@ pci:v00008086d00001C20sv000017AAsd000021CF* + pci:v00008086d00001C20sv00008086sd00002008* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (DQ67SW board) + ++pci:v00008086d00001C20sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (DH61CR motherboard) ++ + pci:v00008086d00001C20sv00008086sd00007270* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Apple MacBookPro8,2 [Core i7, 15", 2011]) + +@@ -72155,8 +80849,11 @@ pci:v00008086d00001C22sv00001043sd0000844D* + pci:v00008086d00001C22sv000017AAsd000021CF* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (ThinkPad T520) + ++pci:v00008086d00001C22sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (DH61CR motherboard) ++ + pci:v00008086d00001C22sv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2) ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Server Board S1200BT Family / Apple MacBook Pro 8,1/8,2) + + pci:v00008086d00001C24* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Thermal Management Controller +@@ -72185,8 +80882,11 @@ pci:v00008086d00001C26sv00001043sd0000844D* + pci:v00008086d00001C26sv000017AAsd000021CF* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (ThinkPad T520) + ++pci:v00008086d00001C26sv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (DH61CR motherboard) ++ + pci:v00008086d00001C26sv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2) ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Server Board S1200BT Family / Apple MacBook Pro 8,1/8,2) + + pci:v00008086d00001C27* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #1 +@@ -72221,8 +80921,11 @@ pci:v00008086d00001C2Dsv00001043sd0000844D* + pci:v00008086d00001C2Dsv000017AAsd000021CF* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (ThinkPad T520) + ++pci:v00008086d00001C2Dsv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (DH61CR motherboard) ++ + pci:v00008086d00001C2Dsv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2) ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Server Board S1200BT Family / Apple MacBook Pro 8,1/8,2) + + pci:v00008086d00001C33* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LAN Controller +@@ -72251,6 +80954,9 @@ pci:v00008086d00001C3Asv00001043sd0000844D* + pci:v00008086d00001C3Asv000017AAsd000021CF* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (ThinkPad T520) + ++pci:v00008086d00001C3Asv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (DH61CR motherboard) ++ + pci:v00008086d00001C3Asv00008086sd00007270* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Apple MacBookPro8,2 [Core i7, 15", 2011]) + +@@ -72276,109 +80982,112 @@ pci:v00008086d00001C43* + ID_MODEL_FROM_DATABASE=Mobile 6 Series Chipset Family LPC Controller + + pci:v00008086d00001C44* +- ID_MODEL_FROM_DATABASE=Z68 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Z68 Express Chipset LPC Controller + + pci:v00008086d00001C45* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C46* +- ID_MODEL_FROM_DATABASE=P67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=P67 Express Chipset LPC Controller + + pci:v00008086d00001C46sv00001043sd0000844D* +- ID_MODEL_FROM_DATABASE=P67 Express Chipset Family LPC Controller (P8P67 Deluxe Motherboard) ++ ID_MODEL_FROM_DATABASE=P67 Express Chipset LPC Controller (P8P67 Deluxe Motherboard) + + pci:v00008086d00001C47* +- ID_MODEL_FROM_DATABASE=UM67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=UM67 Express Chipset LPC Controller + + pci:v00008086d00001C48* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C49* +- ID_MODEL_FROM_DATABASE=HM65 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=HM65 Express Chipset LPC Controller + + pci:v00008086d00001C49sv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=HM65 Express Chipset Family LPC Controller (Apple MacBookPro8,2 [Core i7, 15", 2011]) ++ ID_MODEL_FROM_DATABASE=HM65 Express Chipset LPC Controller (Apple MacBookPro8,2 [Core i7, 15", 2011]) + + pci:v00008086d00001C4A* +- ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=H67 Express Chipset LPC Controller + + pci:v00008086d00001C4Asv00001028sd000004AA* +- ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller (XPS 8300) ++ ID_MODEL_FROM_DATABASE=H67 Express Chipset LPC Controller (XPS 8300) + + pci:v00008086d00001C4Asv00001043sd0000844D* +- ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller (P8H67 Series Motherboard) ++ ID_MODEL_FROM_DATABASE=H67 Express Chipset LPC Controller (P8H67 Series Motherboard) + + pci:v00008086d00001C4B* +- ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=HM67 Express Chipset LPC Controller + + pci:v00008086d00001C4Bsv00001028sd000004B2* +- ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller (Vostro 3350) ++ ID_MODEL_FROM_DATABASE=HM67 Express Chipset LPC Controller (Vostro 3350) + + pci:v00008086d00001C4Bsv00001028sd000004DA* +- ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller (Vostro 3750) ++ ID_MODEL_FROM_DATABASE=HM67 Express Chipset LPC Controller (Vostro 3750) + + pci:v00008086d00001C4C* +- ID_MODEL_FROM_DATABASE=Q65 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Q65 Express Chipset LPC Controller + + pci:v00008086d00001C4D* +- ID_MODEL_FROM_DATABASE=QS67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=QS67 Express Chipset LPC Controller + + pci:v00008086d00001C4E* +- ID_MODEL_FROM_DATABASE=Q67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Q67 Express Chipset LPC Controller + + pci:v00008086d00001C4F* +- ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=QM67 Express Chipset LPC Controller + + pci:v00008086d00001C4Fsv00001028sd000004A3* +- ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (Precision M4600) ++ ID_MODEL_FROM_DATABASE=QM67 Express Chipset LPC Controller (Precision M4600) + + pci:v00008086d00001C4Fsv000017AAsd000021CF* +- ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (ThinkPad T520) ++ ID_MODEL_FROM_DATABASE=QM67 Express Chipset LPC Controller (ThinkPad T520) + + pci:v00008086d00001C50* +- ID_MODEL_FROM_DATABASE=B65 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=B65 Express Chipset LPC Controller + + pci:v00008086d00001C51* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C52* +- ID_MODEL_FROM_DATABASE=C202 Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=C202 Chipset LPC Controller + + pci:v00008086d00001C52sv00008086sd00007270* +- ID_MODEL_FROM_DATABASE=C202 Chipset Family LPC Controller (Server Board S1200BTS) ++ ID_MODEL_FROM_DATABASE=C202 Chipset LPC Controller (Server Board S1200BTS) + + pci:v00008086d00001C53* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C54* +- ID_MODEL_FROM_DATABASE=C204 Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=C204 Chipset LPC Controller + + pci:v00008086d00001C55* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C56* +- ID_MODEL_FROM_DATABASE=C206 Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=C206 Chipset LPC Controller + + pci:v00008086d00001C56sv00001043sd0000844D* +- ID_MODEL_FROM_DATABASE=C206 Chipset Family LPC Controller (P8B WS Motherboard) ++ ID_MODEL_FROM_DATABASE=C206 Chipset LPC Controller (P8B WS Motherboard) + + pci:v00008086d00001C57* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C58* +- ID_MODEL_FROM_DATABASE=Upgraded B65 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Upgraded B65 Express Chipset LPC Controller + + pci:v00008086d00001C59* +- ID_MODEL_FROM_DATABASE=Upgraded HM67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Upgraded HM67 Express Chipset LPC Controller + + pci:v00008086d00001C5A* +- ID_MODEL_FROM_DATABASE=Upgraded Q67 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=Upgraded Q67 Express Chipset LPC Controller + + pci:v00008086d00001C5B* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + + pci:v00008086d00001C5C* +- ID_MODEL_FROM_DATABASE=H61 Express Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=H61 Express Chipset LPC Controller ++ ++pci:v00008086d00001C5Csv00008086sd0000200D* ++ ID_MODEL_FROM_DATABASE=H61 Express Chipset LPC Controller (DH61CR motherboard) + + pci:v00008086d00001C5D* + ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller +@@ -72395,6 +81104,9 @@ pci:v00008086d00001D00* + pci:v00008086d00001D02* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset 6-Port SATA AHCI Controller + ++pci:v00008086d00001D02sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset 6-Port SATA AHCI Controller (C602J on PowerEdge R320 server) ++ + pci:v00008086d00001D04* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller + +@@ -72407,6 +81119,9 @@ pci:v00008086d00001D08* + pci:v00008086d00001D10* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1 + ++pci:v00008086d00001D10sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1 (C602J on PowerEdge R320 server) ++ + pci:v00008086d00001D11* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1 + +@@ -72431,6 +81146,9 @@ pci:v00008086d00001D17* + pci:v00008086d00001D18* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5 + ++pci:v00008086d00001D18sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5 (C602J on PowerEdge R320 server) ++ + pci:v00008086d00001D19* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5 + +@@ -72449,6 +81167,9 @@ pci:v00008086d00001D1D* + pci:v00008086d00001D1E* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8 + ++pci:v00008086d00001D1Esv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8 (C602J on PowerEdge R320 server) ++ + pci:v00008086d00001D1F* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8 + +@@ -72458,18 +81179,39 @@ pci:v00008086d00001D20* + pci:v00008086d00001D22* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset SMBus Host Controller + ++pci:v00008086d00001D22sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SMBus Host Controller (X9SRL-F) ++ + pci:v00008086d00001D24* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset Thermal Management Controller + ++pci:v00008086d00001D24sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset Thermal Management Controller (X9SRL-F) ++ + pci:v00008086d00001D25* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset DMI to PCI Bridge + + pci:v00008086d00001D26* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #1 + ++pci:v00008086d00001D26sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #1 (C602J on PowerEdge R320 server) ++ ++pci:v00008086d00001D26sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #1 (X9SRL-F) ++ + pci:v00008086d00001D2D* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2 + ++pci:v00008086d00001D2Dsv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2 (C602J on PowerEdge R320 server) ++ ++pci:v00008086d00001D2Dsv0000103Csd000018A9* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2 (HP DL360e G8) ++ ++pci:v00008086d00001D2Dsv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2 (X9SRL-F) ++ + pci:v00008086d00001D33* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset LAN Controller + +@@ -72479,9 +81221,21 @@ pci:v00008086d00001D35* + pci:v00008086d00001D3A* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #1 + ++pci:v00008086d00001D3Asv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #1 (C602J on PowerEdge R320 server) ++ ++pci:v00008086d00001D3Asv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #1 (X9SRL-F) ++ + pci:v00008086d00001D3B* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #2 + ++pci:v00008086d00001D3Bsv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #2 (C602J on PowerEdge R320 server) ++ ++pci:v00008086d00001D3Bsv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset MEI Controller #2 (X9SRL-F) ++ + pci:v00008086d00001D3C* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset IDE-r Controller + +@@ -72491,6 +81245,9 @@ pci:v00008086d00001D3D* + pci:v00008086d00001D3E* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Virtual Root Port + ++pci:v00008086d00001D3Esv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset PCI Express Virtual Root Port (C602J on PowerEdge R320 server) ++ + pci:v00008086d00001D3F* + ID_MODEL_FROM_DATABASE=C608/C606/X79 series chipset PCI Express Virtual Switch Port + +@@ -72500,6 +81257,12 @@ pci:v00008086d00001D40* + pci:v00008086d00001D41* + ID_MODEL_FROM_DATABASE=C600/X79 series chipset LPC Controller + ++pci:v00008086d00001D41sv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset LPC Controller (C602J on PowerEdge R320 server) ++ ++pci:v00008086d00001D41sv000015D9sd0000066B* ++ ID_MODEL_FROM_DATABASE=C600/X79 series chipset LPC Controller (X9SRL-F) ++ + pci:v00008086d00001D50* + ID_MODEL_FROM_DATABASE=C608 chipset Dual 4-Port SATA/SAS Storage Control Unit + +@@ -72614,6 +81377,9 @@ pci:v00008086d00001E03sv00001043sd00001477* + pci:v00008086d00001E03sv00001043sd00001517* + ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] (Zenbook Prime UX31A) + ++pci:v00008086d00001E03sv000010CFsd000016E2* ++ ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] (LIFEBOOK E752) ++ + pci:v00008086d00001E03sv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] (NP300E5C series laptop) + +@@ -72656,6 +81422,9 @@ pci:v00008086d00001E10sv00001043sd00001517* + pci:v00008086d00001E10sv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family PCI Express Root Port 1 (P8H77-I Motherboard) + ++pci:v00008086d00001E10sv000010CFsd000016E9* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family PCI Express Root Port 1 (LIFEBOOK E752) ++ + pci:v00008086d00001E10sv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family PCI Express Root Port 1 (NP300E5C series laptop) + +@@ -72677,6 +81446,9 @@ pci:v00008086d00001E12sv00001043sd00001517* + pci:v00008086d00001E14* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 3 + ++pci:v00008086d00001E14sv000010CFsd000016E9* ++ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 3 (LIFEBOOK E752) ++ + pci:v00008086d00001E16* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family PCI Express Root Port 4 + +@@ -72713,6 +81485,9 @@ pci:v00008086d00001E1C* + pci:v00008086d00001E1E* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 + ++pci:v00008086d00001E1Esv000010CFsd000016E9* ++ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 (LIFEBOOK E752) ++ + pci:v00008086d00001E1Esv00001849sd00001E1E* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 (Motherboard) + +@@ -72737,6 +81512,9 @@ pci:v00008086d00001E20sv00001043sd00008415* + pci:v00008086d00001E20sv00001043sd00008445* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (P8Z77-V LX Motherboard) + ++pci:v00008086d00001E20sv000010CFsd00001757* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (LIFEBOOK E752) ++ + pci:v00008086d00001E20sv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (NP300E5C series laptop) + +@@ -72758,6 +81536,9 @@ pci:v00008086d00001E22sv00001043sd00001517* + pci:v00008086d00001E22sv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family SMBus Controller (P8 series motherboard) + ++pci:v00008086d00001E22sv000010CFsd000016E6* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family SMBus Controller (LIFEBOOK E752) ++ + pci:v00008086d00001E22sv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family SMBus Controller (NP300E5C series laptop) + +@@ -72788,6 +81569,9 @@ pci:v00008086d00001E26sv00001043sd00001517* + pci:v00008086d00001E26sv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #1 (P8 series motherboard) + ++pci:v00008086d00001E26sv000010CFsd000016E8* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #1 (LIFEBOOK E752) ++ + pci:v00008086d00001E26sv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #1 (NP300E5C series laptop) + +@@ -72809,6 +81593,9 @@ pci:v00008086d00001E2Dsv00001043sd00001517* + pci:v00008086d00001E2Dsv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #2 (P8 series motherboard) + ++pci:v00008086d00001E2Dsv000010CFsd000016E8* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #2 (LIFEBOOK E752) ++ + pci:v00008086d00001E2Dsv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family USB Enhanced Host Controller #2 (NP300E5C series laptop) + +@@ -72836,6 +81623,12 @@ pci:v00008086d00001E31sv00001043sd00001517* + pci:v00008086d00001E31sv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (P8 series motherboard) + ++pci:v00008086d00001E31sv000010CFsd000016EE* ++ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (LIFEBOOK E752) ++ ++pci:v00008086d00001E31sv000017AAsd000021F3* ++ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (ThinkPad T430) ++ + pci:v00008086d00001E31sv00001849sd00001E31* + ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (Motherboard) + +@@ -72857,6 +81650,9 @@ pci:v00008086d00001E3Asv00001043sd00001517* + pci:v00008086d00001E3Asv00001043sd000084CA* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family MEI Controller #1 (P8 series motherboard) + ++pci:v00008086d00001E3Asv000010CFsd000016EA* ++ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family MEI Controller #1 (LIFEBOOK E752) ++ + pci:v00008086d00001E3Asv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family MEI Controller #1 (NP300E5C series laptop) + +@@ -72962,6 +81758,9 @@ pci:v00008086d00001E59sv00001043sd00001477* + pci:v00008086d00001E59sv00001043sd00001517* + ID_MODEL_FROM_DATABASE=HM76 Express Chipset LPC Controller (Zenbook Prime UX31A) + ++pci:v00008086d00001E59sv000010CFsd000016E0* ++ ID_MODEL_FROM_DATABASE=HM76 Express Chipset LPC Controller (LIFEBOOK E752) ++ + pci:v00008086d00001E5A* + ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller + +@@ -72978,13 +81777,13 @@ pci:v00008086d00001E5Dsv0000144Dsd0000C652* + ID_MODEL_FROM_DATABASE=HM75 Express Chipset LPC Controller (NP300E5C series laptop) + + pci:v00008086d00001E5E* +- ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=HM70 Express Chipset LPC Controller + + pci:v00008086d00001E5Esv00001043sd0000108D* +- ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller (VivoBook X202EV) ++ ID_MODEL_FROM_DATABASE=HM70 Express Chipset LPC Controller (VivoBook X202EV) + + pci:v00008086d00001E5F* +- ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller ++ ID_MODEL_FROM_DATABASE=NM70 Express Chipset LPC Controller + + pci:v00008086d00001F00* + ID_MODEL_FROM_DATABASE=Atom processor C2000 SoC Transaction Router +@@ -73088,6 +81887,9 @@ pci:v00008086d00001F27* + pci:v00008086d00001F2C* + ID_MODEL_FROM_DATABASE=Atom processor C2000 USB Enhanced Host Controller + ++pci:v00008086d00001F2Csv00000200sd00001028* ++ ID_MODEL_FROM_DATABASE=Atom processor C2000 USB Enhanced Host Controller (Atom C2338 on Dell 0K8Y0N motherboard) ++ + pci:v00008086d00001F2E* + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA2 Controller + +@@ -73133,6 +81935,9 @@ pci:v00008086d00001F3B* + pci:v00008086d00001F3C* + ID_MODEL_FROM_DATABASE=Atom processor C2000 PCU SMBus + ++pci:v00008086d00001F3D* ++ ID_MODEL_FROM_DATABASE=Atom Processor C2000 PECI SMBus ++ + pci:v00008086d00001F3E* + ID_MODEL_FROM_DATABASE=Atom processor C2000 RAID SATA3 Controller + +@@ -73175,15 +81980,27 @@ pci:v00008086d0000201A* + pci:v00008086d0000201C* + ID_MODEL_FROM_DATABASE=Sky Lake-E Non-Transparent Bridge Registers + ++pci:v00008086d0000201D* ++ ID_MODEL_FROM_DATABASE=Volume Management Device NVMe RAID Controller ++ + pci:v00008086d00002020* + ID_MODEL_FROM_DATABASE=Sky Lake-E DMI3 Registers + ++pci:v00008086d00002020sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E DMI3 Registers (X11SPM-TF) ++ + pci:v00008086d00002021* + ID_MODEL_FROM_DATABASE=Sky Lake-E CBDMA Registers + + pci:v00008086d00002024* + ID_MODEL_FROM_DATABASE=Sky Lake-E MM/Vt-d Configuration Registers + ++pci:v00008086d00002025* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E RAS ++ ++pci:v00008086d00002026* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E IOAPIC ++ + pci:v00008086d00002030* + ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port A + +@@ -73196,9 +82013,51 @@ pci:v00008086d00002032* + pci:v00008086d00002033* + ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port D + ++pci:v00008086d00002034* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E VT-d ++ + pci:v00008086d00002035* + ID_MODEL_FROM_DATABASE=Sky Lake-E RAS Configuration Registers + ++pci:v00008086d00002036* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E IOxAPIC Configuration Registers ++ ++pci:v00008086d00002040* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ ++pci:v00008086d00002041* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ ++pci:v00008086d00002042* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ ++pci:v00008086d00002043* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ ++pci:v00008086d00002044* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ ++pci:v00008086d00002045* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LM Channel 1 ++ ++pci:v00008086d00002046* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LMS Channel 1 ++ ++pci:v00008086d00002047* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LMDP Channel 1 ++ ++pci:v00008086d00002048* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E DECS Channel 2 ++ ++pci:v00008086d00002049* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LM Channel 2 ++ ++pci:v00008086d0000204A* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LMS Channel 2 ++ ++pci:v00008086d0000204B* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E LMDP Channel 2 ++ + pci:v00008086d0000204C* + ID_MODEL_FROM_DATABASE=Sky Lake-E M3KTI Registers + +@@ -73220,6 +82079,15 @@ pci:v00008086d00002056* + pci:v00008086d00002057* + ID_MODEL_FROM_DATABASE=Sky Lake-E CHA Registers + ++pci:v00008086d00002058* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E KTI 0 ++ ++pci:v00008086d00002059* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E UPI Registers ++ ++pci:v00008086d00002066* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E Integrated Memory Controller ++ + pci:v00008086d00002068* + ID_MODEL_FROM_DATABASE=Sky Lake-E DDRIO Registers + +@@ -73262,12 +82130,18 @@ pci:v00008086d00002085* + pci:v00008086d00002086* + ID_MODEL_FROM_DATABASE=Sky Lake-E PCU Registers + ++pci:v00008086d00002088* ++ ID_MODEL_FROM_DATABASE=Sky Lake-E DDRIO Registers ++ + pci:v00008086d0000208D* + ID_MODEL_FROM_DATABASE=Sky Lake-E CHA Registers + + pci:v00008086d0000208E* + ID_MODEL_FROM_DATABASE=Sky Lake-E CHA Registers + ++pci:v00008086d00002241* ++ ID_MODEL_FROM_DATABASE=Larrabee ++ + pci:v00008086d00002250* + ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 5100 series + +@@ -73280,6 +82154,9 @@ pci:v00008086d0000225D* + pci:v00008086d0000225E* + ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 31S1 + ++pci:v00008086d00002262* ++ ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 7220 ++ + pci:v00008086d00002280* + ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Series SoC Transaction Register + +@@ -73323,7 +82200,7 @@ pci:v00008086d000022A8* + ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Series Low Power Engine Audio + + pci:v00008086d000022B0* +- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Series PCI Configuration Registers ++ ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Integrated Graphics Controller + + pci:v00008086d000022B1* + ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor x5-E8000/J3xxx/N3xxx Integrated Graphics Controller +@@ -73604,6 +82481,9 @@ pci:v00008086d00002442sv00008086sd00004532* + pci:v00008086d00002442sv00008086sd00004557* + ID_MODEL_FROM_DATABASE=82801BA/BAM UHCI USB 1.1 Controller #1 (D815EGEW Mainboard) + ++pci:v00008086d00002442sv00008086sd00004D44* ++ ID_MODEL_FROM_DATABASE=82801BA/BAM UHCI USB 1.1 Controller #1 (D850EMV2 motherboard) ++ + pci:v00008086d00002442sv00008086sd00005744* + ID_MODEL_FROM_DATABASE=82801BA/BAM UHCI USB 1.1 Controller #1 (S845WD1-E mainboard) + +@@ -73727,6 +82607,9 @@ pci:v00008086d00002445sv00008086sd00004557* + pci:v00008086d00002445sv00008086sd00004656* + ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Desktop Board D815EFV) + ++pci:v00008086d00002445sv00008086sd00004D44* ++ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (D850EMV2 motherboard) ++ + pci:v00008086d00002446* + ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller + +@@ -73763,6 +82646,9 @@ pci:v00008086d00002448sv0000103Csd000030A3* + pci:v00008086d00002448sv0000103Csd000030C1* + ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq 6910p) + ++pci:v00008086d00002448sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (X58LE) ++ + pci:v00008086d00002448sv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (VAIO VGN-NR120E) + +@@ -73946,6 +82832,9 @@ pci:v00008086d0000244Bsv00008086sd00004532* + pci:v00008086d0000244Bsv00008086sd00004557* + ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (D815EGEW Mainboard) + ++pci:v00008086d0000244Bsv00008086sd00004D44* ++ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (D850EMV2 motherboard) ++ + pci:v00008086d0000244Bsv00008086sd00005744* + ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (S845WD1-E mainboard) + +@@ -73967,6 +82856,9 @@ pci:v00008086d0000244Esv00001028sd00000211* + pci:v00008086d0000244Esv00001028sd000002DA* + ID_MODEL_FROM_DATABASE=82801 PCI Bridge (OptiPlex 980) + ++pci:v00008086d0000244Esv00001028sd000004F7* ++ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (PowerEdge R320 server) ++ + pci:v00008086d0000244Esv0000103Csd00002A3B* + ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Pavilion A1512X) + +@@ -73985,6 +82877,9 @@ pci:v00008086d0000244Esv00001043sd00008277* + pci:v00008086d0000244Esv00001043sd0000844D* + ID_MODEL_FROM_DATABASE=82801 PCI Bridge (P8 series motherboard) + ++pci:v00008086d0000244Esv00001043sd00008534* ++ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (ASUS B85-PLUS) ++ + pci:v00008086d0000244Esv00001458sd00005000* + ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Motherboard) + +@@ -74873,6 +83768,9 @@ pci:v00008086d000024D1sv00008086sd0000524C* + pci:v00008086d000024D2* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 + ++pci:v00008086d000024D2sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (ThinkCentre S50) ++ + pci:v00008086d000024D2sv00001014sd000002DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (eServer xSeries server mainboard) + +@@ -74942,6 +83840,9 @@ pci:v00008086d000024D2sv00008086sd0000524C* + pci:v00008086d000024D3* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller + ++pci:v00008086d000024D3sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (ThinkCentre S50) ++ + pci:v00008086d000024D3sv00001014sd000002DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (eServer xSeries server mainboard) + +@@ -74999,6 +83900,9 @@ pci:v00008086d000024D3sv00008086sd0000524C* + pci:v00008086d000024D4* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 + ++pci:v00008086d000024D4sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (ThinkCentre S50) ++ + pci:v00008086d000024D4sv00001014sd000002DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (eServer xSeries server mainboard) + +@@ -75074,6 +83978,9 @@ pci:v00008086d000024D5* + pci:v00008086d000024D5sv0000100Asd0000147B* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Abit IS7-E motherboard) + ++pci:v00008086d000024D5sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (ThinkCentre S50) ++ + pci:v00008086d000024D5sv00001028sd00000168* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Precision Workstation 670 Mainboard) + +@@ -75125,6 +84032,9 @@ pci:v00008086d000024D6sv0000103Csd0000006A* + pci:v00008086d000024D7* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 + ++pci:v00008086d000024D7sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (ThinkCentre S50) ++ + pci:v00008086d000024D7sv00001014sd000002ED* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (xSeries server mainboard) + +@@ -75188,6 +84098,9 @@ pci:v00008086d000024D7sv00008086sd0000524C* + pci:v00008086d000024DB* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller + ++pci:v00008086d000024DBsv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (ThinkCentre S50) ++ + pci:v00008086d000024DBsv00001014sd000002DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (eServer xSeries server mainboard) + +@@ -75263,6 +84176,9 @@ pci:v00008086d000024DC* + pci:v00008086d000024DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller + ++pci:v00008086d000024DDsv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (ThinkCentre S50) ++ + pci:v00008086d000024DDsv00001014sd000002DD* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (eServer xSeries server mainboard) + +@@ -75326,6 +84242,9 @@ pci:v00008086d000024DDsv00008086sd0000524C* + pci:v00008086d000024DE* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 + ++pci:v00008086d000024DEsv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (ThinkCentre S50) ++ + pci:v00008086d000024DEsv00001014sd000002ED* + ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (xSeries server mainboard) + +@@ -75416,6 +84335,12 @@ pci:v00008086d000024F0sv00001CB8sd00000003* + pci:v00008086d000024F0sv00001CB8sd00000004* + ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16, TC4600E QSFP28) + ++pci:v00008086d000024F0sv0000434Esd00000001* ++ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, OCP 3.0) ++ ++pci:v00008086d000024F0sv0000434Esd00002628* ++ ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16) ++ + pci:v00008086d000024F0sv00008086sd00002628* + ID_MODEL_FROM_DATABASE=Omni-Path HFI Silicon 100 Series [discrete] (Omni-Path HFI Adapter 100 Series, 1 Port, PCIe x16) + +@@ -75455,6 +84380,12 @@ pci:v00008086d000024FD* + pci:v00008086d000024FDsv00008086sd00000010* + ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265) + ++pci:v00008086d000024FDsv00008086sd00000150* ++ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265) ++ ++pci:v00008086d000024FDsv00008086sd00001010* ++ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265) ++ + pci:v00008086d000024FDsv00008086sd00001130* + ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265) + +@@ -75485,6 +84416,15 @@ pci:v00008086d00002520* + pci:v00008086d00002521* + ID_MODEL_FROM_DATABASE=82804AA MRH-S Memory Repeater Hub for SDRAM + ++pci:v00008086d00002522* ++ ID_MODEL_FROM_DATABASE=NVMe Optane Memory Series ++ ++pci:v00008086d00002522sv00008086sd00003806* ++ ID_MODEL_FROM_DATABASE=NVMe Optane Memory Series (Optane Memory 16GB) ++ ++pci:v00008086d00002522sv00008086sd00003810* ++ ID_MODEL_FROM_DATABASE=NVMe Optane Memory Series (Optane Memory M10 16GB) ++ + pci:v00008086d00002526* + ID_MODEL_FROM_DATABASE=Wireless-AC 9260 + +@@ -75632,6 +84572,9 @@ pci:v00008086d00002571* + pci:v00008086d00002572* + ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller + ++pci:v00008086d00002572sv00001014sd00000287* ++ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (ThinkCentre S50) ++ + pci:v00008086d00002572sv00001028sd0000019D* + ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Dimension 3000) + +@@ -75752,6 +84695,9 @@ pci:v00008086d00002590sv0000103Csd00000944* + pci:v00008086d00002590sv0000103Csd0000099C* + ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (NX6110/NC6120) + ++pci:v00008086d00002590sv00001043sd000082D9* ++ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Asus Eee PC 900) ++ + pci:v00008086d00002590sv0000104Dsd000081B7* + ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Vaio VGN-S3XP) + +@@ -76971,13 +85917,76 @@ pci:v00008086d00002700sv00008086sd00003901* + ID_MODEL_FROM_DATABASE=Optane SSD 900P Series (900P Series [2.5" SFF]) + + pci:v00008086d00002701* +- ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] ++ ++pci:v00008086d00002701sv00001028sd00002000* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (Express Flash NVMe [Optane] 375GB 2.5" U.2 (P4800X)) ++ ++pci:v00008086d00002701sv00001028sd00002001* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (Express Flash NVMe [Optane] 750GB 2.5" U.2 (P4800X)) ++ ++pci:v00008086d00002701sv00001028sd00002002* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (Express Flash NVMe [Optane] 750GB AIC (P4800X)) ++ ++pci:v00008086d00002701sv00001028sd0000200A* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (Express Flash NVMe [Optane] 375GB AIC (P4800X)) + + pci:v00008086d00002701sv00008086sd00003904* +- ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD (DC P4800X Series [Add-in Card]) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (x4 AIC (P4800X)) + + pci:v00008086d00002701sv00008086sd00003905* +- ID_MODEL_FROM_DATABASE=Optane DC P4800X Series SSD (DC P4800X Series [2.5" SFF]) ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (15mm 2.5" U.2 (P4800X)) ++ ++pci:v00008086d00002723* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX200 ++ ++pci:v00008086d00002723sv00001A56sd00001654* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX200 (Killer™ Wi-Fi 6 AX1650x (AX200NGW)) ++ ++pci:v00008086d00002723sv00008086sd00000084* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX200 (NGW) ++ ++pci:v00008086d00002725* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz ++ ++pci:v00008086d00002725sv00008086sd00000020* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00000024* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00000090* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX211 160MHz) ++ ++pci:v00008086d00002725sv00008086sd000000B0* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX411 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00000310* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00000510* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00000A10* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00002020* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00004020* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00006020* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd00006024* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd0000E020* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) ++ ++pci:v00008086d00002725sv00008086sd0000E024* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX210/AX211/AX411 160MHz (Wi-Fi 6 AX210 160MHz) + + pci:v00008086d00002770* + ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub +@@ -76997,6 +86006,9 @@ pci:v00008086d00002770sv0000107Bsd00005048* + pci:v00008086d00002770sv00001462sd00007418* + ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (Wind PC MS-7418) + ++pci:v00008086d00002770sv00001849sd00002770* ++ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (ConRoe1333-D667) ++ + pci:v00008086d00002770sv00008086sd0000544E* + ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (DeskTop Board D945GTP) + +@@ -77012,6 +86024,9 @@ pci:v00008086d00002772sv0000103Csd00002A3B* + pci:v00008086d00002772sv00001462sd00007418* + ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Wind PC MS-7418) + ++pci:v00008086d00002772sv00001849sd00002772* ++ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (ConRoe1333-D667) ++ + pci:v00008086d00002772sv00008086sd0000544E* + ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (DeskTop Board D945GTP) + +@@ -77051,6 +86066,9 @@ pci:v00008086d0000277Csv00001043sd00008178* + pci:v00008086d0000277D* + ID_MODEL_FROM_DATABASE=82975X PCI Express Root Port + ++pci:v00008086d00002780* ++ ID_MODEL_FROM_DATABASE=82915G/GV/GL/910GL [Grantsdale] Graphics Device ++ + pci:v00008086d00002782* + ID_MODEL_FROM_DATABASE=82915G Integrated Graphics Controller + +@@ -77193,7 +86211,7 @@ pci:v00008086d000027B8sv0000103Csd00002A8C* + ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (Compaq 500B Microtower) + + pci:v00008086d000027B8sv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (P5KPL-VM Motherboard) ++ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (P5B-MX/WiFi-AP, P5KPL-VM Motherboard) + + pci:v00008086d000027B8sv0000107Bsd00005048* + ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (E4500) +@@ -77237,6 +86255,9 @@ pci:v00008086d000027B9sv000017AAsd00002009* + pci:v00008086d000027BC* + ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller + ++pci:v00008086d000027BCsv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (Eee PC 1015PX) ++ + pci:v00008086d000027BCsv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (D270S/D250S Motherboard) + +@@ -77274,7 +86295,7 @@ pci:v00008086d000027C0sv0000103Csd00002A8C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (Compaq 500B Microtower) + + pci:v00008086d000027C0sv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (P5KPL-VM Motherboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (P5B-MX/WiFi-AP, P5KPL-VM Motherboard) + + pci:v00008086d000027C0sv0000107Bsd00005048* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (E4500) +@@ -77306,6 +86327,9 @@ pci:v00008086d000027C1sv00001028sd000001DF* + pci:v00008086d000027C1sv0000103Csd00002A3B* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (Pavilion A1512X) + ++pci:v00008086d000027C1sv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (Eee PC 1015PX) ++ + pci:v00008086d000027C1sv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (D270S/D250S Motherboard) + +@@ -77406,7 +86430,10 @@ pci:v00008086d000027C8sv00001043sd00001237* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (A6J-Q008) + + pci:v00008086d000027C8sv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (P5KPL-VM,P5LD2-VM Mainboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard) ++ ++pci:v00008086d000027C8sv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Eee PC 1015PX) + + pci:v00008086d000027C8sv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (D270S/D250S Motherboard) +@@ -77478,7 +86505,10 @@ pci:v00008086d000027C9sv00001043sd00001237* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (A6J-Q008) + + pci:v00008086d000027C9sv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (P5KPL-VM,P5LD2-VM Mainboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard) ++ ++pci:v00008086d000027C9sv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Eee PC 1015PX) + + pci:v00008086d000027C9sv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (D270S/D250S Motherboard) +@@ -77550,7 +86580,10 @@ pci:v00008086d000027CAsv00001043sd00001237* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (A6J-Q008) + + pci:v00008086d000027CAsv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (P5KPL-VM,P5LD2-VM Mainboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard) ++ ++pci:v00008086d000027CAsv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Eee PC 1015PX) + + pci:v00008086d000027CAsv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (D270S/D250S Motherboard) +@@ -77616,7 +86649,10 @@ pci:v00008086d000027CBsv00001043sd00001237* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (A6J-Q008) + + pci:v00008086d000027CBsv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (P5KPL-VM,P5LD2-VM Mainboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard) ++ ++pci:v00008086d000027CBsv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Eee PC 1015PX) + + pci:v00008086d000027CBsv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (D270S/D250S Motherboard) +@@ -77688,7 +86724,10 @@ pci:v00008086d000027CCsv00001043sd00001237* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (A6J-Q008) + + pci:v00008086d000027CCsv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (P5KPL-VM,P5LD2-VM Mainboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (P5B-MX/WiFi-AP, P5KPL-VM, P5LD2-VM Mainboard) ++ ++pci:v00008086d000027CCsv00001043sd000083AD* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Eee PC 1015PX) + + pci:v00008086d000027CCsv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (D270S/D250S Motherboard) +@@ -77858,12 +86897,18 @@ pci:v00008086d000027D8sv00001043sd000013C4* + pci:v00008086d000027D8sv00001043sd0000817F* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5LD2-VM Mainboard (Realtek ALC 882 codec)) + ++pci:v00008086d000027D8sv00001043sd00008249* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5B-MX/WiFi-AP) ++ + pci:v00008086d000027D8sv00001043sd00008290* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5KPL-VM Motherboard) + + pci:v00008086d000027D8sv00001043sd000082EA* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5KPL-CM Motherboard) + ++pci:v00008086d000027D8sv00001043sd00008437* ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Eee PC 1015PX) ++ + pci:v00008086d000027D8sv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (D270S/D250S Motherboard) + +@@ -77946,7 +86991,7 @@ pci:v00008086d000027DAsv0000103Csd00002A8C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Compaq 500B Microtower) + + pci:v00008086d000027DAsv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (P5KPL-VM Motherboard) ++ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (P5B-MX/WiFi-AP, P5KPL-VM Motherboard) + + pci:v00008086d000027DAsv0000105Bsd00000D7C* + ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (D270S/D250S Motherboard) +@@ -78039,7 +87084,7 @@ pci:v00008086d000027DFsv00001043sd00001237* + ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (A6J-Q008) + + pci:v00008086d000027DFsv00001043sd00008179* +- ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (P5KPL-VM Motherboard) ++ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (P5B-MX/WiFi-AP, P5KPL-VM Motherboard) + + pci:v00008086d000027DFsv0000107Bsd00005048* + ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (E4500) +@@ -78116,6 +87161,9 @@ pci:v00008086d00002815sv0000103Csd000030CC* + pci:v00008086d00002815sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Presario C700) + ++pci:v00008086d00002815sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (X58LE) ++ + pci:v00008086d00002815sv0000104Dsd00009005* + ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Vaio VGN-FZ260E) + +@@ -78233,6 +87281,9 @@ pci:v00008086d00002829sv0000103Csd000030CC* + pci:v00008086d00002829sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Presario C700) + ++pci:v00008086d00002829sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (X58LE) ++ + pci:v00008086d00002829sv0000104Dsd00009005* + ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Vaio VGN-FZ260E) + +@@ -78284,6 +87335,9 @@ pci:v00008086d00002830sv0000103Csd000030CC* + pci:v00008086d00002830sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Presario C700) + ++pci:v00008086d00002830sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (X58LE) ++ + pci:v00008086d00002830sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (P5B) + +@@ -78332,6 +87386,9 @@ pci:v00008086d00002831sv0000103Csd000030CC* + pci:v00008086d00002831sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Presario C700) + ++pci:v00008086d00002831sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (X58LE) ++ + pci:v00008086d00002831sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (P5B) + +@@ -78380,6 +87437,9 @@ pci:v00008086d00002832sv0000103Csd000030CC* + pci:v00008086d00002832sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Presario C700) + ++pci:v00008086d00002832sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (X58LE) ++ + pci:v00008086d00002832sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (P5B) + +@@ -78428,6 +87488,9 @@ pci:v00008086d00002834sv0000103Csd000030C1* + pci:v00008086d00002834sv0000103Csd000030CC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Pavilion dv6700) + ++pci:v00008086d00002834sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (X58LE) ++ + pci:v00008086d00002834sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (P5B) + +@@ -78473,6 +87536,9 @@ pci:v00008086d00002835sv0000103Csd000030C1* + pci:v00008086d00002835sv0000103Csd000030CC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Pavilion dv6700) + ++pci:v00008086d00002835sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (X58LE) ++ + pci:v00008086d00002835sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (P5B) + +@@ -78518,6 +87584,9 @@ pci:v00008086d00002836sv0000103Csd000030CC* + pci:v00008086d00002836sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Presario C700) + ++pci:v00008086d00002836sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (X58LE) ++ + pci:v00008086d00002836sv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (P5B) + +@@ -78563,6 +87632,9 @@ pci:v00008086d0000283Asv0000103Csd000030C1* + pci:v00008086d0000283Asv0000103Csd000030CC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Pavilion dv6700) + ++pci:v00008086d0000283Asv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (X58LE) ++ + pci:v00008086d0000283Asv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (P5B) + +@@ -78599,6 +87671,9 @@ pci:v00008086d0000283Esv00001028sd0000022F* + pci:v00008086d0000283Esv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Presario C700) + ++pci:v00008086d0000283Esv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (X58LE) ++ + pci:v00008086d0000283Esv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (P5B) + +@@ -78632,6 +87707,9 @@ pci:v00008086d0000283Fsv00001028sd000001DA* + pci:v00008086d0000283Fsv0000103Csd000030C1* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (Compaq 6910p) + ++pci:v00008086d0000283Fsv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (X58LE) ++ + pci:v00008086d0000283Fsv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (VAIO VGN-NR120E) + +@@ -78647,6 +87725,9 @@ pci:v00008086d00002841* + pci:v00008086d00002841sv0000103Csd000030C1* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (Compaq 6910p) + ++pci:v00008086d00002841sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (X58LE) ++ + pci:v00008086d00002841sv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (VAIO VGN-NR120E) + +@@ -78659,6 +87740,9 @@ pci:v00008086d00002841sv000017C0sd00004083* + pci:v00008086d00002843* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 + ++pci:v00008086d00002843sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 (X58LE) ++ + pci:v00008086d00002843sv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 (VAIO VGN-NR120E) + +@@ -78671,6 +87755,9 @@ pci:v00008086d00002843sv000017C0sd00004083* + pci:v00008086d00002845* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 + ++pci:v00008086d00002845sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 (X58LE) ++ + pci:v00008086d00002845sv000017AAsd000020AD* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 (ThinkPad T61/R61) + +@@ -78740,6 +87827,9 @@ pci:v00008086d0000284Bsv0000103Csd000030CC* + pci:v00008086d0000284Bsv00001043sd00001339* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (M51S series) + ++pci:v00008086d0000284Bsv00001043sd000017F3* ++ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (X58LE) ++ + pci:v00008086d0000284Bsv00001043sd000081EC* + ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (P5B) + +@@ -78797,6 +87887,9 @@ pci:v00008086d00002850sv0000103Csd000030CC* + pci:v00008086d00002850sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Presario C700) + ++pci:v00008086d00002850sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (X58LE) ++ + pci:v00008086d00002850sv0000104Dsd00009005* + ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Vaio VGN-FZ260E) + +@@ -78812,6 +87905,9 @@ pci:v00008086d00002850sv000017C0sd00004083* + pci:v00008086d00002850sv0000E4BFsd0000CC47* + ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (CCG-RUMBA) + ++pci:v00008086d000028C0* ++ ID_MODEL_FROM_DATABASE=Volume Management Device NVMe RAID Controller ++ + pci:v00008086d00002912* + ID_MODEL_FROM_DATABASE=82801IH (ICH9DH) LPC Interface Controller + +@@ -78842,6 +87938,9 @@ pci:v00008086d00002916sv00008086sd00005044* + pci:v00008086d00002917* + ID_MODEL_FROM_DATABASE=ICH9M-E LPC Interface Controller + ++pci:v00008086d00002917sv000017AAsd000020F5* ++ ID_MODEL_FROM_DATABASE=ICH9M-E LPC Interface Controller (ThinkPad T400) ++ + pci:v00008086d00002917sv0000E4BFsd0000CC4D* + ID_MODEL_FROM_DATABASE=ICH9M-E LPC Interface Controller (CCM-BOOGIE) + +@@ -78959,6 +88058,9 @@ pci:v00008086d00002929* + pci:v00008086d00002929sv0000103Csd00003628* + ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] (dv6-1190en) + ++pci:v00008086d00002929sv000017AAsd000020F8* ++ ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] (ThinkPad T400) ++ + pci:v00008086d00002929sv0000E4BFsd0000CC4D* + ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] (CCM-BOOGIE) + +@@ -78995,6 +88097,9 @@ pci:v00008086d00002930sv00001462sd00007345* + pci:v00008086d00002930sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (G33/P35 Neo) + ++pci:v00008086d00002930sv000017AAsd000020F9* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (ThinkPad T400) ++ + pci:v00008086d00002930sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (QEMU Virtual Machine) + +@@ -79058,6 +88163,9 @@ pci:v00008086d00002934sv00001462sd00007345* + pci:v00008086d00002934sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (G33/P35 Neo) + ++pci:v00008086d00002934sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (ThinkPad T400) ++ + pci:v00008086d00002934sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (QEMU Virtual Machine) + +@@ -79112,6 +88220,9 @@ pci:v00008086d00002935sv00001462sd00007345* + pci:v00008086d00002935sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (G33/P35 Neo) + ++pci:v00008086d00002935sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (ThinkPad T400) ++ + pci:v00008086d00002935sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (QEMU Virtual Machine) + +@@ -79160,6 +88271,9 @@ pci:v00008086d00002936sv00001462sd00007345* + pci:v00008086d00002936sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (G33/P35 Neo) + ++pci:v00008086d00002936sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (ThinkPad T400) ++ + pci:v00008086d00002936sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (QEMU Virtual Machine) + +@@ -79208,6 +88322,9 @@ pci:v00008086d00002937sv00001462sd00007345* + pci:v00008086d00002937sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (G33/P35 Neo) + ++pci:v00008086d00002937sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (ThinkPad T400) ++ + pci:v00008086d00002937sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (QEMU Virtual Machine) + +@@ -79259,6 +88376,9 @@ pci:v00008086d00002938sv00001462sd00007345* + pci:v00008086d00002938sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (G33/P35 Neo) + ++pci:v00008086d00002938sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (ThinkPad T400) ++ + pci:v00008086d00002938sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (QEMU Virtual Machine) + +@@ -79295,6 +88415,9 @@ pci:v00008086d00002939sv00001462sd00007345* + pci:v00008086d00002939sv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (G33/P35 Neo) + ++pci:v00008086d00002939sv000017AAsd000020F0* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (ThinkPad T400) ++ + pci:v00008086d00002939sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (QEMU Virtual Machine) + +@@ -79349,6 +88472,9 @@ pci:v00008086d0000293Asv00001462sd00007345* + pci:v00008086d0000293Asv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (G33/P35 Neo) + ++pci:v00008086d0000293Asv000017AAsd000020F1* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (ThinkPad T400) ++ + pci:v00008086d0000293Asv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (QEMU Virtual Machine) + +@@ -79394,6 +88520,9 @@ pci:v00008086d0000293Csv00001462sd00007345* + pci:v00008086d0000293Csv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (G33/P35 Neo) + ++pci:v00008086d0000293Csv000017AAsd000020F1* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (ThinkPad T400) ++ + pci:v00008086d0000293Csv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (QEMU Virtual Machine) + +@@ -79430,6 +88559,9 @@ pci:v00008086d0000293Esv00001462sd0000735A* + pci:v00008086d0000293Esv00001462sd00007360* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (G33/P35 Neo) + ++pci:v00008086d0000293Esv000017AAsd000020F2* ++ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (ThinkPad T400) ++ + pci:v00008086d0000293Esv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (QEMU Virtual Machine) + +@@ -79517,12 +88649,18 @@ pci:v00008086d0000294Csv000017AAsd0000302E* + pci:v00008086d00002970* + ID_MODEL_FROM_DATABASE=82946GZ/PL/GL Memory Controller Hub + ++pci:v00008086d00002970sv00001043sd0000823B* ++ ID_MODEL_FROM_DATABASE=82946GZ/PL/GL Memory Controller Hub (P5B-MX/WiFi-AP) ++ + pci:v00008086d00002971* + ID_MODEL_FROM_DATABASE=82946GZ/PL/GL PCI Express Root Port + + pci:v00008086d00002972* + ID_MODEL_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller + ++pci:v00008086d00002972sv00001043sd0000823B* ++ ID_MODEL_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller (P5B-MX/WiFi-AP) ++ + pci:v00008086d00002973* + ID_MODEL_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller + +@@ -79814,12 +88952,18 @@ pci:v00008086d00002A00sv0000103Csd000030C0* + pci:v00008086d00002A00sv0000103Csd000030C1* + ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Compaq 6910p) + ++pci:v00008086d00002A00sv0000103Csd000030C5* ++ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Compaq 8510p) ++ + pci:v00008086d00002A00sv0000103Csd000030CC* + ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Pavilion dv6700) + + pci:v00008086d00002A00sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Presario C700) + ++pci:v00008086d00002A00sv00001043sd00001017* ++ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (X58LE) ++ + pci:v00008086d00002A00sv0000104Dsd00009005* + ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Vaio VGN-FZ260E) + +@@ -79859,6 +89003,9 @@ pci:v00008086d00002A02sv0000103Csd000030C0* + pci:v00008086d00002A02sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Presario C700) + ++pci:v00008086d00002A02sv00001043sd000014E2* ++ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (X58LE) ++ + pci:v00008086d00002A02sv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (VAIO VGN-NR120E) + +@@ -79886,6 +89033,9 @@ pci:v00008086d00002A03sv0000103Csd000030C0* + pci:v00008086d00002A03sv0000103Csd000030D9* + ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Presario C700) + ++pci:v00008086d00002A03sv00001043sd000014E2* ++ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (X58LE) ++ + pci:v00008086d00002A03sv0000104Dsd0000902D* + ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (VAIO VGN-NR120E) + +@@ -79955,6 +89105,9 @@ pci:v00008086d00002A17* + pci:v00008086d00002A40* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub + ++pci:v00008086d00002A40sv000017AAsd000020E0* ++ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub (ThinkPad T400) ++ + pci:v00008086d00002A40sv0000E4BFsd0000CC4D* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub (CCM-BOOGIE) + +@@ -79967,18 +89120,30 @@ pci:v00008086d00002A41sv0000E4BFsd0000CC4D* + pci:v00008086d00002A42* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller + ++pci:v00008086d00002A42sv00001028sd000002AA* ++ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (Dell Inspiron 1545) ++ ++pci:v00008086d00002A42sv000017AAsd00002112* ++ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (ThinkPad T400) ++ + pci:v00008086d00002A42sv0000E4BFsd0000CC4D* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (CCM-BOOGIE) + + pci:v00008086d00002A43* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller + ++pci:v00008086d00002A43sv000017AAsd00002112* ++ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (ThinkPad T400) ++ + pci:v00008086d00002A43sv0000E4BFsd0000CC4D* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (CCM-BOOGIE) + + pci:v00008086d00002A44* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller + ++pci:v00008086d00002A44sv000017AAsd000020E6* ++ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller (ThinkPad T400) ++ + pci:v00008086d00002A45* + ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller + +@@ -81179,6 +90344,9 @@ pci:v00008086d00002FFD* + pci:v00008086d00002FFE* + ID_MODEL_FROM_DATABASE=Xeon E7 v3/Xeon E5 v3/Core i7 System Address Decoder & Broadcast Registers + ++pci:v00008086d00003140* ++ ID_MODEL_FROM_DATABASE=Easel/Monette Hill Image Processor [Pixel Visual Core] ++ + pci:v00008086d00003165* + ID_MODEL_FROM_DATABASE=Wireless 3165 + +@@ -81191,6 +90359,117 @@ pci:v00008086d00003165sv00008086sd00004210* + pci:v00008086d00003166* + ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3165 Plus Bluetooth + ++pci:v00008086d00003166sv00008086sd00004210* ++ ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3165 Plus Bluetooth (Dual Band Wireless-AC 3165) ++ ++pci:v00008086d00003184* ++ ID_MODEL_FROM_DATABASE=GeminiLake [UHD Graphics 605] ++ ++pci:v00008086d00003185* ++ ID_MODEL_FROM_DATABASE=GeminiLake [UHD Graphics 600] ++ ++pci:v00008086d0000318C* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Dynamic Platform and Thermal Framework Processor Participant ++ ++pci:v00008086d0000318E* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor NorthPeak ++ ++pci:v00008086d00003190* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Gaussian Mixture Model ++ ++pci:v00008086d00003192* ++ ID_MODEL_FROM_DATABASE=Gemini Lake P2SB ++ ++pci:v00008086d00003197* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor PCI-default ISA-bridge ++ ++pci:v00008086d00003198* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor High Definition Audio ++ ++pci:v00008086d00003198sv000017AAsd0000380B* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor High Definition Audio (V130-15IGM Laptop (Lenovo) - Type 81HL) ++ ++pci:v00008086d0000319A* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Trusted Execution Engine Interface ++ ++pci:v00008086d000031A2* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Integrated Sensor Solution ++ ++pci:v00008086d000031A8* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor USB 3.0 xHCI Controller ++ ++pci:v00008086d000031A8sv00001849sd000031A8* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor USB 3.0 xHCI Controller ++ ++pci:v00008086d000031AC* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO I2C Host Controller ++ ++pci:v00008086d000031AE* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO I2C Host Controller ++ ++pci:v00008086d000031BC* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO UART Host Controller ++ ++pci:v00008086d000031BE* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO UART Host Controller ++ ++pci:v00008086d000031C0* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO UART Host Controller ++ ++pci:v00008086d000031C2* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO SPI Host Controller ++ ++pci:v00008086d000031C4* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO SPI Host Controller ++ ++pci:v00008086d000031C6* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO SPI Host Controller ++ ++pci:v00008086d000031CC* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor SDA Standard Compliant SD Host Controller ++ ++pci:v00008086d000031D4* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Gaussian Mixture Model ++ ++pci:v00008086d000031D6* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031D7* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031D8* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031D9* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031DA* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031DB* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCI Express Root Port ++ ++pci:v00008086d000031DC* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCH CNVi WiFi ++ ++pci:v00008086d000031DCsv00001A56sd00001552* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCH CNVi WiFi (Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)) ++ ++pci:v00008086d000031DCsv00008086sd00000034* ++ ID_MODEL_FROM_DATABASE=Gemini Lake PCH CNVi WiFi (Wireless-AC 9560) ++ ++pci:v00008086d000031E3* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor SATA Controller ++ ++pci:v00008086d000031E8* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor LPC Controller ++ ++pci:v00008086d000031EE* ++ ID_MODEL_FROM_DATABASE=Celeron/Pentium Silver Processor Serial IO UART Host Controller ++ ++pci:v00008086d000031F0* ++ ID_MODEL_FROM_DATABASE=Gemini Lake Host Bridge ++ + pci:v00008086d00003200* + ID_MODEL_FROM_DATABASE=GD31244 PCI-X SATA HBA + +@@ -81416,6 +90695,87 @@ pci:v00008086d00003433* + pci:v00008086d00003438* + ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Throttle Registers + ++pci:v00008086d00003482* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP LPC Controller ++ ++pci:v00008086d000034A3* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP SMBus Controller ++ ++pci:v00008086d000034A4* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP SPI Controller ++ ++pci:v00008086d000034A8* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO UART Controller #0 ++ ++pci:v00008086d000034A9* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO UART Controller #1 ++ ++pci:v00008086d000034AA* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO SPI Controller #0 ++ ++pci:v00008086d000034AB* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO SPI Controller #1 ++ ++pci:v00008086d000034B0* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCI Express Root Port #9 ++ ++pci:v00008086d000034B7* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCI Express Root Port #16 ++ ++pci:v00008086d000034BC* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCI Express Root Port #5 ++ ++pci:v00008086d000034C5* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2c Controller #4 ++ ++pci:v00008086d000034C6* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2c Controller #5 ++ ++pci:v00008086d000034C8* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Smart Sound Technology Audio Controller ++ ++pci:v00008086d000034D3* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP SATA Controller [AHCI mode] ++ ++pci:v00008086d000034E0* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Management Engine ++ ++pci:v00008086d000034E8* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2C Controller #0 ++ ++pci:v00008086d000034E9* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2C Controller #1 ++ ++pci:v00008086d000034EA* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2C Controller #2 ++ ++pci:v00008086d000034EB* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Serial IO I2C Controller #3 ++ ++pci:v00008086d000034ED* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP USB 3.1 xHCI Host Controller ++ ++pci:v00008086d000034EF* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP DRAM Controller ++ ++pci:v00008086d000034F0* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCH CNVi WiFi ++ ++pci:v00008086d000034F0sv00001A56sd00001552* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCH CNVi WiFi (Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)) ++ ++pci:v00008086d000034F0sv00008086sd00000074* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCH CNVi WiFi (Wi-Fi 6 AX201) ++ ++pci:v00008086d000034F0sv00008086sd00000264* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP PCH CNVi WiFi (Wireless-AC 9461) ++ ++pci:v00008086d000034F8* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP SD Controller ++ ++pci:v00008086d000034FC* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Integrated Sensor Solution ++ + pci:v00008086d00003500* + ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port + +@@ -81995,6 +91355,18 @@ pci:v00008086d0000373F* + pci:v00008086d000037C8* + ID_MODEL_FROM_DATABASE=C62x Chipset QuickAssist Technology + ++pci:v00008086d000037C8sv00008086sd00000001* ++ ID_MODEL_FROM_DATABASE=C62x Chipset QuickAssist Technology (QuickAssist Adapter 8960) ++ ++pci:v00008086d000037C8sv00008086sd00000002* ++ ID_MODEL_FROM_DATABASE=C62x Chipset QuickAssist Technology (QuickAssist Adapter 8970) ++ ++pci:v00008086d000037C9* ++ ID_MODEL_FROM_DATABASE=C62x Chipset QuickAssist Technology Virtual Function ++ ++pci:v00008086d000037CC* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 ++ + pci:v00008086d000037CD* + ID_MODEL_FROM_DATABASE=Ethernet Virtual Function 700 Series + +@@ -82007,6 +91379,9 @@ pci:v00008086d000037CEsv00001590sd00000215* + pci:v00008086d000037CEsv000017AAsd00004023* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE backplane (Intel Ethernet Connection X722 for 10GbE backplane) + ++pci:v00008086d000037CEsv000017AAsd00004025* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE backplane ++ + pci:v00008086d000037CF* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+ + +@@ -82058,9 +91433,15 @@ pci:v00008086d000037D1sv000017AAsd00004021* + pci:v00008086d000037D1sv000017AAsd00004022* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE + ++pci:v00008086d000037D1sv000017AAsd00004024* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE ++ + pci:v00008086d000037D2* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T + ++pci:v00008086d000037D2sv00001059sd00000180* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (RD10019 10GbE interface) ++ + pci:v00008086d000037D2sv00001170sd000037D2* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T + +@@ -82079,6 +91460,12 @@ pci:v00008086d000037D2sv000017AAsd00004021* + pci:v00008086d000037D2sv000017AAsd00004022* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T + ++pci:v00008086d000037D2sv000017AAsd00004024* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T ++ ++pci:v00008086d000037D2sv000017AAsd00004025* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T ++ + pci:v00008086d000037D3* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ + +@@ -82091,6 +91478,9 @@ pci:v00008086d000037D3sv000017AAsd00004020* + pci:v00008086d000037D3sv000017AAsd00004021* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ + ++pci:v00008086d000037D3sv000017AAsd00004025* ++ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ ++ + pci:v00008086d000037D4* + ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+ + +@@ -82562,6 +91952,9 @@ pci:v00008086d00003B13* + pci:v00008086d00003B14* + ID_MODEL_FROM_DATABASE=3420 Chipset LPC Interface Controller + ++pci:v00008086d00003B14sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=3420 Chipset LPC Interface Controller (X8SIL) ++ + pci:v00008086d00003B15* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +@@ -82607,6 +92000,9 @@ pci:v00008086d00003B22* + pci:v00008086d00003B22sv00001028sd000002DA* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (OptiPlex 980) + ++pci:v00008086d00003B22sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (X8SIL) ++ + pci:v00008086d00003B22sv000015D9sd0000060D* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (C7SIM-Q Motherboard) + +@@ -82700,6 +92096,9 @@ pci:v00008086d00003B30sv00001043sd00008383* + pci:v00008086d00003B30sv0000144Dsd0000C06A* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (R730 Laptop) + ++pci:v00008086d00003B30sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (X8SIL) ++ + pci:v00008086d00003B30sv000015D9sd0000060D* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (C7SIM-Q Motherboard) + +@@ -82742,6 +92141,9 @@ pci:v00008086d00003B34sv00001028sd0000040B* + pci:v00008086d00003B34sv0000144Dsd0000C06A* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (R730 Laptop) + ++pci:v00008086d00003B34sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (X8SIL) ++ + pci:v00008086d00003B34sv000015D9sd0000060D* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (C7SIM-Q Motherboard) + +@@ -82787,6 +92189,9 @@ pci:v00008086d00003B3Csv00001028sd0000040B* + pci:v00008086d00003B3Csv0000144Dsd0000C06A* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (R730 Laptop) + ++pci:v00008086d00003B3Csv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (X8SIL) ++ + pci:v00008086d00003B3Csv000015D9sd0000060D* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (C7SIM-Q Motherboard) + +@@ -82820,6 +92225,9 @@ pci:v00008086d00003B42sv00001028sd0000040A* + pci:v00008086d00003B42sv00001028sd0000040B* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (Latitude E6510) + ++pci:v00008086d00003B42sv0000103Csd00001521* ++ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (EliteBook 8540p) ++ + pci:v00008086d00003B42sv0000144Dsd0000C06A* + ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (R730 Laptop) + +@@ -83177,11 +92585,29 @@ pci:v00008086d00003CF5* + pci:v00008086d00003CF6* + ID_MODEL_FROM_DATABASE=Xeon E5/Core i7 System Address Decoder + ++pci:v00008086d00003E10* ++ ID_MODEL_FROM_DATABASE=8th Gen Core 4-core Processor Host Bridge/DRAM Registers [Coffee Lake H] ++ + pci:v00008086d00003E18* +- ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers ++ ID_MODEL_FROM_DATABASE=8th Gen Core 4-core Workstation Processor Host Bridge/DRAM Registers [Coffee Lake S] + + pci:v00008086d00003E1F* +- ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers ++ ID_MODEL_FROM_DATABASE=8th Gen Core 4-core Desktop Processor Host Bridge/DRAM Registers [Coffee Lake S] ++ ++pci:v00008086d00003E1Fsv00001458sd00005000* ++ ID_MODEL_FROM_DATABASE=8th Gen Core 4-core Desktop Processor Host Bridge/DRAM Registers [Coffee Lake S] (Z370 AORUS Gaming K3-CF) ++ ++pci:v00008086d00003E30* ++ ID_MODEL_FROM_DATABASE=8th/9th Gen Core 8-core Desktop Processor Host Bridge/DRAM Registers [Coffee Lake S] ++ ++pci:v00008086d00003E33* ++ ID_MODEL_FROM_DATABASE=8th/9th Gen Core Processor Host Bridge/DRAM Registers [Coffee Lake] ++ ++pci:v00008086d00003E34* ++ ID_MODEL_FROM_DATABASE=Coffee Lake HOST and DRAM Controller ++ ++pci:v00008086d00003E35* ++ ID_MODEL_FROM_DATABASE=Coffee Lake Host Bridge/DRAM Registers + + pci:v00008086d00003E81* + ID_MODEL_FROM_DATABASE=8th Gen Core Processor PCIe Controller (x16) +@@ -83192,12 +92618,48 @@ pci:v00008086d00003E85* + pci:v00008086d00003E89* + ID_MODEL_FROM_DATABASE=8th Gen Core Processor PCIe Controller (x4) + ++pci:v00008086d00003E90* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-S GT1 [UHD Graphics 610] ++ + pci:v00008086d00003E91* +- ID_MODEL_FROM_DATABASE=8th Gen Core Processor Gaussian Mixture Model ++ ID_MODEL_FROM_DATABASE=CoffeeLake-S GT2 [UHD Graphics 630] ++ ++pci:v00008086d00003E92* ++ ID_MODEL_FROM_DATABASE=CometLake-S GT2 [UHD Graphics 630] ++ ++pci:v00008086d00003E92sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=CometLake-S GT2 [UHD Graphics 630] (Vostro 3470) ++ ++pci:v00008086d00003E93* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-S GT1 [UHD Graphics 610] ++ ++pci:v00008086d00003E96* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-S GT2 [UHD Graphics P630] ++ ++pci:v00008086d00003E98* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-S GT2 [UHD Graphics 630] ++ ++pci:v00008086d00003E9B* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-H GT2 [UHD Graphics 630] ++ ++pci:v00008086d00003EA0* ++ ID_MODEL_FROM_DATABASE=WhiskeyLake-U GT2 [UHD Graphics 620] ++ ++pci:v00008086d00003EA0sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=WhiskeyLake-U GT2 [UHD Graphics 620] (Inspiron 5482) ++ ++pci:v00008086d00003EA5* ++ ID_MODEL_FROM_DATABASE=CoffeeLake-U GT3e [Iris Plus Graphics 655] + + pci:v00008086d00003EC2* + ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00003EC2sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers (Vostro 3470) ++ ++pci:v00008086d00003EC2sv00001043sd00008694* ++ ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers (PRIME H310M-D) ++ + pci:v00008086d00003EC4* + ID_MODEL_FROM_DATABASE=8th Gen Core Processor Host Bridge/DRAM Registers + +@@ -83270,6 +92732,9 @@ pci:v00008086d00004035* + pci:v00008086d00004036* + ID_MODEL_FROM_DATABASE=5400 Chipset FBD Registers + ++pci:v00008086d00004041* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] ++ + pci:v00008086d00004100* + ID_MODEL_FROM_DATABASE=Moorestown Graphics and Video + +@@ -83309,6 +92774,27 @@ pci:v00008086d00004116* + pci:v00008086d00004117* + ID_MODEL_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #4 + ++pci:v00008086d00004140* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] ++ ++pci:v00008086d00004140sv00001028sd00002134* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (SED 400GB 2.5" U.2 (P5800X)) ++ ++pci:v00008086d00004140sv00001028sd00002135* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (SED 800GB 2.5" U.2 (P5800X)) ++ ++pci:v00008086d00004140sv00001028sd00002136* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (SED 1.6TB 2.5" U.2 (P5800X)) ++ ++pci:v00008086d00004140sv00001028sd00002137* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (400GB 2.5" U.2 (P5800X)) ++ ++pci:v00008086d00004140sv00001028sd00002138* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (800GB 2.5" U.2 (P5800X)) ++ ++pci:v00008086d00004140sv00001028sd00002139* ++ ID_MODEL_FROM_DATABASE=NVMe Datacenter SSD [Optane] (1.6TB 2.5" U.2 (P5800X)) ++ + pci:v00008086d00004220* + ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection + +@@ -83576,9 +93062,156 @@ pci:v00008086d0000423Dsv00008086sd00001311* + pci:v00008086d0000423Dsv00008086sd00001316* + ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (ABG) + ++pci:v00008086d0000438B* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H LPC/eSPI Controller ++ ++pci:v00008086d000043A3* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H SMBus Controller ++ ++pci:v00008086d000043A4* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H SPI Controller ++ ++pci:v00008086d000043B0* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H PCI Express Root Port #9 ++ ++pci:v00008086d000043BC* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H PCI Express Root Port #5 ++ ++pci:v00008086d000043C8* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H HD Audio Controller ++ ++pci:v00008086d000043E0* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Management Engine Interface ++ ++pci:v00008086d000043E8* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Serial IO I2C Controller #0 ++ ++pci:v00008086d000043ED* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H USB 3.2 Gen 2x1 xHCI Host Controller ++ ++pci:v00008086d000043EF* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Shared SRAM ++ ++pci:v00008086d000043F0* ++ ID_MODEL_FROM_DATABASE=Tiger Lake PCH CNVi WiFi ++ ++pci:v00008086d000043F0sv00008086sd00000034* ++ ID_MODEL_FROM_DATABASE=Tiger Lake PCH CNVi WiFi (Wireless-AC 9560) ++ ++pci:v00008086d000043F0sv00008086sd00000074* ++ ID_MODEL_FROM_DATABASE=Tiger Lake PCH CNVi WiFi (Wi-Fi 6 AX201 160MHz) ++ ++pci:v00008086d000043F0sv00008086sd00000264* ++ ID_MODEL_FROM_DATABASE=Tiger Lake PCH CNVi WiFi (Wireless-AC 9461) ++ ++pci:v00008086d000043F0sv00008086sd000002A4* ++ ID_MODEL_FROM_DATABASE=Tiger Lake PCH CNVi WiFi (Wireless-AC 9462) ++ + pci:v00008086d0000444E* + ID_MODEL_FROM_DATABASE=Turbo Memory Controller + ++pci:v00008086d0000461E* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 USB Controller ++ ++pci:v00008086d0000461F* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 PCI Express Root Port #3 ++ ++pci:v00008086d0000462F* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 PCI Express Root Port #2 ++ ++pci:v00008086d0000463E* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 NHI #0 ++ ++pci:v00008086d0000463F* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 PCI Express Root Port #1 ++ ++pci:v00008086d0000466D* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 NHI #1 ++ ++pci:v00008086d0000466E* ++ ID_MODEL_FROM_DATABASE=Alder Lake-P Thunderbolt 4 PCI Express Root Port #0 ++ ++pci:v00008086d0000467F* ++ ID_MODEL_FROM_DATABASE=Volume Management Device NVMe RAID Controller ++ ++pci:v00008086d00004680* ++ ID_MODEL_FROM_DATABASE=AlderLake-S GT1 ++ ++pci:v00008086d000046A0* ++ ID_MODEL_FROM_DATABASE=AlderLake-P GT2 ++ ++pci:v00008086d000046C0* ++ ID_MODEL_FROM_DATABASE=AlderLake-M GT1 ++ ++pci:v00008086d00004905* ++ ID_MODEL_FROM_DATABASE=DG1 [Iris Xe MAX Graphics] ++ ++pci:v00008086d00004906* ++ ID_MODEL_FROM_DATABASE=DG1 [Iris Xe Pod] ++ ++pci:v00008086d00004907* ++ ID_MODEL_FROM_DATABASE=SG1 [Server GPU SG-18M] ++ ++pci:v00008086d00004908* ++ ID_MODEL_FROM_DATABASE=DG1 [Iris Xe Graphics] ++ ++pci:v00008086d00004C3D* ++ ID_MODEL_FROM_DATABASE=Volume Management Device NVMe RAID Controller ++ ++pci:v00008086d00004C8A* ++ ID_MODEL_FROM_DATABASE=RocketLake-S GT1 [UHD Graphics 750] ++ ++pci:v00008086d00004C8B* ++ ID_MODEL_FROM_DATABASE=RocketLake-S GT1 [UHD Graphics 730] ++ ++pci:v00008086d00004C90* ++ ID_MODEL_FROM_DATABASE=RocketLake-S GT1 [UHD Graphics P750] ++ ++pci:v00008086d00004C9A* ++ ID_MODEL_FROM_DATABASE=RocketLake-S [UHD Graphics] ++ ++pci:v00008086d00004DA3* ++ ID_MODEL_FROM_DATABASE=JaserLake SMBus ++ ++pci:v00008086d00004DA4* ++ ID_MODEL_FROM_DATABASE=JaserLake SPI (flash) Controller ++ ++pci:v00008086d00004DE0* ++ ID_MODEL_FROM_DATABASE=Management Engine Interface ++ ++pci:v00008086d00004DE8* ++ ID_MODEL_FROM_DATABASE=Serial IO I2C Host Controller ++ ++pci:v00008086d00004DE9* ++ ID_MODEL_FROM_DATABASE=Serial IO I2C Host Controller ++ ++pci:v00008086d00004DF0* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX201 160MHz ++ ++pci:v00008086d00004E03* ++ ID_MODEL_FROM_DATABASE=Dynamic Tuning service ++ ++pci:v00008086d00004E19* ++ ID_MODEL_FROM_DATABASE=JasperLake IPU ++ ++pci:v00008086d00004E55* ++ ID_MODEL_FROM_DATABASE=JasperLake [UHD Graphics] ++ ++pci:v00008086d00004E61* ++ ID_MODEL_FROM_DATABASE=JasperLake [UHD Graphics] ++ ++pci:v00008086d00004E71* ++ ID_MODEL_FROM_DATABASE=JasperLake [UHD Graphics] ++ ++pci:v00008086d00004F80* ++ ID_MODEL_FROM_DATABASE=DG2 ++ ++pci:v00008086d00004F81* ++ ID_MODEL_FROM_DATABASE=DG2 ++ ++pci:v00008086d00004F82* ++ ID_MODEL_FROM_DATABASE=DG2 ++ + pci:v00008086d00005001* + ID_MODEL_FROM_DATABASE=LE80578 + +@@ -83732,39 +93365,81 @@ pci:v00008086d00005201sv00008086sd00000001* + pci:v00008086d0000530D* + ID_MODEL_FROM_DATABASE=80310 (IOP) IO Processor + ++pci:v00008086d00005502* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller (2) I225-LMvP ++ ++pci:v00008086d00005504* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller I226-K ++ + pci:v00008086d00005845* + ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller + + pci:v00008086d00005845sv00001AF4sd00001100* + ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller (QEMU Virtual Machine) + ++pci:v00008086d00005900* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00005901* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor PCIe Controller (x16) ++ + pci:v00008086d00005902* + ID_MODEL_FROM_DATABASE=HD Graphics 610 + + pci:v00008086d00005904* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00005904sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (Aspire E5-575G) ++ + pci:v00008086d00005904sv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad T570) + + pci:v00008086d00005904sv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d00005905* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor PCIe Controller (x8) ++ ++pci:v00008086d00005909* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor PCIe Controller (x4) ++ ++pci:v00008086d0000590C* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers ++ + pci:v00008086d0000590F* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d0000590Fsv00001462sd00007A68* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (B250 KRAIT GAMING (MS-7A68)) ++ ++pci:v00008086d0000590Fsv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (H270 PC MATE) ++ + pci:v00008086d00005910* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00005911* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Gaussian Mixture Model ++ + pci:v00008086d00005912* + ID_MODEL_FROM_DATABASE=HD Graphics 630 + ++pci:v00008086d00005912sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=HD Graphics 630 (H270 PC MATE) ++ + pci:v00008086d00005914* + ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + ++pci:v00008086d00005914sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad T480) ++ + pci:v00008086d00005916* + ID_MODEL_FROM_DATABASE=HD Graphics 620 + ++pci:v00008086d00005916sv00001025sd00001094* ++ ID_MODEL_FROM_DATABASE=HD Graphics 620 (Aspire E5-575G) ++ + pci:v00008086d00005916sv000017AAsd00002248* + ID_MODEL_FROM_DATABASE=HD Graphics 620 (ThinkPad T570) + +@@ -83774,15 +93449,42 @@ pci:v00008086d00005916sv000017AAsd0000224F* + pci:v00008086d00005917* + ID_MODEL_FROM_DATABASE=UHD Graphics 620 + ++pci:v00008086d00005917sv000017AAsd0000225E* ++ ID_MODEL_FROM_DATABASE=UHD Graphics 620 (ThinkPad T480) ++ ++pci:v00008086d00005918* ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d0000591B* ++ ID_MODEL_FROM_DATABASE=HD Graphics 630 ++ ++pci:v00008086d0000591C* ++ ID_MODEL_FROM_DATABASE=UHD Graphics 615 ++ + pci:v00008086d0000591D* + ID_MODEL_FROM_DATABASE=HD Graphics P630 + ++pci:v00008086d0000591E* ++ ID_MODEL_FROM_DATABASE=HD Graphics 615 ++ + pci:v00008086d0000591F* +- ID_MODEL_FROM_DATABASE=Intel Kaby Lake Host Bridge ++ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00005923* ++ ID_MODEL_FROM_DATABASE=HD Graphics 635 ++ ++pci:v00008086d00005926* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics 640 ++ ++pci:v00008086d00005927* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics 650 + + pci:v00008086d00005A84* + ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller + ++pci:v00008086d00005A85* ++ ID_MODEL_FROM_DATABASE=HD Graphics 500 ++ + pci:v00008086d00005A88* + ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Imaging Unit + +@@ -83948,6 +93650,9 @@ pci:v00008086d000065FF* + pci:v00008086d00006F00* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + ++pci:v00008086d00006F00sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 (X10SRL-F) ++ + pci:v00008086d00006F01* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI Express Root Port 0 + +@@ -84032,39 +93737,75 @@ pci:v00008086d00006F1F* + pci:v00008086d00006F20* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 0 + ++pci:v00008086d00006F20sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 0 (X10SRL-F) ++ + pci:v00008086d00006F21* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 1 + ++pci:v00008086d00006F21sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 1 (X10SRL-F) ++ + pci:v00008086d00006F22* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 2 + ++pci:v00008086d00006F22sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 2 (X10SRL-F) ++ + pci:v00008086d00006F23* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 3 + ++pci:v00008086d00006F23sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 3 (X10SRL-F) ++ + pci:v00008086d00006F24* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 4 + ++pci:v00008086d00006F24sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 4 (X10SRL-F) ++ + pci:v00008086d00006F25* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 5 + ++pci:v00008086d00006F25sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 5 (X10SRL-F) ++ + pci:v00008086d00006F26* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 6 + ++pci:v00008086d00006F26sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 6 (X10SRL-F) ++ + pci:v00008086d00006F27* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 7 + ++pci:v00008086d00006F27sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Crystal Beach DMA Channel 7 (X10SRL-F) ++ + pci:v00008086d00006F28* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Map/VTd_Misc/System Management + ++pci:v00008086d00006F28sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Map/VTd_Misc/System Management (X10SRL-F) ++ + pci:v00008086d00006F29* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D IIO Hot Plug + ++pci:v00008086d00006F29sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D IIO Hot Plug (X10SRL-F) ++ + pci:v00008086d00006F2A* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D IIO RAS/Control Status/Global Errors + ++pci:v00008086d00006F2Asv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D IIO RAS/Control Status/Global Errors (X10SRL-F) ++ + pci:v00008086d00006F2C* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC + ++pci:v00008086d00006F2Csv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (X10SRL-F) ++ + pci:v00008086d00006F30* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Home Agent 0 + +@@ -84131,6 +93872,9 @@ pci:v00008086d00006F53* + pci:v00008086d00006F54* + ID_MODEL_FROM_DATABASE=Xeon Processor D Family QuickAssist Technology + ++pci:v00008086d00006F55* ++ ID_MODEL_FROM_DATABASE=Xeon Processor D Family QuickAssist Technology Virtual Fuction ++ + pci:v00008086d00006F60* + ID_MODEL_FROM_DATABASE=Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Home Agent 1 + +@@ -84662,6 +94406,9 @@ pci:v00008086d000071A2* + pci:v00008086d000071A2sv00004C53sd00001000* + ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge (AGP disabled) (CC7/CR7/CP7/VC7/VP7/VR7 mainboard) + ++pci:v00008086d00007360* ++ ID_MODEL_FROM_DATABASE=XMM7360 LTE Advanced Modem ++ + pci:v00008086d00007600* + ID_MODEL_FROM_DATABASE=82372FB PIIX5 ISA + +@@ -84705,49 +94452,55 @@ pci:v00008086d00008003* + ID_MODEL_FROM_DATABASE=Trusted Execution Technology Registers + + pci:v00008086d00008100* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) ++ ID_MODEL_FROM_DATABASE=US15W/US15X SCH [Poulsbo] Host Bridge ++ ++pci:v00008086d00008101* ++ ID_MODEL_FROM_DATABASE=US15L/UL11L SCH [Poulsbo] Host Bridge + + pci:v00008086d00008108* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) Graphics Controller ++ ID_MODEL_FROM_DATABASE=US15W/US15X SCH [Poulsbo] Graphics Controller ++ ++pci:v00008086d00008109* ++ ID_MODEL_FROM_DATABASE=US15L/UL11L SCH [Poulsbo] Graphics Controller + + pci:v00008086d00008110* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 1 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] PCI Express Port 1 + + pci:v00008086d00008112* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 2 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] PCI Express Port 2 + + pci:v00008086d00008114* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #1 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] USB UHCI Controller #1 + + pci:v00008086d00008115* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #2 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] USB UHCI Controller #2 + + pci:v00008086d00008116* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #3 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] USB UHCI Controller #3 + + pci:v00008086d00008117* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB EHCI #1 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] USB EHCI Controller + + pci:v00008086d00008118* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB Client Controller ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] USB Client Controller + + pci:v00008086d00008119* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) LPC Bridge ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] LPC Bridge + + pci:v00008086d0000811A* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) IDE Controller ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] IDE Controller + + pci:v00008086d0000811B* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) HD Audio Controller ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] HD Audio Controller + + pci:v00008086d0000811C* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #1 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] SDIO/MMC Controller #1 + + pci:v00008086d0000811D* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #2 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] SDIO/MMC Controller #2 + + pci:v00008086d0000811E* +- ID_MODEL_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #3 ++ ID_MODEL_FROM_DATABASE=US15W/US15X/US15L/UL11L SCH [Poulsbo] SDIO/MMC Controller #3 + + pci:v00008086d00008180* + ID_MODEL_FROM_DATABASE=Atom Processor E6xx PCI Express Port 3 +@@ -84815,6 +94568,12 @@ pci:v00008086d00008500sv00001993sd00000DEE* + pci:v00008086d00008500sv00001993sd00000DEF* + ID_MODEL_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100) (mGuard-PCI AV#0) + ++pci:v00008086d00008603* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Dynamic Tuning Processor Participant ++ ++pci:v00008086d000087C0* ++ ID_MODEL_FROM_DATABASE=UHD Graphics 617 ++ + pci:v00008086d00008800* + ID_MODEL_FROM_DATABASE=Platform Controller Hub EG20T PCI Express Port + +@@ -84893,6 +94652,48 @@ pci:v00008086d00008818* + pci:v00008086d00008819* + ID_MODEL_FROM_DATABASE=Platform Controller Hub EG20T IEEE 1588 Hardware Assist + ++pci:v00008086d00008A0D* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 NHI #1 ++ ++pci:v00008086d00008A12* ++ ID_MODEL_FROM_DATABASE=Ice Lake-LP Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00008A13* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 USB Controller ++ ++pci:v00008086d00008A17* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 NHI #0 ++ ++pci:v00008086d00008A19* ++ ID_MODEL_FROM_DATABASE=Image Signal Processor ++ ++pci:v00008086d00008A1D* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 PCI Express Root Port #0 ++ ++pci:v00008086d00008A1F* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 PCI Express Root Port #1 ++ ++pci:v00008086d00008A21* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 PCI Express Root Port #2 ++ ++pci:v00008086d00008A23* ++ ID_MODEL_FROM_DATABASE=Ice Lake Thunderbolt 3 PCI Express Root Port #3 ++ ++pci:v00008086d00008A51* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics G7 (Ice Lake) ++ ++pci:v00008086d00008A52* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics G7 ++ ++pci:v00008086d00008A56* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics G1 (Ice Lake) ++ ++pci:v00008086d00008A5A* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics G4 (Ice Lake) ++ ++pci:v00008086d00008A5C* ++ ID_MODEL_FROM_DATABASE=Iris Plus Graphics G4 (Ice Lake) ++ + pci:v00008086d00008C00* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 4-port SATA Controller 1 [IDE mode] + +@@ -84902,6 +94703,18 @@ pci:v00008086d00008C01* + pci:v00008086d00008C02* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] + ++pci:v00008086d00008C02sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (Alienware X51 R2) ++ ++pci:v00008086d00008C02sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (EliteDesk 800 G1) ++ ++pci:v00008086d00008C02sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (ThinkCentre E73) ++ ++pci:v00008086d00008C02sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (ThinkCentre M83) ++ + pci:v00008086d00008C03* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] + +@@ -84938,15 +94751,27 @@ pci:v00008086d00008C0F* + pci:v00008086d00008C10* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 + ++pci:v00008086d00008C10sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 (EliteDesk 800 G1) ++ ++pci:v00008086d00008C10sv00001043sd00008534* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 (ASUS H81I-PLUS) ++ + pci:v00008086d00008C10sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 (ThinkPad T440p) + ++pci:v00008086d00008C10sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 (ThinkCentre E73) ++ + pci:v00008086d00008C11* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 + + pci:v00008086d00008C12* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 + ++pci:v00008086d00008C12sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 (EliteDesk 800 G1) ++ + pci:v00008086d00008C12sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 (ThinkPad T440p) + +@@ -84974,6 +94799,9 @@ pci:v00008086d00008C19* + pci:v00008086d00008C1A* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #6 + ++pci:v00008086d00008C1Asv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #6 (ThinkCentre E73) ++ + pci:v00008086d00008C1B* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #6 + +@@ -84992,24 +94820,45 @@ pci:v00008086d00008C1F* + pci:v00008086d00008C20* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller + ++pci:v00008086d00008C20sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (Alienware X51 R2) ++ + pci:v00008086d00008C20sv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (ZBook 15) + ++pci:v00008086d00008C20sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (EliteDesk 800 G1) ++ + pci:v00008086d00008C20sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (ThinkPad T440p) + ++pci:v00008086d00008C20sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (ThinkCentre M83) ++ + pci:v00008086d00008C21* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller + + pci:v00008086d00008C22* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller + ++pci:v00008086d00008C22sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (Alienware X51 R2) ++ + pci:v00008086d00008C22sv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ZBook 15) + ++pci:v00008086d00008C22sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (EliteDesk 800 G1) ++ + pci:v00008086d00008C22sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ThinkPad T440p) + ++pci:v00008086d00008C22sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ThinkCentre E73) ++ ++pci:v00008086d00008C22sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ThinkCentre M83) ++ + pci:v00008086d00008C23* + ID_MODEL_FROM_DATABASE=8 Series Chipset Family CHAP Counters + +@@ -85019,36 +94868,72 @@ pci:v00008086d00008C24* + pci:v00008086d00008C26* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 + ++pci:v00008086d00008C26sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (Alienware X51 R2) ++ + pci:v00008086d00008C26sv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ZBook 15) + ++pci:v00008086d00008C26sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (EliteDesk 800 G1) ++ + pci:v00008086d00008C26sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T440p) + + pci:v00008086d00008C26sv000017AAsd00002210* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T540p) + ++pci:v00008086d00008C26sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkCentre E73) ++ ++pci:v00008086d00008C26sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkCentre M83) ++ + pci:v00008086d00008C26sv00002210sd000017AA* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T540p) + + pci:v00008086d00008C2D* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 + ++pci:v00008086d00008C2Dsv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (Alienware X51 R2) ++ + pci:v00008086d00008C2Dsv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ZBook 15) + ++pci:v00008086d00008C2Dsv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (EliteDesk 800 G1) ++ + pci:v00008086d00008C2Dsv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ThinkPad T440p) + ++pci:v00008086d00008C2Dsv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ThinkCentre E73) ++ ++pci:v00008086d00008C2Dsv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ThinkCentre M83) ++ + pci:v00008086d00008C31* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI + ++pci:v00008086d00008C31sv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (Alienware X51 R2) ++ + pci:v00008086d00008C31sv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ZBook 15) + ++pci:v00008086d00008C31sv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (EliteDesk 800 G1) ++ + pci:v00008086d00008C31sv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ThinkPad T440p) + ++pci:v00008086d00008C31sv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ThinkCentre E73) ++ ++pci:v00008086d00008C31sv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ThinkCentre M83) ++ + pci:v00008086d00008C33* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LAN Controller + +@@ -85058,12 +94943,24 @@ pci:v00008086d00008C34* + pci:v00008086d00008C3A* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 + ++pci:v00008086d00008C3Asv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (Alienware X51 R2) ++ + pci:v00008086d00008C3Asv0000103Csd00001909* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ZBook 15) + ++pci:v00008086d00008C3Asv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (EliteDesk 800 G1) ++ + pci:v00008086d00008C3Asv000017AAsd0000220E* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ThinkPad T440p) + ++pci:v00008086d00008C3Asv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ThinkCentre E73) ++ ++pci:v00008086d00008C3Asv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ThinkCentre M83) ++ + pci:v00008086d00008C3B* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #2 + +@@ -85073,6 +94970,9 @@ pci:v00008086d00008C3C* + pci:v00008086d00008C3D* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family KT Controller + ++pci:v00008086d00008C3Dsv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family KT Controller (EliteDesk 800 G1) ++ + pci:v00008086d00008C40* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller + +@@ -85106,18 +95006,27 @@ pci:v00008086d00008C49* + pci:v00008086d00008C4A* + ID_MODEL_FROM_DATABASE=H87 Express LPC Controller + ++pci:v00008086d00008C4Asv00001028sd000005D7* ++ ID_MODEL_FROM_DATABASE=H87 Express LPC Controller (Alienware X51 R2) ++ + pci:v00008086d00008C4B* + ID_MODEL_FROM_DATABASE=HM87 Express LPC Controller + + pci:v00008086d00008C4C* + ID_MODEL_FROM_DATABASE=Q85 Express LPC Controller + ++pci:v00008086d00008C4Csv000017AAsd0000309F* ++ ID_MODEL_FROM_DATABASE=Q85 Express LPC Controller (ThinkCentre M83) ++ + pci:v00008086d00008C4D* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller + + pci:v00008086d00008C4E* + ID_MODEL_FROM_DATABASE=Q87 Express LPC Controller + ++pci:v00008086d00008C4Esv0000103Csd00001998* ++ ID_MODEL_FROM_DATABASE=Q87 Express LPC Controller (EliteDesk 800 G1) ++ + pci:v00008086d00008C4F* + ID_MODEL_FROM_DATABASE=QM87 Express LPC Controller + +@@ -85164,7 +95073,10 @@ pci:v00008086d00008C5B* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller + + pci:v00008086d00008C5C* +- ID_MODEL_FROM_DATABASE=C220 Series Chipset Family H81 Express LPC Controller ++ ID_MODEL_FROM_DATABASE=H81 Express LPC Controller ++ ++pci:v00008086d00008C5Csv000017AAsd00003098* ++ ID_MODEL_FROM_DATABASE=H81 Express LPC Controller (ThinkCentre E73) + + pci:v00008086d00008C5D* + ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller +@@ -85275,13 +95187,16 @@ pci:v00008086d00008CC2* + ID_MODEL_FROM_DATABASE=9 Series Chipset Family LPC Controller + + pci:v00008086d00008CC3* +- ID_MODEL_FROM_DATABASE=9 Series Chipset Family HM97 LPC Controller ++ ID_MODEL_FROM_DATABASE=HM97 Chipset LPC Controller + + pci:v00008086d00008CC4* +- ID_MODEL_FROM_DATABASE=9 Series Chipset Family Z97 LPC Controller ++ ID_MODEL_FROM_DATABASE=Z97 Chipset LPC Controller ++ ++pci:v00008086d00008CC5* ++ ID_MODEL_FROM_DATABASE=QM97 Chipset LPC Controller + + pci:v00008086d00008CC6* +- ID_MODEL_FROM_DATABASE=9 Series Chipset Family H97 Controller ++ ID_MODEL_FROM_DATABASE=H97 Chipset LPC Controller + + pci:v00008086d00008D00* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset 4-port SATA Controller [IDE mode] +@@ -85361,18 +95276,30 @@ pci:v00008086d00008D21* + pci:v00008086d00008D22* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset SMBus Controller + ++pci:v00008086d00008D22sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset SMBus Controller (X10SRL-F) ++ + pci:v00008086d00008D24* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset Thermal Subsystem + + pci:v00008086d00008D26* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB Enhanced Host Controller #1 + ++pci:v00008086d00008D26sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB Enhanced Host Controller #1 (X10SRL-F) ++ + pci:v00008086d00008D2D* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB Enhanced Host Controller #2 + ++pci:v00008086d00008D2Dsv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB Enhanced Host Controller #2 (X10SRL-F) ++ + pci:v00008086d00008D31* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB xHCI Host Controller + ++pci:v00008086d00008D31sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset USB xHCI Host Controller (X10SRL-F) ++ + pci:v00008086d00008D33* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset LAN Controller + +@@ -85382,9 +95309,15 @@ pci:v00008086d00008D34* + pci:v00008086d00008D3A* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset MEI Controller #1 + ++pci:v00008086d00008D3Asv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset MEI Controller #1 (X10SRL-F) ++ + pci:v00008086d00008D3B* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset MEI Controller #2 + ++pci:v00008086d00008D3Bsv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset MEI Controller #2 (X10SRL-F) ++ + pci:v00008086d00008D3C* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset IDE-r Controller + +@@ -85406,6 +95339,9 @@ pci:v00008086d00008D43* + pci:v00008086d00008D44* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset LPC Controller + ++pci:v00008086d00008D44sv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset LPC Controller (X10SRL-F) ++ + pci:v00008086d00008D45* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset LPC Controller + +@@ -85460,6 +95396,9 @@ pci:v00008086d00008D6E* + pci:v00008086d00008D7C* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset SPSR + ++pci:v00008086d00008D7Csv000015D9sd00000832* ++ ID_MODEL_FROM_DATABASE=C610/X99 series chipset SPSR (X10SRL-F) ++ + pci:v00008086d00008D7D* + ID_MODEL_FROM_DATABASE=C610/X99 series chipset MS SMBus 0 + +@@ -85493,6 +95432,126 @@ pci:v00008086d00009641* + pci:v00008086d000096A1* + ID_MODEL_FROM_DATABASE=Integrated RAID + ++pci:v00008086d00009A01* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller #1 ++ ++pci:v00008086d00009A03* ++ ID_MODEL_FROM_DATABASE=TigerLake-LP Dynamic Tuning Processor Participant ++ ++pci:v00008086d00009A09* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller ++ ++pci:v00008086d00009A0B* ++ ID_MODEL_FROM_DATABASE=Volume Management Device NVMe RAID Controller ++ ++pci:v00008086d00009A0D* ++ ID_MODEL_FROM_DATABASE=Tigerlake Telemetry Aggregator Driver ++ ++pci:v00008086d00009A0F* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor PCIe Controller #0 ++ ++pci:v00008086d00009A11* ++ ID_MODEL_FROM_DATABASE=GNA Scoring Accelerator module ++ ++pci:v00008086d00009A13* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 USB Controller ++ ++pci:v00008086d00009A14* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009A17* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 USB Controller ++ ++pci:v00008086d00009A1B* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 NHI #0 ++ ++pci:v00008086d00009A1D* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 NHI #1 ++ ++pci:v00008086d00009A1F* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 NHI #0 ++ ++pci:v00008086d00009A21* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 NHI #1 ++ ++pci:v00008086d00009A23* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #0 ++ ++pci:v00008086d00009A25* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #1 ++ ++pci:v00008086d00009A26* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009A27* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #2 ++ ++pci:v00008086d00009A29* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #3 ++ ++pci:v00008086d00009A2B* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 PCI Express Root Port #0 ++ ++pci:v00008086d00009A2D* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 PCI Express Root Port #1 ++ ++pci:v00008086d00009A2F* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 PCI Express Root Port #2 ++ ++pci:v00008086d00009A31* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-H Thunderbolt 4 PCI Express Root Port #3 ++ ++pci:v00008086d00009A33* ++ ID_MODEL_FROM_DATABASE=Tiger Lake Trace Hub ++ ++pci:v00008086d00009A36* ++ ID_MODEL_FROM_DATABASE=11th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009A49* ++ ID_MODEL_FROM_DATABASE=TigerLake-LP GT2 [Iris Xe Graphics] ++ ++pci:v00008086d00009A60* ++ ID_MODEL_FROM_DATABASE=TigerLake-H GT1 [UHD Graphics] ++ ++pci:v00008086d00009A68* ++ ID_MODEL_FROM_DATABASE=TigerLake-H GT1 [UHD Graphics] ++ ++pci:v00008086d00009B41* ++ ID_MODEL_FROM_DATABASE=CometLake-U GT2 [UHD Graphics] ++ ++pci:v00008086d00009B41sv00001028sd000009BD* ++ ID_MODEL_FROM_DATABASE=CometLake-U GT2 [UHD Graphics] (Latitude 7310) ++ ++pci:v00008086d00009B44* ++ ID_MODEL_FROM_DATABASE=10th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009B53* ++ ID_MODEL_FROM_DATABASE=Comet Lake-S 6c Host Bridge/DRAM Controller ++ ++pci:v00008086d00009B54* ++ ID_MODEL_FROM_DATABASE=10th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009B61* ++ ID_MODEL_FROM_DATABASE=Comet Lake-U v1 4c Host Bridge/DRAM Controller ++ ++pci:v00008086d00009B63* ++ ID_MODEL_FROM_DATABASE=10th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009B64* ++ ID_MODEL_FROM_DATABASE=10th Gen Core Processor Host Bridge/DRAM Registers ++ ++pci:v00008086d00009BC4* ++ ID_MODEL_FROM_DATABASE=CometLake-H GT2 [UHD Graphics] ++ ++pci:v00008086d00009BC5* ++ ID_MODEL_FROM_DATABASE=CometLake-S GT2 [UHD Graphics 630] ++ ++pci:v00008086d00009BC8* ++ ID_MODEL_FROM_DATABASE=CometLake-S GT2 [UHD Graphics 630] ++ ++pci:v00008086d00009BCA* ++ ID_MODEL_FROM_DATABASE=Comet Lake UHD Graphics ++ + pci:v00008086d00009C00* + ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [IDE mode] + +@@ -85811,18 +95870,39 @@ pci:v00008086d00009CE6* + pci:v00008086d00009D03* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] + ++pci:v00008086d00009D03sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D03sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (Latitude E7470) ++ ++pci:v00008086d00009D03sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D03sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (Latitude 3570) + ++pci:v00008086d00009D03sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (EliteBook 840 G3) ++ ++pci:v00008086d00009D03sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (ThinkPad T480) ++ + pci:v00008086d00009D03sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (B51-80 Laptop) + + pci:v00008086d00009D10* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #1 + ++pci:v00008086d00009D11* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #2 ++ + pci:v00008086d00009D12* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #3 + ++pci:v00008086d00009D13* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #4 ++ + pci:v00008086d00009D14* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #5 + +@@ -85844,36 +95924,81 @@ pci:v00008086d00009D17* + pci:v00008086d00009D18* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #9 + ++pci:v00008086d00009D18sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #9 (ThinkPad T570) ++ + pci:v00008086d00009D18sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #9 (B51-80 Laptop) + + pci:v00008086d00009D19* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #10 + ++pci:v00008086d00009D1A* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #11 ++ + pci:v00008086d00009D21* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC + ++pci:v00008086d00009D21sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D21sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude 7275 tablet) ++ ++pci:v00008086d00009D21sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude E7470) ++ ++pci:v00008086d00009D21sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D21sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude 3570) + ++pci:v00008086d00009D21sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (EliteBook 840 G3) ++ ++pci:v00008086d00009D21sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (ThinkPad T570) ++ + pci:v00008086d00009D21sv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d00009D21sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (ThinkPad T480) ++ + pci:v00008086d00009D21sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (B51-80 Laptop) + + pci:v00008086d00009D23* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus + ++pci:v00008086d00009D23sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D23sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude 7275 tablet) ++ ++pci:v00008086d00009D23sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude E7470) ++ ++pci:v00008086d00009D23sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D23sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude 3570) + ++pci:v00008086d00009D23sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (EliteBook 840 G3) ++ + pci:v00008086d00009D23sv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (ThinkPad T570) + + pci:v00008086d00009D23sv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d00009D23sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (ThinkPad T480) ++ + pci:v00008086d00009D23sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (B51-80 Laptop) + +@@ -85895,62 +96020,164 @@ pci:v00008086d00009D2D* + pci:v00008086d00009D2F* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller + ++pci:v00008086d00009D2Fsv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D2Fsv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (Latitude 7275 tablet) ++ ++pci:v00008086d00009D2Fsv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (Latitude E7470) ++ ++pci:v00008086d00009D2Fsv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D2Fsv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (Latitude 3570) + ++pci:v00008086d00009D2Fsv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (EliteBook 840 G3) ++ + pci:v00008086d00009D2Fsv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (ThinkPad T570) + ++pci:v00008086d00009D2Fsv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (ThinkPad T480) ++ + pci:v00008086d00009D2Fsv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller (B51-80 Laptop) + + pci:v00008086d00009D31* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem + ++pci:v00008086d00009D31sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D31sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude 7275 tablet) ++ ++pci:v00008086d00009D31sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude E7470) ++ ++pci:v00008086d00009D31sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D31sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude 3570) + ++pci:v00008086d00009D31sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (EliteBook 840 G3) ++ + pci:v00008086d00009D31sv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (ThinkPad T570) + + pci:v00008086d00009D31sv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d00009D31sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (ThinkPad T480) ++ + pci:v00008086d00009D31sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (B51-80 Laptop) + ++pci:v00008086d00009D32* ++ ID_MODEL_FROM_DATABASE=CSI-2 Host Controller ++ ++pci:v00008086d00009D32sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=CSI-2 Host Controller (Latitude 7275 tablet) ++ ++pci:v00008086d00009D32sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=CSI-2 Host Controller (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D35* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Integrated Sensor Hub + ++pci:v00008086d00009D35sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Integrated Sensor Hub (Latitude 7275 tablet) ++ ++pci:v00008086d00009D35sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Integrated Sensor Hub (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D3A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 + ++pci:v00008086d00009D3Asv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D3Asv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude 7275 tablet) ++ ++pci:v00008086d00009D3Asv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude E7470) ++ ++pci:v00008086d00009D3Asv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D3Asv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude 3570) + ++pci:v00008086d00009D3Asv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (EliteBook 840 G3) ++ + pci:v00008086d00009D3Asv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (ThinkPad T570) + + pci:v00008086d00009D3Asv000017AAsd0000224F* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (ThinkPad X1 Carbon 5th Gen) + ++pci:v00008086d00009D3Asv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (ThinkPad T480) ++ + pci:v00008086d00009D3Asv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (B51-80 Laptop) + ++pci:v00008086d00009D3D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Active Management Technology - SOL ++ ++pci:v00008086d00009D3Dsv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Active Management Technology - SOL (EliteBook 840 G3) ++ ++pci:v00008086d00009D3Dsv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Active Management Technology - SOL (ThinkPad T570) ++ + pci:v00008086d00009D43* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller + + pci:v00008086d00009D43sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (B51-80 Laptop) + ++pci:v00008086d00009D46* ++ ID_MODEL_FROM_DATABASE=LPC/eSPI Controller ++ ++pci:v00008086d00009D46sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=LPC/eSPI Controller (Latitude 7275 tablet) ++ ++pci:v00008086d00009D46sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=LPC/eSPI Controller (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D48* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller + ++pci:v00008086d00009D48sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (Latitude E7470) ++ + pci:v00008086d00009D48sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (Latitude 3570) + ++pci:v00008086d00009D48sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (EliteBook 840 G3) ++ ++pci:v00008086d00009D48sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (ThinkPad T570) ++ + pci:v00008086d00009D4E* +- ID_MODEL_FROM_DATABASE=Intel(R) 100 Series Chipset Family LPC Controller/eSPI Controller - 9D4E ++ ID_MODEL_FROM_DATABASE=Sunrise Point LPC Controller/eSPI Controller ++ ++pci:v00008086d00009D4Esv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point LPC Controller/eSPI Controller (ThinkPad T480) ++ ++pci:v00008086d00009D50* ++ ID_MODEL_FROM_DATABASE=Sunrise Point LPC Controller + + pci:v00008086d00009D56* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller +@@ -85958,6 +96185,9 @@ pci:v00008086d00009D56* + pci:v00008086d00009D58* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller + ++pci:v00008086d00009D58sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (Acer Aspire E5-575G) ++ + pci:v00008086d00009D58sv000017AAsd00002247* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (ThinkPad T570) + +@@ -85967,18 +96197,45 @@ pci:v00008086d00009D58sv000017AAsd0000224F* + pci:v00008086d00009D60* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 + ++pci:v00008086d00009D60sv00001025sd0000115F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D60sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (Latitude 7275 tablet) ++ ++pci:v00008086d00009D60sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D60sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (Latitude 3570) + ++pci:v00008086d00009D60sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (EliteBook 840 G3) ++ ++pci:v00008086d00009D60sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (ThinkPad T480) ++ + pci:v00008086d00009D60sv00008086sd00009D60* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0 (100 Series PCH/Sunrise Point PCH I2C0 [Skylake/Kaby Lake LPSS I2C]) + + pci:v00008086d00009D61* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #1 + ++pci:v00008086d00009D61sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #1 (Latitude 7275 tablet) ++ ++pci:v00008086d00009D61sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #1 (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D62* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #2 + ++pci:v00008086d00009D62sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #2 (Latitude 7275 tablet) ++ ++pci:v00008086d00009D62sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #2 (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D63* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #3 + +@@ -85994,15 +96251,135 @@ pci:v00008086d00009D66* + pci:v00008086d00009D70* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio + ++pci:v00008086d00009D70sv00001028sd000006D6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (Latitude 7275 tablet) ++ ++pci:v00008086d00009D70sv00001028sd000006DC* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (Latitude E7470) ++ ++pci:v00008086d00009D70sv00001028sd000006E6* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (Latitude 11 5175 2-in-1) ++ + pci:v00008086d00009D70sv00001028sd000006F3* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (Latitude 3570) + ++pci:v00008086d00009D70sv0000103Csd00008079* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (EliteBook 840 G3) ++ ++pci:v00008086d00009D70sv000017AAsd00002247* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (ThinkPad T570) ++ + pci:v00008086d00009D70sv000017AAsd0000382A* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (B51-80 Laptop) + + pci:v00008086d00009D71* + ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio + ++pci:v00008086d00009D71sv00001025sd00001094* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (Acer Aspire E5-575G) ++ ++pci:v00008086d00009D71sv000017AAsd0000224F* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (ThinkPad X1 Carbon 5th Gen) ++ ++pci:v00008086d00009D71sv000017AAsd0000225D* ++ ID_MODEL_FROM_DATABASE=Sunrise Point-LP HD Audio (ThinkPad T480) ++ ++pci:v00008086d00009D84* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP LPC Controller ++ ++pci:v00008086d00009D84sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP LPC Controller (Inspiron 5482) ++ ++pci:v00008086d00009DA3* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP SMBus Controller ++ ++pci:v00008086d00009DA4* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP SPI Controller ++ ++pci:v00008086d00009DA8* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO UART Controller #2 ++ ++pci:v00008086d00009DAA* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO SPI Controller ++ ++pci:v00008086d00009DB0* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #9 ++ ++pci:v00008086d00009DB1* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #10 ++ ++pci:v00008086d00009DB2* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #1 ++ ++pci:v00008086d00009DB4* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #13 ++ ++pci:v00008086d00009DB4sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #13 (Inspiron 5482) ++ ++pci:v00008086d00009DB6* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #15 ++ ++pci:v00008086d00009DB8* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #1 ++ ++pci:v00008086d00009DBC* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #5 ++ ++pci:v00008086d00009DBE* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP PCI Express Root Port #7 ++ ++pci:v00008086d00009DBF* ++ ID_MODEL_FROM_DATABASE=Cannon Point PCI Express Root Port #8 ++ ++pci:v00008086d00009DC5* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO I2C Host Controller ++ ++pci:v00008086d00009DC8* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP High Definition Audio Controller ++ ++pci:v00008086d00009DC8sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP High Definition Audio Controller (Inspiron 5482) ++ ++pci:v00008086d00009DD3* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP SATA Controller [AHCI Mode] ++ ++pci:v00008086d00009DE0* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP MEI Controller #1 ++ ++pci:v00008086d00009DE3* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Keyboard and Text (KT) Redirection ++ ++pci:v00008086d00009DE8* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO I2C Controller #0 ++ ++pci:v00008086d00009DE8sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO I2C Controller #0 (Inspiron 5482) ++ ++pci:v00008086d00009DE9* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO I2C Controller #1 ++ ++pci:v00008086d00009DE9sv00001028sd0000089E* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Serial IO I2C Controller #1 (Inspiron 5482) ++ ++pci:v00008086d00009DED* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller ++ ++pci:v00008086d00009DEF* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Shared SRAM ++ ++pci:v00008086d00009DF0* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP CNVi [Wireless-AC] ++ ++pci:v00008086d00009DF5* ++ ID_MODEL_FROM_DATABASE=BayHubTech Integrated SD controller ++ ++pci:v00008086d00009DF9* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Thermal Controller ++ ++pci:v00008086d00009DFC* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP Integrated Sensor Hub ++ + pci:v00008086d0000A000* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge + +@@ -86036,149 +96413,266 @@ pci:v00008086d0000A003* + pci:v00008086d0000A010* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge + ++pci:v00008086d0000A010sv00001043sd000083AC* ++ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (Eee PC 1015PX) ++ + pci:v00008086d0000A010sv0000144Dsd0000C072* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (Notebook N150P) + + pci:v00008086d0000A011* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + ++pci:v00008086d0000A011sv00001043sd000083AC* ++ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Eee PC 1015PX) ++ + pci:v00008086d0000A011sv0000144Dsd0000C072* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Notebook N150P) + + pci:v00008086d0000A012* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + ++pci:v00008086d0000A012sv00001043sd000083AC* ++ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Eee PC 1015PX) ++ + pci:v00008086d0000A012sv0000144Dsd0000C072* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Notebook N150P) + + pci:v00008086d0000A013* + ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter + ++pci:v00008086d0000A082* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP LPC Controller ++ ++pci:v00008086d0000A0A3* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP SMBus Controller ++ ++pci:v00008086d0000A0A4* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP SPI Controller ++ ++pci:v00008086d0000A0A6* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Trace Hub ++ ++pci:v00008086d0000A0A8* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO UART Controller #0 ++ ++pci:v00008086d0000A0A9* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO UART Controller #1 ++ ++pci:v00008086d0000A0AB* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO SPI Controller #1 ++ ++pci:v00008086d0000A0B0* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP PCI Express Root Port #9 ++ ++pci:v00008086d0000A0BD* ++ ID_MODEL_FROM_DATABASE=Tigerlake PCH-LP PCI Express Root Port #6 ++ ++pci:v00008086d0000A0BF* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP PCI Express Root Port #8 ++ ++pci:v00008086d0000A0C5* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #4 ++ ++pci:v00008086d0000A0C6* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #5 ++ ++pci:v00008086d0000A0C8* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Smart Sound Technology Audio Controller ++ ++pci:v00008086d0000A0E0* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Management Engine Interface ++ ++pci:v00008086d0000A0E3* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Active Management Technology - SOL ++ ++pci:v00008086d0000A0E8* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #0 ++ ++pci:v00008086d0000A0E9* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #1 ++ ++pci:v00008086d0000A0EA* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #2 ++ ++pci:v00008086d0000A0EB* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Serial IO I2C Controller #3 ++ ++pci:v00008086d0000A0ED* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP USB 3.2 Gen 2x1 xHCI Host Controller ++ ++pci:v00008086d0000A0EF* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Shared SRAM ++ ++pci:v00008086d0000A0F0* ++ ID_MODEL_FROM_DATABASE=Wi-Fi 6 AX201 ++ ++pci:v00008086d0000A0FC* ++ ID_MODEL_FROM_DATABASE=Tiger Lake-LP Integrated Sensor Hub ++ + pci:v00008086d0000A102* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H SATA controller [AHCI mode] ++ ID_MODEL_FROM_DATABASE=Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode] + + pci:v00008086d0000A103* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H SATA Controller [AHCI mode] ++ ID_MODEL_FROM_DATABASE=HM170/QM170 Chipset SATA Controller [AHCI Mode] ++ ++pci:v00008086d0000A103sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=HM170/QM170 Chipset SATA Controller [AHCI Mode] (XPS 15 9550) ++ ++pci:v00008086d0000A103sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=HM170/QM170 Chipset SATA Controller [AHCI Mode] (OMEN-17-w001nv) + + pci:v00008086d0000A105* + ID_MODEL_FROM_DATABASE=Sunrise Point-H SATA Controller [RAID mode] + ++pci:v00008086d0000A106* ++ ID_MODEL_FROM_DATABASE=Q170/H170/Z170/CM236 Chipset SATA Controller [RAID Mode] ++ + pci:v00008086d0000A107* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H SATA Controller [RAID mode] ++ ID_MODEL_FROM_DATABASE=HM170/QM170 Chipset SATA Controller [RAID Mode] + + pci:v00008086d0000A10F* + ID_MODEL_FROM_DATABASE=Sunrise Point-H SATA Controller [RAID mode] + + pci:v00008086d0000A110* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #1 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #1 + + pci:v00008086d0000A111* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #2 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #2 + + pci:v00008086d0000A112* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #3 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #3 + + pci:v00008086d0000A113* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #4 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #4 + + pci:v00008086d0000A114* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #5 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #5 + + pci:v00008086d0000A115* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #6 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #6 + + pci:v00008086d0000A116* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #7 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #7 + + pci:v00008086d0000A117* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #8 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #8 + + pci:v00008086d0000A118* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #9 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #9 + + pci:v00008086d0000A119* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #10 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #10 + + pci:v00008086d0000A11A* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #11 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #11 + + pci:v00008086d0000A11B* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #12 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #12 + + pci:v00008086d0000A11C* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #13 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #13 + + pci:v00008086d0000A11D* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #14 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #14 + + pci:v00008086d0000A11E* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #15 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #15 + + pci:v00008086d0000A11F* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Express Root Port #16 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #16 + + pci:v00008086d0000A120* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H P2SB ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family P2SB + + pci:v00008086d0000A121* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PMC ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Power Management Controller ++ ++pci:v00008086d0000A121sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Power Management Controller (XPS 15 9550) ++ ++pci:v00008086d0000A121sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Power Management Controller (OMEN-17-w001nv) + + pci:v00008086d0000A122* + ID_MODEL_FROM_DATABASE=Sunrise Point-H cAVS + + pci:v00008086d0000A123* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H SMBus ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family SMBus ++ ++pci:v00008086d0000A123sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family SMBus (XPS 15 9550) ++ ++pci:v00008086d0000A123sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family SMBus (OMEN-17-w001nv) + + pci:v00008086d0000A124* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H SPI Controller ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family SPI Controller + + pci:v00008086d0000A125* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Gigabit Ethernet Controller ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Gigabit Ethernet Controller + + pci:v00008086d0000A126* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Northpeak ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Trace Hub + + pci:v00008086d0000A127* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO UART #0 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO UART #0 + + pci:v00008086d0000A128* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO UART #1 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO UART #1 + + pci:v00008086d0000A129* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO SPI #0 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO GSPI #0 + + pci:v00008086d0000A12A* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO SPI #1 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO GSPI #1 + + pci:v00008086d0000A12F* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H USB 3.0 xHCI Controller ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller ++ ++pci:v00008086d0000A12Fsv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller (XPS 15 9550) ++ ++pci:v00008086d0000A12Fsv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller (OMEN-17-w001nv) + + pci:v00008086d0000A130* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H USB Device Controller (OTG) ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family USB Device Controller (OTG) + + pci:v00008086d0000A131* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Thermal subsystem ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Thermal Subsystem ++ ++pci:v00008086d0000A131sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Thermal Subsystem (XPS 15 9550) ++ ++pci:v00008086d0000A131sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Thermal Subsystem (OMEN-17-w001nv) + + pci:v00008086d0000A133* + ID_MODEL_FROM_DATABASE=Sunrise Point-H Northpeak ACPI Function + + pci:v00008086d0000A135* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Integrated Sensor Hub ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Integrated Sensor Hub + + pci:v00008086d0000A13A* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H CSME HECI #1 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family MEI Controller #1 ++ ++pci:v00008086d0000A13Asv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family MEI Controller #1 (XPS 15 9550) ++ ++pci:v00008086d0000A13Asv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family MEI Controller #1 (OMEN-17-w001nv) + + pci:v00008086d0000A13B* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H CSME HECI #2 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family MEI Controller #2 + + pci:v00008086d0000A13C* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H CSME IDE Redirection ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family IDE Redirection + + pci:v00008086d0000A13D* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H KT Redirection ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family KT Redirection + + pci:v00008086d0000A13E* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H CSME HECI #3 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family MEI Controller #3 + + pci:v00008086d0000A140* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller +@@ -86190,28 +96684,28 @@ pci:v00008086d0000A142* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller + + pci:v00008086d0000A143* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=H110 Chipset LPC/eSPI Controller + + pci:v00008086d0000A144* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=H170 Chipset LPC/eSPI Controller + + pci:v00008086d0000A145* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=Z170 Chipset LPC/eSPI Controller + + pci:v00008086d0000A146* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=Q170 Chipset LPC/eSPI Controller + + pci:v00008086d0000A147* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=Q150 Chipset LPC/eSPI Controller + + pci:v00008086d0000A148* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=B150 Chipset LPC/eSPI Controller + + pci:v00008086d0000A149* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=C236 Chipset LPC/eSPI Controller + + pci:v00008086d0000A14A* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=C232 Chipset LPC/eSPI Controller + + pci:v00008086d0000A14B* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller +@@ -86220,28 +96714,34 @@ pci:v00008086d0000A14C* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller + + pci:v00008086d0000A14D* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=QM170 Chipset LPC/eSPI Controller + + pci:v00008086d0000A14E* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=HM170 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A14Esv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=HM170 Chipset LPC/eSPI Controller (XPS 15 9550) ++ ++pci:v00008086d0000A14Esv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=HM170 Chipset LPC/eSPI Controller (OMEN-17-w001nv) + + pci:v00008086d0000A14F* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller + + pci:v00008086d0000A150* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=CM236 Chipset LPC/eSPI Controller + + pci:v00008086d0000A151* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller + + pci:v00008086d0000A152* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=HM175 Chipset LPC/eSPI Controller + + pci:v00008086d0000A153* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=QM175 Chipset LPC/eSPI Controller + + pci:v00008086d0000A154* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller ++ ID_MODEL_FROM_DATABASE=CM238 Chipset LPC/eSPI Controller + + pci:v00008086d0000A155* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller +@@ -86277,166 +96777,217 @@ pci:v00008086d0000A15F* + ID_MODEL_FROM_DATABASE=Sunrise Point-H LPC Controller + + pci:v00008086d0000A160* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO I2C Controller #0 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #0 ++ ++pci:v00008086d0000A160sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #0 (XPS 15 9550) ++ ++pci:v00008086d0000A160sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #0 (OMEN-17-w001nv) + + pci:v00008086d0000A161* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO I2C Controller #1 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #1 ++ ++pci:v00008086d0000A161sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #1 (XPS 15 9550) ++ ++pci:v00008086d0000A162* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #2 ++ ++pci:v00008086d0000A163* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO I2C Controller #3 + + pci:v00008086d0000A166* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H Serial IO UART Controller #2 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family Serial IO UART Controller #2 + + pci:v00008086d0000A167* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Root Port #17 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #17 + + pci:v00008086d0000A168* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Root Port #18 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #18 + + pci:v00008086d0000A169* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Root Port #19 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #19 + + pci:v00008086d0000A16A* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H PCI Root Port #20 ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family PCI Express Root Port #20 + + pci:v00008086d0000A170* +- ID_MODEL_FROM_DATABASE=Sunrise Point-H HD Audio ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family HD Audio Controller ++ ++pci:v00008086d0000A170sv00001028sd000006E4* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family HD Audio Controller (XPS 15 9550) ++ ++pci:v00008086d0000A170sv0000103Csd0000825B* ++ ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family HD Audio Controller (OMEN-17-w001nv) + + pci:v00008086d0000A171* + ID_MODEL_FROM_DATABASE=CM238 HD Audio Controller + + pci:v00008086d0000A182* +- ID_MODEL_FROM_DATABASE=Lewisburg SATA Controller [AHCI mode] ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SATA Controller [AHCI mode] + + pci:v00008086d0000A186* +- ID_MODEL_FROM_DATABASE=Lewisburg SATA Controller [RAID mode] ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SATA Controller [RAID mode] + + pci:v00008086d0000A190* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #1 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #1 + + pci:v00008086d0000A191* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #2 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #2 + + pci:v00008086d0000A192* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #3 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #3 + + pci:v00008086d0000A193* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #4 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #4 + + pci:v00008086d0000A194* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #5 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #5 + + pci:v00008086d0000A195* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #6 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #6 + + pci:v00008086d0000A196* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #7 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #7 + + pci:v00008086d0000A197* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #8 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #8 + + pci:v00008086d0000A198* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #9 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #9 + + pci:v00008086d0000A199* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #10 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #10 + + pci:v00008086d0000A19A* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #11 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #11 + + pci:v00008086d0000A19B* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #12 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #12 + + pci:v00008086d0000A19C* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #13 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #13 + + pci:v00008086d0000A19D* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #14 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #14 + + pci:v00008086d0000A19E* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #15 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #15 + + pci:v00008086d0000A19F* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #16 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #16 + + pci:v00008086d0000A1A0* +- ID_MODEL_FROM_DATABASE=Lewisburg P2SB ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family P2SB + + pci:v00008086d0000A1A1* +- ID_MODEL_FROM_DATABASE=Lewisburg PMC ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family Power Management Controller ++ ++pci:v00008086d0000A1A1sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family Power Management Controller (X11SPM-TF) + + pci:v00008086d0000A1A2* +- ID_MODEL_FROM_DATABASE=Lewisburg cAVS ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family cAVS + + pci:v00008086d0000A1A3* +- ID_MODEL_FROM_DATABASE=Lewisburg SMBus ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SMBus ++ ++pci:v00008086d0000A1A3sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SMBus (X11SPM-TF) + + pci:v00008086d0000A1A4* +- ID_MODEL_FROM_DATABASE=Lewisburg SPI Controller ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SPI Controller ++ ++pci:v00008086d0000A1A4sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SPI Controller (X11SPM-TF) ++ ++pci:v00008086d0000A1A6* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family Trace Hub + + pci:v00008086d0000A1AF* +- ID_MODEL_FROM_DATABASE=Lewisburg USB 3.0 xHCI Controller ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family USB 3.0 xHCI Controller ++ ++pci:v00008086d0000A1AFsv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family USB 3.0 xHCI Controller (X11SPM-TF) + + pci:v00008086d0000A1B1* +- ID_MODEL_FROM_DATABASE=Lewisburg Thermal Subsystem ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family Thermal Subsystem ++ ++pci:v00008086d0000A1B1sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family Thermal Subsystem (X11SPM-TF) + + pci:v00008086d0000A1BA* +- ID_MODEL_FROM_DATABASE=Lewisburg CSME: HECI #1 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #1 ++ ++pci:v00008086d0000A1BAsv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #1 (X11SPM-TF) + + pci:v00008086d0000A1BB* +- ID_MODEL_FROM_DATABASE=Lewisburg CSME: HECI #2 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #2 ++ ++pci:v00008086d0000A1BBsv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #2 (X11SPM-TF) + + pci:v00008086d0000A1BC* +- ID_MODEL_FROM_DATABASE=Lewisburg CSME: IDE-r ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family IDE Redirection + + pci:v00008086d0000A1BD* +- ID_MODEL_FROM_DATABASE=Lewisburg CSME: KT Controller ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family KT Redirection + + pci:v00008086d0000A1BE* +- ID_MODEL_FROM_DATABASE=Lewisburg CSME: HECI #3 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #3 ++ ++pci:v00008086d0000A1BEsv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MEI Controller #3 (X11SPM-TF) + + pci:v00008086d0000A1C1* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C621 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1C2* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C622 Series Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A1C2sv000015D9sd0000095D* ++ ID_MODEL_FROM_DATABASE=C622 Series Chipset LPC/eSPI Controller (X11SPM-TF) + + pci:v00008086d0000A1C3* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C624 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1C4* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C625 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1C5* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C626 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1C6* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C627 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1C7* +- ID_MODEL_FROM_DATABASE=Lewisburg LPC Controller ++ ID_MODEL_FROM_DATABASE=C628 Series Chipset LPC/eSPI Controller + + pci:v00008086d0000A1D2* +- ID_MODEL_FROM_DATABASE=Lewisburg SSATA Controller [AHCI mode] ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SSATA Controller [AHCI mode] + + pci:v00008086d0000A1D6* +- ID_MODEL_FROM_DATABASE=Lewisburg SSATA Controller [RAID mode] ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family SSATA Controller [RAID mode] + + pci:v00008086d0000A1E7* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #17 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #17 + + pci:v00008086d0000A1E8* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #18 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #18 + + pci:v00008086d0000A1E9* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #19 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #19 + + pci:v00008086d0000A1EA* +- ID_MODEL_FROM_DATABASE=Lewisburg PCI Express Root Port #20 ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family PCI Express Root Port #20 + +-pci:v00008086d0000A1F0* +- ID_MODEL_FROM_DATABASE=Lewisburg MROM 0 ++pci:v00008086d0000A1EC* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MROM 0 + +-pci:v00008086d0000A1F1* +- ID_MODEL_FROM_DATABASE=Lewisburg MROM 1 ++pci:v00008086d0000A1ED* ++ ID_MODEL_FROM_DATABASE=C620 Series Chipset Family MROM 1 + + pci:v00008086d0000A1F8* + ID_MODEL_FROM_DATABASE=Lewisburg IE: HECI #1 +@@ -86480,6 +97031,9 @@ pci:v00008086d0000A256* + pci:v00008086d0000A282* + ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [AHCI mode] + ++pci:v00008086d0000A282sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [AHCI mode] (H270 PC MATE) ++ + pci:v00008086d0000A286* + ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [RAID mode] + +@@ -86498,18 +97052,27 @@ pci:v00008086d0000A293* + pci:v00008086d0000A294* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #5 + ++pci:v00008086d0000A294sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #5 (H270 PC MATE) ++ + pci:v00008086d0000A295* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #6 + + pci:v00008086d0000A296* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #7 + ++pci:v00008086d0000A296sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #7 (H270 PC MATE) ++ + pci:v00008086d0000A297* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #8 + + pci:v00008086d0000A298* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #9 + ++pci:v00008086d0000A298sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #9 (H270 PC MATE) ++ + pci:v00008086d0000A299* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #10 + +@@ -86531,39 +97094,69 @@ pci:v00008086d0000A29E* + pci:v00008086d0000A29F* + ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #16 + ++pci:v00008086d0000A2A0* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family P2SB ++ + pci:v00008086d0000A2A1* +- ID_MODEL_FROM_DATABASE=200 Series PCH PMC ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Power Management Controller ++ ++pci:v00008086d0000A2A1sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Power Management Controller (H270 PC MATE) + + pci:v00008086d0000A2A3* +- ID_MODEL_FROM_DATABASE=200 Series PCH SMBus Controller ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family SMBus Controller ++ ++pci:v00008086d0000A2A3sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family SMBus Controller (H270 PC MATE) ++ ++pci:v00008086d0000A2A4* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family SPI Controller ++ ++pci:v00008086d0000A2A5* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Gigabit Ethernet Controller ++ ++pci:v00008086d0000A2A6* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Trace Hub + + pci:v00008086d0000A2A7* +- ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #0 ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Serial IO UART Controller #0 + + pci:v00008086d0000A2A8* +- ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #1 ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Serial IO UART Controller #1 + + pci:v00008086d0000A2A9* +- ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO SPI Controller #0 ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Serial IO SPI Controller #0 + + pci:v00008086d0000A2AA* +- ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO SPI Controller #1 ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family Serial IO SPI Controller #1 + + pci:v00008086d0000A2AF* +- ID_MODEL_FROM_DATABASE=200 Series PCH USB 3.0 xHCI Controller ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family USB 3.0 xHCI Controller ++ ++pci:v00008086d0000A2AFsv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series/Z370 Chipset Family USB 3.0 xHCI Controller (H270 PC MATE) + + pci:v00008086d0000A2B1* + ID_MODEL_FROM_DATABASE=200 Series PCH Thermal Subsystem + ++pci:v00008086d0000A2B1sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH Thermal Subsystem (H270 PC MATE) ++ + pci:v00008086d0000A2BA* + ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #1 + ++pci:v00008086d0000A2BAsv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #1 (H270 PC MATE) ++ + pci:v00008086d0000A2BB* + ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #2 + + pci:v00008086d0000A2C4* + ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (H270) + ++pci:v00008086d0000A2C4sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (H270) (H270 PC MATE) ++ + pci:v00008086d0000A2C5* + ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Z270) + +@@ -86576,6 +97169,15 @@ pci:v00008086d0000A2C7* + pci:v00008086d0000A2C8* + ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (B250) + ++pci:v00008086d0000A2C9* ++ ID_MODEL_FROM_DATABASE=Z370 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A2D2* ++ ID_MODEL_FROM_DATABASE=X299 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A2D3* ++ ID_MODEL_FROM_DATABASE=C422 Chipset LPC/eSPI Controller ++ + pci:v00008086d0000A2E0* + ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #0 + +@@ -86618,48 +97220,204 @@ pci:v00008086d0000A2EE* + pci:v00008086d0000A2F0* + ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio + ++pci:v00008086d0000A2F0sv00001462sd00007A72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio (H270 PC MATE) ++ ++pci:v00008086d0000A2F0sv00001462sd0000FA72* ++ ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio (H270 PC MATE) ++ + pci:v00008086d0000A304* + ID_MODEL_FROM_DATABASE=H370 Chipset LPC/eSPI Controller + ++pci:v00008086d0000A304sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=H370 Chipset LPC/eSPI Controller (Vostro 3470) ++ ++pci:v00008086d0000A305* ++ ID_MODEL_FROM_DATABASE=Z390 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A306* ++ ID_MODEL_FROM_DATABASE=Q370 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A309* ++ ID_MODEL_FROM_DATABASE=Cannon Point-LP LPC Controller ++ ++pci:v00008086d0000A30C* ++ ID_MODEL_FROM_DATABASE=QM370 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A30D* ++ ID_MODEL_FROM_DATABASE=HM470 Chipset LPC/eSPI Controller ++ ++pci:v00008086d0000A30E* ++ ID_MODEL_FROM_DATABASE=Cannon Lake LPC Controller ++ + pci:v00008086d0000A323* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH SMBus Controller + ++pci:v00008086d0000A323sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH SMBus Controller (Vostro 3470) ++ + pci:v00008086d0000A324* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH SPI Controller + ++pci:v00008086d0000A324sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH SPI Controller (Vostro 3470) ++ ++pci:v00008086d0000A328* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO UART Host Controller ++ ++pci:v00008086d0000A32B* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH SPI Host Controller ++ + pci:v00008086d0000A32C* +- ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port 21 ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #21 ++ ++pci:v00008086d0000A32D* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #22 ++ ++pci:v00008086d0000A32E* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #23 ++ ++pci:v00008086d0000A32F* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #24 + + pci:v00008086d0000A330* +- ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port 9 ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #9 ++ ++pci:v00008086d0000A331* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #10 ++ ++pci:v00008086d0000A332* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #11 ++ ++pci:v00008086d0000A333* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #12 ++ ++pci:v00008086d0000A334* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #13 ++ ++pci:v00008086d0000A335* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #14 ++ ++pci:v00008086d0000A336* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #15 ++ ++pci:v00008086d0000A337* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #16 ++ ++pci:v00008086d0000A338* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #1 ++ ++pci:v00008086d0000A339* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #2 ++ ++pci:v00008086d0000A33A* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #3 ++ ++pci:v00008086d0000A33B* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #4 ++ ++pci:v00008086d0000A33C* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #5 ++ ++pci:v00008086d0000A33D* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #6 ++ ++pci:v00008086d0000A33E* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #7 ++ ++pci:v00008086d0000A33F* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #8 ++ ++pci:v00008086d0000A340* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #17 ++ ++pci:v00008086d0000A341* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #18 + + pci:v00008086d0000A342* +- ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port 19 ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #19 + + pci:v00008086d0000A343* +- ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port 20 ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH PCI Express Root Port #20 + + pci:v00008086d0000A348* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH cAVS + ++pci:v00008086d0000A348sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH cAVS (Vostro 3470) ++ + pci:v00008086d0000A352* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH SATA AHCI Controller + ++pci:v00008086d0000A352sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH SATA AHCI Controller (Vostro 3470) ++ ++pci:v00008086d0000A353* ++ ID_MODEL_FROM_DATABASE=Cannon Lake Mobile PCH SATA AHCI Controller ++ + pci:v00008086d0000A360* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH HECI Controller + ++pci:v00008086d0000A360sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH HECI Controller (Vostro 3470) ++ ++pci:v00008086d0000A363* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Active Management Technology - SOL ++ ++pci:v00008086d0000A364* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH HECI Controller #2 ++ ++pci:v00008086d0000A368* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO I2C Controller #0 ++ ++pci:v00008086d0000A369* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO I2C Controller #1 ++ ++pci:v00008086d0000A36A* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO I2C Controller #2 ++ ++pci:v00008086d0000A36B* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Serial IO I2C Controller #3 ++ + pci:v00008086d0000A36D* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH USB 3.1 xHCI Host Controller + ++pci:v00008086d0000A36Dsv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH USB 3.1 xHCI Host Controller (Vostro 3470) ++ + pci:v00008086d0000A36F* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH Shared SRAM + + pci:v00008086d0000A370* +- ID_MODEL_FROM_DATABASE=Wireless-AC 9560 [Jefferson Peak] ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH CNVi WiFi ++ ++pci:v00008086d0000A370sv00001A56sd00001552* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH CNVi WiFi (Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)) ++ ++pci:v00008086d0000A370sv00008086sd00000034* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH CNVi WiFi (Wireless-AC 9560) + + pci:v00008086d0000A379* + ID_MODEL_FROM_DATABASE=Cannon Lake PCH Thermal Controller + ++pci:v00008086d0000A379sv00001028sd00000869* ++ ID_MODEL_FROM_DATABASE=Cannon Lake PCH Thermal Controller (Vostro 3470) ++ ++pci:v00008086d0000A382* ++ ID_MODEL_FROM_DATABASE=400 Series Chipset Family SATA AHCI Controller ++ ++pci:v00008086d0000A3A1* ++ ID_MODEL_FROM_DATABASE=Memory controller ++ ++pci:v00008086d0000A3A3* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-V SMBus Host Controller ++ ++pci:v00008086d0000A3AF* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-V USB Controller ++ ++pci:v00008086d0000A3B1* ++ ID_MODEL_FROM_DATABASE=Comet Lake PCH-V Thermal Subsystem ++ + pci:v00008086d0000A620* + ID_MODEL_FROM_DATABASE=6400/6402 Advanced Memory Buffer (AMB) + +@@ -86699,6 +97457,9 @@ pci:v00008086d0000B555sv0000E4BFsd00001000* + pci:v00008086d0000D130* + ID_MODEL_FROM_DATABASE=Core Processor DMI + ++pci:v00008086d0000D130sv000015D9sd00000605* ++ ID_MODEL_FROM_DATABASE=Core Processor DMI (X8SIL) ++ + pci:v00008086d0000D131* + ID_MODEL_FROM_DATABASE=Core Processor DMI + +@@ -86768,9 +97529,171 @@ pci:v00008086d0000D157* + pci:v00008086d0000D158* + ID_MODEL_FROM_DATABASE=Core Processor Miscellaneous Registers + ++pci:v00008086d0000F1A5* ++ ID_MODEL_FROM_DATABASE=SSD 600P Series ++ ++pci:v00008086d0000F1A5sv00008086sd0000390A* ++ ID_MODEL_FROM_DATABASE=SSD 600P Series (SSDPEKKW256G7 256GB) ++ + pci:v00008086d0000F1A6* + ID_MODEL_FROM_DATABASE=SSD Pro 7600p/760p/E 6100p Series + ++pci:v00008086d0000F1A6sv00008086sd0000390B* ++ ID_MODEL_FROM_DATABASE=SSD Pro 7600p/760p/E 6100p Series ([NVM Express]) ++ ++pci:v00008086d0000F1A8* ++ ID_MODEL_FROM_DATABASE=SSD 660P Series ++ ++pci:v00008088* ++ ID_VENDOR_FROM_DATABASE=Beijing Wangxun Technology Co., Ltd. ++ ++pci:v00008088d00000101* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Gigabit Ethernet Controller ++ ++pci:v00008088d00000101sv00008088sd00000201* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200T) ++ ++pci:v00008088d00000101sv00008088sd00004201* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200T (WOL)) ++ ++pci:v00008088d00000101sv00008088sd00008201* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200T (NCSI)) ++ ++pci:v00008088d00000101sv00008088sd0000C201* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200T (WOL, NCSI)) ++ ++pci:v00008088d00000102* ++ ID_MODEL_FROM_DATABASE=WX1860A2S Gigabit Ethernet Controller ++ ++pci:v00008088d00000102sv00008088sd00000210* ++ ID_MODEL_FROM_DATABASE=WX1860A2S Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200T-S) ++ ++pci:v00008088d00000103* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller ++ ++pci:v00008088d00000103sv00008088sd00000401* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller (Qual-Port Ethernet Network Adaptor SF400T) ++ ++pci:v00008088d00000103sv00008088sd00000440* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller (Qual-Port Ethernet Network Adaptor SF400-OCP) ++ ++pci:v00008088d00000103sv00008088sd00004103* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400T (WOL)) ++ ++pci:v00008088d00000103sv00008088sd00008103* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400T (NCSI)) ++ ++pci:v00008088d00000103sv00008088sd0000C103* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400T (WOL, NCSI)) ++ ++pci:v00008088d00000104* ++ ID_MODEL_FROM_DATABASE=WX1860A4S Gigabit Ethernet Controller ++ ++pci:v00008088d00000104sv00008088sd00000410* ++ ID_MODEL_FROM_DATABASE=WX1860A4S Gigabit Ethernet Controller (Qual-Port Ethernet Network Adaptor SF400T-S) ++ ++pci:v00008088d00000105* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Gigabit Ethernet Controller ++ ++pci:v00008088d00000105sv00008088sd00000202* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200HT) ++ ++pci:v00008088d00000105sv00008088sd00004202* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200HT (WOL)) ++ ++pci:v00008088d00000105sv00008088sd00008202* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200HT (NCSI)) ++ ++pci:v00008088d00000105sv00008088sd0000C202* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200HT (WOL, NCSI)) ++ ++pci:v00008088d00000106* ++ ID_MODEL_FROM_DATABASE=WX1860AL2S Gigabit Ethernet Controller ++ ++pci:v00008088d00000106sv00008088sd00000220* ++ ID_MODEL_FROM_DATABASE=WX1860AL2S Gigabit Ethernet Controller (Dual-Port Ethernet Network Adaptor SF200HT-S) ++ ++pci:v00008088d00000107* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Gigabit Ethernet Controller ++ ++pci:v00008088d00000107sv00008088sd00000402* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Gigabit Ethernet Controller (Qual-Port Ethernet Network Adaptor SF400HT) ++ ++pci:v00008088d00000107sv00008088sd00004402* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400HT (WOL)) ++ ++pci:v00008088d00000107sv00008088sd00008402* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400HT (NCSI)) ++ ++pci:v00008088d00000107sv00008088sd0000C402* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Gigabit Ethernet Controller (Quad-Port Ethernet Network Adaptor SF400HT (WOL, NCSI)) ++ ++pci:v00008088d00000108* ++ ID_MODEL_FROM_DATABASE=WX1860AL4S Gigabit Ethernet Controller ++ ++pci:v00008088d00000108sv00008088sd00000420* ++ ID_MODEL_FROM_DATABASE=WX1860AL4S Gigabit Ethernet Controller (Qual-Port Ethernet Network Adaptor SF400HT-S) ++ ++pci:v00008088d00000109* ++ ID_MODEL_FROM_DATABASE=WX1860-LC Gigabit Ethernet Controller ++ ++pci:v00008088d0000010A* ++ ID_MODEL_FROM_DATABASE=WX1860A1 Gigabit Ethernet Controller ++ ++pci:v00008088d0000010B* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller ++ ++pci:v00008088d0000010Bsv00008088sd00000102* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller (Single-Port Ethernet Network Adaptor SF100HT) ++ ++pci:v00008088d0000010Bsv00008088sd00004102* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller (Single-Port Ethernet Network Adaptor SF100HT (WOL)) ++ ++pci:v00008088d0000010Bsv00008088sd00008102* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller (Single-Port Ethernet Network Adaptor SF100HT (NCSI)) ++ ++pci:v00008088d0000010Bsv00008088sd0000C102* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller (Single-Port Ethernet Network Adaptor SF100HT (WOL, NCSI)) ++ ++pci:v00008088d00000111* ++ ID_MODEL_FROM_DATABASE=WX1860A2 Ethernet Controller Virtual Function ++ ++pci:v00008088d00000113* ++ ID_MODEL_FROM_DATABASE=WX1860A4 Ethernet Controller Virtual Function ++ ++pci:v00008088d00000115* ++ ID_MODEL_FROM_DATABASE=WX1860AL2 Ethernet Controller Virtual Function ++ ++pci:v00008088d00000117* ++ ID_MODEL_FROM_DATABASE=WX1860AL4 Ethernet Controller Virtual Function ++ ++pci:v00008088d00000119* ++ ID_MODEL_FROM_DATABASE=WX1860-LC Gigabit Ethernet Controller Virtual Function ++ ++pci:v00008088d0000011A* ++ ID_MODEL_FROM_DATABASE=WX1860A1 Gigabit Ethernet Controller Virtual Function ++ ++pci:v00008088d0000011B* ++ ID_MODEL_FROM_DATABASE=WX1860AL1 Gigabit Ethernet Controller Virtual Function ++ ++pci:v00008088d00001000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP1000 Virtual Function for 10GbE SFP+ ++ ++pci:v00008088d00001001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP1000 for 10GbE SFP+ ++ ++pci:v00008088d00001001sv00008088sd00000000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP1000 for 10GbE SFP+ (Ethernet Network Adaptor RP1000 for 10GbE SFP+) ++ ++pci:v00008088d00002000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP2000 Virtual Function for 10GbE SFP+ ++ ++pci:v00008088d00002001* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP2000 for 10GbE SFP+ ++ ++pci:v00008088d00002001sv00008088sd00002000* ++ ID_MODEL_FROM_DATABASE=Ethernet Controller RP2000 for 10GbE SFP+ (Ethernet Network Adaptor RP2000 for 10GbE SFP+) ++ + pci:v000080EE* + ID_VENDOR_FROM_DATABASE=InnoTek Systemberatung GmbH + +@@ -86804,6 +97727,12 @@ pci:v00008800* + pci:v00008800d00002008* + ID_MODEL_FROM_DATABASE=Video assistant component + ++pci:v00008820* ++ ID_VENDOR_FROM_DATABASE=Stryker Corporation ++ ++pci:v00008820d00002724* ++ ID_MODEL_FROM_DATABASE=Mako Front Side Motor Controller [cPCI] ++ + pci:v00008866* + ID_VENDOR_FROM_DATABASE=T-Square Design Inc. + +@@ -87744,145 +98673,238 @@ pci:v00009005d0000028Dsv00009005sd00000554* + ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0) + + pci:v00009005d0000028F* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS + + pci:v00009005d0000028Fsv0000103Csd00000600* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-p SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P408i-p SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000601* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-p SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P408e-p SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000602* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-a SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P408i-a SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000603* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-c SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P408i-c SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000650* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-p SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array E208i-p SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000651* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208e-p SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array E208e-p SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000652* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-c SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array E208i-c SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000654* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-a SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array E208i-a SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000655* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-m SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P408e-m SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000700* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-c SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P204i-c SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00000701* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-b SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P204i-b SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00001100* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P816i-a SR Gen10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P816i-a SR Gen10) + + pci:v00009005d0000028Fsv0000103Csd00001101* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P416ie-m SR G10) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (Smart Array P416ie-m SR G10) ++ ++pci:v00009005d0000028Fsv0000105Bsd00001211* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 8238-16i) ++ ++pci:v00009005d0000028Fsv0000105Bsd00001321* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 8242-24i) ++ ++pci:v00009005d0000028Fsv000013FEsd00008312* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SKY-9200 MIC-8312BridgeB) + + pci:v00009005d0000028Fsv0000152Dsd00008A22* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8204-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (QS-8204-8i) + + pci:v00009005d0000028Fsv0000152Dsd00008A23* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8238-16i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (QS-8238-16i) + + pci:v00009005d0000028Fsv0000152Dsd00008A24* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8236-16i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (QS-8236-16i) + + pci:v00009005d0000028Fsv0000152Dsd00008A36* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8240-24i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (QS-8240-24i) + + pci:v00009005d0000028Fsv0000152Dsd00008A37* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (QS-8242-24i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (QS-8242-24i) ++ ++pci:v00009005d0000028Fsv0000193Dsd00001104* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P2404-Mf-4i-2GB) ++ ++pci:v00009005d0000028Fsv0000193Dsd00001105* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P4408-Mf-8i-2GB) ++ ++pci:v00009005d0000028Fsv0000193Dsd00001106* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P2404-Mf-4i-1GB) ++ ++pci:v00009005d0000028Fsv0000193Dsd00001107* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P4408-Mf-8i-4GB) ++ ++pci:v00009005d0000028Fsv0000193Dsd00008460* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA H460-M1) ++ ++pci:v00009005d0000028Fsv0000193Dsd00008461* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA H460-B1) ++ ++pci:v00009005d0000028Fsv0000193Dsd0000C460* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P460-M2) ++ ++pci:v00009005d0000028Fsv0000193Dsd0000C461* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P460-B2) ++ ++pci:v00009005d0000028Fsv0000193Dsd0000F460* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P460-M4) ++ ++pci:v00009005d0000028Fsv0000193Dsd0000F461* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID P460-B4) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D227* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartROC-HD SR465C-M 4G) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D228* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartROC SR455C-M 2G) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D229* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartIOC SR155-M) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D22A* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartIOC-HD SR765-M) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D22B* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartROC-e SR455C-ME 4G) ++ ++pci:v00009005d0000028Fsv000019E5sd0000D22C* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartROC SR455C-M 4G) ++ ++pci:v00009005d0000028Fsv00001BD4sd00000045* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SMART-HBA 8242-24i) ++ ++pci:v00009005d0000028Fsv00001BD4sd00000046* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID 8236-16i) ++ ++pci:v00009005d0000028Fsv00001BD4sd00000047* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID 8240-24i) ++ ++pci:v00009005d0000028Fsv00001BD4sd00000048* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SMART-HBA 8238-16i) ++ ++pci:v00009005d0000028Fsv00001BD4sd0000004A* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (PM8222-SHBA) ++ ++pci:v00009005d0000028Fsv00001BD4sd0000004B* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID PM8204-2GB) ++ ++pci:v00009005d0000028Fsv00001BD4sd0000004C* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (RAID PM8204-4GB) ++ ++pci:v00009005d0000028Fsv00001BD4sd0000004F* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (PM8222-HBA) ++ ++pci:v00009005d0000028Fsv00009005sd00000608* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3162-8i /e) + + pci:v00009005d0000028Fsv00009005sd00000800* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-8i) + + pci:v00009005d0000028Fsv00009005sd00000801* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3152-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3152-8i) + + pci:v00009005d0000028Fsv00009005sd00000802* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3151-4i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3151-4i) + + pci:v00009005d0000028Fsv00009005sd00000803* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3101-4i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3101-4i) + + pci:v00009005d0000028Fsv00009005sd00000804* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-8e) + + pci:v00009005d0000028Fsv00009005sd00000805* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3102-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3102-8i) + + pci:v00009005d0000028Fsv00009005sd00000806* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3100) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3100) + + pci:v00009005d0000028Fsv00009005sd00000807* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3162-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3162-8i) ++ ++pci:v00009005d0000028Fsv00009005sd00000808* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3101E-4i) ++ ++pci:v00009005d0000028Fsv00009005sd00000809* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3102E-8i) + + pci:v00009005d0000028Fsv00009005sd00000900* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-8i) + + pci:v00009005d0000028Fsv00009005sd00000901* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-4i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-4i) + + pci:v00009005d0000028Fsv00009005sd00000902* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-8i) + + pci:v00009005d0000028Fsv00009005sd00000903* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-4i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-4i) + + pci:v00009005d0000028Fsv00009005sd00000904* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-8e) + + pci:v00009005d0000028Fsv00009005sd00000905* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-8e) + + pci:v00009005d0000028Fsv00009005sd00000906* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-4i4e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-4i4e) + + pci:v00009005d0000028Fsv00009005sd00000907* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100) + + pci:v00009005d0000028Fsv00009005sd00000908* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100) + + pci:v00009005d0000028Fsv00009005sd0000090A* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100A-8i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100A-8i) + + pci:v00009005d0000028Fsv00009005sd00001200* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-24i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-24i) + + pci:v00009005d0000028Fsv00009005sd00001201* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i16e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-8i16e) + + pci:v00009005d0000028Fsv00009005sd00001202* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-8i8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-8i8e) + + pci:v00009005d0000028Fsv00009005sd00001280* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-16i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-16i) + + pci:v00009005d0000028Fsv00009005sd00001281* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-16e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-16e) ++ ++pci:v00009005d0000028Fsv00009005sd00001282* ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-16i) + + pci:v00009005d0000028Fsv00009005sd00001300* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-8i8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-8i8e) + + pci:v00009005d0000028Fsv00009005sd00001301* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (HBA 1100-24i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (HBA 1100-24i) + + pci:v00009005d0000028Fsv00009005sd00001302* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-8i8e) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-8i8e) + + pci:v00009005d0000028Fsv00009005sd00001303* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartHBA 2100-24i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartHBA 2100-24i) + + pci:v00009005d0000028Fsv00009005sd00001380* +- ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (SmartRAID 3154-16i) ++ ID_MODEL_FROM_DATABASE=Smart Storage PQI SAS (SmartRAID 3154-16i) + + pci:v00009005d00000410* + ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID) +@@ -88205,6 +99227,33 @@ pci:v00009902d00000002* + pci:v00009902d00000003* + ID_MODEL_FROM_DATABASE=SG1010 Starfabric Switch and PCI Bridge + ++pci:v00009A11* ++ ID_VENDOR_FROM_DATABASE=Tiger Lake-H Gaussian & Neural Accelerator ++ ++pci:v00009D32* ++ ID_VENDOR_FROM_DATABASE=Beijing Starblaze Technology Co. Ltd. ++ ++pci:v00009D32d00000000* ++ ID_MODEL_FROM_DATABASE=STAR1000 PCIe NVMe SSD Controller ++ ++pci:v00009D32d00001001* ++ ID_MODEL_FROM_DATABASE=STAR1000P PCIe NVMe SSD Controller ++ ++pci:v00009D32d00001201* ++ ID_MODEL_FROM_DATABASE=STAR1200C NVMe SSD ++ ++pci:v00009D32d00001202* ++ ID_MODEL_FROM_DATABASE=STAR1200I NVMe SSD ++ ++pci:v00009D32d00001203* ++ ID_MODEL_FROM_DATABASE=STAR1200L NVMe SSD ++ ++pci:v00009D32d00001204* ++ ID_MODEL_FROM_DATABASE=STAR1200E NVMe SSD ++ ++pci:v0000A000* ++ ID_VENDOR_FROM_DATABASE=Asix Electronics Corporation (Wrong ID) ++ + pci:v0000A0A0* + ID_VENDOR_FROM_DATABASE=AOPEN Inc. + +@@ -88442,21 +99491,39 @@ pci:v0000BDBDd0000A143* + pci:v0000BDBDd0000A144* + ID_MODEL_FROM_DATABASE=DeckLink Mini Monitor 4K + ++pci:v0000BDBDd0000A148* ++ ID_MODEL_FROM_DATABASE=DeckLink SDI Micro ++ + pci:v0000BDBDd0000A14B* + ID_MODEL_FROM_DATABASE=DeckLink 8K Pro + ++pci:v0000BDBDd0000A14E* ++ ID_MODEL_FROM_DATABASE=DeckLink Quad HDMI Recorder ++ ++pci:v0000BDBDd0000A1FF* ++ ID_MODEL_FROM_DATABASE=eGPU RX580 ++ + pci:v0000C001* + ID_VENDOR_FROM_DATABASE=TSI Telsys + + pci:v0000C0A9* + ID_VENDOR_FROM_DATABASE=Micron/Crucial Technology + ++pci:v0000C0A9d00002263* ++ ID_MODEL_FROM_DATABASE=P1 NVMe PCIe SSD ++ ++pci:v0000C0A9d0000540A* ++ ID_MODEL_FROM_DATABASE=P2 NVMe PCIe SSD ++ + pci:v0000C0DE* + ID_VENDOR_FROM_DATABASE=Motorola + + pci:v0000C0FE* + ID_VENDOR_FROM_DATABASE=Motion Engineering, Inc. + ++pci:v0000CA3B* ++ ID_VENDOR_FROM_DATABASE=Cambrionix Ltd. ++ + pci:v0000CA50* + ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd + +@@ -88484,6 +99551,15 @@ pci:v0000CAFEd00000003* + pci:v0000CAFEd00000006* + ID_MODEL_FROM_DATABASE=Luna PCI-e 3000 Hardware Security Module + ++pci:v0000CAFEd00000007* ++ ID_MODEL_FROM_DATABASE=Luna K6 Hardware Security Module ++ ++pci:v0000CAFEd00000008* ++ ID_MODEL_FROM_DATABASE=Luna K7 Hardware Security Module ++ ++pci:v0000CC53* ++ ID_VENDOR_FROM_DATABASE=ScaleFlux Inc. ++ + pci:v0000CCCC* + ID_VENDOR_FROM_DATABASE=Catapult Communications + +@@ -88607,6 +99683,18 @@ pci:v0000D161d00008013* + pci:v0000D161d0000B410* + ID_MODEL_FROM_DATABASE=Wildcard B410 quad-BRI card + ++pci:v0000D209* ++ ID_VENDOR_FROM_DATABASE=Ultimarc ++ ++pci:v0000D209d00001500* ++ ID_MODEL_FROM_DATABASE=PAC Drive ++ ++pci:v0000D209d000015A2* ++ ID_MODEL_FROM_DATABASE=SpinTrak ++ ++pci:v0000D209d00001601* ++ ID_MODEL_FROM_DATABASE=AimTrak ++ + pci:v0000D4D4* + ID_VENDOR_FROM_DATABASE=Dy4 Systems Inc + +@@ -88785,7 +99873,7 @@ pci:v0000E000d0000E000* + ID_MODEL_FROM_DATABASE=W89C940 + + pci:v0000E159* +- ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc. ++ ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc. / ICP DAS + + pci:v0000E159d00000001* + ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface +@@ -88877,6 +99965,9 @@ pci:v0000EA01d00000052* + pci:v0000EA01d00000800* + ID_MODEL_FROM_DATABASE=PCI-800 Digital I/O Card + ++pci:v0000EA50* ++ ID_VENDOR_FROM_DATABASE=Emerson Automation Solutions ++ + pci:v0000EA60* + ID_VENDOR_FROM_DATABASE=RME + +@@ -89096,6 +100187,12 @@ pci:v0000F043* + pci:v0000F05B* + ID_VENDOR_FROM_DATABASE=Foxconn International, Inc. (Wrong ID) + ++pci:v0000F15E* ++ ID_VENDOR_FROM_DATABASE=SiFive, Inc. ++ ++pci:v0000F15Ed00000000* ++ ID_MODEL_FROM_DATABASE=FU740-C000 RISC-V SoC PCI Express x8 to AXI4 Bridge ++ + pci:v0000F1D0* + ID_VENDOR_FROM_DATABASE=AJA Video + +@@ -89111,24 +100208,105 @@ pci:v0000F1D0d0000CAFE* + pci:v0000F1D0d0000CFEE* + ID_MODEL_FROM_DATABASE=Xena LS/SD-22-DA/SD-DA + ++pci:v0000F1D0d0000DAFE* ++ ID_MODEL_FROM_DATABASE=Corvid 1 ++ + pci:v0000F1D0d0000DAFF* + ID_MODEL_FROM_DATABASE=KONA LHi + ++pci:v0000F1D0d0000DB00* ++ ID_MODEL_FROM_DATABASE=IoExpress ++ + pci:v0000F1D0d0000DB01* + ID_MODEL_FROM_DATABASE=Corvid22 + ++pci:v0000F1D0d0000DB02* ++ ID_MODEL_FROM_DATABASE=Kona 3G ++ ++pci:v0000F1D0d0000DB03* ++ ID_MODEL_FROM_DATABASE=Corvid 3G ++ ++pci:v0000F1D0d0000DB04* ++ ID_MODEL_FROM_DATABASE=Kona 3G QUAD ++ ++pci:v0000F1D0d0000DB05* ++ ID_MODEL_FROM_DATABASE=Kona LHe+ ++ ++pci:v0000F1D0d0000DB06* ++ ID_MODEL_FROM_DATABASE=IoXT ++ ++pci:v0000F1D0d0000DB07* ++ ID_MODEL_FROM_DATABASE=Kona 3G P2P ++ ++pci:v0000F1D0d0000DB08* ++ ID_MODEL_FROM_DATABASE=Kona 3G QUAD P2P ++ + pci:v0000F1D0d0000DB09* + ID_MODEL_FROM_DATABASE=Corvid 24 + ++pci:v0000F1D0d0000DB11* ++ ID_MODEL_FROM_DATABASE=T-Tap ++ + pci:v0000F1D0d0000DCAF* + ID_MODEL_FROM_DATABASE=Kona HD + + pci:v0000F1D0d0000DFEE* + ID_MODEL_FROM_DATABASE=Xena HD-DA + ++pci:v0000F1D0d0000EB07* ++ ID_MODEL_FROM_DATABASE=Io4K ++ ++pci:v0000F1D0d0000EB0A* ++ ID_MODEL_FROM_DATABASE=Io4K UFC ++ ++pci:v0000F1D0d0000EB0B* ++ ID_MODEL_FROM_DATABASE=Kona 4 ++ ++pci:v0000F1D0d0000EB0C* ++ ID_MODEL_FROM_DATABASE=Kona 4 UFC ++ ++pci:v0000F1D0d0000EB0D* ++ ID_MODEL_FROM_DATABASE=Corvid 88 ++ + pci:v0000F1D0d0000EB0E* + ID_MODEL_FROM_DATABASE=Corvid 44 + ++pci:v0000F1D0d0000EB16* ++ ID_MODEL_FROM_DATABASE=Corvid HEVC ++ ++pci:v0000F1D0d0000EB16sv000010CFsd00001049* ++ ID_MODEL_FROM_DATABASE=Corvid HEVC (M31) ++ ++pci:v0000F1D0d0000EB18* ++ ID_MODEL_FROM_DATABASE=Corvid HB-R ++ ++pci:v0000F1D0d0000EB1A* ++ ID_MODEL_FROM_DATABASE=Kona IP 1SFP ++ ++pci:v0000F1D0d0000EB1C* ++ ID_MODEL_FROM_DATABASE=Kona IP 2SFP ++ ++pci:v0000F1D0d0000EB1D* ++ ID_MODEL_FROM_DATABASE=Io4KPlus ++ ++pci:v0000F1D0d0000EB1E* ++ ID_MODEL_FROM_DATABASE=IoIP ++ ++pci:v0000F1D0d0000EB1F* ++ ID_MODEL_FROM_DATABASE=Kona 5 ++ ++pci:v0000F1D0d0000EB23* ++ ID_MODEL_FROM_DATABASE=Kona 1 ++ ++pci:v0000F1D0d0000EB24* ++ ID_MODEL_FROM_DATABASE=Kona HDMI ++ ++pci:v0000F1D0d0000EB25* ++ ID_MODEL_FROM_DATABASE=Corvid 44 12g ++ ++pci:v0000F1D0d0000EB26* ++ ID_MODEL_FROM_DATABASE=T-Tap Pro ++ + pci:v0000F1D0d0000EFAC* + ID_MODEL_FROM_DATABASE=Xena SD-MM/SD-22-MM + +diff --git a/hwdb/20-sdio-classes.hwdb b/hwdb/20-sdio-classes.hwdb +index 72cce9d898..3bf56bbf90 100644 +--- a/hwdb/20-sdio-classes.hwdb ++++ b/hwdb/20-sdio-classes.hwdb +@@ -1,9 +1,9 @@ + # This file is part of systemd. + # +-# Data imported from: hwdb/sdio.ids ++# Data imported from: hwdb.d/sdio.ids + + sdio:c00v*d* +- ID_SDIO_CLASS_FROM_DATABASE=Not a SDIO standard interface ++ ID_SDIO_CLASS_FROM_DATABASE=Non-standard SDIO interface + + sdio:c01v*d* + ID_SDIO_CLASS_FROM_DATABASE=UART standard interface +diff --git a/hwdb/20-sdio-vendor-model.hwdb b/hwdb/20-sdio-vendor-model.hwdb +index 6c4dbe8ac4..8d3e72439a 100644 +--- a/hwdb/20-sdio-vendor-model.hwdb ++++ b/hwdb/20-sdio-vendor-model.hwdb +@@ -1,6 +1,6 @@ + # This file is part of systemd. + # +-# Data imported from: hwdb/sdio.ids ++# Data imported from: hwdb.d/sdio.ids + + sdio:c*v0020* + ID_VENDOR_FROM_DATABASE=ST-Ericsson +@@ -110,6 +110,9 @@ sdio:c*v02D0dA94D* + sdio:c*v02D0dA962* + ID_MODEL_FROM_DATABASE=BCM43362 WLAN card + ++sdio:c*v02D0dA9A6* ++ ID_MODEL_FROM_DATABASE=BCM43438 combo WLAN and Bluetooth Low Energy (BLE) # As in RPi3B ++ + sdio:c*v02DB* + ID_VENDOR_FROM_DATABASE=SyChip Inc. + +diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb +index 94ac8f2ff1..0e2bdea7a2 100644 +--- a/hwdb/20-usb-vendor-model.hwdb ++++ b/hwdb/20-usb-vendor-model.hwdb +@@ -11,6 +11,9 @@ usb:v0001p7778* + usb:v0002* + ID_VENDOR_FROM_DATABASE=Ingram + ++usb:v0002p0002* ++ ID_MODEL_FROM_DATABASE=passport00 ++ + usb:v0003* + ID_VENDOR_FROM_DATABASE=Club Mac + +@@ -56,12 +59,21 @@ usb:v0079p1843* + usb:v0079p1844* + ID_MODEL_FROM_DATABASE=Mayflash GameCube Controller + ++usb:v0080* ++ ID_VENDOR_FROM_DATABASE=Unknown ++ ++usb:v0080pA001* ++ ID_MODEL_FROM_DATABASE=JMS578 based SATA bridge ++ + usb:v0085* + ID_VENDOR_FROM_DATABASE=Boeye Technology Co., Ltd. + + usb:v0085p0600* + ID_MODEL_FROM_DATABASE=eBook Reader + ++usb:v0102* ++ ID_VENDOR_FROM_DATABASE=miniSTREAK ++ + usb:v0105* + ID_VENDOR_FROM_DATABASE=Trust International B.V. + +@@ -158,6 +170,12 @@ usb:v03E7* + usb:v03E7p2150* + ID_MODEL_FROM_DATABASE=Myriad VPU [Movidius Neural Compute Stick] + ++usb:v03E7p2485* ++ ID_MODEL_FROM_DATABASE=Movidius MyriadX ++ ++usb:v03E7pF63B* ++ ID_MODEL_FROM_DATABASE=Myriad VPU [Movidius Neural Compute Stick] ++ + usb:v03E8* + ID_VENDOR_FROM_DATABASE=EndPoints, Inc. + +@@ -446,6 +464,12 @@ usb:v03EBp7800* + usb:v03EBp800C* + ID_MODEL_FROM_DATABASE=Airspy HF+ + ++usb:v03EBpFF01* ++ ID_MODEL_FROM_DATABASE=WootingOne ++ ++usb:v03EBpFF02* ++ ID_MODEL_FROM_DATABASE=WootingTwo ++ + usb:v03EBpFF07* + ID_MODEL_FROM_DATABASE=Tux Droid fish dongle + +@@ -509,6 +533,9 @@ usb:v03F0p0024* + usb:v03F0p002A* + ID_MODEL_FROM_DATABASE=LaserJet P1102 + ++usb:v03F0p0053* ++ ID_MODEL_FROM_DATABASE=DeskJet 2620 All-in-One Printer ++ + usb:v03F0p0101* + ID_MODEL_FROM_DATABASE=ScanJet 4100c + +@@ -671,6 +698,9 @@ usb:v03F0p0517* + usb:v03F0p051D* + ID_MODEL_FROM_DATABASE=Bluetooth Interface + ++usb:v03F0p052A* ++ ID_MODEL_FROM_DATABASE=LaserJet M1212nf MFP ++ + usb:v03F0p0601* + ID_MODEL_FROM_DATABASE=ScanJet 6300c + +@@ -680,6 +710,9 @@ usb:v03F0p0604* + usb:v03F0p0605* + ID_MODEL_FROM_DATABASE=ScanJet 2200c + ++usb:v03F0p0610* ++ ID_MODEL_FROM_DATABASE=Z24i Monitor Hub ++ + usb:v03F0p0611* + ID_MODEL_FROM_DATABASE=OfficeJet K60xi + +@@ -746,6 +779,9 @@ usb:v03F0p0917* + usb:v03F0p0924* + ID_MODEL_FROM_DATABASE=Modular Smartcard Keyboard + ++usb:v03F0p0941* ++ ID_MODEL_FROM_DATABASE=X500 Optical Mouse ++ + usb:v03F0p094A* + ID_MODEL_FROM_DATABASE=Optical Mouse [672662-001] + +@@ -1154,6 +1190,9 @@ usb:v03F0p241D* + usb:v03F0p2424* + ID_MODEL_FROM_DATABASE=LP1965 19" Monitor Hub + ++usb:v03F0p2441* ++ ID_MODEL_FROM_DATABASE=Prime G2 [2AP18AA] ++ + usb:v03F0p2502* + ID_MODEL_FROM_DATABASE=PhotoSmart 7700 series + +@@ -1292,6 +1331,9 @@ usb:v03F0p3011* + usb:v03F0p3017* + ID_MODEL_FROM_DATABASE=Printing Support + ++usb:v03F0p304A* ++ ID_MODEL_FROM_DATABASE=Slim Keyboard ++ + usb:v03F0p3102* + ID_MODEL_FROM_DATABASE=PhotoSmart P1100 Printer w/ Card Reader + +@@ -1307,6 +1349,9 @@ usb:v03F0p3117* + usb:v03F0p311D* + ID_MODEL_FROM_DATABASE=Atheros AR9285 Malbec Bluetooth Adapter + ++usb:v03F0p312A* ++ ID_MODEL_FROM_DATABASE=LaserJet Pro M701n ++ + usb:v03F0p3202* + ID_MODEL_FROM_DATABASE=PhotoSmart 1215 + +@@ -1355,12 +1400,18 @@ usb:v03F0p3511* + usb:v03F0p3517* + ID_MODEL_FROM_DATABASE=LaserJet 3390 + ++usb:v03F0p354A* ++ ID_MODEL_FROM_DATABASE=Slim Keyboard ++ + usb:v03F0p3602* + ID_MODEL_FROM_DATABASE=PhotoSmart 1315 + + usb:v03F0p3611* + ID_MODEL_FROM_DATABASE=PSC 2410 PhotoSmart + ++usb:v03F0p3612* ++ ID_MODEL_FROM_DATABASE=Officejet Pro 8000 A809 ++ + usb:v03F0p3617* + ID_MODEL_FROM_DATABASE=Color LaserJet 2605 + +@@ -1451,6 +1502,9 @@ usb:v03F0p3F02* + usb:v03F0p3F11* + ID_MODEL_FROM_DATABASE=PSC-1315/PSC-1317 + ++usb:v03F0p3F17* ++ ID_MODEL_FROM_DATABASE=Laserjet P1505 ++ + usb:v03F0p4002* + ID_MODEL_FROM_DATABASE=PhotoSmart 635/715/720/735/935/E337 (storage) + +@@ -1667,6 +1721,9 @@ usb:v03F0p6302* + usb:v03F0p6317* + ID_MODEL_FROM_DATABASE=Color LaserJet 4730mfp + ++usb:v03F0p632A* ++ ID_MODEL_FROM_DATABASE=LaserJet M203-M206 ++ + usb:v03F0p6402* + ID_MODEL_FROM_DATABASE=PhotoSmart 715 (ptp) + +@@ -1814,6 +1871,9 @@ usb:v03F0p7A02* + usb:v03F0p7A04* + ID_MODEL_FROM_DATABASE=DeskJet D2460 + ++usb:v03F0p7A11* ++ ID_MODEL_FROM_DATABASE=Photosmart B109 ++ + usb:v03F0p7A17* + ID_MODEL_FROM_DATABASE=LaserJet M3027 MFP + +@@ -1910,9 +1970,15 @@ usb:v03F0p9302* + usb:v03F0p9402* + ID_MODEL_FROM_DATABASE=PhotoSmart R837 + ++usb:v03F0p942A* ++ ID_MODEL_FROM_DATABASE=LaserJet Pro M12a ++ + usb:v03F0p9502* + ID_MODEL_FROM_DATABASE=PhotoSmart R840 series + ++usb:v03F0p952A* ++ ID_MODEL_FROM_DATABASE=LaserJet Pro M12w ++ + usb:v03F0p9602* + ID_MODEL_FROM_DATABASE=PhotoSmart M730 series + +@@ -2009,6 +2075,9 @@ usb:v03F0pC111* + usb:v03F0pC202* + ID_MODEL_FROM_DATABASE=PhotoSmart 8200 series + ++usb:v03F0pC211* ++ ID_MODEL_FROM_DATABASE=Deskjet 2540 series ++ + usb:v03F0pC302* + ID_MODEL_FROM_DATABASE=DeskJet D2300 + +@@ -2219,6 +2288,9 @@ usb:v0402p5661* + usb:v0402p5667* + ID_MODEL_FROM_DATABASE=M5667 MP3 player + ++usb:v0402p8841* ++ ID_MODEL_FROM_DATABASE=Newmine Camera ++ + usb:v0402p9665* + ID_MODEL_FROM_DATABASE=Gateway Webcam + +@@ -2267,6 +2339,15 @@ usb:v0403p6014* + usb:v0403p6015* + ID_MODEL_FROM_DATABASE=Bridge(I2C/SPI/UART/FIFO) + ++usb:v0403p601F* ++ ID_MODEL_FROM_DATABASE=Myriad-RF LimeSDR-Mini ++ ++usb:v0403p6EE0* ++ ID_MODEL_FROM_DATABASE=EZO Carrier Board ++ ++usb:v0403p6F70* ++ ID_MODEL_FROM_DATABASE=HB-RF-USB ++ + usb:v0403p8028* + ID_MODEL_FROM_DATABASE=Dev board JTAG (FT232H based) + +@@ -2282,6 +2363,9 @@ usb:v0403p8140* + usb:v0403p8210* + ID_MODEL_FROM_DATABASE=MGTimer - MGCC (Vic) Timing System + ++usb:v0403p8348* ++ ID_MODEL_FROM_DATABASE=FT232BM [SIENNA Serial Interface] ++ + usb:v0403p8370* + ID_MODEL_FROM_DATABASE=7 Port Hub + +@@ -2291,6 +2375,12 @@ usb:v0403p8371* + usb:v0403p8372* + ID_MODEL_FROM_DATABASE=FT8U100AX Serial Port + ++usb:v0403p8508* ++ ID_MODEL_FROM_DATABASE=Selectronic SP PRO ++ ++usb:v0403p87D0* ++ ID_MODEL_FROM_DATABASE=Cressi Dive Computer Interface ++ + usb:v0403p8A28* + ID_MODEL_FROM_DATABASE=Rainforest Automation ZigBee Controller + +@@ -2321,15 +2411,24 @@ usb:v0403p9132* + usb:v0403p9133* + ID_MODEL_FROM_DATABASE=CallerID + ++usb:v0403p9134* ++ ID_MODEL_FROM_DATABASE=Virtual keyboard ++ + usb:v0403p9135* + ID_MODEL_FROM_DATABASE=Rotary Pub alarm + + usb:v0403p9136* + ID_MODEL_FROM_DATABASE=Pulsecounter + ++usb:v0403p9137* ++ ID_MODEL_FROM_DATABASE=Ledbutton interface ++ + usb:v0403p9E90* + ID_MODEL_FROM_DATABASE=Marvell OpenRD Base/Client + ++usb:v0403p9F08* ++ ID_MODEL_FROM_DATABASE=CIB-1894 Conclusion SmartLink Box: ++ + usb:v0403p9F80* + ID_MODEL_FROM_DATABASE=Ewert Energy Systems CANdapter + +@@ -2387,6 +2486,9 @@ usb:v0403pBCD9* + usb:v0403pBCDA* + ID_MODEL_FROM_DATABASE=Stellaris ICDI Board + ++usb:v0403pBD90* ++ ID_MODEL_FROM_DATABASE=PICAXE Download Cable [AXE027] ++ + usb:v0403pBDC8* + ID_MODEL_FROM_DATABASE=Egnite GmbH - JTAG/RS-232 adapter + +@@ -2594,6 +2696,9 @@ usb:v0403pF0C9* + usb:v0403pF0E9* + ID_MODEL_FROM_DATABASE=Tagsys L-P101 + ++usb:v0403pF0EE* ++ ID_MODEL_FROM_DATABASE=Tagsys Medio P200x ++ + usb:v0403pF1A0* + ID_MODEL_FROM_DATABASE=Asix PRESTO Programmer + +@@ -2603,6 +2708,9 @@ usb:v0403pF208* + usb:v0403pF3C0* + ID_MODEL_FROM_DATABASE=4N-GALAXY Serial Converter + ++usb:v0403pF458* ++ ID_MODEL_FROM_DATABASE=ABACUS ELECTRICS Optical Probe ++ + usb:v0403pF608* + ID_MODEL_FROM_DATABASE=CTI USB-485-Mini + +@@ -2624,6 +2732,9 @@ usb:v0403pF850* + usb:v0403pF918* + ID_MODEL_FROM_DATABASE=Ant8 Logic Probe + ++usb:v0403pF9D9* ++ ID_MODEL_FROM_DATABASE=Wetterempfanger 147.3kHz ++ + usb:v0403pFA00* + ID_MODEL_FROM_DATABASE=Matrix Orbital USB Serial + +@@ -2765,6 +2876,9 @@ usb:v0408p030C* + usb:v0408p03B2* + ID_MODEL_FROM_DATABASE=HP Webcam + ++usb:v0408p03F4* ++ ID_MODEL_FROM_DATABASE=HP Webcam ++ + usb:v0408p1030* + ID_MODEL_FROM_DATABASE=FV TouchCam N1 (Video) + +@@ -2774,6 +2888,12 @@ usb:v0408p3000* + usb:v0408p3001* + ID_MODEL_FROM_DATABASE=Optical Touch Screen + ++usb:v0408p3008* ++ ID_MODEL_FROM_DATABASE=Optical Touch Screen ++ ++usb:v0408pA060* ++ ID_MODEL_FROM_DATABASE=HD Webcam ++ + usb:v0409* + ID_VENDOR_FROM_DATABASE=NEC Corp. + +@@ -2882,6 +3002,9 @@ usb:v0409p00F7* + usb:v0409p011D* + ID_MODEL_FROM_DATABASE=e228 Mobile Phone + ++usb:v0409p0193* ++ ID_MODEL_FROM_DATABASE=RVT-R Writer ++ + usb:v0409p0203* + ID_MODEL_FROM_DATABASE=HID Audio Controls + +@@ -3317,6 +3440,18 @@ usb:v040Ap402E* + usb:v040Ap4034* + ID_MODEL_FROM_DATABASE=805 Photo Printer + ++usb:v040Ap4035* ++ ID_MODEL_FROM_DATABASE=7000 Photo Printer ++ ++usb:v040Ap4037* ++ ID_MODEL_FROM_DATABASE=7010 Photo Printer ++ ++usb:v040Ap4038* ++ ID_MODEL_FROM_DATABASE=7015 Photo Printer ++ ++usb:v040Ap404D* ++ ID_MODEL_FROM_DATABASE=8810 Photo Printer ++ + usb:v040Ap404F* + ID_MODEL_FROM_DATABASE=305 Photo Printer + +@@ -3362,6 +3497,9 @@ usb:v040B* + usb:v040Bp0A68* + ID_MODEL_FROM_DATABASE=Func MS-3 gaming mouse [WT6573F MCU] + ++usb:v040Bp2000* ++ ID_MODEL_FROM_DATABASE=wired Keyboard [Dynex DX-WRK1401] ++ + usb:v040Bp2367* + ID_MODEL_FROM_DATABASE=Human Interface Device [HP CalcPad 200 Calculator and Numeric Keypad] + +@@ -3386,6 +3524,9 @@ usb:v040D* + usb:v040Dp3184* + ID_MODEL_FROM_DATABASE=VNT VT6656 USB-802.11 Wireless LAN Adapter + ++usb:v040Dp340F* ++ ID_MODEL_FROM_DATABASE=Audinst HUD-mx2 ++ + usb:v040Dp6205* + ID_MODEL_FROM_DATABASE=USB 2.0 Card Reader + +@@ -3515,6 +3656,9 @@ usb:v0411p00DB* + usb:v0411p00E8* + ID_MODEL_FROM_DATABASE=WLI-UC-G300N Wireless LAN Adapter [Ralink RT2870] + ++usb:v0411p00F9* ++ ID_MODEL_FROM_DATABASE=Portable DVD Writer (DVSM-PL58U2) ++ + usb:v0411p0105* + ID_MODEL_FROM_DATABASE=External Hard Drive HD-CEU2 [Drive Station] + +@@ -3554,12 +3698,18 @@ usb:v0411p01A1* + usb:v0411p01A2* + ID_MODEL_FROM_DATABASE=WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070] + ++usb:v0411p01BA* ++ ID_MODEL_FROM_DATABASE=SATA Bridge ++ + usb:v0411p01DC* + ID_MODEL_FROM_DATABASE=Ultra-Slim Portable DVD Writer (DVSM-PC58U2V) + + usb:v0411p01DE* + ID_MODEL_FROM_DATABASE=External Hard Drive HD-PCTU3 [Buffalo MiniStation] + ++usb:v0411p01EA* ++ ID_MODEL_FROM_DATABASE=SATA Bridge ++ + usb:v0411p01EE* + ID_MODEL_FROM_DATABASE=WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070] + +@@ -3569,6 +3719,9 @@ usb:v0411p01F1* + usb:v0411p01FD* + ID_MODEL_FROM_DATABASE=WLI-UC-G450 Wireless LAN Adapter + ++usb:v0411p027E* ++ ID_MODEL_FROM_DATABASE=HD-LCU3 ++ + usb:v0412* + ID_VENDOR_FROM_DATABASE=Award Software International + +@@ -3722,6 +3875,30 @@ usb:v0416p3813* + usb:v0416p5011* + ID_MODEL_FROM_DATABASE=Virtual Com Port + ++usb:v0416p511B* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link1 ICE ++ ++usb:v0416p511C* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link1 ICE ++ ++usb:v0416p511D* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link1 ICE/VCOM ++ ++usb:v0416p511E* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link1 MSC/VCOM ++ ++usb:v0416p5200* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link2-ME ICE/MSC/VCOM ++ ++usb:v0416p5201* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link2-Pro ICE/MSC/VCOM ++ ++usb:v0416p5210* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link2 MSC FW UPGRADE ++ ++usb:v0416p5211* ++ ID_MODEL_FROM_DATABASE=Nuvoton Nu-Link2 HID FW UPGRADE ++ + usb:v0416p5518* + ID_MODEL_FROM_DATABASE=4-Port Hub + +@@ -3758,6 +3935,9 @@ usb:v0416p7722* + usb:v0416p7723* + ID_MODEL_FROM_DATABASE=SD Card Reader + ++usb:v0416pC141* ++ ID_MODEL_FROM_DATABASE=Barcode Scanner ++ + usb:v0417* + ID_VENDOR_FROM_DATABASE=Symbios Logic + +@@ -3773,6 +3953,9 @@ usb:v0419p0001* + usb:v0419p0600* + ID_MODEL_FROM_DATABASE=Desktop Wireless 6000 + ++usb:v0419p2694* ++ ID_MODEL_FROM_DATABASE=Laila ++ + usb:v0419p3001* + ID_MODEL_FROM_DATABASE=Xerox P1202 Laser Printer + +@@ -3821,6 +4004,9 @@ usb:v041D* + usb:v041E* + ID_VENDOR_FROM_DATABASE=Creative Technology, Ltd + ++usb:v041Ep0414* ++ ID_MODEL_FROM_DATABASE=HS-720 Headset ++ + usb:v041Ep1002* + ID_MODEL_FROM_DATABASE=Nomad II + +@@ -3896,6 +4082,15 @@ usb:v041Ep3220* + usb:v041Ep3232* + ID_MODEL_FROM_DATABASE=Sound Blaster Premium HD [SBX] + ++usb:v041Ep3237* ++ ID_MODEL_FROM_DATABASE=SB X-Fi Surround 5.1 Pro ++ ++usb:v041Ep3241* ++ ID_MODEL_FROM_DATABASE=Sound Blaster JAM ++ ++usb:v041Ep3263* ++ ID_MODEL_FROM_DATABASE=SB X-Fi Surround 5.1 Pro ++ + usb:v041Ep3F00* + ID_MODEL_FROM_DATABASE=E-Mu Xboard 25 MIDI Controller + +@@ -4094,6 +4289,9 @@ usb:v041Ep4095* + usb:v041Ep4097* + ID_MODEL_FROM_DATABASE=Live! Cam Chat HD [VF0700] + ++usb:v041Ep4099* ++ ID_MODEL_FROM_DATABASE=Creative VF0800 [RealSense Camera SR300] ++ + usb:v041Ep4100* + ID_MODEL_FROM_DATABASE=Nomad Jukebox 2 + +@@ -4340,6 +4538,9 @@ usb:v0421p0156* + usb:v0421p0157* + ID_MODEL_FROM_DATABASE=5800 XpressMusic (Imaging mode) + ++usb:v0421p0189* ++ ID_MODEL_FROM_DATABASE=N810 Internet Tablet WiMAX ++ + usb:v0421p0199* + ID_MODEL_FROM_DATABASE=6700 Classic (msc) + +@@ -4362,7 +4563,7 @@ usb:v0421p01C7* + ID_MODEL_FROM_DATABASE=N900 (Storage Mode) + + usb:v0421p01C8* +- ID_MODEL_FROM_DATABASE=N900 (PC-Suite Mode) ++ ID_MODEL_FROM_DATABASE=N900/N950 (PC-Suite Mode) + + usb:v0421p0228* + ID_MODEL_FROM_DATABASE=5530 XpressMusic +@@ -4415,11 +4616,17 @@ usb:v0421p03C0* + usb:v0421p03C1* + ID_MODEL_FROM_DATABASE=C7-00 (Media transfer mode) + ++usb:v0421p03C2* ++ ID_MODEL_FROM_DATABASE=Sim ++ + usb:v0421p03CD* + ID_MODEL_FROM_DATABASE=C7-00 (Nokia Suite mode) + + usb:v0421p03D1* +- ID_MODEL_FROM_DATABASE=N950 ++ ID_MODEL_FROM_DATABASE=N950 (Storage Mode) ++ ++usb:v0421p03D2* ++ ID_MODEL_FROM_DATABASE=N950 (PC Suite mode) + + usb:v0421p0400* + ID_MODEL_FROM_DATABASE=7600 Phone Parent +@@ -4512,7 +4719,7 @@ usb:v0421p0429* + ID_MODEL_FROM_DATABASE=6230i MultiMedia Card + + usb:v0421p0431* +- ID_MODEL_FROM_DATABASE=770 Internet Tablet ++ ID_MODEL_FROM_DATABASE=770/N800 Internet Tablet + + usb:v0421p0432* + ID_MODEL_FROM_DATABASE=N90 Phone Parent +@@ -4614,7 +4821,13 @@ usb:v0421p0509* + ID_MODEL_FROM_DATABASE=E65 (Storage mode) + + usb:v0421p0518* +- ID_MODEL_FROM_DATABASE=N9 Phone ++ ID_MODEL_FROM_DATABASE=N9 (Storage mode) ++ ++usb:v0421p0519* ++ ID_MODEL_FROM_DATABASE=N9 (RNDIS/Ethernet mode) ++ ++usb:v0421p051A* ++ ID_MODEL_FROM_DATABASE=N9 (PC Suite mode) + + usb:v0421p054D* + ID_MODEL_FROM_DATABASE=C2-01 +@@ -4692,7 +4905,7 @@ usb:v0423p1237* + ID_MODEL_FROM_DATABASE=Andromeda Hub + + usb:v0424* +- ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp. ++ ID_VENDOR_FROM_DATABASE=Microchip Technology, Inc. (formerly SMSC) + + usb:v0424p0001* + ID_MODEL_FROM_DATABASE=Integrated Hub +@@ -4730,9 +4943,6 @@ usb:v0424p223A* + usb:v0424p2503* + ID_MODEL_FROM_DATABASE=USB 2.0 Hub + +-usb:v0424p2504* +- ID_MODEL_FROM_DATABASE=USB 2.0 Hub +- + usb:v0424p2507* + ID_MODEL_FROM_DATABASE=hub + +@@ -4760,9 +4970,18 @@ usb:v0424p2640* + usb:v0424p2660* + ID_MODEL_FROM_DATABASE=Hub + ++usb:v0424p2744* ++ ID_MODEL_FROM_DATABASE=Hub ++ + usb:v0424p274D* + ID_MODEL_FROM_DATABASE=HTC Hub Controller + ++usb:v0424p2807* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v0424p3FC7* ++ ID_MODEL_FROM_DATABASE=RME Babyface audio system ++ + usb:v0424p3FCC* + ID_MODEL_FROM_DATABASE=RME MADIface + +@@ -4775,12 +4994,87 @@ usb:v0424p4060* + usb:v0424p4064* + ID_MODEL_FROM_DATABASE=Ultra Fast Media Reader + ++usb:v0424p4712* ++ ID_MODEL_FROM_DATABASE=USB4712 high-speed hub ++ ++usb:v0424p4713* ++ ID_MODEL_FROM_DATABASE=USB4715 high-speed hub (2 ports disabled) ++ ++usb:v0424p4714* ++ ID_MODEL_FROM_DATABASE=USB4715 high-speed hub (1 port disabled) ++ ++usb:v0424p4715* ++ ID_MODEL_FROM_DATABASE=USB4715 high-speed hub ++ ++usb:v0424p4910* ++ ID_MODEL_FROM_DATABASE=USB491x hub integrated functions (primary) ++ ++usb:v0424p4912* ++ ID_MODEL_FROM_DATABASE=USB4912 high-speed hub (1 port disabled) ++ ++usb:v0424p4914* ++ ID_MODEL_FROM_DATABASE=USB4914 high-speed hub ++ ++usb:v0424p4916* ++ ID_MODEL_FROM_DATABASE=USB4916 high-speed hub ++ ++usb:v0424p4920* ++ ID_MODEL_FROM_DATABASE=USB491x hub integrated functions (secondary) ++ ++usb:v0424p4925* ++ ID_MODEL_FROM_DATABASE=USB4925 high-speed hub (primary upstream) ++ ++usb:v0424p4927* ++ ID_MODEL_FROM_DATABASE=USB4927 high-speed hub (primary upstream) ++ ++usb:v0424p4931* ++ ID_MODEL_FROM_DATABASE=USB4925/4927 high-speed hub (secondary upstream) ++ ++usb:v0424p4940* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB ++ ++usb:v0424p4942* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated I2S audio port ++ ++usb:v0424p4943* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated I2S audio + HID port ++ ++usb:v0424p4944* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated serial port ++ ++usb:v0424p4946* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated serial + I2S audio port ++ ++usb:v0424p4947* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated serial + I2S audio + HID port ++ ++usb:v0424p494A* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB + I2S audio port ++ ++usb:v0424p494B* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB + I2S audio + HID port ++ ++usb:v0424p494C* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB + serial port ++ ++usb:v0424p494E* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB + serial + I2S audio port ++ ++usb:v0424p494F* ++ ID_MODEL_FROM_DATABASE=USB47xx/49xx hub integrated WinUSB + serial + I2S audio + HID port ++ + usb:v0424p5434* + ID_MODEL_FROM_DATABASE=Hub + + usb:v0424p5534* + ID_MODEL_FROM_DATABASE=Hub + ++usb:v0424p5744* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v0424p5807* ++ ID_MODEL_FROM_DATABASE=Hub ++ + usb:v0424p7500* + ID_MODEL_FROM_DATABASE=LAN7500 Ethernet 10/100/1000 Adapter + +@@ -4883,6 +5177,9 @@ usb:v0430p00A2* + usb:v0430p0100* + ID_MODEL_FROM_DATABASE=3-button Mouse + ++usb:v0430p0502* ++ ID_MODEL_FROM_DATABASE=Panasonic CF-19 HID Touch Panel ++ + usb:v0430p100E* + ID_MODEL_FROM_DATABASE=24.1" LCD Monitor v4 / FID-638 Mouse + +@@ -4952,6 +5249,9 @@ usb:v0437* + usb:v0438* + ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. + ++usb:v0438p7900* ++ ID_MODEL_FROM_DATABASE=Root Hub ++ + usb:v0439* + ID_VENDOR_FROM_DATABASE=Voice Technologies Group + +@@ -5279,6 +5579,9 @@ usb:v043Dp008E* + usb:v043Dp008F* + ID_MODEL_FROM_DATABASE=X422 + ++usb:v043Dp0091* ++ ID_MODEL_FROM_DATABASE=Laser Printer E232 ++ + usb:v043Dp0093* + ID_MODEL_FROM_DATABASE=X5250 + +@@ -5408,6 +5711,9 @@ usb:v043Ep3001* + usb:v043Ep3004* + ID_MODEL_FROM_DATABASE=TWFM-B003D 802.11abgn Wireless Module [Broadcom BCM43236B] + ++usb:v043Ep3009* ++ ID_MODEL_FROM_DATABASE=VC400 ++ + usb:v043Ep3101* + ID_MODEL_FROM_DATABASE=AN-WF500 802.11abgn + BT Wireless Adapter [Broadcom BCM43242] + +@@ -5639,6 +5945,9 @@ usb:v044FpB30B* + usb:v044FpB315* + ID_MODEL_FROM_DATABASE=Firestorm Dual Analog 3 + ++usb:v044FpB320* ++ ID_MODEL_FROM_DATABASE=Dual Trigger gamepad PC/PS2 2.0 ++ + usb:v044FpB323* + ID_MODEL_FROM_DATABASE=Dual Trigger 3-in-1 (PC Mode) + +@@ -5648,6 +5957,15 @@ usb:v044FpB324* + usb:v044FpB326* + ID_MODEL_FROM_DATABASE=Gamepad GP XID + ++usb:v044FpB351* ++ ID_MODEL_FROM_DATABASE=F16 MFD 1 ++ ++usb:v044FpB352* ++ ID_MODEL_FROM_DATABASE=F16 MFD 2 ++ ++usb:v044FpB365* ++ ID_MODEL_FROM_DATABASE=UbiSoft UbiConnect ++ + usb:v044FpB603* + ID_MODEL_FROM_DATABASE=force feedback Wheel + +@@ -5663,9 +5981,15 @@ usb:v044FpB653* + usb:v044FpB654* + ID_MODEL_FROM_DATABASE=Ferrari GT Force Feedback Wheel + ++usb:v044FpB677* ++ ID_MODEL_FROM_DATABASE=T150 Racing Wheel ++ + usb:v044FpB678* + ID_MODEL_FROM_DATABASE=T.Flight Rudder Pedals + ++usb:v044FpB679* ++ ID_MODEL_FROM_DATABASE=T-Rudder ++ + usb:v044FpB687* + ID_MODEL_FROM_DATABASE=TWCS Throttle + +@@ -5678,6 +6002,9 @@ usb:v0450* + usb:v0451* + ID_VENDOR_FROM_DATABASE=Texas Instruments, Inc. + ++usb:v0451p0422* ++ ID_MODEL_FROM_DATABASE=TUSB422 Port Controller with Power Delivery ++ + usb:v0451p1234* + ID_MODEL_FROM_DATABASE=Bluetooth Device + +@@ -5687,9 +6014,18 @@ usb:v0451p1428* + usb:v0451p1446* + ID_MODEL_FROM_DATABASE=TUSB2040/2070 Hub + ++usb:v0451p16A2* ++ ID_MODEL_FROM_DATABASE=CC Debugger ++ + usb:v0451p16A6* + ID_MODEL_FROM_DATABASE=BM-USBD1 BlueRobin RF heart rate sensor receiver + ++usb:v0451p16A8* ++ ID_MODEL_FROM_DATABASE=CC2531 ZigBee ++ ++usb:v0451p16AE* ++ ID_MODEL_FROM_DATABASE=CC2531 Dongle ++ + usb:v0451p2036* + ID_MODEL_FROM_DATABASE=TUSB2036 Hub + +@@ -5702,6 +6038,9 @@ usb:v0451p2077* + usb:v0451p2F90* + ID_MODEL_FROM_DATABASE=SM-USB-DIG + ++usb:v0451p3200* ++ ID_MODEL_FROM_DATABASE=TUSB3200 Boot Loader ++ + usb:v0451p3410* + ID_MODEL_FROM_DATABASE=TUSB3410 Microcontroller + +@@ -5753,6 +6092,9 @@ usb:v0451p8142* + usb:v0451p926B* + ID_MODEL_FROM_DATABASE=TUSB9260 Boot Loader + ++usb:v0451pBEF3* ++ ID_MODEL_FROM_DATABASE=CC1352R1 Launchpad ++ + usb:v0451pDBC0* + ID_MODEL_FROM_DATABASE=Device Bay Controller + +@@ -5768,9 +6110,39 @@ usb:v0451pE004* + usb:v0451pE008* + ID_MODEL_FROM_DATABASE=TI-84 Plus Silver Calculator + ++usb:v0451pE00E* ++ ID_MODEL_FROM_DATABASE=TI-89 Titanium Presentation Link ++ ++usb:v0451pE00F* ++ ID_MODEL_FROM_DATABASE=TI-84 Plus Presentation Link ++ ++usb:v0451pE010* ++ ID_MODEL_FROM_DATABASE=TI SmartPad Keyboard ++ ++usb:v0451pE011* ++ ID_MODEL_FROM_DATABASE=Nspire CAS+ prototype ++ + usb:v0451pE012* + ID_MODEL_FROM_DATABASE=TI-Nspire Calculator + ++usb:v0451pE013* ++ ID_MODEL_FROM_DATABASE=Network Bridge ++ ++usb:v0451pE01C* ++ ID_MODEL_FROM_DATABASE=Data Collection Sled [Nspire Lab Cradle, Nspire Datatracker Cradle] ++ ++usb:v0451pE01E* ++ ID_MODEL_FROM_DATABASE=Nspire CX Navigator Access Point ++ ++usb:v0451pE01F* ++ ID_MODEL_FROM_DATABASE=Python Adapter (firmware install mode) ++ ++usb:v0451pE020* ++ ID_MODEL_FROM_DATABASE=Python Adapter ++ ++usb:v0451pE022* ++ ID_MODEL_FROM_DATABASE=Nspire CX II ++ + usb:v0451pF430* + ID_MODEL_FROM_DATABASE=MSP-FET430UIF JTAG Tool + +@@ -5858,6 +6230,9 @@ usb:v0458p0003* + usb:v0458p0006* + ID_MODEL_FROM_DATABASE=Easy Mouse+ + ++usb:v0458p0007* ++ ID_MODEL_FROM_DATABASE=Trackbar Emotion ++ + usb:v0458p000B* + ID_MODEL_FROM_DATABASE=NetMouse Wheel(P+U) + +@@ -5924,6 +6299,9 @@ usb:v0458p0083* + usb:v0458p0087* + ID_MODEL_FROM_DATABASE=Ergo 525V Laser Mouse + ++usb:v0458p0088* ++ ID_MODEL_FROM_DATABASE=Genius Traveler 515 Laser ++ + usb:v0458p0089* + ID_MODEL_FROM_DATABASE=Genius Traveler 350 + +@@ -5939,6 +6317,9 @@ usb:v0458p0101* + usb:v0458p011B* + ID_MODEL_FROM_DATABASE=NetScroll T220 + ++usb:v0458p0186* ++ ID_MODEL_FROM_DATABASE=Genius DX-120 Mouse ++ + usb:v0458p1001* + ID_MODEL_FROM_DATABASE=Joystick + +@@ -6035,6 +6416,9 @@ usb:v0458p3019* + usb:v0458p301A* + ID_MODEL_FROM_DATABASE=MaxFire G-12U Vibration + ++usb:v0458p301C* ++ ID_MODEL_FROM_DATABASE=Genius MaxFighter F-16U ++ + usb:v0458p301D* + ID_MODEL_FROM_DATABASE=Genius MaxFire MiniPad + +@@ -6050,6 +6434,15 @@ usb:v0458p5003* + usb:v0458p5004* + ID_MODEL_FROM_DATABASE=G-pen Tablet + ++usb:v0458p5005* ++ ID_MODEL_FROM_DATABASE=Genius EasyPen M406 ++ ++usb:v0458p5012* ++ ID_MODEL_FROM_DATABASE=Genius EasyPen M406W ++ ++usb:v0458p5014* ++ ID_MODEL_FROM_DATABASE=Genius EasyPen 340 ++ + usb:v0458p505E* + ID_MODEL_FROM_DATABASE=Genius iSlim 330 + +@@ -6218,6 +6611,9 @@ usb:v045Ap501F* + usb:v045Ap503F* + ID_MODEL_FROM_DATABASE=Cali256 MP3 Player + ++usb:v045Ap5042* ++ ID_MODEL_FROM_DATABASE=Rio Forge ++ + usb:v045Ap5202* + ID_MODEL_FROM_DATABASE=Rio Riot MP3 Player + +@@ -6236,6 +6632,9 @@ usb:v045B* + usb:v045Bp0053* + ID_MODEL_FROM_DATABASE=RX610 RX-Stick + ++usb:v045Bp0229* ++ ID_MODEL_FROM_DATABASE=mSATA Adapter [renkforce Pi-102] ++ + usb:v045D* + ID_VENDOR_FROM_DATABASE=Nortel Networks, Ltd + +@@ -6458,6 +6857,9 @@ usb:v045Ep00CE* + usb:v045Ep00D1* + ID_MODEL_FROM_DATABASE=Optical Mouse with Tilt Wheel + ++usb:v045Ep00D2* ++ ID_MODEL_FROM_DATABASE=Notebook Optical Mouse with Tilt Wheel ++ + usb:v045Ep00DA* + ID_MODEL_FROM_DATABASE=eHome Infrared Receiver + +@@ -7088,11 +7490,17 @@ usb:v045Ep0799* + usb:v045Ep07A5* + ID_MODEL_FROM_DATABASE=Wireless Receiver 1461C + ++usb:v045Ep07B2* ++ ID_MODEL_FROM_DATABASE=2.4GHz Transceiver v8.0 used by mouse Wireless Desktop 900 ++ ++usb:v045Ep07B6* ++ ID_MODEL_FROM_DATABASE=Comfort Curve Keyboard 3000 ++ + usb:v045Ep07B9* + ID_MODEL_FROM_DATABASE=Wired Keyboard 200 + + usb:v045Ep07C6* +- ID_MODEL_FROM_DATABASE=RTL8153 GigE [Surface Dock Ethernet] ++ ID_MODEL_FROM_DATABASE=RTL8153 GigE [Surface Ethernet Adapter] + + usb:v045Ep07CA* + ID_MODEL_FROM_DATABASE=Surface Pro 3 Docking Station Audio Device +@@ -7106,6 +7514,15 @@ usb:v045Ep07F8* + usb:v045Ep07FD* + ID_MODEL_FROM_DATABASE=Nano Transceiver 1.1 + ++usb:v045Ep0800* ++ ID_MODEL_FROM_DATABASE=Wireless keyboard (All-in-One-Media) ++ ++usb:v045Ep0810* ++ ID_MODEL_FROM_DATABASE=LifeCam HD-3000 ++ ++usb:v045Ep0823* ++ ID_MODEL_FROM_DATABASE=Classic IntelliMouse ++ + usb:v045Ep0900* + ID_MODEL_FROM_DATABASE=Surface Dock Hub + +@@ -7133,9 +7550,27 @@ usb:v045Ep090C* + usb:v045Ep091A* + ID_MODEL_FROM_DATABASE=Hub + ++usb:v045Ep0927* ++ ID_MODEL_FROM_DATABASE=RTL8153B GigE [Surface Ethernet Adapter] ++ ++usb:v045Ep0955* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v045Ep0957* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v045Ep09A0* ++ ID_MODEL_FROM_DATABASE=RTL8153B GigE [Surface Ethernet Adapter] ++ ++usb:v045Ep09C0* ++ ID_MODEL_FROM_DATABASE=Surface Type Cover ++ + usb:v045Ep0A00* + ID_MODEL_FROM_DATABASE=Lumia 950 Dual SIM (RM-1118) + ++usb:v045Ep0B12* ++ ID_MODEL_FROM_DATABASE=Xbox Wireless Controller (model 1914) ++ + usb:v045Ep930A* + ID_MODEL_FROM_DATABASE=ISOUSB.SYS Intel 82930 Isochronous IO Test Board + +@@ -7334,6 +7769,18 @@ usb:v0461p4D75* + usb:v0461p4D81* + ID_MODEL_FROM_DATABASE=Dell N889 Optical Mouse + ++usb:v0461p4D8A* ++ ID_MODEL_FROM_DATABASE=HP Multimedia Keyboard ++ ++usb:v0461p4D91* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-D16DL ++ ++usb:v0461p4D92* ++ ID_MODEL_FROM_DATABASE=Optical mouse M-D17DR ++ ++usb:v0461p4DB1* ++ ID_MODEL_FROM_DATABASE=Dell Laptop Integrated Webcam 2Mpix ++ + usb:v0461p4DE3* + ID_MODEL_FROM_DATABASE=HP 5-Button Optical Comfort Mouse + +@@ -7343,6 +7790,12 @@ usb:v0461p4DE7* + usb:v0461p4E04* + ID_MODEL_FROM_DATABASE=Lenovo Keyboard KB1021 + ++usb:v0461p4E22* ++ ID_MODEL_FROM_DATABASE=Dell Mouse, 2 Buttons, Modell: MS111-P ++ ++usb:v0461p4E6F* ++ ID_MODEL_FROM_DATABASE=Acer Wired Keyboard Model KBAY211 ++ + usb:v0463* + ID_VENDOR_FROM_DATABASE=MGE UPS Systems + +@@ -7427,6 +7880,9 @@ usb:v046Ap0106* + usb:v046Ap010D* + ID_MODEL_FROM_DATABASE=MX-Board 3.0 Keyboard + ++usb:v046Ap0180* ++ ID_MODEL_FROM_DATABASE=Strait 3.0 ++ + usb:v046ApB090* + ID_MODEL_FROM_DATABASE=Keyboard + +@@ -7517,6 +7973,9 @@ usb:v046Dp0810* + usb:v046Dp0819* + ID_MODEL_FROM_DATABASE=Webcam C210 + ++usb:v046Dp081A* ++ ID_MODEL_FROM_DATABASE=Webcam C260 ++ + usb:v046Dp081B* + ID_MODEL_FROM_DATABASE=Webcam C310 + +@@ -7565,20 +8024,41 @@ usb:v046Dp0840* + usb:v046Dp0843* + ID_MODEL_FROM_DATABASE=Webcam C930e + ++usb:v046Dp0845* ++ ID_MODEL_FROM_DATABASE=ConferenceCam CC3000e Camera ++ ++usb:v046Dp0846* ++ ID_MODEL_FROM_DATABASE=ConferenceCam CC3000e Speakerphone ++ ++usb:v046Dp084B* ++ ID_MODEL_FROM_DATABASE=ConferenceCam Connect Video ++ + usb:v046Dp0850* + ID_MODEL_FROM_DATABASE=QuickCam Web + ++usb:v046Dp0857* ++ ID_MODEL_FROM_DATABASE=Logi Group Speakerphone ++ + usb:v046Dp085C* + ID_MODEL_FROM_DATABASE=C922 Pro Stream Webcam + ++usb:v046Dp085E* ++ ID_MODEL_FROM_DATABASE=BRIO Ultra HD Webcam ++ + usb:v046Dp0870* + ID_MODEL_FROM_DATABASE=QuickCam Express + ++usb:v046Dp0882* ++ ID_MODEL_FROM_DATABASE=Logi Group Speakerphone ++ + usb:v046Dp0890* + ID_MODEL_FROM_DATABASE=QuickCam Traveler + + usb:v046Dp0892* +- ID_MODEL_FROM_DATABASE=OrbiCam ++ ID_MODEL_FROM_DATABASE=C920 HD Pro Webcam ++ ++usb:v046Dp0893* ++ ID_MODEL_FROM_DATABASE=StreamCam + + usb:v046Dp0894* + ID_MODEL_FROM_DATABASE=CrystalCam +@@ -7859,6 +8339,9 @@ usb:v046Dp0A0B* + usb:v046Dp0A0C* + ID_MODEL_FROM_DATABASE=Clear Chat Comfort USB Headset + ++usb:v046Dp0A10* ++ ID_MODEL_FROM_DATABASE=V10 Notebook Speakers ++ + usb:v046Dp0A13* + ID_MODEL_FROM_DATABASE=Z-5 Speakers + +@@ -7895,9 +8378,15 @@ usb:v046Dp0A4D* + usb:v046Dp0A5B* + ID_MODEL_FROM_DATABASE=G933 Wireless Headset Dongle + ++usb:v046Dp0A5D* ++ ID_MODEL_FROM_DATABASE=G933 Headset Battery Charger ++ + usb:v046Dp0A66* + ID_MODEL_FROM_DATABASE=[G533 Wireless Headset Dongle] + ++usb:v046Dp0A8F* ++ ID_MODEL_FROM_DATABASE=H390 headset with microphone ++ + usb:v046Dp0B02* + ID_MODEL_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode) + +@@ -8123,9 +8612,21 @@ usb:v046DpC07D* + usb:v046DpC07E* + ID_MODEL_FROM_DATABASE=G402 Gaming Mouse + ++usb:v046DpC080* ++ ID_MODEL_FROM_DATABASE=G303 Gaming Mouse ++ + usb:v046DpC083* + ID_MODEL_FROM_DATABASE=G403 Prodigy Gaming Mouse + ++usb:v046DpC084* ++ ID_MODEL_FROM_DATABASE=G203 Gaming Mouse ++ ++usb:v046DpC08B* ++ ID_MODEL_FROM_DATABASE=G502 SE HERO Gaming Mouse ++ ++usb:v046DpC092* ++ ID_MODEL_FROM_DATABASE=G203 LIGHTSYNC Gaming Mouse ++ + usb:v046DpC101* + ID_MODEL_FROM_DATABASE=UltraX Media Remote + +@@ -8270,12 +8771,18 @@ usb:v046DpC22E* + usb:v046DpC231* + ID_MODEL_FROM_DATABASE=G13 Virtual Mouse + ++usb:v046DpC232* ++ ID_MODEL_FROM_DATABASE=Gaming Virtual Keyboard ++ + usb:v046DpC245* + ID_MODEL_FROM_DATABASE=G400 Optical Mouse + + usb:v046DpC246* + ID_MODEL_FROM_DATABASE=Gaming Mouse G300 + ++usb:v046DpC247* ++ ID_MODEL_FROM_DATABASE=G100S Optical Gaming Mouse ++ + usb:v046DpC248* + ID_MODEL_FROM_DATABASE=G105 Gaming Keyboard + +@@ -8291,6 +8798,15 @@ usb:v046DpC24D* + usb:v046DpC24E* + ID_MODEL_FROM_DATABASE=G500s Laser Gaming Mouse + ++usb:v046DpC24F* ++ ID_MODEL_FROM_DATABASE=G29 Driving Force Racing Wheel [PS3] ++ ++usb:v046DpC260* ++ ID_MODEL_FROM_DATABASE=G29 Driving Force Racing Wheel [PS4] ++ ++usb:v046DpC262* ++ ID_MODEL_FROM_DATABASE=G920 Driving Force Racing Wheel ++ + usb:v046DpC281* + ID_MODEL_FROM_DATABASE=WingMan Force + +@@ -8414,15 +8930,27 @@ usb:v046DpC31D* + usb:v046DpC31F* + ID_MODEL_FROM_DATABASE=Comfort Keyboard K290 + ++usb:v046DpC326* ++ ID_MODEL_FROM_DATABASE=Washable Keyboard K310 ++ + usb:v046DpC328* + ID_MODEL_FROM_DATABASE=Corded Keyboard K280e + ++usb:v046DpC32B* ++ ID_MODEL_FROM_DATABASE=G910 Orion Spark Mechanical Keyboard ++ + usb:v046DpC332* + ID_MODEL_FROM_DATABASE=G502 Proteus Spectrum Optical Mouse + + usb:v046DpC335* + ID_MODEL_FROM_DATABASE=G910 Orion Spectrum Mechanical Keyboard + ++usb:v046DpC33A* ++ ID_MODEL_FROM_DATABASE=G413 Gaming Keyboard ++ ++usb:v046DpC33F* ++ ID_MODEL_FROM_DATABASE=G815 Mechanical Keyboard ++ + usb:v046DpC401* + ID_MODEL_FROM_DATABASE=TrackMan Marble Wheel + +@@ -8537,6 +9065,15 @@ usb:v046DpC532* + usb:v046DpC534* + ID_MODEL_FROM_DATABASE=Unifying Receiver + ++usb:v046DpC537* ++ ID_MODEL_FROM_DATABASE=Cordless Mouse Receiver ++ ++usb:v046DpC53A* ++ ID_MODEL_FROM_DATABASE=PowerPlay Wireless Charging System ++ ++usb:v046DpC53D* ++ ID_MODEL_FROM_DATABASE=G631 Keyboard ++ + usb:v046DpC603* + ID_MODEL_FROM_DATABASE=3Dconnexion Spacemouse Plus XT + +@@ -9017,6 +9554,9 @@ usb:v0471p21E0* + usb:v0471p262C* + ID_MODEL_FROM_DATABASE=SPC230NC Webcam + ++usb:v0471p2721* ++ ID_MODEL_FROM_DATABASE=PTA 317 TV Camera ++ + usb:v0471p485D* + ID_MODEL_FROM_DATABASE=Senselock SenseIV v2.x + +@@ -9374,6 +9914,12 @@ usb:v047Dp5002* + usb:v047Dp5003* + ID_MODEL_FROM_DATABASE=VideoCam + ++usb:v047Dp8018* ++ ID_MODEL_FROM_DATABASE=Expert Wireless Trackball Mouse (K72359WW) ++ ++usb:v047Dp8068* ++ ID_MODEL_FROM_DATABASE=Pro Fit Ergo Vertical Wireless Trackball ++ + usb:v047E* + ID_VENDOR_FROM_DATABASE=Agere Systems, Inc. (Lucent) + +@@ -9398,6 +9944,9 @@ usb:v047F* + usb:v047Fp0101* + ID_MODEL_FROM_DATABASE=Bulk Driver + ++usb:v047Fp02EE* ++ ID_MODEL_FROM_DATABASE=BT600 ++ + usb:v047Fp0301* + ID_MODEL_FROM_DATABASE=Bulk Driver + +@@ -9410,18 +9959,33 @@ usb:v047Fp0CA1* + usb:v047Fp4254* + ID_MODEL_FROM_DATABASE=BUA-100 Bluetooth Adapter + ++usb:v047FpAA05* ++ ID_MODEL_FROM_DATABASE=DA45 ++ + usb:v047FpAC01* + ID_MODEL_FROM_DATABASE=Savi 7xx + + usb:v047FpAD01* + ID_MODEL_FROM_DATABASE=GameCom 777 5.1 Headset + ++usb:v047FpAF01* ++ ID_MODEL_FROM_DATABASE=DA80 ++ + usb:v047FpC008* + ID_MODEL_FROM_DATABASE=Audio 655 DSP + + usb:v047FpC00E* + ID_MODEL_FROM_DATABASE=Blackwire C310 headset + ++usb:v047FpC03B* ++ ID_MODEL_FROM_DATABASE=HD1 ++ ++usb:v047FpCA01* ++ ID_MODEL_FROM_DATABASE=Calisto 800 Series ++ ++usb:v047FpDA60* ++ ID_MODEL_FROM_DATABASE=DA60 ++ + usb:v0480* + ID_VENDOR_FROM_DATABASE=Toshiba America Inc + +@@ -9443,6 +10007,15 @@ usb:v0480p0100* + usb:v0480p0200* + ID_MODEL_FROM_DATABASE=External Disk + ++usb:v0480p0820* ++ ID_MODEL_FROM_DATABASE=Canvio Advance Disk ++ ++usb:v0480p0821* ++ ID_MODEL_FROM_DATABASE=Canvio Advance 2TB model DTC920 ++ ++usb:v0480p0900* ++ ID_MODEL_FROM_DATABASE=MQ04UBF100 ++ + usb:v0480pA006* + ID_MODEL_FROM_DATABASE=External Disk 1.5TB + +@@ -9458,6 +10031,9 @@ usb:v0480pA00D* + usb:v0480pA100* + ID_MODEL_FROM_DATABASE=Canvio Alu 2TB 2.5" Black External Disk Model HDTH320EK3CA + ++usb:v0480pA102* ++ ID_MODEL_FROM_DATABASE=Canvio Alu 2TB 2.5" Black External Disk Model HDTH320EK3CA ++ + usb:v0480pA202* + ID_MODEL_FROM_DATABASE=Canvio Basics HDD + +@@ -9530,6 +10106,9 @@ usb:v0482p0640* + usb:v0482p069B* + ID_MODEL_FROM_DATABASE=ECOSYS M2635dn + ++usb:v0482p06B4* ++ ID_MODEL_FROM_DATABASE=ECOSYS M5526cdw ++ + usb:v0483* + ID_VENDOR_FROM_DATABASE=STMicroelectronics + +@@ -9539,6 +10118,12 @@ usb:v0483p0137* + usb:v0483p0138* + ID_MODEL_FROM_DATABASE=Unicorn II (ST70138B + MTC-20174TQ chipset) + ++usb:v0483p0ADB* ++ ID_MODEL_FROM_DATABASE=Android Debug Bridge (ADB) device ++ ++usb:v0483p0AFB* ++ ID_MODEL_FROM_DATABASE=Android Fastboot device ++ + usb:v0483p1307* + ID_MODEL_FROM_DATABASE=Cytronix 6in1 Card Reader + +@@ -9572,6 +10157,21 @@ usb:v0483p3748* + usb:v0483p374B* + ID_MODEL_FROM_DATABASE=ST-LINK/V2.1 + ++usb:v0483p374D* ++ ID_MODEL_FROM_DATABASE=STLINK-V3 Loader ++ ++usb:v0483p374E* ++ ID_MODEL_FROM_DATABASE=STLINK-V3 ++ ++usb:v0483p374F* ++ ID_MODEL_FROM_DATABASE=STLINK-V3 ++ ++usb:v0483p3752* ++ ID_MODEL_FROM_DATABASE=ST-LINK/V2.1 ++ ++usb:v0483p3753* ++ ID_MODEL_FROM_DATABASE=STLINK-V3 ++ + usb:v0483p4810* + ID_MODEL_FROM_DATABASE=ISDN adapter + +@@ -9591,7 +10191,7 @@ usb:v0483p5720* + ID_MODEL_FROM_DATABASE=Mass Storage Device + + usb:v0483p5721* +- ID_MODEL_FROM_DATABASE=Hantek DDS-3X25 Arbitrary Waveform Generator ++ ID_MODEL_FROM_DATABASE=Interrupt Demo + + usb:v0483p5722* + ID_MODEL_FROM_DATABASE=Bulk Demo +@@ -9605,6 +10205,9 @@ usb:v0483p5731* + usb:v0483p5740* + ID_MODEL_FROM_DATABASE=Virtual COM Port + ++usb:v0483p5750* ++ ID_MODEL_FROM_DATABASE=LED badge -- mini LED display -- 11x44 ++ + usb:v0483p7270* + ID_MODEL_FROM_DATABASE=ST Micro Serial Bridge + +@@ -9623,6 +10226,9 @@ usb:v0483p91D1* + usb:v0483pA171* + ID_MODEL_FROM_DATABASE=ThermaData WiFi + ++usb:v0483pA2E0* ++ ID_MODEL_FROM_DATABASE=BMeasure instrument ++ + usb:v0483pDF11* + ID_MODEL_FROM_DATABASE=STM Device in DFU Mode + +@@ -9710,12 +10316,18 @@ usb:v048Dp1165* + usb:v048Dp1172* + ID_MODEL_FROM_DATABASE=Flash Drive + ++usb:v048Dp1234* ++ ID_MODEL_FROM_DATABASE=Chipsbank CBM2199 Flash Drive ++ + usb:v048Dp1336* + ID_MODEL_FROM_DATABASE=SD/MMC Cardreader + + usb:v048Dp1345* + ID_MODEL_FROM_DATABASE=Multi Cardreader + ++usb:v048Dp8297* ++ ID_MODEL_FROM_DATABASE=IT8297 RGB LED Controller ++ + usb:v048Dp9006* + ID_MODEL_FROM_DATABASE=IT9135 BDA Afatech DVB-T HDTV Dongle + +@@ -9737,6 +10349,9 @@ usb:v048Dp9507* + usb:v048Dp9910* + ID_MODEL_FROM_DATABASE=IT9910 chipset based grabber + ++usb:v048DpFF59* ++ ID_MODEL_FROM_DATABASE=Hdmi-CEC Bridge ++ + usb:v048F* + ID_VENDOR_FROM_DATABASE=Eicon Tech. + +@@ -9938,6 +10553,9 @@ usb:v0499p160F* + usb:v0499p1613* + ID_MODEL_FROM_DATABASE=Clavinova CLP535 + ++usb:v0499p1617* ++ ID_MODEL_FROM_DATABASE=PSR-E353 digital keyboard ++ + usb:v0499p1704* + ID_MODEL_FROM_DATABASE=Steinberg UR44 + +@@ -10505,6 +11123,9 @@ usb:v04A7p04BB* + usb:v04A7p04CD* + ID_MODEL_FROM_DATABASE=Xerox Travel Scanner 150 + ++usb:v04A7p04EE* ++ ID_MODEL_FROM_DATABASE=Duplex Combo Scanner ++ + usb:v04A8* + ID_VENDOR_FROM_DATABASE=Multivideo Labs, Inc. + +@@ -10739,6 +11360,9 @@ usb:v04A9p10CA* + usb:v04A9p10E3* + ID_MODEL_FROM_DATABASE=PIXMA iX6850 Printer + ++usb:v04A9p12FE* ++ ID_MODEL_FROM_DATABASE=Printer in service mode ++ + usb:v04A9p1404* + ID_MODEL_FROM_DATABASE=W6400PG + +@@ -11081,6 +11705,12 @@ usb:v04A9p178A* + usb:v04A9p178D* + ID_MODEL_FROM_DATABASE=PIXMA MG6853 + ++usb:v04A9p180B* ++ ID_MODEL_FROM_DATABASE=PIXMA MG3000 series ++ ++usb:v04A9p1856* ++ ID_MODEL_FROM_DATABASE=PIXMA TS6250 ++ + usb:v04A9p1900* + ID_MODEL_FROM_DATABASE=CanoScan LiDE 90 + +@@ -11114,6 +11744,9 @@ usb:v04A9p190E* + usb:v04A9p190F* + ID_MODEL_FROM_DATABASE=CanoScan LiDE 220 + ++usb:v04A9p1913* ++ ID_MODEL_FROM_DATABASE=CanoScan LiDE 300 ++ + usb:v04A9p2200* + ID_MODEL_FROM_DATABASE=CanoScan LiDE 25 + +@@ -11285,6 +11918,9 @@ usb:v04A9p2634* + usb:v04A9p2635* + ID_MODEL_FROM_DATABASE=MPC190 + ++usb:v04A9p2636* ++ ID_MODEL_FROM_DATABASE=LBP3200 ++ + usb:v04A9p2637* + ID_MODEL_FROM_DATABASE=iR C6800 + +@@ -11327,12 +11963,18 @@ usb:v04A9p2650* + usb:v04A9p2651* + ID_MODEL_FROM_DATABASE=iR 3100C EUR + ++usb:v04A9p2654* ++ ID_MODEL_FROM_DATABASE=LBP3600 ++ + usb:v04A9p2655* + ID_MODEL_FROM_DATABASE=FP-L170/MF350/L380/L398 + + usb:v04A9p2656* + ID_MODEL_FROM_DATABASE=iR1510-1670 CAPT Printer + ++usb:v04A9p2657* ++ ID_MODEL_FROM_DATABASE=LBP3210 ++ + usb:v04A9p2659* + ID_MODEL_FROM_DATABASE=MF8100 + +@@ -11373,7 +12015,7 @@ usb:v04A9p2669* + ID_MODEL_FROM_DATABASE=iR105PLUS + + usb:v04A9p266A* +- ID_MODEL_FROM_DATABASE=CAPT Device ++ ID_MODEL_FROM_DATABASE=LBP3000 + + usb:v04A9p266B* + ID_MODEL_FROM_DATABASE=iR8070 +@@ -11418,7 +12060,7 @@ usb:v04A9p2678* + ID_MODEL_FROM_DATABASE=iR 2570C EUR + + usb:v04A9p2679* +- ID_MODEL_FROM_DATABASE=CAPT Device ++ ID_MODEL_FROM_DATABASE=LBP5000 + + usb:v04A9p267A* + ID_MODEL_FROM_DATABASE=iR2016 +@@ -11429,6 +12071,9 @@ usb:v04A9p267B* + usb:v04A9p267D* + ID_MODEL_FROM_DATABASE=MF7100 series + ++usb:v04A9p267E* ++ ID_MODEL_FROM_DATABASE=LBP3300 ++ + usb:v04A9p2684* + ID_MODEL_FROM_DATABASE=MF3200 series + +@@ -11447,6 +12092,9 @@ usb:v04A9p2689* + usb:v04A9p268A* + ID_MODEL_FROM_DATABASE=LC310/L390/L408S + ++usb:v04A9p268B* ++ ID_MODEL_FROM_DATABASE=LBP3500 ++ + usb:v04A9p268C* + ID_MODEL_FROM_DATABASE=iR C6870 + +@@ -11462,9 +12110,15 @@ usb:v04A9p268F* + usb:v04A9p2691* + ID_MODEL_FROM_DATABASE=iR7105 + ++usb:v04A9p26A1* ++ ID_MODEL_FROM_DATABASE=LBP5300 ++ + usb:v04A9p26A3* + ID_MODEL_FROM_DATABASE=MF4100 series + ++usb:v04A9p26A4* ++ ID_MODEL_FROM_DATABASE=LBP5100 ++ + usb:v04A9p26B0* + ID_MODEL_FROM_DATABASE=MF4600 series + +@@ -11474,21 +12128,60 @@ usb:v04A9p26B4* + usb:v04A9p26B5* + ID_MODEL_FROM_DATABASE=MF4200 series + ++usb:v04A9p26B6* ++ ID_MODEL_FROM_DATABASE=FAX-L140/L130 ++ ++usb:v04A9p26B9* ++ ID_MODEL_FROM_DATABASE=LBP3310 ++ ++usb:v04A9p26BA* ++ ID_MODEL_FROM_DATABASE=LBP5050 ++ + usb:v04A9p26DA* +- ID_MODEL_FROM_DATABASE=LBP3010B printer ++ ID_MODEL_FROM_DATABASE=LBP3010/LBP3018/LBP3050 ++ ++usb:v04A9p26DB* ++ ID_MODEL_FROM_DATABASE=LBP3100/LBP3108/LBP3150 + + usb:v04A9p26E6* + ID_MODEL_FROM_DATABASE=iR1024 + ++usb:v04A9p26EA* ++ ID_MODEL_FROM_DATABASE=LBP9100C ++ ++usb:v04A9p26EE* ++ ID_MODEL_FROM_DATABASE=MF4320-4350 ++ ++usb:v04A9p26F1* ++ ID_MODEL_FROM_DATABASE=LBP7200C ++ ++usb:v04A9p26FF* ++ ID_MODEL_FROM_DATABASE=LBP6300 ++ + usb:v04A9p271A* + ID_MODEL_FROM_DATABASE=LBP6000 + ++usb:v04A9p271B* ++ ID_MODEL_FROM_DATABASE=LBP6200 ++ ++usb:v04A9p271C* ++ ID_MODEL_FROM_DATABASE=LBP7010C/7018C ++ + usb:v04A9p2736* + ID_MODEL_FROM_DATABASE=I-SENSYS MF4550d + + usb:v04A9p2737* + ID_MODEL_FROM_DATABASE=MF4410 + ++usb:v04A9p2742* ++ ID_MODEL_FROM_DATABASE=imageRUNNER1133 series ++ ++usb:v04A9p2771* ++ ID_MODEL_FROM_DATABASE=LBP6020 ++ ++usb:v04A9p2796* ++ ID_MODEL_FROM_DATABASE=LBP6230/6240 ++ + usb:v04A9p3041* + ID_MODEL_FROM_DATABASE=PowerShot S10 + +@@ -12395,9 +13088,18 @@ usb:v04A9p329D* + usb:v04A9p329F* + ID_MODEL_FROM_DATABASE=PowerShot SX530 HS + ++usb:v04A9p32A0* ++ ID_MODEL_FROM_DATABASE=EOS M10 ++ + usb:v04A9p32A6* + ID_MODEL_FROM_DATABASE=PowerShot SX710 HS + ++usb:v04A9p32A7* ++ ID_MODEL_FROM_DATABASE=PowerShot SX610 HS ++ ++usb:v04A9p32A8* ++ ID_MODEL_FROM_DATABASE=PowerShot G3 X ++ + usb:v04A9p32AA* + ID_MODEL_FROM_DATABASE=Powershot ELPH 160 / IXUS 160 + +@@ -12416,6 +13118,9 @@ usb:v04A9p32B1* + usb:v04A9p32B2* + ID_MODEL_FROM_DATABASE=PowerShot G9 X + ++usb:v04A9p32B3* ++ ID_MODEL_FROM_DATABASE=PowerShot G5 X ++ + usb:v04A9p32B4* + ID_MODEL_FROM_DATABASE=EOS Rebel T6 + +@@ -12425,12 +13130,30 @@ usb:v04A9p32BB* + usb:v04A9p32BF* + ID_MODEL_FROM_DATABASE=PowerShot SX420 IS + ++usb:v04A9p32C0* ++ ID_MODEL_FROM_DATABASE=PowerShot ELPH 190IS ++ + usb:v04A9p32C1* + ID_MODEL_FROM_DATABASE=PowerShot ELPH 180 / IXUS 175 + + usb:v04A9p32C2* + ID_MODEL_FROM_DATABASE=PowerShot SX720 HS + ++usb:v04A9p32C5* ++ ID_MODEL_FROM_DATABASE=EOS M6 ++ ++usb:v04A9p32CC* ++ ID_MODEL_FROM_DATABASE=EOS 200D ++ ++usb:v04A9p32D1* ++ ID_MODEL_FROM_DATABASE=EOS M100 ++ ++usb:v04A9p32D2* ++ ID_MODEL_FROM_DATABASE=EOS M50 ++ ++usb:v04A9p32D4* ++ ID_MODEL_FROM_DATABASE=Powershot ELPH 185 / IXUS 185 / IXY 200 ++ + usb:v04A9p32D5* + ID_MODEL_FROM_DATABASE=PowerShot SX430 IS + +@@ -12638,6 +13361,12 @@ usb:v04B0p040F* + usb:v04B0p0410* + ID_MODEL_FROM_DATABASE=D200 (ptp) + ++usb:v04B0p0411* ++ ID_MODEL_FROM_DATABASE=D80 (mass storage mode) ++ ++usb:v04B0p0412* ++ ID_MODEL_FROM_DATABASE=D80 (MTP/PTP mode) ++ + usb:v04B0p0413* + ID_MODEL_FROM_DATABASE=D40 (mass storage mode) + +@@ -12665,6 +13394,12 @@ usb:v04B0p0429* + usb:v04B0p042A* + ID_MODEL_FROM_DATABASE=D800 (ptp) + ++usb:v04B0p0430* ++ ID_MODEL_FROM_DATABASE=D7100 ++ ++usb:v04B0p0436* ++ ID_MODEL_FROM_DATABASE=D810 ++ + usb:v04B0p043F* + ID_MODEL_FROM_DATABASE=D5600 + +@@ -12791,12 +13526,18 @@ usb:v04B4p0001* + usb:v04B4p0002* + ID_MODEL_FROM_DATABASE=CY7C63x0x Thermometer + ++usb:v04B4p0008* ++ ID_MODEL_FROM_DATABASE=CDC ACM serial port ++ + usb:v04B4p0033* + ID_MODEL_FROM_DATABASE=Mouse + + usb:v04B4p0060* + ID_MODEL_FROM_DATABASE=Wireless optical mouse + ++usb:v04B4p00F3* ++ ID_MODEL_FROM_DATABASE=FX3 micro-controller (DFU mode) ++ + usb:v04B4p0100* + ID_MODEL_FROM_DATABASE=Cino FuzzyScan F760-B + +@@ -12815,6 +13556,9 @@ usb:v04B4p0306* + usb:v04B4p0407* + ID_MODEL_FROM_DATABASE=Optical Skype Mouse + ++usb:v04B4p0818* ++ ID_MODEL_FROM_DATABASE=AE-SMKD92-* [Thumb Keyboard] ++ + usb:v04B4p0BAD* + ID_MODEL_FROM_DATABASE=MetaGeek Wi-Spy + +@@ -12848,6 +13592,9 @@ usb:v04B4p4616* + usb:v04B4p4624* + ID_MODEL_FROM_DATABASE=DS-Xtreme Flash Card + ++usb:v04B4p4717* ++ ID_MODEL_FROM_DATABASE=West Bridge ++ + usb:v04B4p5201* + ID_MODEL_FROM_DATABASE=Combi Keyboard-Hub (Hub) + +@@ -12875,6 +13622,12 @@ usb:v04B4p650A* + usb:v04B4p6560* + ID_MODEL_FROM_DATABASE=CY7C65640 USB-2.0 "TetraHub" + ++usb:v04B4p6570* ++ ID_MODEL_FROM_DATABASE=Unprogrammed CY7C65632/34 hub HX2VL ++ ++usb:v04B4p6572* ++ ID_MODEL_FROM_DATABASE=Unprogrammed CY7C65642 hub ++ + usb:v04B4p6830* + ID_MODEL_FROM_DATABASE=CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI + +@@ -12929,8 +13682,14 @@ usb:v04B4pF231* + usb:v04B4pF232* + ID_MODEL_FROM_DATABASE=Mono embedded computer + ++usb:v04B4pFD10* ++ ID_MODEL_FROM_DATABASE=Gembird MSIS-PM ++ + usb:v04B4pFD13* +- ID_MODEL_FROM_DATABASE=Programmable power socket ++ ID_MODEL_FROM_DATABASE=Energenie EG-PMS ++ ++usb:v04B4pFD15* ++ ID_MODEL_FROM_DATABASE=Energenie EG-PMS2 + + usb:v04B5* + ID_VENDOR_FROM_DATABASE=ROHM LSI Systems USA, LLC +@@ -13125,7 +13884,7 @@ usb:v04B8p0151* + ID_MODEL_FROM_DATABASE=Perfection V800 Photo + + usb:v04B8p0202* +- ID_MODEL_FROM_DATABASE=Receipt Printer M129C/TM-T70 ++ ID_MODEL_FROM_DATABASE=Interface Card UB-U05 for Thermal Receipt Printers [M129C/TM-T70/TM-T88IV] + + usb:v04B8p0401* + ID_MODEL_FROM_DATABASE=CP 800 Digital Camera +@@ -13359,7 +14118,7 @@ usb:v04B8p084D* + ID_MODEL_FROM_DATABASE=PX-402A [Stylus SX115/Stylus NX110 Series] + + usb:v04B8p084F* +- ID_MODEL_FROM_DATABASE=ME OFFICE 510 ++ ID_MODEL_FROM_DATABASE=Multifunctional Printer Scanner [ME Office 510 / Epson Stylus SX215] + + usb:v04B8p0850* + ID_MODEL_FROM_DATABASE=EP-702A [Stylus Photo PX650/TX650 Series] +@@ -13481,6 +14240,18 @@ usb:v04B8p0892* + usb:v04B8p0893* + ID_MODEL_FROM_DATABASE=EP-774A + ++usb:v04B8p0E03* ++ ID_MODEL_FROM_DATABASE=Thermal Receipt Printer [TM-T20] ++ ++usb:v04B8p1114* ++ ID_MODEL_FROM_DATABASE=XP-440 [Expression Home Small-in-One Printer] ++ ++usb:v04B8p1129* ++ ID_MODEL_FROM_DATABASE=ET-4750 [WorkForce ET-4750 EcoTank All-in-One] ++ ++usb:v04B8p1168* ++ ID_MODEL_FROM_DATABASE=Workforce WF-7820/7840 Series ++ + usb:v04B9* + ID_VENDOR_FROM_DATABASE=Rainbow Technologies, Inc. + +@@ -13562,6 +14333,9 @@ usb:v04BB* + usb:v04BBp0101* + ID_MODEL_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + ++usb:v04BBp014A* ++ ID_MODEL_FROM_DATABASE=HDCL-UT ++ + usb:v04BBp0201* + ID_MODEL_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +@@ -13811,12 +14585,27 @@ usb:v04C5p10E7* + usb:v04C5p10FE* + ID_MODEL_FROM_DATABASE=S500 + ++usb:v04C5p1104* ++ ID_MODEL_FROM_DATABASE=KD02906 Line Thermal Printer ++ ++usb:v04C5p114F* ++ ID_MODEL_FROM_DATABASE=fi-6130 ++ + usb:v04C5p1150* + ID_MODEL_FROM_DATABASE=fi-6230 + ++usb:v04C5p11F3* ++ ID_MODEL_FROM_DATABASE=fi-6130Z ++ + usb:v04C5p125A* + ID_MODEL_FROM_DATABASE=PalmSecure Sensor Device - MP + ++usb:v04C5p132E* ++ ID_MODEL_FROM_DATABASE=fi-7160 ++ ++usb:v04C5p159F* ++ ID_MODEL_FROM_DATABASE=ScanSnap iX1500 ++ + usb:v04C5p200F* + ID_MODEL_FROM_DATABASE=Sigma DP2 (Mass Storage) + +@@ -13865,12 +14654,18 @@ usb:v04C8p072D* + usb:v04CA* + ID_VENDOR_FROM_DATABASE=Lite-On Technology Corp. + ++usb:v04CAp0020* ++ ID_MODEL_FROM_DATABASE=USB Keyboard ++ + usb:v04CAp004B* + ID_MODEL_FROM_DATABASE=Keyboard + + usb:v04CAp004F* + ID_MODEL_FROM_DATABASE=SK-9020 keyboard + ++usb:v04CAp008A* ++ ID_MODEL_FROM_DATABASE=Acer Wired Mouse Model SM-9023 ++ + usb:v04CAp1766* + ID_MODEL_FROM_DATABASE=HID Monitor Controls + +@@ -13898,6 +14693,9 @@ usb:v04CAp300F* + usb:v04CAp3014* + ID_MODEL_FROM_DATABASE=Qualcomm Atheros Bluetooth + ++usb:v04CAp3015* ++ ID_MODEL_FROM_DATABASE=Qualcomm Atheros QCA9377 Bluetooth ++ + usb:v04CAp7022* + ID_MODEL_FROM_DATABASE=HP HD Webcam + +@@ -14165,6 +14963,9 @@ usb:v04CBp01D4* + usb:v04CBp01D5* + ID_MODEL_FROM_DATABASE=FinePix F47 (PTP) + ++usb:v04CBp01E7* ++ ID_MODEL_FROM_DATABASE=Fujifilm A850 Digital Camera ++ + usb:v04CBp01F7* + ID_MODEL_FROM_DATABASE=FinePix J250 (PTP) + +@@ -14186,6 +14987,9 @@ usb:v04CBp0278* + usb:v04CBp02C5* + ID_MODEL_FROM_DATABASE=FinePix S9900W Digital Camera (PTP) + ++usb:v04CBp02E0* ++ ID_MODEL_FROM_DATABASE=X-T200 Digital Camera ++ + usb:v04CBp5006* + ID_MODEL_FROM_DATABASE=ASK-300 + +@@ -14360,18 +15164,33 @@ usb:v04D8p8108* + usb:v04D8p9004* + ID_MODEL_FROM_DATABASE=Microchip REAL ICE + ++usb:v04D8p9009* ++ ID_MODEL_FROM_DATABASE=ICD3 ++ + usb:v04D8p900A* + ID_MODEL_FROM_DATABASE=PICkit3 + + usb:v04D8p9012* + ID_MODEL_FROM_DATABASE=PICkit4 + ++usb:v04D8p9015* ++ ID_MODEL_FROM_DATABASE=ICD 4 In-Circuit Debugger ++ + usb:v04D8pC001* + ID_MODEL_FROM_DATABASE=PicoLCD 20x4 + + usb:v04D8pE11C* + ID_MODEL_FROM_DATABASE=TL866CS EEPROM Programmer [MiniPRO] + ++usb:v04D8pED16* ++ ID_MODEL_FROM_DATABASE=BeamiRC 2.0 CNC remote controller analoge ++ ++usb:v04D8pEDB4* ++ ID_MODEL_FROM_DATABASE=micro PLC (ATSAMD51G19A) [Black Brix ECU II] ++ ++usb:v04D8pEDB5* ++ ID_MODEL_FROM_DATABASE=ATMEGA32U4 [Black Brix ECU] ++ + usb:v04D8pF2C4* + ID_MODEL_FROM_DATABASE=Macareux-labs Hygrometry Temperature Sensor + +@@ -14387,6 +15206,9 @@ usb:v04D8pF437* + usb:v04D8pF4B5* + ID_MODEL_FROM_DATABASE=SmartScope + ++usb:v04D8pF5FE* ++ ID_MODEL_FROM_DATABASE=TrueRNG ++ + usb:v04D8pF8DA* + ID_MODEL_FROM_DATABASE=Hughski Ltd. ColorHug + +@@ -14426,9 +15248,18 @@ usb:v04D8pFFEF* + usb:v04D9* + ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. + ++usb:v04D9p0006* ++ ID_MODEL_FROM_DATABASE=Wired Keyboard (78/79 key) [RPI Wired Keyboard 5] ++ + usb:v04D9p0022* + ID_MODEL_FROM_DATABASE=Portable Keyboard + ++usb:v04D9p0348* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ ++usb:v04D9p0407* ++ ID_MODEL_FROM_DATABASE=Keyboard [TEX Shinobi] ++ + usb:v04D9p048E* + ID_MODEL_FROM_DATABASE=Optical Mouse + +@@ -14480,6 +15311,9 @@ usb:v04D9p2832* + usb:v04D9p2834* + ID_MODEL_FROM_DATABASE=HT82A834R Audio MCU + ++usb:v04D9p4545* ++ ID_MODEL_FROM_DATABASE=Keyboard [Diatec Majestouch 2 Tenkeyless] ++ + usb:v04D9pA01C* + ID_MODEL_FROM_DATABASE=wireless multimedia keyboard with trackball [Trust ADURA 17911] + +@@ -14492,6 +15326,9 @@ usb:v04D9pA052* + usb:v04D9pA055* + ID_MODEL_FROM_DATABASE=Keyboard + ++usb:v04D9pA075* ++ ID_MODEL_FROM_DATABASE=Optical Gaming Mouse ++ + usb:v04D9pA096* + ID_MODEL_FROM_DATABASE=Keyboard + +@@ -14504,9 +15341,33 @@ usb:v04D9pA100* + usb:v04D9pA11B* + ID_MODEL_FROM_DATABASE=Mouse [MX-3200] + ++usb:v04D9pA153* ++ ID_MODEL_FROM_DATABASE=Optical Gaming Mouse ++ ++usb:v04D9pA29F* ++ ID_MODEL_FROM_DATABASE=Microarray fingerprint reader ++ ++usb:v04D9pB534* ++ ID_MODEL_FROM_DATABASE=LGT8F328P Microprocessor ++ + usb:v04D9pE002* + ID_MODEL_FROM_DATABASE=MCU + ++usb:v04D9pFC2A* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Redragon M709] ++ ++usb:v04D9pFC30* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Redragon M711] ++ ++usb:v04D9pFC38* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Redragon M602-RGB] ++ ++usb:v04D9pFC4D* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Redragon M908] ++ ++usb:v04D9pFC55* ++ ID_MODEL_FROM_DATABASE=Venus MMO Gaming Mouse ++ + usb:v04DA* + ID_VENDOR_FROM_DATABASE=Panasonic (Matsushita) + +@@ -14537,6 +15398,9 @@ usb:v04DAp0D0D* + usb:v04DAp0D0E* + ID_MODEL_FROM_DATABASE=DVD-ROM & CD-R/RW + ++usb:v04DAp0D14* ++ ID_MODEL_FROM_DATABASE=DVD-RAM MLT08 ++ + usb:v04DAp0F07* + ID_MODEL_FROM_DATABASE=KX-MB2030 Multifunction Laser Printer + +@@ -15068,6 +15932,9 @@ usb:v04E8p0111* + usb:v04E8p0300* + ID_MODEL_FROM_DATABASE=E2530 / GT-C3350 Phones (Mass storage mode) + ++usb:v04E8p04E8* ++ ID_MODEL_FROM_DATABASE=Galaxy (MIDI mode) ++ + usb:v04E8p1003* + ID_MODEL_FROM_DATABASE=MP3 Player and Recorder + +@@ -15284,6 +16151,9 @@ usb:v04E8p342D* + usb:v04E8p344F* + ID_MODEL_FROM_DATABASE=SCX-3400 Series + ++usb:v04E8p347E* ++ ID_MODEL_FROM_DATABASE=C48x Series Color Laser Multifunction Printer ++ + usb:v04E8p3605* + ID_MODEL_FROM_DATABASE=InkJet Color Printer + +@@ -15521,6 +16391,9 @@ usb:v04E8p61B5* + usb:v04E8p61B6* + ID_MODEL_FROM_DATABASE=M3 Portable Hard Drive 1TB + ++usb:v04E8p61B7* ++ ID_MODEL_FROM_DATABASE=M3 Portable Hard Drive 4TB ++ + usb:v04E8p61F3* + ID_MODEL_FROM_DATABASE=Portable SSD T3 (MU-PT250B, MU-PT500B) + +@@ -15648,10 +16521,10 @@ usb:v04E8p685E* + ID_MODEL_FROM_DATABASE=GT-I9100 / GT-C3350 Phones (USB Debugging mode) + + usb:v04E8p6860* +- ID_MODEL_FROM_DATABASE=Galaxy (MTP) ++ ID_MODEL_FROM_DATABASE=Galaxy A5 (MTP) + + usb:v04E8p6863* +- ID_MODEL_FROM_DATABASE=GT-I9500 [Galaxy S4] / GT-I9250 [Galaxy Nexus] (network tethering) ++ ID_MODEL_FROM_DATABASE=Galaxy series, misc. (tethering mode) + + usb:v04E8p6864* + ID_MODEL_FROM_DATABASE=GT-I9070 (network tethering, USB debugging enabled) +@@ -15707,9 +16580,21 @@ usb:v04E8p7080* + usb:v04E8p7081* + ID_MODEL_FROM_DATABASE=Human Interface Device + ++usb:v04E8p7301* ++ ID_MODEL_FROM_DATABASE=Fingerprint Device ++ + usb:v04E8p8001* + ID_MODEL_FROM_DATABASE=Handheld + ++usb:v04E8p8002* ++ ID_MODEL_FROM_DATABASE=Portable SSD 500GB Model Number: MU - P8500B ++ ++usb:v04E8p8003* ++ ID_MODEL_FROM_DATABASE=Portable SSD T1 ++ ++usb:v04E8pD003* ++ ID_MODEL_FROM_DATABASE=GT-I9003 ++ + usb:v04E8pE020* + ID_MODEL_FROM_DATABASE=SERI E02 SCOM 6200 UMTS Phone + +@@ -15836,6 +16721,9 @@ usb:v04F2p0841* + usb:v04F2p0860* + ID_MODEL_FROM_DATABASE=2.4G Multimedia Wireless Kit + ++usb:v04F2p0939* ++ ID_MODEL_FROM_DATABASE=Amazon Basics mouse ++ + usb:v04F2p1061* + ID_MODEL_FROM_DATABASE=HP KG-1061 Wireless Keyboard+Mouse + +@@ -15995,6 +16883,9 @@ usb:v04F2pB1B4* + usb:v04F2pB1B9* + ID_MODEL_FROM_DATABASE=Asus Integrated Webcam + ++usb:v04F2pB1BB* ++ ID_MODEL_FROM_DATABASE=2.0M UVC WebCam ++ + usb:v04F2pB1CF* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Camera + +@@ -16019,6 +16910,9 @@ usb:v04F2pB221* + usb:v04F2pB230* + ID_MODEL_FROM_DATABASE=Integrated HP HD Webcam + ++usb:v04F2pB249* ++ ID_MODEL_FROM_DATABASE=HP Integrated Webcam ++ + usb:v04F2pB257* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Camera + +@@ -16070,12 +16964,33 @@ usb:v04F2pB40E* + usb:v04F2pB444* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam + ++usb:v04F2pB49F* ++ ID_MODEL_FROM_DATABASE=Bluetooth (RTL8723BE) ++ ++usb:v04F2pB563* ++ ID_MODEL_FROM_DATABASE=Integrated Camera ++ ++usb:v04F2pB5AB* ++ ID_MODEL_FROM_DATABASE=Integrated Camera ++ ++usb:v04F2pB5AC* ++ ID_MODEL_FROM_DATABASE=Integrated IR Camera ++ + usb:v04F2pB5CE* + ID_MODEL_FROM_DATABASE=Integrated Camera + + usb:v04F2pB5CF* + ID_MODEL_FROM_DATABASE=Integrated IR Camera + ++usb:v04F2pB5DB* ++ ID_MODEL_FROM_DATABASE=HP Webcam ++ ++usb:v04F2pB604* ++ ID_MODEL_FROM_DATABASE=Integrated Camera (1280x720@30) ++ ++usb:v04F2pB681* ++ ID_MODEL_FROM_DATABASE=ThinkPad T490 Webcam ++ + usb:v04F3* + ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp. + +@@ -16124,6 +17039,12 @@ usb:v04F3p0381* + usb:v04F3p04A0* + ID_MODEL_FROM_DATABASE=Dream Cheeky Stress/Panic Button + ++usb:v04F3p0C28* ++ ID_MODEL_FROM_DATABASE=fingerprint sensor [FeinTech FPS00200] ++ ++usb:v04F3p2234* ++ ID_MODEL_FROM_DATABASE=Touchscreen ++ + usb:v04F4* + ID_VENDOR_FROM_DATABASE=Harting Elektronik, Inc. + +@@ -16253,6 +17174,12 @@ usb:v04F9p002C* + usb:v04F9p002D* + ID_MODEL_FROM_DATABASE=Printer + ++usb:v04F9p0037* ++ ID_MODEL_FROM_DATABASE=HL-3040CN series ++ ++usb:v04F9p0038* ++ ID_MODEL_FROM_DATABASE=HL-3070CW series ++ + usb:v04F9p0039* + ID_MODEL_FROM_DATABASE=HL-5340 series + +@@ -16262,6 +17189,12 @@ usb:v04F9p0041* + usb:v04F9p0042* + ID_MODEL_FROM_DATABASE=HL-2270DW Laser Printer + ++usb:v04F9p004D* ++ ID_MODEL_FROM_DATABASE=HL-6180DW series ++ ++usb:v04F9p0080* ++ ID_MODEL_FROM_DATABASE=HL-L6250DN series ++ + usb:v04F9p0100* + ID_MODEL_FROM_DATABASE=MFC8600/9650 series + +@@ -16787,6 +17720,9 @@ usb:v04F9p01EC* + usb:v04F9p01F4* + ID_MODEL_FROM_DATABASE=MFC-5890CN + ++usb:v04F9p0204* ++ ID_MODEL_FROM_DATABASE=DCP-165C ++ + usb:v04F9p020A* + ID_MODEL_FROM_DATABASE=MFC-8670DN + +@@ -16892,6 +17828,9 @@ usb:v04F9p023F* + usb:v04F9p0240* + ID_MODEL_FROM_DATABASE=MFC-J950DN + ++usb:v04F9p0245* ++ ID_MODEL_FROM_DATABASE=MFC-9560CDW ++ + usb:v04F9p0248* + ID_MODEL_FROM_DATABASE=DCP-7055 scanner/printer + +@@ -17615,6 +18554,48 @@ usb:v04F9p03BC* + usb:v04F9p03BD* + ID_MODEL_FROM_DATABASE=DCP-J762N + ++usb:v04F9p03FD* ++ ID_MODEL_FROM_DATABASE=ADS-2700W ++ ++usb:v04F9p043F* ++ ID_MODEL_FROM_DATABASE=MFC-L3770CDW ++ ++usb:v04F9p0440* ++ ID_MODEL_FROM_DATABASE=MFC-9350CDW ++ ++usb:v04F9p0441* ++ ID_MODEL_FROM_DATABASE=MFC-L3750CDW ++ ++usb:v04F9p0442* ++ ID_MODEL_FROM_DATABASE=MFC-L3745CDW ++ ++usb:v04F9p0443* ++ ID_MODEL_FROM_DATABASE=MFC-L3735CDN ++ ++usb:v04F9p0444* ++ ID_MODEL_FROM_DATABASE=MFC-9150CDN ++ ++usb:v04F9p0445* ++ ID_MODEL_FROM_DATABASE=MFC-L3730CDN ++ ++usb:v04F9p0446* ++ ID_MODEL_FROM_DATABASE=MFC-L3710CW ++ ++usb:v04F9p0447* ++ ID_MODEL_FROM_DATABASE=DCP-9030CDN ++ ++usb:v04F9p0448* ++ ID_MODEL_FROM_DATABASE=DCP-L3550CDW ++ ++usb:v04F9p044A* ++ ID_MODEL_FROM_DATABASE=HL-L3290CDW ++ ++usb:v04F9p044B* ++ ID_MODEL_FROM_DATABASE=DCP-L3510CDW ++ ++usb:v04F9p044C* ++ ID_MODEL_FROM_DATABASE=DCP-L3551CDW ++ + usb:v04F9p1000* + ID_MODEL_FROM_DATABASE=Printer + +@@ -17631,35 +18612,95 @@ usb:v04F9p2007* + ID_MODEL_FROM_DATABASE=PT-2420PC P-touch Label Printer + + usb:v04F9p2015* +- ID_MODEL_FROM_DATABASE=QL-500 P-touch label printer ++ ID_MODEL_FROM_DATABASE=QL-500 label printer + + usb:v04F9p2016* +- ID_MODEL_FROM_DATABASE=QL-550 P-touch label printer ++ ID_MODEL_FROM_DATABASE=QL-550 printer + + usb:v04F9p201A* + ID_MODEL_FROM_DATABASE=PT-18R P-touch label printer + + usb:v04F9p201B* +- ID_MODEL_FROM_DATABASE=QL-650TD P-touch Label Printer ++ ID_MODEL_FROM_DATABASE=QL-650TD Label Printer ++ ++usb:v04F9p2020* ++ ID_MODEL_FROM_DATABASE=QL-1050 Label Printer + + usb:v04F9p2027* +- ID_MODEL_FROM_DATABASE=QL-560 P-touch Label Printer ++ ID_MODEL_FROM_DATABASE=QL-560 Label Printer + + usb:v04F9p2028* +- ID_MODEL_FROM_DATABASE=QL-570 P-touch Label Printer ++ ID_MODEL_FROM_DATABASE=QL-570 Label Printer ++ ++usb:v04F9p202A* ++ ID_MODEL_FROM_DATABASE=QL-1060N Label Printer + + usb:v04F9p202B* + ID_MODEL_FROM_DATABASE=PT-7600 P-touch Label Printer + ++usb:v04F9p202C* ++ ID_MODEL_FROM_DATABASE=PT-1230PC P-touch Label Printer E mode ++ ++usb:v04F9p202D* ++ ID_MODEL_FROM_DATABASE=PT-2430PC P-touch Label Printer ++ ++usb:v04F9p2030* ++ ID_MODEL_FROM_DATABASE=PT-1230PC P-touch Label Printer EL mode ++ + usb:v04F9p2041* + ID_MODEL_FROM_DATABASE=PT-2730 P-touch Label Printer + ++usb:v04F9p2042* ++ ID_MODEL_FROM_DATABASE=QL-700 Label Printer ++ ++usb:v04F9p2043* ++ ID_MODEL_FROM_DATABASE=QL-710W Label Printer ++ ++usb:v04F9p2044* ++ ID_MODEL_FROM_DATABASE=QL-720NW Label Printer ++ ++usb:v04F9p204D* ++ ID_MODEL_FROM_DATABASE=QL-720NW Label Printer (mass storage mode) ++ + usb:v04F9p2061* + ID_MODEL_FROM_DATABASE=PT-P700 P-touch Label Printer + + usb:v04F9p2064* + ID_MODEL_FROM_DATABASE=PT-P700 P-touch Label Printer RemovableDisk + ++usb:v04F9p2074* ++ ID_MODEL_FROM_DATABASE=PT-D600 P-touch Label Printer ++ ++usb:v04F9p209B* ++ ID_MODEL_FROM_DATABASE=QL-800 Label Printer ++ ++usb:v04F9p209C* ++ ID_MODEL_FROM_DATABASE=QL-810W Label Printer ++ ++usb:v04F9p209D* ++ ID_MODEL_FROM_DATABASE=QL-820NWB Label Printer ++ ++usb:v04F9p20A7* ++ ID_MODEL_FROM_DATABASE=QL-1100 Label Printer ++ ++usb:v04F9p20A8* ++ ID_MODEL_FROM_DATABASE=QL-1110NWB Label Printer ++ ++usb:v04F9p20A9* ++ ID_MODEL_FROM_DATABASE=QL-1100 Label Printer (mass storage) ++ ++usb:v04F9p20AA* ++ ID_MODEL_FROM_DATABASE=QL-1110NWB Label Printer (mass storage) ++ ++usb:v04F9p20AB* ++ ID_MODEL_FROM_DATABASE=QL-1115NWB Label Printer ++ ++usb:v04F9p20AC* ++ ID_MODEL_FROM_DATABASE=QL-1115NWB Label Printer (mass storage) ++ ++usb:v04F9p20C0* ++ ID_MODEL_FROM_DATABASE=QL-600 Label Printer ++ + usb:v04F9p2100* + ID_MODEL_FROM_DATABASE=Card Reader Writer + +@@ -17801,6 +18842,9 @@ usb:v04FDp0003* + usb:v04FE* + ID_VENDOR_FROM_DATABASE=PFU, Ltd + ++usb:v04FEp0006* ++ ID_MODEL_FROM_DATABASE=Happy Hacking Keyboard Lite2 ++ + usb:v04FF* + ID_VENDOR_FROM_DATABASE=E-CMOS Corp. + +@@ -18074,6 +19118,9 @@ usb:v050Dp0304* + usb:v050Dp0307* + ID_MODEL_FROM_DATABASE=USB 2.0 - 7 ports Hub [FSU307] + ++usb:v050Dp038C* ++ ID_MODEL_FROM_DATABASE=F2CU038 HDMI Adapter ++ + usb:v050Dp0409* + ID_MODEL_FROM_DATABASE=F5U409 Serial + +@@ -18375,7 +19422,7 @@ usb:v0525p1265* + ID_MODEL_FROM_DATABASE=File-backed Storage Gadget + + usb:v0525p3424* +- ID_MODEL_FROM_DATABASE=Lumidigm Venus fingerprint sensor ++ ID_MODEL_FROM_DATABASE=V30x/V4xx fingerprint sensor [Lumidigm] + + usb:v0525pA0F0* + ID_MODEL_FROM_DATABASE=Cambridge Electronic Devices Power1401 mk 2 +@@ -18405,7 +19452,7 @@ usb:v0525pA4A4* + ID_MODEL_FROM_DATABASE=Linux-USB user-mode bulk source/sink + + usb:v0525pA4A5* +- ID_MODEL_FROM_DATABASE=Pocketbook Pro 903 / Mobius 2 Action Cam ++ ID_MODEL_FROM_DATABASE=Linux-USB File-backed Storage Gadget + + usb:v0525pA4A6* + ID_MODEL_FROM_DATABASE=Linux-USB Serial Gadget +@@ -18422,6 +19469,12 @@ usb:v0525pA4A9* + usb:v0525pA4AA* + ID_MODEL_FROM_DATABASE=Linux-USB CDC Composite Gadge (Ethernet and ACM) + ++usb:v0525pA4AB* ++ ID_MODEL_FROM_DATABASE=Linux-USB Multifunction Composite Gadget ++ ++usb:v0525pA4AC* ++ ID_MODEL_FROM_DATABASE=Linux-USB HID Gadget ++ + usb:v0526* + ID_VENDOR_FROM_DATABASE=Temic MHS S.A. + +@@ -18770,6 +19823,9 @@ usb:v0547* + usb:v0547p0001* + ID_MODEL_FROM_DATABASE=ICSI Bluetooth Device + ++usb:v0547p0080* ++ ID_MODEL_FROM_DATABASE=I3SYSTEM HYUNY ++ + usb:v0547p1002* + ID_MODEL_FROM_DATABASE=Python2 WDM Encoder + +@@ -18902,6 +19958,9 @@ usb:v054Cp0045* + usb:v054Cp0046* + ID_MODEL_FROM_DATABASE=Network Walkman + ++usb:v054Cp0049* ++ ID_MODEL_FROM_DATABASE=UP-D895 ++ + usb:v054Cp004A* + ID_MODEL_FROM_DATABASE=Memory Stick Hi-Fi System + +@@ -19154,6 +20213,9 @@ usb:v054Cp01D5* + usb:v054Cp01DE* + ID_MODEL_FROM_DATABASE=VRD-VC10 [Video Capture] + ++usb:v054Cp01E7* ++ ID_MODEL_FROM_DATABASE=UP-D897 ++ + usb:v054Cp01E8* + ID_MODEL_FROM_DATABASE=UP-DR150 Photo Printer + +@@ -19286,6 +20348,9 @@ usb:v054Cp02D1* + usb:v054Cp02D2* + ID_MODEL_FROM_DATABASE=PSP Slim + ++usb:v054Cp02D4* ++ ID_MODEL_FROM_DATABASE=UP-CX1 ++ + usb:v054Cp02D8* + ID_MODEL_FROM_DATABASE=SBAC-US10 SxS PRO memory card reader/writer + +@@ -19328,6 +20393,9 @@ usb:v054Cp035C* + usb:v054Cp035F* + ID_MODEL_FROM_DATABASE=UP-DR200 Photo Printer + ++usb:v054Cp0360* ++ ID_MODEL_FROM_DATABASE=M2 Card Reader ++ + usb:v054Cp0382* + ID_MODEL_FROM_DATABASE=Memory Stick PRO-HG Duo Adaptor (MSAC-UAH1) + +@@ -19340,6 +20408,15 @@ usb:v054Cp0387* + usb:v054Cp03BC* + ID_MODEL_FROM_DATABASE=Webbie HD - MHS-CM1 + ++usb:v054Cp03C3* ++ ID_MODEL_FROM_DATABASE=UP-DR80MD ++ ++usb:v054Cp03C4* ++ ID_MODEL_FROM_DATABASE=Stryker SDP1000 ++ ++usb:v054Cp03C5* ++ ID_MODEL_FROM_DATABASE=UP-DR80 ++ + usb:v054Cp03CC* + ID_MODEL_FROM_DATABASE=SD Card Reader + +@@ -19385,6 +20462,9 @@ usb:v054Cp06BB* + usb:v054Cp06C3* + ID_MODEL_FROM_DATABASE=RC-S380 + ++usb:v054Cp07C3* ++ ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in Mass Storage mode ++ + usb:v054Cp07C4* + ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in Mass Storage mode + +@@ -19394,6 +20474,12 @@ usb:v054Cp082F* + usb:v054Cp0847* + ID_MODEL_FROM_DATABASE=WG-C10 Portable Wireless Server + ++usb:v054Cp0877* ++ ID_MODEL_FROM_DATABASE=UP-D898/X898 series ++ ++usb:v054Cp0884* ++ ID_MODEL_FROM_DATABASE=MDR-ZX770BN [Wireless Noise Canceling Stereo Headset] ++ + usb:v054Cp088C* + ID_MODEL_FROM_DATABASE=Portable Headphone Amplifier + +@@ -19415,6 +20501,33 @@ usb:v054Cp0BA0* + usb:v054Cp0BB5* + ID_MODEL_FROM_DATABASE=Headset MDR-1000X + ++usb:v054Cp0C02* ++ ID_MODEL_FROM_DATABASE=ILCE-7M3 [A7III] in Mass Storage mode ++ ++usb:v054Cp0C03* ++ ID_MODEL_FROM_DATABASE=ILCE-7M3 [A7III] in MTP mode ++ ++usb:v054Cp0C34* ++ ID_MODEL_FROM_DATABASE=ILCE-7M3 [A7III] in PC Remote mode ++ ++usb:v054Cp0C7F* ++ ID_MODEL_FROM_DATABASE=WH-CH700N [Wireless Noise-Canceling Headphones] ++ ++usb:v054Cp0CD3* ++ ID_MODEL_FROM_DATABASE=WH-1000XM3 [Wireless Noise-Canceling Headphones] ++ ++usb:v054Cp0CDA* ++ ID_MODEL_FROM_DATABASE=PlayStation Classic controller ++ ++usb:v054Cp0CE0* ++ ID_MODEL_FROM_DATABASE=WF-1000XM3 [Wireless Noise-Canceling Headphones] ++ ++usb:v054Cp0CF0* ++ ID_MODEL_FROM_DATABASE=MRW-G1 ++ ++usb:v054Cp0D58* ++ ID_MODEL_FROM_DATABASE=WH-1000XM4 [Wireless Noise-Canceling Headphones] ++ + usb:v054Cp1000* + ID_MODEL_FROM_DATABASE=Wireless Buzz! Receiver + +@@ -19547,6 +20660,9 @@ usb:v0557p2221* + usb:v0557p2404* + ID_MODEL_FROM_DATABASE=4-port switch + ++usb:v0557p2419* ++ ID_MODEL_FROM_DATABASE=Virtual mouse/keyboard device ++ + usb:v0557p2600* + ID_MODEL_FROM_DATABASE=IDE Bridge + +@@ -19883,9 +20999,21 @@ usb:v0566p3002* + usb:v0566p3004* + ID_MODEL_FROM_DATABASE=Genius KB-29E + ++usb:v0566p3013* ++ ID_MODEL_FROM_DATABASE=BakkerElkhuizen Wired Keyboard S-board 840 Design ++ ++usb:v0566p3020* ++ ID_MODEL_FROM_DATABASE=BakkerElkhuizen Wired Keyboard S-board 840 Design USB-Hub ++ ++usb:v0566p3027* ++ ID_MODEL_FROM_DATABASE=Sun-Flex ProTouch ++ + usb:v0566p3107* + ID_MODEL_FROM_DATABASE=Keyboard + ++usb:v0566p3132* ++ ID_MODEL_FROM_DATABASE=Optical mouse M-DY4DR / M-DY6DR ++ + usb:v0566p4006* + ID_MODEL_FROM_DATABASE=FID 638 Mouse (Sun Microsystems) + +@@ -20000,6 +21128,12 @@ usb:v056Ap0038* + usb:v056Ap0039* + ID_MODEL_FROM_DATABASE=DTU-710 + ++usb:v056Ap003A* ++ ID_MODEL_FROM_DATABASE=DTI-520 ++ ++usb:v056Ap003B* ++ ID_MODEL_FROM_DATABASE=Integrated Hub ++ + usb:v056Ap003F* + ID_MODEL_FROM_DATABASE=DTZ-2100 [Cintiq 21UX] + +@@ -20067,7 +21201,7 @@ usb:v056Ap0081* + ID_MODEL_FROM_DATABASE=CTE-630BT [Graphire Wireless (6x8)] + + usb:v056Ap0084* +- ID_MODEL_FROM_DATABASE=Wireless adapter for Bamboo tablets ++ ID_MODEL_FROM_DATABASE=ACK-40401 [Wireless Accessory Kit] + + usb:v056Ap0090* + ID_MODEL_FROM_DATABASE=TPC90 +@@ -20081,6 +21215,9 @@ usb:v056Ap0097* + usb:v056Ap009A* + ID_MODEL_FROM_DATABASE=TPC9A + ++usb:v056Ap00A2* ++ ID_MODEL_FROM_DATABASE=STU-300B [LCD signature pad] ++ + usb:v056Ap00B0* + ID_MODEL_FROM_DATABASE=PTZ-430 [Intuos3 (4x5)] + +@@ -20204,6 +21341,9 @@ usb:v056Ap00ED* + usb:v056Ap00EF* + ID_MODEL_FROM_DATABASE=TPCEF + ++usb:v056Ap00F0* ++ ID_MODEL_FROM_DATABASE=DTU-1631 ++ + usb:v056Ap00F4* + ID_MODEL_FROM_DATABASE=DTK-2400 [Cintiq 24HD] tablet + +@@ -20213,6 +21353,9 @@ usb:v056Ap00F6* + usb:v056Ap00F8* + ID_MODEL_FROM_DATABASE=DTH-2400 [Cintiq 24HD touch] tablet + ++usb:v056Ap00F9* ++ ID_MODEL_FROM_DATABASE=DTK-2200 [Cintiq 22HD] hub ++ + usb:v056Ap00FA* + ID_MODEL_FROM_DATABASE=DTK-2200 [Cintiq 22HD] tablet + +@@ -20279,14 +21422,56 @@ usb:v056Ap0317* + usb:v056Ap0318* + ID_MODEL_FROM_DATABASE=CTH-301 [Bamboo] + ++usb:v056Ap0319* ++ ID_MODEL_FROM_DATABASE=CTH-300 [Bamboo Pad wireless] ++ ++usb:v056Ap0323* ++ ID_MODEL_FROM_DATABASE=CTL-680 [Intuos Pen (M)] ++ ++usb:v056Ap032A* ++ ID_MODEL_FROM_DATABASE=DTK-2700 [Cintiq 27QHD] ++ ++usb:v056Ap032B* ++ ID_MODEL_FROM_DATABASE=DTH-2700 [Cintiq 27QHD touch] tablet ++ ++usb:v056Ap032C* ++ ID_MODEL_FROM_DATABASE=DTH-2700 [Cintiq 27QHD touch] touchscreen ++ + usb:v056Ap032F* + ID_MODEL_FROM_DATABASE=DTU-1031X + ++usb:v056Ap0331* ++ ID_MODEL_FROM_DATABASE=ACK-411050 [ExpressKey Remote] ++ ++usb:v056Ap0333* ++ ID_MODEL_FROM_DATABASE=DTH-1300 [Cintiq 13HD Touch] tablet ++ ++usb:v056Ap0335* ++ ID_MODEL_FROM_DATABASE=DTH-1300 [Cintiq 13HD Touch] touchscreen ++ ++usb:v056Ap0336* ++ ID_MODEL_FROM_DATABASE=DTU-1141 ++ ++usb:v056Ap033B* ++ ID_MODEL_FROM_DATABASE=CTL-490 [Intuos Draw (S)] ++ ++usb:v056Ap033C* ++ ID_MODEL_FROM_DATABASE=CTH-490 [Intuos Art/Photo/Comic (S)] ++ ++usb:v056Ap033D* ++ ID_MODEL_FROM_DATABASE=CTL-690 [Intuos Draw (M)] ++ ++usb:v056Ap033E* ++ ID_MODEL_FROM_DATABASE=CTH-690 [Intuos Art (M)] ++ ++usb:v056Ap0343* ++ ID_MODEL_FROM_DATABASE=DTK-1651 ++ + usb:v056Ap0347* +- ID_MODEL_FROM_DATABASE=Integrated Hub ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] internal hub + + usb:v056Ap0348* +- ID_MODEL_FROM_DATABASE=Integrated Hub ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] external hub + + usb:v056Ap034A* + ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 13] touchscreen +@@ -20330,6 +21515,9 @@ usb:v056Ap0357* + usb:v056Ap0358* + ID_MODEL_FROM_DATABASE=PTH-860 [Intuos Pro (L)] + ++usb:v056Ap0359* ++ ID_MODEL_FROM_DATABASE=DTU-1141B ++ + usb:v056Ap035A* + ID_MODEL_FROM_DATABASE=DTH-1152 tablet + +@@ -20378,6 +21566,39 @@ usb:v056Ap038E* + usb:v056Ap038F* + ID_MODEL_FROM_DATABASE=DTH-3220 [Cintiq Pro 32] internal hub + ++usb:v056Ap0390* ++ ID_MODEL_FROM_DATABASE=DTK-1660 [Cintiq 16] ++ ++usb:v056Ap0392* ++ ID_MODEL_FROM_DATABASE=PTH-460 [Intuos Pro (S)] ++ ++usb:v056Ap0396* ++ ID_MODEL_FROM_DATABASE=DTK-1660E ++ ++usb:v056Ap0398* ++ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 13] tablet ++ ++usb:v056Ap0399* ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] tablet ++ ++usb:v056Ap039A* ++ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 13] touchscreen ++ ++usb:v056Ap039B* ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] touchscreen ++ ++usb:v056Ap039C* ++ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 16] external hub ++ ++usb:v056Ap039D* ++ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 16] internal hub ++ ++usb:v056Ap03AA* ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] tablet ++ ++usb:v056Ap03AC* ++ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] touchscreen ++ + usb:v056Ap0400* + ID_MODEL_FROM_DATABASE=PenPartner 4x5 + +@@ -20432,6 +21653,45 @@ usb:v056Dp0002* + usb:v056Dp0003* + ID_MODEL_FROM_DATABASE=Device Bay Controller + ++usb:v056Dp4000* ++ ID_MODEL_FROM_DATABASE=FlexScan EV3237 ++ ++usb:v056Dp4001* ++ ID_MODEL_FROM_DATABASE=Monitor ++ ++usb:v056Dp4002* ++ ID_MODEL_FROM_DATABASE=USB HID Monitor ++ ++usb:v056Dp4014* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2750 ++ ++usb:v056Dp4026* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2451 ++ ++usb:v056Dp4027* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2456 ++ ++usb:v056Dp4036* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2785 ++ ++usb:v056Dp4037* ++ ID_MODEL_FROM_DATABASE=FlexScan EV3285 ++ ++usb:v056Dp4044* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2457 ++ ++usb:v056Dp4059* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2760 ++ ++usb:v056Dp405B* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2460 ++ ++usb:v056Dp405F* ++ ID_MODEL_FROM_DATABASE=FlexScan EV2795 ++ ++usb:v056Dp4065* ++ ID_MODEL_FROM_DATABASE=FlexScan EV3895 ++ + usb:v056E* + ID_VENDOR_FROM_DATABASE=Elecom Co., Ltd + +@@ -20439,41 +21699,344 @@ usb:v056Ep0002* + ID_MODEL_FROM_DATABASE=29UO Mouse + + usb:v056Ep0057* +- ID_MODEL_FROM_DATABASE=M-PGDL Mouse ++ ID_MODEL_FROM_DATABASE=Micro Grast Pop M-PGDL + + usb:v056Ep005C* +- ID_MODEL_FROM_DATABASE=M-PGDL Mouse ++ ID_MODEL_FROM_DATABASE=Micro Grast Pop M-PG2DL + + usb:v056Ep005D* +- ID_MODEL_FROM_DATABASE=M-FGDL Mouse ++ ID_MODEL_FROM_DATABASE=Micro Grast Fit M-FGDL + + usb:v056Ep005E* +- ID_MODEL_FROM_DATABASE=M-FG2DL Mouse ++ ID_MODEL_FROM_DATABASE=Micro Grast Fit M-FG2DL + + usb:v056Ep0062* +- ID_MODEL_FROM_DATABASE=M-D18DR Mouse ++ ID_MODEL_FROM_DATABASE=Optical mouse M-D18DR + + usb:v056Ep0063* +- ID_MODEL_FROM_DATABASE=M-SODL Mouse ++ ID_MODEL_FROM_DATABASE=Laser mouse M-SODL + + usb:v056Ep0069* +- ID_MODEL_FROM_DATABASE=M-GE1UL Mouse ++ ID_MODEL_FROM_DATABASE=Laser mouse M-GE1UL + + usb:v056Ep0071* +- ID_MODEL_FROM_DATABASE=M-GE3DL Mouse ++ ID_MODEL_FROM_DATABASE=Laser mouse M-GE3DL + + usb:v056Ep0072* +- ID_MODEL_FROM_DATABASE=M-LS6UL Mouse ++ ID_MODEL_FROM_DATABASE=Laser mouse M-LS6UL + + usb:v056Ep0073* +- ID_MODEL_FROM_DATABASE=M-LS7UL Mouse ++ ID_MODEL_FROM_DATABASE=Laser mouse M-LS7UL + + usb:v056Ep0074* +- ID_MODEL_FROM_DATABASE=M-FW1UL Mouse ++ ID_MODEL_FROM_DATABASE=Optical mouse M-FW1UL ++ ++usb:v056Ep0075* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-FW2DL ++ ++usb:v056Ep0077* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-LY2UL ++ ++usb:v056Ep0079* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-D21DL ++ ++usb:v056Ep007B* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-D20DR ++ ++usb:v056Ep007C* ++ ID_MODEL_FROM_DATABASE=Laser Bluetooth mouse M-BT5BL ++ ++usb:v056Ep007E* ++ ID_MODEL_FROM_DATABASE=Option mouse M-M8UR ++ ++usb:v056Ep007F* ++ ID_MODEL_FROM_DATABASE=Option mouse M-M9UR ++ ++usb:v056Ep0081* ++ ID_MODEL_FROM_DATABASE=Option mouse M-DY6DR ++ ++usb:v056Ep0082* ++ ID_MODEL_FROM_DATABASE=Laser mouse M-D22DR ++ ++usb:v056Ep0088* ++ ID_MODEL_FROM_DATABASE=Micro Grast2 Bit M-BG3DL ++ ++usb:v056Ep0089* ++ ID_MODEL_FROM_DATABASE=Micro Grast2 Pop M-PG3DL ++ ++usb:v056Ep008C* ++ ID_MODEL_FROM_DATABASE=M-NE3DL Mouse ++ ++usb:v056Ep008D* ++ ID_MODEL_FROM_DATABASE=ORIME M-NE4DR ++ ++usb:v056Ep008F* ++ ID_MODEL_FROM_DATABASE=M-BT8BL Bluetooth Mouse ++ ++usb:v056Ep0092* ++ ID_MODEL_FROM_DATABASE=Wireless BlueLED Mouse (M-BL2DB) ++ ++usb:v056Ep009C* ++ ID_MODEL_FROM_DATABASE=IR Mouse M-IR02DR ++ ++usb:v056Ep009D* ++ ID_MODEL_FROM_DATABASE=IR Mouse M-IR03DR ++ ++usb:v056Ep009F* ++ ID_MODEL_FROM_DATABASE=BlueLED Mouse M-HS1DB ++ ++usb:v056Ep00A1* ++ ID_MODEL_FROM_DATABASE=IR Mouse M-IR05DR ++ ++usb:v056Ep00A4* ++ ID_MODEL_FROM_DATABASE=Blue LED Mouse M-BL06DB ++ ++usb:v056Ep00A5* ++ ID_MODEL_FROM_DATABASE=M-NV1BR Bluetooth Mouse ++ ++usb:v056Ep00A7* ++ ID_MODEL_FROM_DATABASE=Blue LED Mouse M-BL08DB ++ ++usb:v056Ep00A8* ++ ID_MODEL_FROM_DATABASE=M-BL09DB Mouse ++ ++usb:v056Ep00A9* ++ ID_MODEL_FROM_DATABASE=M-BL10UB Mouse ++ ++usb:v056Ep00AA* ++ ID_MODEL_FROM_DATABASE=M-BL11DB Mouse ++ ++usb:v056Ep00AC* ++ ID_MODEL_FROM_DATABASE=M-A-BL01UL / M-BL15DB Mouse ++ ++usb:v056Ep00B4* ++ ID_MODEL_FROM_DATABASE=Track on Glass Mouse M-TG02DL ++ ++usb:v056Ep00B5* ++ ID_MODEL_FROM_DATABASE=Track on Glass Mouse M-TG03UL ++ ++usb:v056Ep00B6* ++ ID_MODEL_FROM_DATABASE=Track on Glass Mouse M-TG04DL ++ ++usb:v056Ep00B8* ++ ID_MODEL_FROM_DATABASE=M-A-BL01UL or M-ASKL2 Mouse ++ ++usb:v056Ep00B9* ++ ID_MODEL_FROM_DATABASE=M-A-BL02DB or M-ASKL Mouse ++ ++usb:v056Ep00CB* ++ ID_MODEL_FROM_DATABASE=M-BL21DB Mouse ++ ++usb:v056Ep00CD* ++ ID_MODEL_FROM_DATABASE=M-XG1UB Mouse ++ ++usb:v056Ep00CE* ++ ID_MODEL_FROM_DATABASE=M-XG1DB Mouse ++ ++usb:v056Ep00CF* ++ ID_MODEL_FROM_DATABASE=M-XG1BB Bluetooth Mouse ++ ++usb:v056Ep00D0* ++ ID_MODEL_FROM_DATABASE=M-XG2UB Mouse ++ ++usb:v056Ep00D1* ++ ID_MODEL_FROM_DATABASE=M-XG2DB Mouse ++ ++usb:v056Ep00D2* ++ ID_MODEL_FROM_DATABASE=M-XG2BB Bluetooth Mouse ++ ++usb:v056Ep00D3* ++ ID_MODEL_FROM_DATABASE=M-XG3DL Mouse ++ ++usb:v056Ep00D4* ++ ID_MODEL_FROM_DATABASE=M-LS11DL Mouse ++ ++usb:v056Ep00DA* ++ ID_MODEL_FROM_DATABASE=M-XG4UB Mouse ++ ++usb:v056Ep00DB* ++ ID_MODEL_FROM_DATABASE=M-XG4DB Mouse ++ ++usb:v056Ep00DC* ++ ID_MODEL_FROM_DATABASE=M-XG4BB Bluetooth Mouse ++ ++usb:v056Ep00DD* ++ ID_MODEL_FROM_DATABASE=M-LS12UL Mouse ++ ++usb:v056Ep00DE* ++ ID_MODEL_FROM_DATABASE=M-LS13UL Mouse ++ ++usb:v056Ep00DF* ++ ID_MODEL_FROM_DATABASE=M-BL22DB Mouse ++ ++usb:v056Ep00E1* ++ ID_MODEL_FROM_DATABASE=M-WK01DB or M-A-BL04DB ++ ++usb:v056Ep00E2* ++ ID_MODEL_FROM_DATABASE=M-A-BL03DB ++ ++usb:v056Ep00E3* ++ ID_MODEL_FROM_DATABASE=M-XGx10UB ++ ++usb:v056Ep00E4* ++ ID_MODEL_FROM_DATABASE=M-XGx10DB ++ ++usb:v056Ep00E5* ++ ID_MODEL_FROM_DATABASE=M-XGx10BB ++ ++usb:v056Ep00E6* ++ ID_MODEL_FROM_DATABASE=M-XGx20DL or M-XGx20DB UltimateLaser Mouse ++ ++usb:v056Ep00F1* ++ ID_MODEL_FROM_DATABASE=M-XT1DRBK USB EX-G Wireless Optical TrackBall ++ ++usb:v056Ep00F2* ++ ID_MODEL_FROM_DATABASE=M-XT1URBK EX-G Optical Trackball ++ ++usb:v056Ep00F3* ++ ID_MODEL_FROM_DATABASE=M-BL23DB ++ ++usb:v056Ep00F4* ++ ID_MODEL_FROM_DATABASE=M-BT13BL LBT-UAN05C2 ++ ++usb:v056Ep00F7* ++ ID_MODEL_FROM_DATABASE=M-KN1DB ++ ++usb:v056Ep00F8* ++ ID_MODEL_FROM_DATABASE=M-BL22DB Mouse (other version) ++ ++usb:v056Ep00F9* ++ ID_MODEL_FROM_DATABASE=M-XT2URBK EX-G Optical TrackBall ++ ++usb:v056Ep00FA* ++ ID_MODEL_FROM_DATABASE=M-XT2DRBK EX-G Wireless Optical TrackBall ++ ++usb:v056Ep00FB* ++ ID_MODEL_FROM_DATABASE=M-XT3URBK EX-G Optical TrackBall ++ ++usb:v056Ep00FC* ++ ID_MODEL_FROM_DATABASE=M-XT3DRBK EX-G Wireless Optical TrackBall ++ ++usb:v056Ep00FD* ++ ID_MODEL_FROM_DATABASE=M-XT4DRBK EX-G Wireless Optical TrackBall ++ ++usb:v056Ep00FE* ++ ID_MODEL_FROM_DATABASE=M-DT1URBK or M-DT2URBK DEFT Optical TrackBall ++ ++usb:v056Ep00FF* ++ ID_MODEL_FROM_DATABASE=M-DT1DRBK or M-DT2DRBK DEFT Wireless Optical Mouse ++ ++usb:v056Ep0101* ++ ID_MODEL_FROM_DATABASE=M-BL25UBS ++ ++usb:v056Ep0103* ++ ID_MODEL_FROM_DATABASE=M-BT16BBS ++ ++usb:v056Ep0104* ++ ID_MODEL_FROM_DATABASE=M-BL26UBC ++ ++usb:v056Ep0105* ++ ID_MODEL_FROM_DATABASE=M-BL26DBC ++ ++usb:v056Ep0107* ++ ID_MODEL_FROM_DATABASE=M-LS15UL ++ ++usb:v056Ep0108* ++ ID_MODEL_FROM_DATABASE=M-LS15DL ++ ++usb:v056Ep0109* ++ ID_MODEL_FROM_DATABASE=M-LS16UL Mouse ++ ++usb:v056Ep010A* ++ ID_MODEL_FROM_DATABASE=M-LS16DL / M-KN2DLS ++ ++usb:v056Ep010B* ++ ID_MODEL_FROM_DATABASE=M-BL21DB Mouse ++ ++usb:v056Ep010C* ++ ID_MODEL_FROM_DATABASE=M-HT1URBK HUGE Optical TrackBall ++ ++usb:v056Ep010D* ++ ID_MODEL_FROM_DATABASE=M-HT1DRBK HUGE Wireless Optical TrackBall ++ ++usb:v056Ep010E* ++ ID_MODEL_FROM_DATABASE=M-KS1DBS / M-FPG3DBS ++ ++usb:v056Ep010F* ++ ID_MODEL_FROM_DATABASE=M-FBG3DB ++ ++usb:v056Ep0115* ++ ID_MODEL_FROM_DATABASE=M-BT13BL ++ ++usb:v056Ep0121* ++ ID_MODEL_FROM_DATABASE=M-ED01DB ++ ++usb:v056Ep0122* ++ ID_MODEL_FROM_DATABASE=M-NK01DB ++ ++usb:v056Ep0124* ++ ID_MODEL_FROM_DATABASE=Dual connect Mouse M-DC01MB Bluetooth ++ ++usb:v056Ep0128* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-XPT1MR Wired ++ ++usb:v056Ep0129* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-XPT1MR Wireless ++ ++usb:v056Ep0130* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-XPT1MR Bluetooth ++ ++usb:v056Ep0131* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-DPT1MR Wired ++ ++usb:v056Ep0132* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-DPT1MR Wireless ++ ++usb:v056Ep0133* ++ ID_MODEL_FROM_DATABASE=TrackBall Mouse M-DPT1MR Bluetooth ++ ++usb:v056Ep0136* ++ ID_MODEL_FROM_DATABASE=M-BT20BB ++ ++usb:v056Ep0137* ++ ID_MODEL_FROM_DATABASE=BlueTooth 4.0 Mouse M-BT21BB ++ ++usb:v056Ep0138* ++ ID_MODEL_FROM_DATABASE=M-A-BL07DB ++ ++usb:v056Ep0140* ++ ID_MODEL_FROM_DATABASE=M-G01UR ++ ++usb:v056Ep0141* ++ ID_MODEL_FROM_DATABASE=M-Y9UB ++ ++usb:v056Ep0142* ++ ID_MODEL_FROM_DATABASE=M-DY13DB ++ ++usb:v056Ep0144* ++ ID_MODEL_FROM_DATABASE=M-FBL01DB ++ ++usb:v056Ep1055* ++ ID_MODEL_FROM_DATABASE=TK-DCP03 WIRED ++ ++usb:v056Ep1057* ++ ID_MODEL_FROM_DATABASE=TK-DCP03 BT ++ ++usb:v056Ep2003* ++ ID_MODEL_FROM_DATABASE=JC-U3613M ++ ++usb:v056Ep2004* ++ ID_MODEL_FROM_DATABASE=JC-U3613M + + usb:v056Ep200C* + ID_MODEL_FROM_DATABASE=LD-USB/TX + ++usb:v056Ep200F* ++ ID_MODEL_FROM_DATABASE=JC-U4013S Gamepad ++ ++usb:v056Ep2012* ++ ID_MODEL_FROM_DATABASE=JC-U4013S Gamepad ++ + usb:v056Ep4002* + ID_MODEL_FROM_DATABASE=Laneed 100Mbps Ethernet LD-USB/TX [pegasus] + +@@ -20933,6 +22496,12 @@ usb:v057D* + usb:v057E* + ID_VENDOR_FROM_DATABASE=Nintendo Co., Ltd + ++usb:v057Ep0300* ++ ID_MODEL_FROM_DATABASE=USB-EXI Adapter (GCP-2000) ++ ++usb:v057Ep0304* ++ ID_MODEL_FROM_DATABASE=RVT-H Reader ++ + usb:v057Ep0305* + ID_MODEL_FROM_DATABASE=Broadcom BCM2045A Bluetooth Radio [Nintendo Wii] + +@@ -20942,12 +22511,24 @@ usb:v057Ep0306* + usb:v057Ep0337* + ID_MODEL_FROM_DATABASE=Wii U GameCube Controller Adapter + ++usb:v057Ep2000* ++ ID_MODEL_FROM_DATABASE=Switch ++ + usb:v057Ep2006* + ID_MODEL_FROM_DATABASE=Joy-Con L + + usb:v057Ep2007* + ID_MODEL_FROM_DATABASE=Joy-Con R + ++usb:v057Ep2009* ++ ID_MODEL_FROM_DATABASE=Switch Pro Controller ++ ++usb:v057Ep200E* ++ ID_MODEL_FROM_DATABASE=Joy-Con Charging Grip ++ ++usb:v057Ep3000* ++ ID_MODEL_FROM_DATABASE=SDK Debugger ++ + usb:v057F* + ID_VENDOR_FROM_DATABASE=QuickShot, Ltd + +@@ -20960,6 +22541,12 @@ usb:v0580* + usb:v0581* + ID_VENDOR_FROM_DATABASE=Racal Data Group + ++usb:v0581p0107* ++ ID_MODEL_FROM_DATABASE=Tera Barcode Scanner 2.4 GHz Receiver ++ ++usb:v0581p020C* ++ ID_MODEL_FROM_DATABASE=Tera 2D Barcode Scanner EVHK0012 ++ + usb:v0582* + ID_VENDOR_FROM_DATABASE=Roland Corp. + +@@ -21449,6 +23036,24 @@ usb:v0582p015B* + usb:v0582p015D* + ID_MODEL_FROM_DATABASE=R-88 + ++usb:v0582p01B5* ++ ID_MODEL_FROM_DATABASE=Boutique Series Synthesizer (Normal mode) ++ ++usb:v0582p01B6* ++ ID_MODEL_FROM_DATABASE=Boutique Series Synthesizer (Storage mode) ++ ++usb:v0582p01DF* ++ ID_MODEL_FROM_DATABASE=Rubix22 ++ ++usb:v0582p01E0* ++ ID_MODEL_FROM_DATABASE=Rubix24 ++ ++usb:v0582p01E1* ++ ID_MODEL_FROM_DATABASE=Rubix44 ++ ++usb:v0582p01EF* ++ ID_MODEL_FROM_DATABASE=Go:KEYS MIDI ++ + usb:v0582p0505* + ID_MODEL_FROM_DATABASE=EDIROL UA-101 + +@@ -21479,6 +23084,9 @@ usb:v0583p2050* + usb:v0583p205F* + ID_MODEL_FROM_DATABASE=PSX/USB converter + ++usb:v0583p2060* ++ ID_MODEL_FROM_DATABASE=2-axis 8-button gamepad ++ + usb:v0583p206F* + ID_MODEL_FROM_DATABASE=USB, 2-axis 8-button gamepad + +@@ -21905,6 +23513,9 @@ usb:v058F* + usb:v058Fp1234* + ID_MODEL_FROM_DATABASE=Flash Drive + ++usb:v058Fp198B* ++ ID_MODEL_FROM_DATABASE=Webcam (Gigatech P-09) ++ + usb:v058Fp2412* + ID_MODEL_FROM_DATABASE=SCard R/W CSR-145 + +@@ -21959,6 +23570,9 @@ usb:v058Fp6390* + usb:v058Fp6391* + ID_MODEL_FROM_DATABASE=IDE Bridge + ++usb:v058Fp6998* ++ ID_MODEL_FROM_DATABASE=AU6998 Flash Disk Controller ++ + usb:v058Fp9213* + ID_MODEL_FROM_DATABASE=MacAlly Kbd Hub + +@@ -22046,6 +23660,9 @@ usb:v0590p000B* + usb:v0590p0028* + ID_MODEL_FROM_DATABASE=HJ-720IT / HEM-7080IT-E / HEM-790IT + ++usb:v0590p0051* ++ ID_MODEL_FROM_DATABASE=FT232BM [E58CIFQ1 with FTDI USB2Serial Converter] ++ + usb:v0591* + ID_VENDOR_FROM_DATABASE=Questra Consulting + +@@ -22280,6 +23897,9 @@ usb:v059Fp0525* + usb:v059Fp0641* + ID_MODEL_FROM_DATABASE=Mobile Hard Drive + ++usb:v059Fp0828* ++ ID_MODEL_FROM_DATABASE=d2 Quadra ++ + usb:v059Fp0829* + ID_MODEL_FROM_DATABASE=BigDisk Extreme+ + +@@ -22310,12 +23930,18 @@ usb:v059Fp1027* + usb:v059Fp102A* + ID_MODEL_FROM_DATABASE=Rikiki Hard Drive + ++usb:v059Fp103D* ++ ID_MODEL_FROM_DATABASE=D2 ++ + usb:v059Fp1049* + ID_MODEL_FROM_DATABASE=rikiki Harddrive + + usb:v059Fp1052* + ID_MODEL_FROM_DATABASE=P'9220 Mobile Drive + ++usb:v059Fp1053* ++ ID_MODEL_FROM_DATABASE=P'9230 2TB [Porsche Design Desktop Drive 2TB] ++ + usb:v059Fp1061* + ID_MODEL_FROM_DATABASE=Rugged USB3-FW + +@@ -22331,6 +23957,12 @@ usb:v059Fp106D* + usb:v059Fp106E* + ID_MODEL_FROM_DATABASE=Porsche Design Desktop Drive + ++usb:v059Fp1094* ++ ID_MODEL_FROM_DATABASE=Rugged THB ++ ++usb:v059Fp1095* ++ ID_MODEL_FROM_DATABASE=Rugged ++ + usb:v059FpA601* + ID_MODEL_FROM_DATABASE=HardDrive + +@@ -22361,6 +23993,9 @@ usb:v05A3p9320* + usb:v05A3p9331* + ID_MODEL_FROM_DATABASE=Camera + ++usb:v05A3p9332* ++ ID_MODEL_FROM_DATABASE=Camera - 1080p ++ + usb:v05A3p9422* + ID_MODEL_FROM_DATABASE=Camera + +@@ -22415,6 +24050,21 @@ usb:v05A6p0003* + usb:v05A6p0004* + ID_MODEL_FROM_DATABASE=CVA122E Cable Voice Adapter (WDM) + ++usb:v05A6p0008* ++ ID_MODEL_FROM_DATABASE=STA1520 Tuning Adapter ++ ++usb:v05A6p0A00* ++ ID_MODEL_FROM_DATABASE=Integrated Management Controller Hub ++ ++usb:v05A6p0A01* ++ ID_MODEL_FROM_DATABASE=Virtual Keyboard/Mouse ++ ++usb:v05A6p0A02* ++ ID_MODEL_FROM_DATABASE=Virtual Mass Storage ++ ++usb:v05A6p0A03* ++ ID_MODEL_FROM_DATABASE=Virtual Ethernet/RNDIS ++ + usb:v05A7* + ID_VENDOR_FROM_DATABASE=Bose Corp. + +@@ -22430,6 +24080,12 @@ usb:v05A7p4002* + usb:v05A7p4003* + ID_MODEL_FROM_DATABASE=Bluetooth Headset Series 2 in DFU mode + ++usb:v05A7p400D* ++ ID_MODEL_FROM_DATABASE=SoundLink Color II speaker in DFU mode ++ ++usb:v05A7p40FE* ++ ID_MODEL_FROM_DATABASE=SoundLink Color II speaker ++ + usb:v05A7pBC50* + ID_MODEL_FROM_DATABASE=SoundLink Wireless Mobile speaker + +@@ -22457,6 +24113,9 @@ usb:v05A9p1550* + usb:v05A9p2640* + ID_MODEL_FROM_DATABASE=OV2640 Webcam + ++usb:v05A9p2642* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam for Dell XPS 2010 ++ + usb:v05A9p2643* + ID_MODEL_FROM_DATABASE=Monitor Webcam + +@@ -22700,6 +24359,9 @@ usb:v05ACp024A* + usb:v05ACp024D* + ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Air) (ISO) + ++usb:v05ACp024F* ++ ID_MODEL_FROM_DATABASE=Aluminium Keyboard (ANSI) ++ + usb:v05ACp0250* + ID_MODEL_FROM_DATABASE=Aluminium Keyboard (ISO) + +@@ -22715,6 +24377,9 @@ usb:v05ACp0254* + usb:v05ACp0259* + ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad + ++usb:v05ACp025A* ++ ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad ++ + usb:v05ACp0263* + ID_MODEL_FROM_DATABASE=Apple Internal Keyboard / Trackpad (MacBook Retina) + +@@ -22923,7 +24588,7 @@ usb:v05ACp12A6* + ID_MODEL_FROM_DATABASE=iPad 3 (3G, 16 GB) + + usb:v05ACp12A8* +- ID_MODEL_FROM_DATABASE=iPhone5/5C/5S/6 ++ ID_MODEL_FROM_DATABASE=iPhone 5/5C/5S/6/SE + + usb:v05ACp12A9* + ID_MODEL_FROM_DATABASE=iPad 2 +@@ -22946,6 +24611,18 @@ usb:v05ACp1302* + usb:v05ACp1303* + ID_MODEL_FROM_DATABASE=iPod Shuffle 4.Gen + ++usb:v05ACp1392* ++ ID_MODEL_FROM_DATABASE=Apple Watch charger ++ ++usb:v05ACp1393* ++ ID_MODEL_FROM_DATABASE=AirPods case ++ ++usb:v05ACp1395* ++ ID_MODEL_FROM_DATABASE=Smart Battery Case [iPhone 6] ++ ++usb:v05ACp1398* ++ ID_MODEL_FROM_DATABASE=Smart Battery Case ++ + usb:v05ACp1401* + ID_MODEL_FROM_DATABASE=Modem + +@@ -22979,6 +24656,9 @@ usb:v05ACp8205* + usb:v05ACp8206* + ID_MODEL_FROM_DATABASE=Bluetooth HCI + ++usb:v05ACp8207* ++ ID_MODEL_FROM_DATABASE=Built-in Bluetooth ++ + usb:v05ACp820A* + ID_MODEL_FROM_DATABASE=Bluetooth HID Keyboard + +@@ -23009,6 +24689,9 @@ usb:v05ACp821A* + usb:v05ACp821F* + ID_MODEL_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI + ++usb:v05ACp8233* ++ ID_MODEL_FROM_DATABASE=iBridge ++ + usb:v05ACp8240* + ID_MODEL_FROM_DATABASE=Built-in IR Receiver + +@@ -23024,6 +24707,9 @@ usb:v05ACp8281* + usb:v05ACp8286* + ID_MODEL_FROM_DATABASE=Bluetooth Host Controller + ++usb:v05ACp8289* ++ ID_MODEL_FROM_DATABASE=Bluetooth Host Controller ++ + usb:v05ACp828C* + ID_MODEL_FROM_DATABASE=Bluetooth Host Controller + +@@ -23039,6 +24725,9 @@ usb:v05ACp8403* + usb:v05ACp8404* + ID_MODEL_FROM_DATABASE=Internal Memory Card Reader + ++usb:v05ACp8406* ++ ID_MODEL_FROM_DATABASE=Internal Memory Card Reader ++ + usb:v05ACp8501* + ID_MODEL_FROM_DATABASE=Built-in iSight [Micron] + +@@ -23063,6 +24752,9 @@ usb:v05ACp850A* + usb:v05ACp8510* + ID_MODEL_FROM_DATABASE=FaceTime HD Camera (Built-in) + ++usb:v05ACp8600* ++ ID_MODEL_FROM_DATABASE=iBridge ++ + usb:v05ACp911C* + ID_MODEL_FROM_DATABASE=Hub in A1082 [Cinema HD Display 23"] + +@@ -23160,11 +24852,14 @@ usb:v05B7* + ID_VENDOR_FROM_DATABASE=Medianix Semiconductor, Inc. + + usb:v05B8* +- ID_VENDOR_FROM_DATABASE=Agiler, Inc. ++ ID_VENDOR_FROM_DATABASE=SYSGRATION + + usb:v05B8p3002* + ID_MODEL_FROM_DATABASE=Scroll Mouse + ++usb:v05B8p3126* ++ ID_MODEL_FROM_DATABASE=APT-905 Wireless presenter ++ + usb:v05B8p3223* + ID_MODEL_FROM_DATABASE=ISY Wireless Presenter + +@@ -23228,6 +24923,15 @@ usb:v05C6* + usb:v05C6p0114* + ID_MODEL_FROM_DATABASE=Select RW-200 CDMA Wireless Modem + ++usb:v05C6p0A02* ++ ID_MODEL_FROM_DATABASE=Jolla Device Developer Mode ++ ++usb:v05C6p0A07* ++ ID_MODEL_FROM_DATABASE=Jolla Device MTP ++ ++usb:v05C6p0AFE* ++ ID_MODEL_FROM_DATABASE=Jolla Device Charging Only ++ + usb:v05C6p1000* + ID_MODEL_FROM_DATABASE=Mass Storage Device + +@@ -23271,7 +24975,25 @@ usb:v05C6p9018* + ID_MODEL_FROM_DATABASE=Qualcomm HSUSB Device + + usb:v05C6p9025* +- ID_MODEL_FROM_DATABASE=Qualcomm HSUSB Device ++ ID_MODEL_FROM_DATABASE=HSUSB Device ++ ++usb:v05C6p9090* ++ ID_MODEL_FROM_DATABASE=Quectel UC15 ++ ++usb:v05C6p9091* ++ ID_MODEL_FROM_DATABASE=Intex Aqua Fish & Jolla C Diagnostic Mode ++ ++usb:v05C6p9092* ++ ID_MODEL_FROM_DATABASE=Nokia 8110 4G ++ ++usb:v05C6p90BA* ++ ID_MODEL_FROM_DATABASE=Audio 1.0 device ++ ++usb:v05C6p90BB* ++ ID_MODEL_FROM_DATABASE=Snapdragon interface (MIDI + ADB) ++ ++usb:v05C6p90DC* ++ ID_MODEL_FROM_DATABASE=Fairphone 2 (Charging & ADB) + + usb:v05C6p9201* + ID_MODEL_FROM_DATABASE=Gobi Wireless Modem (QDL mode) +@@ -23295,7 +25017,7 @@ usb:v05C6p9214* + ID_MODEL_FROM_DATABASE=Acer Gobi 2000 Wireless Modem (QDL mode) + + usb:v05C6p9215* +- ID_MODEL_FROM_DATABASE=Acer Gobi 2000 Wireless Modem ++ ID_MODEL_FROM_DATABASE=Quectel EC20 LTE modem / Acer Gobi 2000 Wireless Modem + + usb:v05C6p9221* + ID_MODEL_FROM_DATABASE=Gobi Wireless Modem (QDL mode) +@@ -23336,6 +25058,9 @@ usb:v05C6p9274* + usb:v05C6p9275* + ID_MODEL_FROM_DATABASE=iRex Technologies Gobi 2000 Wireless Modem + ++usb:v05C6pF003* ++ ID_MODEL_FROM_DATABASE=Nokia 8110 4G ++ + usb:v05C7* + ID_VENDOR_FROM_DATABASE=Qtronix Corp. + +@@ -23366,6 +25091,9 @@ usb:v05C8p010B* + usb:v05C8p021A* + ID_MODEL_FROM_DATABASE=HP Webcam + ++usb:v05C8p0233* ++ ID_MODEL_FROM_DATABASE=HP Webcam ++ + usb:v05C8p0318* + ID_MODEL_FROM_DATABASE=Webcam + +@@ -23375,6 +25103,24 @@ usb:v05C8p0361* + usb:v05C8p036E* + ID_MODEL_FROM_DATABASE=Webcam + ++usb:v05C8p0374* ++ ID_MODEL_FROM_DATABASE=HP EliteBook integrated HD Webcam ++ ++usb:v05C8p038E* ++ ID_MODEL_FROM_DATABASE=HP Wide Vision HD integrated webcam ++ ++usb:v05C8p03A1* ++ ID_MODEL_FROM_DATABASE=XiaoMi Webcam ++ ++usb:v05C8p03B1* ++ ID_MODEL_FROM_DATABASE=Webcam ++ ++usb:v05C8p03BC* ++ ID_MODEL_FROM_DATABASE=HP Wide Vision HD Integrated Webcam ++ ++usb:v05C8p03CB* ++ ID_MODEL_FROM_DATABASE=HP Wide Vision HD Integrated Webcam ++ + usb:v05C8p0403* + ID_MODEL_FROM_DATABASE=Webcam + +@@ -23411,6 +25157,12 @@ usb:v05CAp0405* + usb:v05CAp0406* + ID_MODEL_FROM_DATABASE=Type 102 + ++usb:v05CAp0437* ++ ID_MODEL_FROM_DATABASE=Aficio SP 3510SF ++ ++usb:v05CAp044E* ++ ID_MODEL_FROM_DATABASE=SP C250SF (multifunction device: printer, scanner, fax) ++ + usb:v05CAp1803* + ID_MODEL_FROM_DATABASE=V5 camera [R5U870] + +@@ -23465,12 +25217,18 @@ usb:v05CAp183D* + usb:v05CAp183E* + ID_MODEL_FROM_DATABASE=Visual Communication Camera VGP-VCC9 [R5U870] + ++usb:v05CAp183F* ++ ID_MODEL_FROM_DATABASE=Sony Visual Communication Camera Integrated Webcam ++ + usb:v05CAp1841* + ID_MODEL_FROM_DATABASE=Fujitsu F01/ Lifebook U810 [R5U870] + + usb:v05CAp1870* + ID_MODEL_FROM_DATABASE=Webcam 1000 + ++usb:v05CAp1880* ++ ID_MODEL_FROM_DATABASE=R5U880 ++ + usb:v05CAp18B0* + ID_MODEL_FROM_DATABASE=Sony Vaio Integrated Webcam + +@@ -24128,6 +25886,9 @@ usb:v05DCp4D12* + usb:v05DCp4D30* + ID_MODEL_FROM_DATABASE=MP3 Player + ++usb:v05DCpA201* ++ ID_MODEL_FROM_DATABASE=JumpDrive S70 4GB ++ + usb:v05DCpA209* + ID_MODEL_FROM_DATABASE=JumpDrive S70 + +@@ -24245,6 +26006,9 @@ usb:v05DCpC75C* + usb:v05DD* + ID_VENDOR_FROM_DATABASE=Delta Electronics, Inc. + ++usb:v05DDpA011* ++ ID_MODEL_FROM_DATABASE=HID UPS Battery ++ + usb:v05DDpFF31* + ID_MODEL_FROM_DATABASE=AWU-120 + +@@ -24377,11 +26141,14 @@ usb:v05E3p0503* + usb:v05E3p0504* + ID_MODEL_FROM_DATABASE=HID Keyboard Filter + ++usb:v05E3p0510* ++ ID_MODEL_FROM_DATABASE=Camera ++ + usb:v05E3p0604* + ID_MODEL_FROM_DATABASE=USB 1.1 Hub + + usb:v05E3p0605* +- ID_MODEL_FROM_DATABASE=USB 2.0 Hub ++ ID_MODEL_FROM_DATABASE=Hub + + usb:v05E3p0606* + ID_MODEL_FROM_DATABASE=USB 2.0 Hub / D-Link DUB-H4 USB 2.0 Hub +@@ -24393,7 +26160,7 @@ usb:v05E3p0608* + ID_MODEL_FROM_DATABASE=Hub + + usb:v05E3p0610* +- ID_MODEL_FROM_DATABASE=4-port hub ++ ID_MODEL_FROM_DATABASE=Hub + + usb:v05E3p0612* + ID_MODEL_FROM_DATABASE=Hub +@@ -24459,7 +26226,7 @@ usb:v05E3p0715* + ID_MODEL_FROM_DATABASE=USB 2.0 microSD Reader + + usb:v05E3p0716* +- ID_MODEL_FROM_DATABASE=USB 2.0 Multislot Card Reader/Writer ++ ID_MODEL_FROM_DATABASE=Multislot Card Reader/Writer + + usb:v05E3p0717* + ID_MODEL_FROM_DATABASE=All-in-1 Card Reader +@@ -24489,7 +26256,7 @@ usb:v05E3p0732* + ID_MODEL_FROM_DATABASE=All-in-One Cardreader + + usb:v05E3p0736* +- ID_MODEL_FROM_DATABASE=microSD Reader/Writer ++ ID_MODEL_FROM_DATABASE=Colour arc SD Card Reader [PISEN] + + usb:v05E3p0738* + ID_MODEL_FROM_DATABASE=Card reader +@@ -24506,6 +26273,9 @@ usb:v05E3p0745* + usb:v05E3p0748* + ID_MODEL_FROM_DATABASE=All-in-One Cardreader + ++usb:v05E3p0749* ++ ID_MODEL_FROM_DATABASE=SD Card Reader and Writer ++ + usb:v05E3p0751* + ID_MODEL_FROM_DATABASE=microSD Card Reader + +@@ -24542,6 +26312,9 @@ usb:v05E3pF103* + usb:v05E3pF104* + ID_MODEL_FROM_DATABASE=VX7012 TV Box + ++usb:v05E3pF12A* ++ ID_MODEL_FROM_DATABASE=Digital Microscope ++ + usb:v05E3pFD21* + ID_MODEL_FROM_DATABASE=3M TL20 Temperature Logger + +@@ -24665,6 +26438,9 @@ usb:v05F9p1104* + usb:v05F9p1206* + ID_MODEL_FROM_DATABASE=Gryphon series (OEM mode) + ++usb:v05F9p120C* ++ ID_MODEL_FROM_DATABASE=Gryphon GD4430-BK ++ + usb:v05F9p2202* + ID_MODEL_FROM_DATABASE=Point of Sale Handheld Scanner + +@@ -24707,6 +26483,9 @@ usb:v05FCp0001* + usb:v05FCp0010* + ID_MODEL_FROM_DATABASE=Soundcraft Si MADI combo card + ++usb:v05FCp0021* ++ ID_MODEL_FROM_DATABASE=Soundcraft Signature 12 MTK ++ + usb:v05FCp7849* + ID_MODEL_FROM_DATABASE=Harman/Kardon SoundSticks + +@@ -24725,6 +26504,9 @@ usb:v05FDp0253* + usb:v05FDp0286* + ID_MODEL_FROM_DATABASE=SV-286 Cyclone Digital + ++usb:v05FDp1007* ++ ID_MODEL_FROM_DATABASE=Mad Catz Controller ++ + usb:v05FDp107A* + ID_MODEL_FROM_DATABASE=PowerPad Pro X-Box pad + +@@ -24770,6 +26552,12 @@ usb:v05FEp1010* + usb:v05FEp2001* + ID_MODEL_FROM_DATABASE=Microsoft Wireless Receiver 700 + ++usb:v05FEp3030* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v05FEp3031* ++ ID_MODEL_FROM_DATABASE=Controller ++ + usb:v05FF* + ID_VENDOR_FROM_DATABASE=LeCroy Corp. + +@@ -24791,12 +26579,18 @@ usb:v0602p1001* + usb:v0603* + ID_VENDOR_FROM_DATABASE=Novatek Microelectronics Corp. + ++usb:v0603p0002* ++ ID_MODEL_FROM_DATABASE=Sino Wealth keyboard/mouse 2.4 GHz receiver ++ + usb:v0603p00F1* + ID_MODEL_FROM_DATABASE=Keyboard (Labtec Ultra Flat Keyboard) + + usb:v0603p00F2* + ID_MODEL_FROM_DATABASE=Keyboard (Labtec Ultra Flat Keyboard) + ++usb:v0603p1002* ++ ID_MODEL_FROM_DATABASE=Mobius actioncam (webcam mode) ++ + usb:v0603p6871* + ID_MODEL_FROM_DATABASE=Mouse + +@@ -24860,6 +26654,9 @@ usb:v060Bp2231* + usb:v060Bp2270* + ID_MODEL_FROM_DATABASE=Gigabyte K8100 Aivia Gaming Keyboard + ++usb:v060Bp500A* ++ ID_MODEL_FROM_DATABASE=Cougar 500k Gaming Keyboard ++ + usb:v060Bp5253* + ID_MODEL_FROM_DATABASE=Thermaltake MEKA G-Unit Gaming Keyboard + +@@ -25019,6 +26816,9 @@ usb:v0623* + usb:v0624* + ID_VENDOR_FROM_DATABASE=Avocent Corp. + ++usb:v0624p0013* ++ ID_MODEL_FROM_DATABASE=SC Secure KVM ++ + usb:v0624p0248* + ID_MODEL_FROM_DATABASE=Virtual Hub + +@@ -25028,6 +26828,9 @@ usb:v0624p0249* + usb:v0624p0251* + ID_MODEL_FROM_DATABASE=Virtual Mass Storage + ++usb:v0624p0252* ++ ID_MODEL_FROM_DATABASE=Virtual SD card reader ++ + usb:v0624p0294* + ID_MODEL_FROM_DATABASE=Dell 03R874 KVM dongle + +@@ -25037,6 +26840,9 @@ usb:v0624p0402* + usb:v0624p0403* + ID_MODEL_FROM_DATABASE=Cisco Virtual Mass Storage + ++usb:v0624p1774* ++ ID_MODEL_FROM_DATABASE=Cybex SC985 ++ + usb:v0625* + ID_VENDOR_FROM_DATABASE=TiMedia Technology Co., Ltd + +@@ -25061,6 +26867,12 @@ usb:v062Ap0000* + usb:v062Ap0001* + ID_MODEL_FROM_DATABASE=Notebook Optical Mouse + ++usb:v062Ap0020* ++ ID_MODEL_FROM_DATABASE=Logic3 Gamepad ++ ++usb:v062Ap0033* ++ ID_MODEL_FROM_DATABASE=Competition Pro Steering Wheel ++ + usb:v062Ap0102* + ID_MODEL_FROM_DATABASE=Wireless Keyboard/Mouse Combo [MK1152WC] + +@@ -25079,6 +26891,15 @@ usb:v062Ap3286* + usb:v062Ap4101* + ID_MODEL_FROM_DATABASE=Wireless Keyboard/Mouse + ++usb:v062Ap4102* ++ ID_MODEL_FROM_DATABASE=Wireless Mouse ++ ++usb:v062Ap4106* ++ ID_MODEL_FROM_DATABASE=Wireless Mouse 2.4G ++ ++usb:v062Ap4C01* ++ ID_MODEL_FROM_DATABASE=2,4Ghz Wireless Transceiver [for Delux M618 Plus Wireless Vertical Mouse] ++ + usb:v062Ap6301* + ID_MODEL_FROM_DATABASE=Trust Wireless Optical Mouse MI-4150K + +@@ -25145,6 +26966,9 @@ usb:v0638p0A15* + usb:v0638p0A16* + ID_MODEL_FROM_DATABASE=Konica Minolta SC-215 + ++usb:v0638p0A2A* ++ ID_MODEL_FROM_DATABASE=AV220 C2 ++ + usb:v0638p0A30* + ID_MODEL_FROM_DATABASE=UMAX Astra 6700 Scanner + +@@ -25280,6 +27104,9 @@ usb:v064E* + usb:v064Ep2100* + ID_MODEL_FROM_DATABASE=Sony Visual Communication Camera + ++usb:v064Ep3410* ++ ID_MODEL_FROM_DATABASE=RGBIR Camera ++ + usb:v064Ep9700* + ID_MODEL_FROM_DATABASE=Asus Integrated Webcam + +@@ -25304,6 +27131,9 @@ usb:v064EpA114* + usb:v064EpA116* + ID_MODEL_FROM_DATABASE=UVC 1.3MPixel WebCam + ++usb:v064EpA127* ++ ID_MODEL_FROM_DATABASE=HP Integrated Webcam ++ + usb:v064EpA136* + ID_MODEL_FROM_DATABASE=Asus Integrated Webcam [CN031B] + +@@ -25343,6 +27173,9 @@ usb:v064EpF102* + usb:v064EpF103* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + ++usb:v064EpF207* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera Integrated Webcam ++ + usb:v064EpF209* + ID_MODEL_FROM_DATABASE=HP Webcam + +@@ -25868,6 +27701,9 @@ usb:v066Fp8320* + usb:v066Fp835D* + ID_MODEL_FROM_DATABASE=MP3 Player + ++usb:v066Fp83B5* ++ ID_MODEL_FROM_DATABASE=Transcend T.sonic 530 MP3 Player ++ + usb:v066Fp9000* + ID_MODEL_FROM_DATABASE=MP3 Player + +@@ -25961,8 +27797,11 @@ usb:v067Bp0610* + usb:v067Bp0611* + ID_MODEL_FROM_DATABASE=AlDiga AL-11U Quad-band GSM/GPRS/EDGE modem + ++usb:v067Bp1231* ++ ID_MODEL_FROM_DATABASE=Orico SATA External Hard Disk Drive Lay-Flat Docking Station with USB 3.0 & eSATA interfaces. ++ + usb:v067Bp2303* +- ID_MODEL_FROM_DATABASE=PL2303 Serial Port ++ ID_MODEL_FROM_DATABASE=PL2303 Serial Port / Mobile Action MA-8910P + + usb:v067Bp2305* + ID_MODEL_FROM_DATABASE=PL2305 Parallel Port +@@ -26003,6 +27842,9 @@ usb:v067Bp2517* + usb:v067Bp2528* + ID_MODEL_FROM_DATABASE=Storage device (8gB thumb drive) + ++usb:v067Bp2571* ++ ID_MODEL_FROM_DATABASE=LG Electronics GE24LU21 ++ + usb:v067Bp25A1* + ID_MODEL_FROM_DATABASE=PL25A1 Host-Host Bridge + +@@ -26201,6 +28043,12 @@ usb:v0686p300B* + usb:v0686p300C* + ID_MODEL_FROM_DATABASE=PagePro 1300W + ++usb:v0686p301B* ++ ID_MODEL_FROM_DATABASE=Develop D 1650iD ++ ++usb:v0686p3023* ++ ID_MODEL_FROM_DATABASE=Develop D 2050iD ++ + usb:v0686p302E* + ID_MODEL_FROM_DATABASE=Develop D 1650iD PCL + +@@ -26330,6 +28178,12 @@ usb:v068Ep0501* + usb:v068Ep0504* + ID_MODEL_FROM_DATABASE=F-16 Combat Stick + ++usb:v068F* ++ ID_VENDOR_FROM_DATABASE=Nihon KOHDEN ++ ++usb:v068FpC00D* ++ ID_MODEL_FROM_DATABASE=MEK-6500 ++ + usb:v0690* + ID_VENDOR_FROM_DATABASE=Golden Bridge Electech, Inc. + +@@ -26387,6 +28241,9 @@ usb:v0699* + usb:v0699p0347* + ID_MODEL_FROM_DATABASE=AFG 3022B + ++usb:v0699p0365* ++ ID_MODEL_FROM_DATABASE=TDS 2004B ++ + usb:v0699p036A* + ID_MODEL_FROM_DATABASE=TDS 2024B + +@@ -26529,7 +28386,10 @@ usb:v06A3p0160* + ID_MODEL_FROM_DATABASE=ST290 Pro + + usb:v06A3p0200* +- ID_MODEL_FROM_DATABASE=Xbox Adrenalin Hub ++ ID_MODEL_FROM_DATABASE=Racing Wheel ++ ++usb:v06A3p0201* ++ ID_MODEL_FROM_DATABASE=Adrenalin Gamepad + + usb:v06A3p0241* + ID_MODEL_FROM_DATABASE=Xbox Adrenalin Gamepad +@@ -26696,6 +28556,9 @@ usb:v06A3pA502* + usb:v06A3pF518* + ID_MODEL_FROM_DATABASE=P3200 Rumble Force Game Pad + ++usb:v06A3pF51A* ++ ID_MODEL_FROM_DATABASE=P3600 ++ + usb:v06A3pFF04* + ID_MODEL_FROM_DATABASE=R440 Force Wheel + +@@ -26828,12 +28691,33 @@ usb:v06BCp015E* + usb:v06BCp01C9* + ID_MODEL_FROM_DATABASE=OKI B430 Mono Printer + ++usb:v06BCp01DB* ++ ID_MODEL_FROM_DATABASE=MC860 Multifunction Printer ++ ++usb:v06BCp01DC* ++ ID_MODEL_FROM_DATABASE=MC860 Multifunction Printer ++ ++usb:v06BCp01DD* ++ ID_MODEL_FROM_DATABASE=MC860 Multifunction Printer ++ ++usb:v06BCp01DE* ++ ID_MODEL_FROM_DATABASE=MC860 Multifunction Printer ++ ++usb:v06BCp01DF* ++ ID_MODEL_FROM_DATABASE=CX2633 Multifunction Printer ++ ++usb:v06BCp01E0* ++ ID_MODEL_FROM_DATABASE=ES8460 Multifunction Printer ++ + usb:v06BCp020B* + ID_MODEL_FROM_DATABASE=OKI ES4140 Mono Printer + + usb:v06BCp02BB* + ID_MODEL_FROM_DATABASE=OKI PT390 POS Printer + ++usb:v06BCp0383* ++ ID_MODEL_FROM_DATABASE=MC563 Multifunction Printer ++ + usb:v06BCp0A91* + ID_MODEL_FROM_DATABASE=B2500MFP (printer+scanner) + +@@ -27050,6 +28934,15 @@ usb:v06CBp0010* + usb:v06CBp0013* + ID_MODEL_FROM_DATABASE=DisplayPad + ++usb:v06CBp009A* ++ ID_MODEL_FROM_DATABASE=Metallica MIS Touch Fingerprint Reader ++ ++usb:v06CBp00A2* ++ ID_MODEL_FROM_DATABASE=Metallica MOH Touch Fingerprint Reader ++ ++usb:v06CBp00BD* ++ ID_MODEL_FROM_DATABASE=Prometheus MIS Touch Fingerprint Reader ++ + usb:v06CBp2970* + ID_MODEL_FROM_DATABASE=touchpad + +@@ -27251,6 +29144,9 @@ usb:v06D3p03AD* + usb:v06D3p03AE* + ID_MODEL_FROM_DATABASE=CP-9800DW-S + ++usb:v06D3p0F10* ++ ID_MODEL_FROM_DATABASE=Hori/Namco FlightStick 2 ++ + usb:v06D3p3B10* + ID_MODEL_FROM_DATABASE=P95D + +@@ -27272,6 +29168,9 @@ usb:v06D3p3B50* + usb:v06D3p3B60* + ID_MODEL_FROM_DATABASE=CP-D90DW + ++usb:v06D3p3B80* ++ ID_MODEL_FROM_DATABASE=CP-M1 ++ + usb:v06D4* + ID_VENDOR_FROM_DATABASE=Cisco Systems + +@@ -27755,6 +29654,9 @@ usb:v06F8pA300* + usb:v06F8pB000* + ID_MODEL_FROM_DATABASE=Hercules DJ Console + ++usb:v06F8pB121* ++ ID_MODEL_FROM_DATABASE=Hercules P32 DJ ++ + usb:v06F8pC000* + ID_MODEL_FROM_DATABASE=Hercules Muse Pocket + +@@ -27899,6 +29801,9 @@ usb:v0711p0232* + usb:v0711p0240* + ID_MODEL_FROM_DATABASE=PS/2 to USB Converter + ++usb:v0711p0260* ++ ID_MODEL_FROM_DATABASE=PS/2 Keyboard and Mouse ++ + usb:v0711p0300* + ID_MODEL_FROM_DATABASE=BAY-3U1S1P Parallel Port + +@@ -28307,26 +30212,41 @@ usb:v0736* + usb:v0738* + ID_VENDOR_FROM_DATABASE=Mad Catz, Inc. + ++usb:v0738p2215* ++ ID_MODEL_FROM_DATABASE=X-55 Rhino Stick ++ ++usb:v0738p2237* ++ ID_MODEL_FROM_DATABASE=V.1 Stick ++ ++usb:v0738p4506* ++ ID_MODEL_FROM_DATABASE=Wireless Controller ++ + usb:v0738p4507* + ID_MODEL_FROM_DATABASE=XBox Device + + usb:v0738p4516* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Control Pad + + usb:v0738p4520* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Control Pad Pro ++ ++usb:v0738p4522* ++ ID_MODEL_FROM_DATABASE=LumiCON + + usb:v0738p4526* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Control Pad Pro ++ ++usb:v0738p4530* ++ ID_MODEL_FROM_DATABASE=Universal MC2 Racing Wheel and Pedals + + usb:v0738p4536* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=MicroCON + + usb:v0738p4540* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Beat Pad + + usb:v0738p4556* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Lynx Wireless Controller + + usb:v0738p4566* + ID_MODEL_FROM_DATABASE=XBox Device +@@ -28335,14 +30255,83 @@ usb:v0738p4576* + ID_MODEL_FROM_DATABASE=XBox Device + + usb:v0738p4586* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=MicroCON Wireless Controller + + usb:v0738p4588* +- ID_MODEL_FROM_DATABASE=XBox Device ++ ID_MODEL_FROM_DATABASE=Blaster ++ ++usb:v0738p45FF* ++ ID_MODEL_FROM_DATABASE=Beat Pad ++ ++usb:v0738p4716* ++ ID_MODEL_FROM_DATABASE=Wired Xbox 360 Controller ++ ++usb:v0738p4718* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV FightStick SE for Xbox 360 ++ ++usb:v0738p4726* ++ ID_MODEL_FROM_DATABASE=Xbox 360 Controller ++ ++usb:v0738p4728* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV FightPad for Xbox 360 ++ ++usb:v0738p4730* ++ ID_MODEL_FROM_DATABASE=MC2 Racing Wheel for Xbox 360 ++ ++usb:v0738p4736* ++ ID_MODEL_FROM_DATABASE=MicroCON for Xbox 360 ++ ++usb:v0738p4738* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV Wired Controller for Xbox 360 ++ ++usb:v0738p4740* ++ ID_MODEL_FROM_DATABASE=Beat Pad for Xbox 360 ++ ++usb:v0738p4743* ++ ID_MODEL_FROM_DATABASE=Beat Pad Pro ++ ++usb:v0738p4758* ++ ID_MODEL_FROM_DATABASE=Arcade Game Stick ++ ++usb:v0738p4A01* ++ ID_MODEL_FROM_DATABASE=FightStick TE 2 for Xbox One ++ ++usb:v0738p6040* ++ ID_MODEL_FROM_DATABASE=Beat Pad Pro + + usb:v0738p8818* + ID_MODEL_FROM_DATABASE=Street Fighter IV Arcade FightStick (PS3) + ++usb:v0738p9871* ++ ID_MODEL_FROM_DATABASE=Portable Drum Kit ++ ++usb:v0738pA109* ++ ID_MODEL_FROM_DATABASE=S.T.R.I.K.E.7 Keyboard ++ ++usb:v0738pA215* ++ ID_MODEL_FROM_DATABASE=X-55 Rhino Throttle ++ ++usb:v0738pB726* ++ ID_MODEL_FROM_DATABASE=Modern Warfare 2 Controller for Xbox 360 ++ ++usb:v0738pB738* ++ ID_MODEL_FROM_DATABASE=Marvel VS Capcom 2 TE FightStick for Xbox 360 ++ ++usb:v0738pBEEF* ++ ID_MODEL_FROM_DATABASE=Joytech Neo SE Advanced Gamepad ++ ++usb:v0738pCB02* ++ ID_MODEL_FROM_DATABASE=Saitek Cyborg Rumble Pad ++ ++usb:v0738pCB03* ++ ID_MODEL_FROM_DATABASE=Saitek P3200 Rumble Pad ++ ++usb:v0738pCB29* ++ ID_MODEL_FROM_DATABASE=Saitek Aviator Stick AV8R02 ++ ++usb:v0738pF738* ++ ID_MODEL_FROM_DATABASE=Super Street Fighter IV FightStick TE S for Xbox 360 ++ + usb:v073A* + ID_VENDOR_FROM_DATABASE=Chaplet Systems, Inc. + +@@ -28385,6 +30374,9 @@ usb:v073Cp0624* + usb:v073D* + ID_VENDOR_FROM_DATABASE=Eutron S.p.a. + ++usb:v073Dp0000* ++ ID_MODEL_FROM_DATABASE=SmartKey ++ + usb:v073Dp0005* + ID_MODEL_FROM_DATABASE=Crypto Token + +@@ -28424,6 +30416,9 @@ usb:v0745* + usb:v0746* + ID_VENDOR_FROM_DATABASE=Onkyo Corp. + ++usb:v0746p4700* ++ ID_MODEL_FROM_DATABASE=Integra MZA-4.7 ++ + usb:v0746p5500* + ID_MODEL_FROM_DATABASE=SE-U55 Audio Device + +@@ -28472,6 +30467,9 @@ usb:v0755* + usb:v0757* + ID_VENDOR_FROM_DATABASE=Network Technologies, Inc. + ++usb:v0757p0A00* ++ ID_MODEL_FROM_DATABASE=SUN Adapter ++ + usb:v0758* + ID_VENDOR_FROM_DATABASE=Carl Zeiss Microscopy GmbH + +@@ -28697,6 +30695,9 @@ usb:v0765pD094* + usb:v0766* + ID_VENDOR_FROM_DATABASE=Jess-Link Products Co., Ltd + ++usb:v0766p0017* ++ ID_MODEL_FROM_DATABASE=Packard Bell Carbon ++ + usb:v0766p001B* + ID_MODEL_FROM_DATABASE=Packard Bell Go + +@@ -28749,10 +30750,10 @@ usb:v076Bp1784* + ID_MODEL_FROM_DATABASE=CardMan 6020 + + usb:v076Bp3021* +- ID_MODEL_FROM_DATABASE=CardMan 3121 ++ ID_MODEL_FROM_DATABASE=CardMan 3021 / 3121 + + usb:v076Bp3022* +- ID_MODEL_FROM_DATABASE=CardMan 3021 ++ ID_MODEL_FROM_DATABASE=CardMan 3121 (HID Technologies) + + usb:v076Bp3610* + ID_MODEL_FROM_DATABASE=CardMan 3620 +@@ -28799,6 +30800,12 @@ usb:v076BpC001* + usb:v076C* + ID_VENDOR_FROM_DATABASE=Partner Tech + ++usb:v076Cp0204* ++ ID_MODEL_FROM_DATABASE=CD7220 Communications Port ++ ++usb:v076Cp0302* ++ ID_MODEL_FROM_DATABASE=RP-600 ++ + usb:v076D* + ID_VENDOR_FROM_DATABASE=Denso Corp. + +@@ -28839,7 +30846,13 @@ usb:v0778* + ID_VENDOR_FROM_DATABASE=Volex, Inc. + + usb:v0779* +- ID_VENDOR_FROM_DATABASE=Fairchild Semiconductor ++ ID_VENDOR_FROM_DATABASE=ON Semiconductor (formerly Fairchild) ++ ++usb:v0779p0133* ++ ID_MODEL_FROM_DATABASE=FUSB307B ++ ++usb:v0779p0134* ++ ID_MODEL_FROM_DATABASE=FUSB308B + + usb:v077A* + ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg. Co., Ltd +@@ -28892,6 +30905,18 @@ usb:v077Dp1016* + usb:v077Dp627A* + ID_MODEL_FROM_DATABASE=Radio SHARK + ++usb:v077E* ++ ID_VENDOR_FROM_DATABASE=Softing AG ++ ++usb:v077Ep008A* ++ ID_MODEL_FROM_DATABASE=NetLink Compact MPI/Profibus adapter ++ ++usb:v077Ep0160* ++ ID_MODEL_FROM_DATABASE=EDICblue ++ ++usb:v077Ep0220* ++ ID_MODEL_FROM_DATABASE=VAS5054A ++ + usb:v077F* + ID_VENDOR_FROM_DATABASE=Well Excellent & Most Corp. + +@@ -29001,7 +31026,7 @@ usb:v0781p5577* + ID_MODEL_FROM_DATABASE=Cruzer Pop (8GB) + + usb:v0781p557D* +- ID_MODEL_FROM_DATABASE=Cruzer Force (64GB) ++ ID_MODEL_FROM_DATABASE=Cruzer Force + + usb:v0781p5580* + ID_MODEL_FROM_DATABASE=SDCZ80 Flash Drive +@@ -29012,6 +31037,15 @@ usb:v0781p5581* + usb:v0781p5583* + ID_MODEL_FROM_DATABASE=Ultra Fit + ++usb:v0781p5588* ++ ID_MODEL_FROM_DATABASE=Extreme Pro ++ ++usb:v0781p5589* ++ ID_MODEL_FROM_DATABASE=SD8SB8U512G[Extreme 500] ++ ++usb:v0781p558C* ++ ID_MODEL_FROM_DATABASE=Extreme Portable SSD ++ + usb:v0781p5590* + ID_MODEL_FROM_DATABASE=Ultra Dual + +@@ -29024,6 +31058,9 @@ usb:v0781p5E10* + usb:v0781p6100* + ID_MODEL_FROM_DATABASE=Ultra II SD Plus 2GB + ++usb:v0781p6500* ++ ID_MODEL_FROM_DATABASE=uSSD 5000 ++ + usb:v0781p7100* + ID_MODEL_FROM_DATABASE=Cruzer Mini + +@@ -29195,12 +31232,21 @@ usb:v0781pA7E8* + usb:v0781pB2B3* + ID_MODEL_FROM_DATABASE=SDDR-103 MobileMate SD+ Reader + ++usb:v0781pB2B5* ++ ID_MODEL_FROM_DATABASE=SDDR-104 MobileMate SD+ Reader ++ + usb:v0781pB4B5* + ID_MODEL_FROM_DATABASE=SDDR-89 V4 ImageMate 12-in-1 Reader + ++usb:v0781pB6B7* ++ ID_MODEL_FROM_DATABASE=SDDR-99 V4 ImageMate 5-in-1 Reader ++ + usb:v0781pB6BA* + ID_MODEL_FROM_DATABASE=CF SDDR-289 + ++usb:v0781pCFC9* ++ ID_MODEL_FROM_DATABASE=SDDR-489 ImageMate Pro Reader ++ + usb:v0782* + ID_VENDOR_FROM_DATABASE=Trackerball + +@@ -29279,6 +31325,9 @@ usb:v0789p0064* + usb:v0789p00B3* + ID_MODEL_FROM_DATABASE=DVD Multi-plus unit LDR-H443U2 + ++usb:v0789p00CC* ++ ID_MODEL_FROM_DATABASE=LHD Device ++ + usb:v0789p0105* + ID_MODEL_FROM_DATABASE=LAN-TX/U1H2 10/100 Ethernet Adapter [pegasus II] + +@@ -29487,10 +31536,10 @@ usb:v07A6p8511* + ID_MODEL_FROM_DATABASE=ADM8511 Pegasus II Ethernet + + usb:v07A6p8513* +- ID_MODEL_FROM_DATABASE=AN8513 Ethernet ++ ID_MODEL_FROM_DATABASE=ADM8513 Pegasus II Ethernet + + usb:v07A6p8515* +- ID_MODEL_FROM_DATABASE=AN8515 Ethernet ++ ID_MODEL_FROM_DATABASE=ADM8515 Pegasus II Ethernet + + usb:v07AA* + ID_VENDOR_FROM_DATABASE=Corega K.K. +@@ -29576,6 +31625,9 @@ usb:v07ABpFC02* + usb:v07ABpFC03* + ID_MODEL_FROM_DATABASE=USB2-IDE IDE bridge + ++usb:v07ABpFC77* ++ ID_MODEL_FROM_DATABASE=Quattro 3.0 ++ + usb:v07ABpFCD6* + ID_MODEL_FROM_DATABASE=Freecom HD Classic + +@@ -29678,6 +31730,9 @@ usb:v07B2p5120* + usb:v07B2p5121* + ID_MODEL_FROM_DATABASE=Surfboard 5121 Cable Modem + ++usb:v07B2p6002* ++ ID_MODEL_FROM_DATABASE=MTR7000 Cable Tuning Adapter ++ + usb:v07B2p7030* + ID_MODEL_FROM_DATABASE=WU830G 802.11bg Wireless Adapter [Envara WiND512] + +@@ -29744,6 +31799,9 @@ usb:v07B3p0601* + usb:v07B3p0800* + ID_MODEL_FROM_DATABASE=OpticPro ST48 Scanner + ++usb:v07B3p0807* ++ ID_MODEL_FROM_DATABASE=OpticFilm 7200 scanner ++ + usb:v07B3p0900* + ID_MODEL_FROM_DATABASE=OpticBook 3600 Scanner + +@@ -29783,6 +31841,9 @@ usb:v07B3p1300* + usb:v07B3p1301* + ID_MODEL_FROM_DATABASE=OpticBook 4800 Scanner + ++usb:v07B3p130F* ++ ID_MODEL_FROM_DATABASE=Bookreader v200 ++ + usb:v07B4* + ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd + +@@ -29858,6 +31919,9 @@ usb:v07B4p024F* + usb:v07B4p0280* + ID_MODEL_FROM_DATABASE=m:robe 100 + ++usb:v07B4p0295* ++ ID_MODEL_FROM_DATABASE=Digital Voice Recorder VN-541PC ++ + usb:v07B5* + ID_VENDOR_FROM_DATABASE=Mega World International, Ltd + +@@ -30053,6 +32117,9 @@ usb:v07BD* + usb:v07BE* + ID_VENDOR_FROM_DATABASE=Veridicom + ++usb:v07BEp1935* ++ ID_MODEL_FROM_DATABASE=Elektron Music Machines ++ + usb:v07C0* + ID_VENDOR_FROM_DATABASE=Code Mercenaries Hard- und Software GmbH + +@@ -30230,6 +32297,9 @@ usb:v07CAp1228* + usb:v07CAp1830* + ID_MODEL_FROM_DATABASE=AVerTV Volar Video Capture (H830) + ++usb:v07CAp1871* ++ ID_MODEL_FROM_DATABASE=TD310 DVB-T/T2/C dongle ++ + usb:v07CAp3835* + ID_MODEL_FROM_DATABASE=AVerTV Volar Green HD (A835B) + +@@ -30452,6 +32522,18 @@ usb:v07CD* + usb:v07CDp0001* + ID_MODEL_FROM_DATABASE=USBuart Serial Port + ++usb:v07CE* ++ ID_VENDOR_FROM_DATABASE=Nidec Copal ++ ++usb:v07CEpC007* ++ ID_MODEL_FROM_DATABASE=DPB-4000 ++ ++usb:v07CEpC009* ++ ID_MODEL_FROM_DATABASE=DPB-6000 ++ ++usb:v07CEpC010* ++ ID_MODEL_FROM_DATABASE=CPB-7000 ++ + usb:v07CF* + ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd + +@@ -30515,6 +32597,9 @@ usb:v07CFp6801* + usb:v07CFp6802* + ID_MODEL_FROM_DATABASE=MIDI Keyboard + ++usb:v07CFp6803* ++ ID_MODEL_FROM_DATABASE=CTK-3500 (MIDI keyboard) ++ + usb:v07D0* + ID_VENDOR_FROM_DATABASE=Dazzle + +@@ -30851,12 +32936,21 @@ usb:v07FDp0001* + usb:v07FDp0002* + ID_MODEL_FROM_DATABASE=MOTU Audio for 64 bit + ++usb:v07FDp0004* ++ ID_MODEL_FROM_DATABASE=MicroBook ++ ++usb:v07FDp0008* ++ ID_MODEL_FROM_DATABASE=M Series ++ + usb:v07FF* + ID_VENDOR_FROM_DATABASE=Unknown + + usb:v07FFp00FF* + ID_MODEL_FROM_DATABASE=Portable Hard Drive + ++usb:v07FFpFFFF* ++ ID_MODEL_FROM_DATABASE=Mad Catz Gamepad ++ + usb:v0801* + ID_VENDOR_FROM_DATABASE=MagTek + +@@ -31001,6 +33095,12 @@ usb:v081E* + usb:v081EpDF00* + ID_MODEL_FROM_DATABASE=Handheld + ++usb:v081F* ++ ID_VENDOR_FROM_DATABASE=Manta ++ ++usb:v081FpE401* ++ ID_MODEL_FROM_DATABASE=MM812 ++ + usb:v0822* + ID_VENDOR_FROM_DATABASE=Reudo Corp. + +@@ -31235,6 +33335,9 @@ usb:v0839p1009* + usb:v0839p1012* + ID_MODEL_FROM_DATABASE=6500 Document Camera + ++usb:v0839p103F* ++ ID_MODEL_FROM_DATABASE=Digimax S500 ++ + usb:v0839p1058* + ID_MODEL_FROM_DATABASE=S730 Camera + +@@ -31436,6 +33539,9 @@ usb:v0846p4301* + usb:v0846p5F00* + ID_MODEL_FROM_DATABASE=WPN111 802.11g Wireless Adapter [Atheros AR5523] + ++usb:v0846p68E1* ++ ID_MODEL_FROM_DATABASE=LB1120-100NAS ++ + usb:v0846p6A00* + ID_MODEL_FROM_DATABASE=WG111v2 54 Mbps Wireless [RealTek RTL8187L] + +@@ -31493,6 +33599,9 @@ usb:v0846p9051* + usb:v0846p9052* + ID_MODEL_FROM_DATABASE=A6100 AC600 DB Wireless Adapter [Realtek RTL8811AU] + ++usb:v0846p9054* ++ ID_MODEL_FROM_DATABASE=Nighthawk A7000 802.11ac Wireless Adapter AC1900 [Realtek 8814AU] ++ + usb:v0846pA001* + ID_MODEL_FROM_DATABASE=PA101 10 Mbps HPNA Home Phoneline RJ-1 + +@@ -31565,6 +33674,12 @@ usb:v0853* + usb:v0853p0100* + ID_MODEL_FROM_DATABASE=HHKB Professional + ++usb:v0853p0119* ++ ID_MODEL_FROM_DATABASE=RealForce 105UB ++ ++usb:v0853p0200* ++ ID_MODEL_FROM_DATABASE=RealForce Compact Keyboard ++ + usb:v0854* + ID_VENDOR_FROM_DATABASE=ActiveWire, Inc. + +@@ -33008,6 +35123,9 @@ usb:v0910* + usb:v0911* + ID_VENDOR_FROM_DATABASE=Philips Speech Processing + ++usb:v0911p0C1C* ++ ID_MODEL_FROM_DATABASE=SpeechMike III ++ + usb:v0911p149A* + ID_MODEL_FROM_DATABASE=SpeechMike II Pro Plus LFH5276 + +@@ -33170,6 +35288,9 @@ usb:v091Ep2459* + usb:v091Ep2491* + ID_MODEL_FROM_DATABASE=Edge 800 + ++usb:v091Ep2518* ++ ID_MODEL_FROM_DATABASE=eTrex 10 ++ + usb:v091Ep2519* + ID_MODEL_FROM_DATABASE=eTrex 30 + +@@ -33182,12 +35303,24 @@ usb:v091Ep253C* + usb:v091Ep255B* + ID_MODEL_FROM_DATABASE=Nuvi 2505LM + ++usb:v091Ep2613* ++ ID_MODEL_FROM_DATABASE=Edge 200 TWN ++ + usb:v091Ep26A1* + ID_MODEL_FROM_DATABASE=Nuvi 55 + ++usb:v091Ep2802* ++ ID_MODEL_FROM_DATABASE=fenix 3 ++ ++usb:v091Ep28DB* ++ ID_MODEL_FROM_DATABASE=Drive 5 ++ + usb:v091Ep47FB* + ID_MODEL_FROM_DATABASE=nuviCam + ++usb:v091Ep4CDB* ++ ID_MODEL_FROM_DATABASE=Fenix 6 ++ + usb:v0920* + ID_VENDOR_FROM_DATABASE=Echelon Co. + +@@ -33209,6 +35342,9 @@ usb:v0922p0007* + usb:v0922p0009* + ID_MODEL_FROM_DATABASE=LabelWriter 310 + ++usb:v0922p0013* ++ ID_MODEL_FROM_DATABASE=LabelManager 400 ++ + usb:v0922p0019* + ID_MODEL_FROM_DATABASE=LabelWriter 400 + +@@ -33218,12 +35354,21 @@ usb:v0922p001A* + usb:v0922p0020* + ID_MODEL_FROM_DATABASE=LabelWriter 450 + ++usb:v0922p0400* ++ ID_MODEL_FROM_DATABASE=LabelWriter SE450 ++ + usb:v0922p1001* + ID_MODEL_FROM_DATABASE=LabelManager PnP + ++usb:v0922p8003* ++ ID_MODEL_FROM_DATABASE=M10 Digital Postal Scale ++ + usb:v0922p8004* + ID_MODEL_FROM_DATABASE=M25 Digital Postal Scale + ++usb:v0922p8009* ++ ID_MODEL_FROM_DATABASE=S250 Digital Postal Scale ++ + usb:v0923* + ID_VENDOR_FROM_DATABASE=IC Media Corp. + +@@ -33278,6 +35423,12 @@ usb:v0925p0005* + usb:v0925p03E8* + ID_MODEL_FROM_DATABASE=Wii Classic Controller Adapter + ++usb:v0925p1031* ++ ID_MODEL_FROM_DATABASE=WiseGroup Ltd, Gameport Controller ++ ++usb:v0925p1700* ++ ID_MODEL_FROM_DATABASE=PS/SS/N64 Joypad ++ + usb:v0925p3881* + ID_MODEL_FROM_DATABASE=Saleae Logic + +@@ -33314,6 +35465,9 @@ usb:v092A* + usb:v092B* + ID_VENDOR_FROM_DATABASE=Sena Technologies, Inc. + ++usb:v092Bp4210* ++ ID_MODEL_FROM_DATABASE=20S - Bluetooth Motorcycle headset & universal intercom ++ + usb:v092F* + ID_VENDOR_FROM_DATABASE=Northern Embedded Science/CAVNEX + +@@ -33396,7 +35550,7 @@ usb:v0930p0707* + ID_MODEL_FROM_DATABASE=Pocket PC e330 Series + + usb:v0930p0708* +- ID_MODEL_FROM_DATABASE=Pocket PC e350 Series ++ ID_MODEL_FROM_DATABASE=Pocket PC e350 Series + + usb:v0930p0709* + ID_MODEL_FROM_DATABASE=Pocket PC e750 Series +@@ -33455,6 +35609,9 @@ usb:v0930p1311* + usb:v0930p1400* + ID_MODEL_FROM_DATABASE=Memory Stick 2GB + ++usb:v0930p140B* ++ ID_MODEL_FROM_DATABASE=Memory Stick 64GB ++ + usb:v0930p642F* + ID_MODEL_FROM_DATABASE=TravelDrive + +@@ -33578,6 +35735,9 @@ usb:v0930p6544* + usb:v0930p6545* + ID_MODEL_FROM_DATABASE=Kingston DataTraveler 102/2.0 / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick + ++usb:v0930pA002* ++ ID_MODEL_FROM_DATABASE=SunplusIT SATA bridge ++ + usb:v0931* + ID_VENDOR_FROM_DATABASE=Harmonic Data Systems, Ltd + +@@ -33644,6 +35804,9 @@ usb:v0939* + usb:v0939p0B15* + ID_MODEL_FROM_DATABASE=Toshiba Stor.E Alu 2 + ++usb:v0939p0B16* ++ ID_MODEL_FROM_DATABASE=Toshiba StorE HDD ++ + usb:v093A* + ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc. + +@@ -33710,6 +35873,12 @@ usb:v093Ap2622* + usb:v093Ap2624* + ID_MODEL_FROM_DATABASE=Webcam + ++usb:v093Ap2628* ++ ID_MODEL_FROM_DATABASE=Webcam Genius iLook 300 ++ ++usb:v093Ap2700* ++ ID_MODEL_FROM_DATABASE=GE 1.3 MP MiniCam Pro ++ + usb:v093B* + ID_VENDOR_FROM_DATABASE=Plextor Corp. + +@@ -33719,6 +35888,9 @@ usb:v093Bp0010* + usb:v093Bp0011* + ID_MODEL_FROM_DATABASE=PlexWriter 40/12/40U + ++usb:v093Bp0012* ++ ID_MODEL_FROM_DATABASE=PlexWriter 48/24/48U ++ + usb:v093Bp0041* + ID_MODEL_FROM_DATABASE=PX-708A DVD RW + +@@ -33848,6 +36020,9 @@ usb:v0951p0008* + usb:v0951p000A* + ID_MODEL_FROM_DATABASE=KNU101TX 100baseTX Ethernet + ++usb:v0951p1539* ++ ID_MODEL_FROM_DATABASE=Iron Key D300 (Virtual CD-ROM and USB Stick) ++ + usb:v0951p1600* + ID_MODEL_FROM_DATABASE=DataTraveler II Pen Drive + +@@ -33921,10 +36096,10 @@ usb:v0951p1660* + ID_MODEL_FROM_DATABASE=Data Traveller 108 + + usb:v0951p1665* +- ID_MODEL_FROM_DATABASE=Digital DataTraveler SE9 64GB ++ ID_MODEL_FROM_DATABASE=Digital DataTraveler SE9 + + usb:v0951p1666* +- ID_MODEL_FROM_DATABASE=DataTraveler 100 G3/G4/SE9 G2 ++ ID_MODEL_FROM_DATABASE=DataTraveler 100 G3/G4/SE9 G2/50 + + usb:v0951p1689* + ID_MODEL_FROM_DATABASE=DataTraveler SE9 +@@ -33935,15 +36110,36 @@ usb:v0951p168A* + usb:v0951p168C* + ID_MODEL_FROM_DATABASE=DT Elite 3.0 + ++usb:v0951p16A4* ++ ID_MODEL_FROM_DATABASE=HyperX 7.1 Audio ++ + usb:v0951p16B3* + ID_MODEL_FROM_DATABASE=HyperX Savage + ++usb:v0951p16D2* ++ ID_MODEL_FROM_DATABASE=HX-KB4BL1-US [HYPERX Alloy FPS Pro] ++ ++usb:v0951p16D4* ++ ID_MODEL_FROM_DATABASE=HyperX SavageEXO [0382] ++ ++usb:v0951p16D5* ++ ID_MODEL_FROM_DATABASE=DataTraveler Elite G2 ++ ++usb:v0951p16DF* ++ ID_MODEL_FROM_DATABASE=HyperX QuadCast ++ ++usb:v0951p16E4* ++ ID_MODEL_FROM_DATABASE=HyperX Pulsefire Raid ++ + usb:v0954* + ID_VENDOR_FROM_DATABASE=RPM Systems Corp. + + usb:v0955* + ID_VENDOR_FROM_DATABASE=NVIDIA Corp. + ++usb:v0955p7005* ++ ID_MODEL_FROM_DATABASE=Bootloader ++ + usb:v0955p7018* + ID_MODEL_FROM_DATABASE=T186 [Tegra Parker] + +@@ -33965,12 +36161,18 @@ usb:v0955p7140* + usb:v0955p7210* + ID_MODEL_FROM_DATABASE=SHIELD Controller + ++usb:v0955p7321* ++ ID_MODEL_FROM_DATABASE=Switch [Tegra Erista] recovery mode ++ + usb:v0955p7721* +- ID_MODEL_FROM_DATABASE=T210 [Tegra Erista] ++ ID_MODEL_FROM_DATABASE=T210 [TX1 Tegra Erista] recovery mode + + usb:v0955p7820* + ID_MODEL_FROM_DATABASE=T20 [Tegra 2] recovery mode + ++usb:v0955p7C18* ++ ID_MODEL_FROM_DATABASE=T186 [TX2 Tegra Parker] recovery mode ++ + usb:v0955pB400* + ID_MODEL_FROM_DATABASE=SHIELD (debug) + +@@ -34019,6 +36221,9 @@ usb:v0957p1507* + usb:v0957p1745* + ID_MODEL_FROM_DATABASE=Test and Measurement Device (IVI) + ++usb:v0957p1F01* ++ ID_MODEL_FROM_DATABASE=N5181A MXG Analog Signal Generator ++ + usb:v0957p2918* + ID_MODEL_FROM_DATABASE=U2702A oscilloscope + +@@ -34070,6 +36275,9 @@ usb:v096E* + usb:v096Ep0005* + ID_MODEL_FROM_DATABASE=ePass2000 + ++usb:v096Ep0006* ++ ID_MODEL_FROM_DATABASE=HID Dongle (for OEMs - manufacturer string is "OEM") ++ + usb:v096Ep0120* + ID_MODEL_FROM_DATABASE=Microcosm Ltd Dinkey + +@@ -34082,6 +36290,12 @@ usb:v096Ep0309* + usb:v096Ep0401* + ID_MODEL_FROM_DATABASE=ePass3000 + ++usb:v096Ep0405* ++ ID_MODEL_FROM_DATABASE=Zzkey Dongle ++ ++usb:v096Ep0608* ++ ID_MODEL_FROM_DATABASE=SC Reader KP382 ++ + usb:v096Ep0702* + ID_MODEL_FROM_DATABASE=ePass3003 + +@@ -34184,6 +36398,9 @@ usb:v0984p0040* + usb:v0984p0200* + ID_MODEL_FROM_DATABASE=Hard Drive Storage (TPP) + ++usb:v0984p1407* ++ ID_MODEL_FROM_DATABASE=Secure Key 3.0 ++ + usb:v0985* + ID_VENDOR_FROM_DATABASE=cab Produkttechnik GmbH & Co KG + +@@ -34226,9 +36443,15 @@ usb:v099A* + usb:v099Ap0638* + ID_MODEL_FROM_DATABASE=Sanwa Supply Inc. Small Keyboard + ++usb:v099Ap2620* ++ ID_MODEL_FROM_DATABASE=Graphics tablet [Polostar PT1001, Zeniq PT1001, Leogics PT1001] ++ + usb:v099Ap610C* + ID_MODEL_FROM_DATABASE=EL-610 Super Mini Electron luminescent Keyboard + ++usb:v099Ap6330* ++ ID_MODEL_FROM_DATABASE=SANWA Supply Inc. Slim Keyboard ++ + usb:v099Ap713A* + ID_MODEL_FROM_DATABASE=WK-713 Multimedia Keyboard + +@@ -34277,6 +36500,15 @@ usb:v09AB* + usb:v09AE* + ID_VENDOR_FROM_DATABASE=Tripp Lite + ++usb:v09AEp0002* ++ ID_MODEL_FROM_DATABASE=Any Device (see discussion) ++ ++usb:v09B0* ++ ID_VENDOR_FROM_DATABASE=Fargo ++ ++usb:v09B0p2400* ++ ID_MODEL_FROM_DATABASE=HDP5000 ++ + usb:v09B2* + ID_VENDOR_FROM_DATABASE=Franklin Electronic Publishers, Inc. + +@@ -34380,7 +36612,7 @@ usb:v09C2* + ID_VENDOR_FROM_DATABASE=Nisca Corp. + + usb:v09C3* +- ID_VENDOR_FROM_DATABASE=ActivCard, Inc. ++ ID_VENDOR_FROM_DATABASE=HID Global + + usb:v09C3p0007* + ID_MODEL_FROM_DATABASE=Reader V2 +@@ -34391,6 +36623,24 @@ usb:v09C3p0008* + usb:v09C3p0014* + ID_MODEL_FROM_DATABASE=ActivIdentity ActivKey SIM USB Token + ++usb:v09C3p0028* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ ++usb:v09C3p0029* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ ++usb:v09C3p002A* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ ++usb:v09C3p002B* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ ++usb:v09C3p002C* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ ++usb:v09C3p002E* ++ ID_MODEL_FROM_DATABASE=Crescendo Key ++ + usb:v09C4* + ID_VENDOR_FROM_DATABASE=ACTiSYS Corp. + +@@ -34433,6 +36683,9 @@ usb:v09CBp1008* + usb:v09CBp1996* + ID_MODEL_FROM_DATABASE=FLIR ONE Camera + ++usb:v09CBp4007* ++ ID_MODEL_FROM_DATABASE=Breach ++ + usb:v09CC* + ID_VENDOR_FROM_DATABASE=Workbit Corp. + +@@ -34464,16 +36717,19 @@ usb:v09D3p0001* + ID_MODEL_FROM_DATABASE=ISDN TA / Light Rider 128K + + usb:v09D3p000B* +- ID_MODEL_FROM_DATABASE=Bluetooth Adapter class 1 [BlueLight] ++ ID_MODEL_FROM_DATABASE=Bluetooth Adapter class 2 + + usb:v09D7* +- ID_VENDOR_FROM_DATABASE=NovAtel Inc. ++ ID_VENDOR_FROM_DATABASE=Hexagon NovAtel Inc. + + usb:v09D7p0100* +- ID_MODEL_FROM_DATABASE=NovAtel FlexPack GPS receiver ++ ID_MODEL_FROM_DATABASE=GPS/GNSS/SPAN sensor + + usb:v09D8* +- ID_VENDOR_FROM_DATABASE=ELATEC ++ ID_VENDOR_FROM_DATABASE=ELATEC GmbH ++ ++usb:v09D8p0320* ++ ID_MODEL_FROM_DATABASE=TWN3 Multi125 + + usb:v09D8p0406* + ID_MODEL_FROM_DATABASE=TWN4 MIFARE NFC +@@ -34514,9 +36770,18 @@ usb:v09DAp0260* + usb:v09DAp032B* + ID_MODEL_FROM_DATABASE=Wireless Mouse (Battery Free) + ++usb:v09DAp09DA* ++ ID_MODEL_FROM_DATABASE=Bloody V8 Mouse ++ + usb:v09DAp1068* + ID_MODEL_FROM_DATABASE=Bloody A90 Mouse + ++usb:v09DAp112C* ++ ID_MODEL_FROM_DATABASE=Bloody V5 Mouse ++ ++usb:v09DAp3A60* ++ ID_MODEL_FROM_DATABASE=Bloody V8M Core 2 Mouse ++ + usb:v09DAp8090* + ID_MODEL_FROM_DATABASE=X-718BK Oscar Optical Gaming Mouse + +@@ -34529,6 +36794,9 @@ usb:v09DAp9066* + usb:v09DAp9090* + ID_MODEL_FROM_DATABASE=XL-730K / XL-750BK / XL-755BK Mice + ++usb:v09DApF613* ++ ID_MODEL_FROM_DATABASE=Bloody V7M Mouse ++ + usb:v09DB* + ID_VENDOR_FROM_DATABASE=Measurement Computing Corp. + +@@ -34577,6 +36845,9 @@ usb:v09E7* + usb:v09E8* + ID_VENDOR_FROM_DATABASE=AKAI Professional M.I. Corp. + ++usb:v09E8p0045* ++ ID_MODEL_FROM_DATABASE=MPK Mini Mk II MIDI Controller ++ + usb:v09E8p0062* + ID_MODEL_FROM_DATABASE=MPD16 MIDI Pad Controller Unit + +@@ -35003,6 +37274,9 @@ usb:v0A48p5025* + usb:v0A4A* + ID_VENDOR_FROM_DATABASE=Ploytec GmbH + ++usb:v0A4ApA400* ++ ID_MODEL_FROM_DATABASE=AUDIO JUNCTION 2.0 ++ + usb:v0A4B* + ID_VENDOR_FROM_DATABASE=Fujitsu Media Devices, Ltd + +@@ -35150,6 +37424,9 @@ usb:v0A5C* + usb:v0A5Cp0201* + ID_MODEL_FROM_DATABASE=iLine10(tm) Network Adapter + ++usb:v0A5Cp0BDC* ++ ID_MODEL_FROM_DATABASE=802.11a/b/g/n/ac Wireless Adapter ++ + usb:v0A5Cp2000* + ID_MODEL_FROM_DATABASE=Bluetooth Device + +@@ -35309,6 +37586,9 @@ usb:v0A5Cp21E6* + usb:v0A5Cp21E8* + ID_MODEL_FROM_DATABASE=BCM20702A0 Bluetooth 4.0 + ++usb:v0A5Cp21EC* ++ ID_MODEL_FROM_DATABASE=BCM20702A0 Bluetooth 4.0 ++ + usb:v0A5Cp21F1* + ID_MODEL_FROM_DATABASE=HP Portable Bumble Bee + +@@ -35381,9 +37661,18 @@ usb:v0A5F* + usb:v0A5Fp0009* + ID_MODEL_FROM_DATABASE=LP2844 Printer + ++usb:v0A5Fp0050* ++ ID_MODEL_FROM_DATABASE=P120i / WM120i ++ ++usb:v0A5Fp0080* ++ ID_MODEL_FROM_DATABASE=GK420d Label Printer ++ + usb:v0A5Fp0081* + ID_MODEL_FROM_DATABASE=GK420t Label Printer + ++usb:v0A5Fp0084* ++ ID_MODEL_FROM_DATABASE=GX420d Desktop Label Printer ++ + usb:v0A5Fp008B* + ID_MODEL_FROM_DATABASE=HC100 wristbands Printer + +@@ -35393,6 +37682,9 @@ usb:v0A5Fp008C* + usb:v0A5Fp00D1* + ID_MODEL_FROM_DATABASE=Zebra GC420d Label Printer + ++usb:v0A5Fp0110* ++ ID_MODEL_FROM_DATABASE=ZD500 Desktop Label Printer ++ + usb:v0A5Fp930A* + ID_MODEL_FROM_DATABASE=Printer + +@@ -35492,6 +37784,9 @@ usb:v0A82* + usb:v0A82p4600* + ID_MODEL_FROM_DATABASE=TravelScan 460/464 + ++usb:v0A82p6605* ++ ID_MODEL_FROM_DATABASE=ScanShell 800N ++ + usb:v0A83* + ID_VENDOR_FROM_DATABASE=NextComm, Inc. + +@@ -35894,6 +38189,15 @@ usb:v0AADp0083* + usb:v0AADp0095* + ID_MODEL_FROM_DATABASE=NRP-Z86 + ++usb:v0AADp0117* ++ ID_MODEL_FROM_DATABASE=HMF / HMP / HMS-X / HMO series Oscilloscopes ++ ++usb:v0AADp0118* ++ ID_MODEL_FROM_DATABASE=HMF / HMP / HMS-X / HMO series Oscilloscopes ++ ++usb:v0AADp0119* ++ ID_MODEL_FROM_DATABASE=HMF / HMP / HMS-X / HMO series Oscilloscopes ++ + usb:v0AAE* + ID_VENDOR_FROM_DATABASE=NEC infrontia Corp. (Nitsuko) + +@@ -36011,6 +38315,9 @@ usb:v0AC8pC326* + usb:v0AC8pC33F* + ID_MODEL_FROM_DATABASE=Webcam + ++usb:v0AC8pC412* ++ ID_MODEL_FROM_DATABASE=Lenovo IdeaCentre Web Camera ++ + usb:v0AC8pC429* + ID_MODEL_FROM_DATABASE=Lenovo ThinkCentre Web Camera + +@@ -36413,6 +38720,9 @@ usb:v0B05p1788* + usb:v0B05p1791* + ID_MODEL_FROM_DATABASE=WL-167G v3 802.11n Adapter [Realtek RTL8188SU] + ++usb:v0B05p179C* ++ ID_MODEL_FROM_DATABASE=Bluetooth Adapter ++ + usb:v0B05p179D* + ID_MODEL_FROM_DATABASE=USB-N53 802.11abgn Network Adapter [Ralink RT3572] + +@@ -36434,6 +38744,9 @@ usb:v0B05p17AB* + usb:v0B05p17BA* + ID_MODEL_FROM_DATABASE=N10 Nano 802.11n Network Adapter [Realtek RTL8192CU] + ++usb:v0B05p17C2* ++ ID_MODEL_FROM_DATABASE=ROG Spitfire ++ + usb:v0B05p17C7* + ID_MODEL_FROM_DATABASE=WL-330NUL + +@@ -36461,6 +38774,9 @@ usb:v0B05p17E8* + usb:v0B05p17EB* + ID_MODEL_FROM_DATABASE=USB-AC55 802.11a/b/g/n/ac Wireless Adapter [MediaTek MT7612U] + ++usb:v0B05p17F5* ++ ID_MODEL_FROM_DATABASE=Xonar U5 sound card ++ + usb:v0B05p180A* + ID_MODEL_FROM_DATABASE=Broadcom BCM20702 Single-Chip Bluetooth 4.0 + LE + +@@ -36470,6 +38786,9 @@ usb:v0B05p1817* + usb:v0B05p1825* + ID_MODEL_FROM_DATABASE=Qualcomm Bluetooth 4.1 + ++usb:v0B05p18F0* ++ ID_MODEL_FROM_DATABASE=Realtek 8188EUS [USB-N10 Nano] ++ + usb:v0B05p4C80* + ID_MODEL_FROM_DATABASE=Transformer Pad TF300TG + +@@ -36563,18 +38882,39 @@ usb:v0B0Dp0000* + usb:v0B0E* + ID_VENDOR_FROM_DATABASE=GN Netcom + ++usb:v0B0Ep0305* ++ ID_MODEL_FROM_DATABASE=Jabra EVOLVE Link MS ++ ++usb:v0B0Ep0311* ++ ID_MODEL_FROM_DATABASE=Jabra EVOLVE 65 ++ ++usb:v0B0Ep0312* ++ ID_MODEL_FROM_DATABASE=enc060:Buttons Volume up/down/mute + phone [Jabra] ++ ++usb:v0B0Ep0343* ++ ID_MODEL_FROM_DATABASE=Jabra UC VOICE 150a ++ + usb:v0B0Ep0348* + ID_MODEL_FROM_DATABASE=Jabra UC VOICE 550a MS + + usb:v0B0Ep034C* + ID_MODEL_FROM_DATABASE=Jabra UC Voice 750 MS + ++usb:v0B0Ep034D* ++ ID_MODEL_FROM_DATABASE=Jabra UC VOICE 750 ++ + usb:v0B0Ep0410* + ID_MODEL_FROM_DATABASE=Jabra SPEAK 410 + + usb:v0B0Ep0420* + ID_MODEL_FROM_DATABASE=Jabra SPEAK 510 + ++usb:v0B0Ep0422* ++ ID_MODEL_FROM_DATABASE=Jabra SPEAK 510 USB ++ ++usb:v0B0Ep0933* ++ ID_MODEL_FROM_DATABASE=Jabra Freeway ++ + usb:v0B0Ep094D* + ID_MODEL_FROM_DATABASE=GN Netcom / Jabra REVO Wireless + +@@ -36593,15 +38933,30 @@ usb:v0B0Ep1900* + usb:v0B0Ep2007* + ID_MODEL_FROM_DATABASE=GN 2000 Stereo Corded Headset + ++usb:v0B0Ep2456* ++ ID_MODEL_FROM_DATABASE=Jabra SPEAK 810 ++ ++usb:v0B0Ep245E* ++ ID_MODEL_FROM_DATABASE=Jabra Link 370 ++ + usb:v0B0Ep620C* + ID_MODEL_FROM_DATABASE=Jabra BT620s + + usb:v0B0Ep9330* + ID_MODEL_FROM_DATABASE=Jabra GN9330 Headset + ++usb:v0B0EpA346* ++ ID_MODEL_FROM_DATABASE=Jabra Engage 75 Stereo ++ ++usb:v0B0EpA50A* ++ ID_MODEL_FROM_DATABASE=Alienware Wireless Gaming Headset AW988 ++ + usb:v0B0F* + ID_VENDOR_FROM_DATABASE=AVID Technology + ++usb:v0B0Fp0400* ++ ID_MODEL_FROM_DATABASE=DNxID ++ + usb:v0B10* + ID_VENDOR_FROM_DATABASE=Pcally + +@@ -36662,6 +39017,15 @@ usb:v0B33p0401* + usb:v0B33p0700* + ID_MODEL_FROM_DATABASE=RollerMouse Pro + ++usb:v0B33p08A0* ++ ID_MODEL_FROM_DATABASE=Perfit Mouse ++ ++usb:v0B33p1000* ++ ID_MODEL_FROM_DATABASE=RollerMouse Red ++ ++usb:v0B33p1010* ++ ID_MODEL_FROM_DATABASE=Vidamic Technomouse IQ ++ + usb:v0B37* + ID_VENDOR_FROM_DATABASE=Hitachi ULSI Systems Co., Ltd + +@@ -36860,6 +39224,9 @@ usb:v0B4D* + usb:v0B4Dp110A* + ID_MODEL_FROM_DATABASE=Graphtec CC200-20 + ++usb:v0B4Dp1123* ++ ID_MODEL_FROM_DATABASE=Electronic Cutting Tool [Silhouette Portrait] ++ + usb:v0B4E* + ID_VENDOR_FROM_DATABASE=Musical Electronics, Ltd + +@@ -37076,6 +39443,9 @@ usb:v0B95p1780* + usb:v0B95p1790* + ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet + ++usb:v0B95p6802* ++ ID_MODEL_FROM_DATABASE=AX68002 KVM Switch SoC ++ + usb:v0B95p7720* + ID_MODEL_FROM_DATABASE=AX88772 + +@@ -37217,6 +39587,9 @@ usb:v0BB4p00CE* + usb:v0BB4p00CF* + ID_MODEL_FROM_DATABASE=SPV C500 Smart Phone + ++usb:v0BB4p0306* ++ ID_MODEL_FROM_DATABASE=Vive Hub Bluetooth 4.1 (Broadcom BCM920703) ++ + usb:v0BB4p0A01* + ID_MODEL_FROM_DATABASE=PocketPC Sync + +@@ -37722,7 +40095,7 @@ usb:v0BB4p0BCE* + ID_MODEL_FROM_DATABASE=Vario MDA + + usb:v0BB4p0C01* +- ID_MODEL_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo ++ ID_MODEL_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo / FP1 + + usb:v0BB4p0C02* + ID_MODEL_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo (Debug) +@@ -37769,6 +40142,9 @@ usb:v0BB4p0CA2* + usb:v0BB4p0CA5* + ID_MODEL_FROM_DATABASE=Android Phone [Evo Shift 4G] + ++usb:v0BB4p0CAB* ++ ID_MODEL_FROM_DATABASE=Desire / Desire HD / Hero / Thunderbolt (HTC Sync Mode) ++ + usb:v0BB4p0CAE* + ID_MODEL_FROM_DATABASE=T-Mobile MyTouch 4G Slide [Doubleshot] + +@@ -37790,6 +40166,9 @@ usb:v0BB4p0F64* + usb:v0BB4p0FB4* + ID_MODEL_FROM_DATABASE=Remote NDIS based Device + ++usb:v0BB4p0FF0* ++ ID_MODEL_FROM_DATABASE=One Mini (M4) ++ + usb:v0BB4p0FF8* + ID_MODEL_FROM_DATABASE=Desire HD (Tethering Mode) + +@@ -37803,11 +40182,20 @@ usb:v0BB4p0FFF* + ID_MODEL_FROM_DATABASE=Android Fastboot Bootloader + + usb:v0BB4p2008* +- ID_MODEL_FROM_DATABASE=Android Phone via MTP [Wiko Cink Peax 2] ++ ID_MODEL_FROM_DATABASE=Android Phone via MTP [MT65xx] + + usb:v0BB4p200B* + ID_MODEL_FROM_DATABASE=Android Phone via PTP [Wiko Cink Peax 2] + ++usb:v0BB4p2134* ++ ID_MODEL_FROM_DATABASE=Vive Hub (SMSC USB2137B) ++ ++usb:v0BB4p2744* ++ ID_MODEL_FROM_DATABASE=Vive Hub (HTC CB USB2) ++ ++usb:v0BB4p2C87* ++ ID_MODEL_FROM_DATABASE=Vive ++ + usb:v0BB5* + ID_VENDOR_FROM_DATABASE=Murata Manufacturing Co., Ltd + +@@ -37865,6 +40253,9 @@ usb:v0BC2p2300* + usb:v0BC2p231A* + ID_MODEL_FROM_DATABASE=Expansion Portable + ++usb:v0BC2p231C* ++ ID_MODEL_FROM_DATABASE=Expansion Portable ++ + usb:v0BC2p2320* + ID_MODEL_FROM_DATABASE=USB 3.0 bridge [Portable Expansion Drive] + +@@ -37889,15 +40280,24 @@ usb:v0BC2p3101* + usb:v0BC2p3312* + ID_MODEL_FROM_DATABASE=SRD00F2 Expansion Desktop Drive (STBV) + ++usb:v0BC2p331A* ++ ID_MODEL_FROM_DATABASE=Desktop HDD 5TB (ST5000DM000) ++ + usb:v0BC2p3320* + ID_MODEL_FROM_DATABASE=SRD00F2 [Expansion Desktop Drive] + + usb:v0BC2p3322* + ID_MODEL_FROM_DATABASE=SRD0NF2 [Expansion Desktop Drive] + ++usb:v0BC2p3323* ++ ID_MODEL_FROM_DATABASE=Seagate RSS LLC ++ + usb:v0BC2p3332* + ID_MODEL_FROM_DATABASE=Expansion + ++usb:v0BC2p3343* ++ ID_MODEL_FROM_DATABASE=desktop drive stgy8000400 ++ + usb:v0BC2p5020* + ID_MODEL_FROM_DATABASE=FreeAgent GoFlex + +@@ -37934,6 +40334,9 @@ usb:v0BC2p5161* + usb:v0BC2p6126* + ID_MODEL_FROM_DATABASE=Maxtor D3 Station 5TB + ++usb:v0BC2p61B5* ++ ID_MODEL_FROM_DATABASE=Maxtor HX-M201TCB [M3 Portable 2TB] ++ + usb:v0BC2p61B6* + ID_MODEL_FROM_DATABASE=Maxtor HX-M101TCB/GM [M3 Portable 1TB] + +@@ -37949,6 +40352,9 @@ usb:v0BC2pA0A1* + usb:v0BC2pA0A4* + ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive + ++usb:v0BC2pAA14* ++ ID_MODEL_FROM_DATABASE=STJ4000400 [Seagate Basic Portable Drive 4TB] ++ + usb:v0BC2pAB00* + ID_MODEL_FROM_DATABASE=Slim Portable Drive + +@@ -37967,6 +40373,12 @@ usb:v0BC2pAB24* + usb:v0BC2pAB26* + ID_MODEL_FROM_DATABASE=Backup Plus Slim Portable Drive 1 TB + ++usb:v0BC2pAB28* ++ ID_MODEL_FROM_DATABASE=Seagate Backup Plus Portable 5TB SRD00F1 ++ ++usb:v0BC2pAB2D* ++ ID_MODEL_FROM_DATABASE=SRD00F1 [Backup Plus Ultra Slim] ++ + usb:v0BC2pAB31* + ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive (5TB) + +@@ -37974,8 +40386,14 @@ usb:v0BC2pAB34* + ID_MODEL_FROM_DATABASE=Backup Plus + + usb:v0BC2pAB38* ++ ID_MODEL_FROM_DATABASE=Backup Plus Hub (Mass Storage) ++ ++usb:v0BC2pAB44* + ID_MODEL_FROM_DATABASE=Backup Plus Hub + ++usb:v0BC2pAC20* ++ ID_MODEL_FROM_DATABASE=Backup Plus Slim 2TB ++ + usb:v0BC3* + ID_VENDOR_FROM_DATABASE=IPWireless, Inc. + +@@ -38162,12 +40580,27 @@ usb:v0BDAp0301* + usb:v0BDAp0307* + ID_MODEL_FROM_DATABASE=Card Reader + ++usb:v0BDAp0316* ++ ID_MODEL_FROM_DATABASE=Card Reader ++ + usb:v0BDAp0326* + ID_MODEL_FROM_DATABASE=Card reader + ++usb:v0BDAp0411* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v0BDAp0811* ++ ID_MODEL_FROM_DATABASE=Realtek 8812AU/8821AU 802.11ac WLAN Adapter [USB Wireless Dual-Band Adapter 2.4/5Ghz] ++ ++usb:v0BDAp0821* ++ ID_MODEL_FROM_DATABASE=RTL8821A Bluetooth ++ + usb:v0BDAp1724* + ID_MODEL_FROM_DATABASE=RTL8723AU 802.11n WLAN Adapter + ++usb:v0BDAp1A2B* ++ ID_MODEL_FROM_DATABASE=RTL8188GU 802.11n WLAN Adapter (Driver CDROM Mode) ++ + usb:v0BDAp2831* + ID_MODEL_FROM_DATABASE=RTL2831U DVB-T + +@@ -38180,6 +40613,12 @@ usb:v0BDAp2838* + usb:v0BDAp5401* + ID_MODEL_FROM_DATABASE=RTL 8153 USB 3.0 hub with gigabit ethernet + ++usb:v0BDAp5411* ++ ID_MODEL_FROM_DATABASE=RTS5411 Hub ++ ++usb:v0BDAp568C* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam HD ++ + usb:v0BDAp570C* + ID_MODEL_FROM_DATABASE=Asus laptop camera + +@@ -38192,12 +40631,24 @@ usb:v0BDAp5751* + usb:v0BDAp5775* + ID_MODEL_FROM_DATABASE=HP "Truevision HD" laptop camera + ++usb:v0BDAp5776* ++ ID_MODEL_FROM_DATABASE=HP Truevision HD integrated webcam ++ + usb:v0BDAp57B3* + ID_MODEL_FROM_DATABASE=Acer 640 × 480 laptop camera + ++usb:v0BDAp57CC* ++ ID_MODEL_FROM_DATABASE=HD Webcam - Realtek Semiconductor ++ ++usb:v0BDAp57CF* ++ ID_MODEL_FROM_DATABASE=HD WebCam ++ + usb:v0BDAp57DA* + ID_MODEL_FROM_DATABASE=Built-In Video Camera + ++usb:v0BDAp58C2* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam HD ++ + usb:v0BDAp58C8* + ID_MODEL_FROM_DATABASE=Integrated Webcam HD + +@@ -38258,15 +40709,60 @@ usb:v0BDAp8198* + usb:v0BDAp8199* + ID_MODEL_FROM_DATABASE=RTL8187SU 802.11g WLAN Adapter + ++usb:v0BDAp8723* ++ ID_MODEL_FROM_DATABASE=RTL8723A Bluetooth ++ + usb:v0BDAp8812* + ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter + + usb:v0BDAp8813* + ID_MODEL_FROM_DATABASE=RTL8814AU 802.11a/b/g/n/ac Wireless Adapter + ++usb:v0BDAp881A* ++ ID_MODEL_FROM_DATABASE=RTL8812AU-VS 802.11a/b/g/n/ac 2T2R DB WLAN Adapter ++ ++usb:v0BDAp8821* ++ ID_MODEL_FROM_DATABASE=RTL8821A Bluetooth ++ ++usb:v0BDAp9210* ++ ID_MODEL_FROM_DATABASE=RTL9210 M.2 NVME Adapter ++ + usb:v0BDApA811* + ID_MODEL_FROM_DATABASE=RTL8811AU 802.11a/b/g/n/ac WLAN Adapter + ++usb:v0BDApB009* ++ ID_MODEL_FROM_DATABASE=Realtek Bluetooth 4.2 Adapter ++ ++usb:v0BDApB00A* ++ ID_MODEL_FROM_DATABASE=Realtek Bluetooth 4.2 Adapter ++ ++usb:v0BDApB00B* ++ ID_MODEL_FROM_DATABASE=Realtek Bluetooth 4.2 Adapter ++ ++usb:v0BDApB023* ++ ID_MODEL_FROM_DATABASE=RTL8822BE Bluetooth 4.2 Adapter ++ ++usb:v0BDApB711* ++ ID_MODEL_FROM_DATABASE=RTL8188GU 802.11n WLAN Adapter (After Modeswitch) ++ ++usb:v0BDApB720* ++ ID_MODEL_FROM_DATABASE=RTL8723BU 802.11b/g/n WLAN Adapter ++ ++usb:v0BDApB723* ++ ID_MODEL_FROM_DATABASE=RTL8723B Bluetooth ++ ++usb:v0BDApB728* ++ ID_MODEL_FROM_DATABASE=RTL8723B Bluetooth ++ ++usb:v0BDApB72A* ++ ID_MODEL_FROM_DATABASE=RTL8723B Bluetooth ++ ++usb:v0BDApB812* ++ ID_MODEL_FROM_DATABASE=RTL88x2bu [AC1200 Techkey] ++ ++usb:v0BDApF179* ++ ID_MODEL_FROM_DATABASE=RTL8188FTV 802.11b/g/n 1T1R 2.4G WLAN Adapter ++ + usb:v0BDB* + ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV + +@@ -38304,7 +40800,7 @@ usb:v0BDBp190B* + ID_MODEL_FROM_DATABASE=C3607w v2 Mobile Broadband Module + + usb:v0BDBp1926* +- ID_MODEL_FROM_DATABASE=H5321 gw Mobile Broadband Driver ++ ID_MODEL_FROM_DATABASE=H5321 gw Mobile Broadband Module + + usb:v0BDC* + ID_VENDOR_FROM_DATABASE=Y Media Corp. +@@ -38345,6 +40841,9 @@ usb:v0BEF* + usb:v0BF0* + ID_VENDOR_FROM_DATABASE=Pace Micro Technology PLC + ++usb:v0BF0pC010* ++ ID_MODEL_FROM_DATABASE=EHD100SD ++ + usb:v0BF1* + ID_VENDOR_FROM_DATABASE=Intracom S.A. + +@@ -38408,6 +40907,12 @@ usb:v0BF8p1017* + usb:v0BF8p101F* + ID_MODEL_FROM_DATABASE=Fujitsu Full HD Pro Webcam + ++usb:v0BFB* ++ ID_VENDOR_FROM_DATABASE=Grass Valley Group ++ ++usb:v0BFBp0200* ++ ID_MODEL_FROM_DATABASE=TURBO iDDR Front Panel ++ + usb:v0BFD* + ID_VENDOR_FROM_DATABASE=Kvaser AB + +@@ -38453,6 +40958,9 @@ usb:v0C09pA5A5* + usb:v0C0A* + ID_VENDOR_FROM_DATABASE=Highpoint Technologies, Inc. + ++usb:v0C0Ap6124* ++ ID_MODEL_FROM_DATABASE=RocketStor 6124V ++ + usb:v0C0B* + ID_VENDOR_FROM_DATABASE=Dura Micro, Inc. (Acomdata) + +@@ -38502,7 +41010,7 @@ usb:v0C12* + ID_VENDOR_FROM_DATABASE=Zeroplus + + usb:v0C12p0005* +- ID_MODEL_FROM_DATABASE=PSX Vibration Feedback Converter ++ ID_MODEL_FROM_DATABASE=PSX Vibration Feedback Converter / Intec Wireless Controller for Xbox + + usb:v0C12p0030* + ID_MODEL_FROM_DATABASE=PSX Vibration Feedback Converter +@@ -38511,7 +41019,7 @@ usb:v0C12p700E* + ID_MODEL_FROM_DATABASE=Logic Analyzer (LAP-C-16032) + + usb:v0C12p8801* +- ID_MODEL_FROM_DATABASE=Xbox Controller ++ ID_MODEL_FROM_DATABASE=Nyko Xbox Controller + + usb:v0C12p8802* + ID_MODEL_FROM_DATABASE=Xbox Controller +@@ -38567,6 +41075,12 @@ usb:v0C1B* + usb:v0C1C* + ID_VENDOR_FROM_DATABASE=Hang Zhou Silan Electronics Co., Ltd + ++usb:v0C1F* ++ ID_VENDOR_FROM_DATABASE=Magicard ++ ++usb:v0C1Fp1800* ++ ID_MODEL_FROM_DATABASE=Tango 2E ++ + usb:v0C22* + ID_VENDOR_FROM_DATABASE=Tally Printer Corp. + +@@ -38630,9 +41144,15 @@ usb:v0C26* + usb:v0C26p0018* + ID_MODEL_FROM_DATABASE=USB-Serial Controller [Icom Inc. OPC-478UC] + ++usb:v0C26p002B* ++ ID_MODEL_FROM_DATABASE=Icom Inc. IC-R30 ++ + usb:v0C27* + ID_VENDOR_FROM_DATABASE=RFIDeas, Inc + ++usb:v0C27p232A* ++ ID_MODEL_FROM_DATABASE=pcProx Plus RFID Reader (CDC serial) ++ + usb:v0C27p3BFA* + ID_MODEL_FROM_DATABASE=pcProx Card Reader + +@@ -38657,6 +41177,9 @@ usb:v0C2Ep0700* + usb:v0C2Ep0720* + ID_MODEL_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (bi-directional serial mode) + ++usb:v0C2Ep0A64* ++ ID_MODEL_FROM_DATABASE=[Stratos 2700] ++ + usb:v0C2Ep0B61* + ID_MODEL_FROM_DATABASE=Vuquest 3310g + +@@ -38702,6 +41225,12 @@ usb:v0C3D* + usb:v0C3E* + ID_VENDOR_FROM_DATABASE=Nextcell, Inc. + ++usb:v0C40* ++ ID_VENDOR_FROM_DATABASE=ELMCU ++ ++usb:v0C40p8000* ++ ID_MODEL_FROM_DATABASE=2.4GHz receiver ++ + usb:v0C44* + ID_VENDOR_FROM_DATABASE=Motorola iDEN + +@@ -38795,6 +41324,15 @@ usb:v0C45p1158* + usb:v0C45p184C* + ID_MODEL_FROM_DATABASE=VoIP Phone + ++usb:v0C45p1A90* ++ ID_MODEL_FROM_DATABASE=2M pixel Microscope Camera (with capture button) [Andonstar V160] ++ ++usb:v0C45p5004* ++ ID_MODEL_FROM_DATABASE=Redragon Mitra RGB Keyboard ++ ++usb:v0C45p5101* ++ ID_MODEL_FROM_DATABASE=2.4G Wireless Device [Rii MX3] ++ + usb:v0C45p6001* + ID_MODEL_FROM_DATABASE=Genius VideoCAM NB + +@@ -39086,12 +41624,18 @@ usb:v0C45p6300* + usb:v0C45p6310* + ID_MODEL_FROM_DATABASE=Sonix USB 2.0 Camera + ++usb:v0C45p6321* ++ ID_MODEL_FROM_DATABASE=HP Integrated Webcam ++ + usb:v0C45p6340* + ID_MODEL_FROM_DATABASE=Camera + + usb:v0C45p6341* + ID_MODEL_FROM_DATABASE=Defender G-Lens 2577 HD720p Camera + ++usb:v0C45p6366* ++ ID_MODEL_FROM_DATABASE=Webcam Vitade AF ++ + usb:v0C45p63E0* + ID_MODEL_FROM_DATABASE=Sonix Integrated Webcam + +@@ -39131,6 +41675,9 @@ usb:v0C45p6480* + usb:v0C45p648B* + ID_MODEL_FROM_DATABASE=Integrated Webcam + ++usb:v0C45p64AD* ++ ID_MODEL_FROM_DATABASE=Dell Laptop Integrated Webcam HD ++ + usb:v0C45p64BD* + ID_MODEL_FROM_DATABASE=Sony Visual Communication Camera + +@@ -39143,12 +41690,24 @@ usb:v0C45p64D2* + usb:v0C45p651B* + ID_MODEL_FROM_DATABASE=HP Webcam + ++usb:v0C45p652F* ++ ID_MODEL_FROM_DATABASE=Backlit Gaming Keyboard ++ + usb:v0C45p6705* + ID_MODEL_FROM_DATABASE=Integrated HD Webcam + ++usb:v0C45p670C* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam HD ++ + usb:v0C45p6710* + ID_MODEL_FROM_DATABASE=Integrated Webcam + ++usb:v0C45p6712* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam HD ++ ++usb:v0C45p671D* ++ ID_MODEL_FROM_DATABASE=Integrated_Webcam_HD ++ + usb:v0C45p7401* + ID_MODEL_FROM_DATABASE=TEMPer Temperature Sensor + +@@ -39536,6 +42095,9 @@ usb:v0C76p1605* + usb:v0C76p1607* + ID_MODEL_FROM_DATABASE=audio controller + ++usb:v0C76p5663* ++ ID_MODEL_FROM_DATABASE=Audio Device ++ + usb:v0C77* + ID_VENDOR_FROM_DATABASE=Sipix Group, Ltd + +@@ -39620,6 +42182,21 @@ usb:v0C9A* + usb:v0C9B* + ID_VENDOR_FROM_DATABASE=Jobin Yvon, Inc. + ++usb:v0C9C* ++ ID_VENDOR_FROM_DATABASE=Brand Innovators BV ++ ++usb:v0C9Cp1511* ++ ID_MODEL_FROM_DATABASE=BI-1511 Laser Simulator ++ ++usb:v0C9Cp1512* ++ ID_MODEL_FROM_DATABASE=BI-1512 Syncbus Monitor ++ ++usb:v0C9Cp1514* ++ ID_MODEL_FROM_DATABASE=BI-1514 HPC ++ ++usb:v0C9Cp1532* ++ ID_MODEL_FROM_DATABASE=BI-1532 GPC ++ + usb:v0C9D* + ID_VENDOR_FROM_DATABASE=SemTek + +@@ -39662,6 +42239,12 @@ usb:v0CA6p3050* + usb:v0CA7* + ID_VENDOR_FROM_DATABASE=Information Systems Laboratories + ++usb:v0CAA* ++ ID_VENDOR_FROM_DATABASE=Allied Telesis KK. ++ ++usb:v0CAAp3001* ++ ID_MODEL_FROM_DATABASE=AT-VT-Kit3 Serial Adapter ++ + usb:v0CAD* + ID_VENDOR_FROM_DATABASE=Motorola CGISS + +@@ -39681,7 +42264,7 @@ usb:v0CADp1602* + ID_MODEL_FROM_DATABASE=IMPRES Battery Data Reader + + usb:v0CADp9001* +- ID_MODEL_FROM_DATABASE=PowerPad Pocket PC Device ++ ID_MODEL_FROM_DATABASE=PowerPad Pocket PC Device + + usb:v0CAE* + ID_VENDOR_FROM_DATABASE=Ascom Business Systems, Ltd +@@ -39899,6 +42482,9 @@ usb:v0CCDp00A9* + usb:v0CCDp00B3* + ID_MODEL_FROM_DATABASE=NOXON DAB/DAB+ Stick + ++usb:v0CCDp00B9* ++ ID_MODEL_FROM_DATABASE=WDR DAB/DAB+ Stick ++ + usb:v0CCDp00E0* + ID_MODEL_FROM_DATABASE=NOXON DAB/DAB+ Stick V2 + +@@ -39911,6 +42497,9 @@ usb:v0CCDp0105* + usb:v0CCDp10A7* + ID_MODEL_FROM_DATABASE=TerraTec G3 + ++usb:v0CCDp10AD* ++ ID_MODEL_FROM_DATABASE=Cinergy H5 Rev. 2 ++ + usb:v0CD4* + ID_VENDOR_FROM_DATABASE=Bang Olufsen + +@@ -40115,6 +42704,9 @@ usb:v0CF3p0005* + usb:v0CF3p0006* + ID_MODEL_FROM_DATABASE=AR5523 (no firmware) + ++usb:v0CF3p0036* ++ ID_MODEL_FROM_DATABASE=AR9462 Bluetooth ++ + usb:v0CF3p1001* + ID_MODEL_FROM_DATABASE=Thomson TG121N [Atheros AR9001U-(2)NG] + +@@ -40148,6 +42740,9 @@ usb:v0CF3p3007* + usb:v0CF3p3008* + ID_MODEL_FROM_DATABASE=Bluetooth (AR3011) + ++usb:v0CF3p311D* ++ ID_MODEL_FROM_DATABASE=Bluetooth ++ + usb:v0CF3p311F* + ID_MODEL_FROM_DATABASE=AR3012 Bluetooth + +@@ -40160,6 +42755,9 @@ usb:v0CF3p9170* + usb:v0CF3p9271* + ID_MODEL_FROM_DATABASE=AR9271 802.11n + ++usb:v0CF3p9378* ++ ID_MODEL_FROM_DATABASE=QCA9377-7 ++ + usb:v0CF3pB002* + ID_MODEL_FROM_DATABASE=Ubiquiti WiFiStation 802.11n [Atheros AR9271] + +@@ -40169,6 +42767,9 @@ usb:v0CF3pB003* + usb:v0CF3pE006* + ID_MODEL_FROM_DATABASE=Dell Wireless 1802 Bluetooth 4.0 LE + ++usb:v0CF3pE300* ++ ID_MODEL_FROM_DATABASE=QCA61x4 Bluetooth 4.0 ++ + usb:v0CF4* + ID_VENDOR_FROM_DATABASE=Fomtex Corp. + +@@ -40274,9 +42875,27 @@ usb:v0D16p0002* + usb:v0D16p0004* + ID_MODEL_FROM_DATABASE=Photo Printer 63xPL/PS + ++usb:v0D16p0007* ++ ID_MODEL_FROM_DATABASE=P510K ++ ++usb:v0D16p0009* ++ ID_MODEL_FROM_DATABASE=P72x Series ++ ++usb:v0D16p000A* ++ ID_MODEL_FROM_DATABASE=P728L ++ ++usb:v0D16p000B* ++ ID_MODEL_FROM_DATABASE=P510L ++ ++usb:v0D16p000D* ++ ID_MODEL_FROM_DATABASE=P518A ++ + usb:v0D16p000E* + ID_MODEL_FROM_DATABASE=P910L + ++usb:v0D16p0010* ++ ID_MODEL_FROM_DATABASE=M610 ++ + usb:v0D16p0100* + ID_MODEL_FROM_DATABASE=Photo Printer 63xPL/PS + +@@ -40292,9 +42911,45 @@ usb:v0D16p0104* + usb:v0D16p0105* + ID_MODEL_FROM_DATABASE=Photo Printer 64xPS + ++usb:v0D16p010E* ++ ID_MODEL_FROM_DATABASE=P510S ++ ++usb:v0D16p0110* ++ ID_MODEL_FROM_DATABASE=P110S ++ ++usb:v0D16p0111* ++ ID_MODEL_FROM_DATABASE=P510Si ++ ++usb:v0D16p0112* ++ ID_MODEL_FROM_DATABASE=P518S ++ + usb:v0D16p0200* + ID_MODEL_FROM_DATABASE=Photo Printer 64xDL + ++usb:v0D16p0309* ++ ID_MODEL_FROM_DATABASE=CS-200e ++ ++usb:v0D16p030A* ++ ID_MODEL_FROM_DATABASE=CS-220e ++ ++usb:v0D16p0501* ++ ID_MODEL_FROM_DATABASE=P75x Series ++ ++usb:v0D16p0502* ++ ID_MODEL_FROM_DATABASE=P52x Series ++ ++usb:v0D16p0503* ++ ID_MODEL_FROM_DATABASE=P310L ++ ++usb:v0D16p050A* ++ ID_MODEL_FROM_DATABASE=P310W ++ ++usb:v0D16p050F* ++ ID_MODEL_FROM_DATABASE=P530D ++ ++usb:v0D16p0800* ++ ID_MODEL_FROM_DATABASE=X610 ++ + usb:v0D17* + ID_VENDOR_FROM_DATABASE=NALTEC, Inc. + +@@ -40310,6 +42965,12 @@ usb:v0D28* + usb:v0D28p0204* + ID_MODEL_FROM_DATABASE=ARM mbed + ++usb:v0D2F* ++ ID_VENDOR_FROM_DATABASE=Andamiro ++ ++usb:v0D2Fp0002* ++ ID_MODEL_FROM_DATABASE=Pump It Up Pad ++ + usb:v0D32* + ID_VENDOR_FROM_DATABASE=Leo Hui Electric Wire & Cable Co., Ltd + +@@ -40400,6 +43061,9 @@ usb:v0D49* + usb:v0D49p3000* + ID_MODEL_FROM_DATABASE=Drive + ++usb:v0D49p3005* ++ ID_MODEL_FROM_DATABASE=Personal Storage 3000LS ++ + usb:v0D49p3010* + ID_MODEL_FROM_DATABASE=3000LE Drive + +@@ -40469,6 +43133,9 @@ usb:v0D50* + usb:v0D50p0011* + ID_MODEL_FROM_DATABASE=USB-Temp2 Thermometer + ++usb:v0D50p0030* ++ ID_MODEL_FROM_DATABASE=Multiplexer ++ + usb:v0D50p0040* + ID_MODEL_FROM_DATABASE=F4 foot switch + +@@ -40490,6 +43157,12 @@ usb:v0D56* + usb:v0D57* + ID_VENDOR_FROM_DATABASE=Solomon Microtech, Ltd + ++usb:v0D59* ++ ID_VENDOR_FROM_DATABASE=TRC Simulators b.v. ++ ++usb:v0D59p02A8* ++ ID_MODEL_FROM_DATABASE=Digital Clock ++ + usb:v0D5C* + ID_VENDOR_FROM_DATABASE=SMC Networks, Inc. + +@@ -40547,6 +43220,9 @@ usb:v0D62p2050* + usb:v0D62p2106* + ID_MODEL_FROM_DATABASE=Dell L20U Multimedia Keyboard + ++usb:v0D62p910E* ++ ID_MODEL_FROM_DATABASE=HP Business Slim Keyboard ++ + usb:v0D62pA100* + ID_MODEL_FROM_DATABASE=Optical Mouse + +@@ -40754,6 +43430,9 @@ usb:v0D8Cp0002* + usb:v0D8Cp0003* + ID_MODEL_FROM_DATABASE=Sound Device + ++usb:v0D8Cp0004* ++ ID_MODEL_FROM_DATABASE=CM6631A Audio Processor ++ + usb:v0D8Cp0005* + ID_MODEL_FROM_DATABASE=Blue Snowball + +@@ -41063,6 +43742,9 @@ usb:v0DA4* + usb:v0DA4p0001* + ID_MODEL_FROM_DATABASE=Interface + ++usb:v0DA4p0003* ++ ID_MODEL_FROM_DATABASE=FlowLink ++ + usb:v0DA4p0008* + ID_MODEL_FROM_DATABASE=Loop + +@@ -41195,6 +43877,9 @@ usb:v0DB0pB970* + usb:v0DB0pB97A* + ID_MODEL_FROM_DATABASE=Bluetooth EDR Device + ++usb:v0DB0pFFFF* ++ ID_MODEL_FROM_DATABASE=Bluetooth Adapter in DFU mode ++ + usb:v0DB1* + ID_VENDOR_FROM_DATABASE=Wen Te Electronics Co., Ltd + +@@ -41222,6 +43907,9 @@ usb:v0DB5p013B* + usb:v0DB5p0160* + ID_MODEL_FROM_DATABASE=NFC and Smartcard Module (NSM) + ++usb:v0DB5p0164* ++ ID_MODEL_FROM_DATABASE=NFC and Smartcard Module (NSM)with 4 SAM slots ++ + usb:v0DB7* + ID_VENDOR_FROM_DATABASE=ELCON Systemtechnik + +@@ -41318,6 +44006,9 @@ usb:v0DC4p0209* + usb:v0DC4p020A* + ID_MODEL_FROM_DATABASE=Oyen Digital MiniPro 2.5" hard drive enclosure + ++usb:v0DC4p0290* ++ ID_MODEL_FROM_DATABASE=Mass Storage Device [NT2 U3.1] ++ + usb:v0DC5* + ID_VENDOR_FROM_DATABASE=SDK Co., Ltd + +@@ -41360,6 +44051,9 @@ usb:v0DD3* + usb:v0DD4* + ID_VENDOR_FROM_DATABASE=Custom Engineering SPA + ++usb:v0DD4p0237* ++ ID_MODEL_FROM_DATABASE=K80 80mm Thermal Printer ++ + usb:v0DD5* + ID_VENDOR_FROM_DATABASE=California Micro Devices + +@@ -41369,6 +44063,9 @@ usb:v0DD7* + usb:v0DD8* + ID_VENDOR_FROM_DATABASE=Netac Technology Co., Ltd + ++usb:v0DD8p0562* ++ ID_MODEL_FROM_DATABASE=Netac Portable SSD Z6s ++ + usb:v0DD8p1060* + ID_MODEL_FROM_DATABASE=USB-CF-Card + +@@ -41376,7 +44073,7 @@ usb:v0DD8pE007* + ID_MODEL_FROM_DATABASE=OnlyDisk U222 Pendrive + + usb:v0DD8pF607* +- ID_MODEL_FROM_DATABASE=OnlyDisk U208 1G flash drive [U-SAFE] ++ ID_MODEL_FROM_DATABASE=OnlyDisk U210 1G flash drive [U-SAFE] + + usb:v0DD9* + ID_VENDOR_FROM_DATABASE=HighSpeed Surfing +@@ -41699,9 +44396,15 @@ usb:v0DFC* + usb:v0DFCp0001* + ID_MODEL_FROM_DATABASE=Touchscreen + ++usb:v0DFCp0003* ++ ID_MODEL_FROM_DATABASE=MultiTouch TouchScreen(Dualtouch) ++ + usb:v0DFCp0101* + ID_MODEL_FROM_DATABASE=5-point Touch Screen + ++usb:v0DFCpD107* ++ ID_MODEL_FROM_DATABASE=MultiTouch TouchScreen ++ + usb:v0E03* + ID_VENDOR_FROM_DATABASE=Nippon Systemware Co., Ltd + +@@ -41750,6 +44453,9 @@ usb:v0E0Fp0005* + usb:v0E0Fp0006* + ID_MODEL_FROM_DATABASE=Virtual Keyboard + ++usb:v0E0Fp000A* ++ ID_MODEL_FROM_DATABASE=Virtual Sensors ++ + usb:v0E0Fp8001* + ID_MODEL_FROM_DATABASE=Root Hub + +@@ -41774,6 +44480,9 @@ usb:v0E1A* + usb:v0E1B* + ID_VENDOR_FROM_DATABASE=Crewave + ++usb:v0E1E* ++ ID_VENDOR_FROM_DATABASE=Green Hills Software ++ + usb:v0E20* + ID_VENDOR_FROM_DATABASE=Pegasus Technologies Ltd. + +@@ -41966,8 +44675,14 @@ usb:v0E4C* + usb:v0E4Cp1097* + ID_MODEL_FROM_DATABASE=Gamester Controller + ++usb:v0E4Cp1103* ++ ID_MODEL_FROM_DATABASE=Gamester Reflex ++ + usb:v0E4Cp2390* +- ID_MODEL_FROM_DATABASE=Games Jtech Controller ++ ID_MODEL_FROM_DATABASE=Jtech Controller ++ ++usb:v0E4Cp3510* ++ ID_MODEL_FROM_DATABASE=Gamester for Xbox + + usb:v0E4Cp7288* + ID_MODEL_FROM_DATABASE=funkey reader +@@ -42068,6 +44783,9 @@ usb:v0E6A* + usb:v0E6Ap0101* + ID_MODEL_FROM_DATABASE=MA100 [USB-UART Bridge IC] + ++usb:v0E6Ap02C0* ++ ID_MODEL_FROM_DATABASE=Defender Gaming Keyboard ++ + usb:v0E6Ap030B* + ID_MODEL_FROM_DATABASE=Truly Ergonomic Computer Keyboard (Device Firmware Update mode) + +@@ -42092,9 +44810,90 @@ usb:v0E6Fp0005* + usb:v0E6Fp0006* + ID_MODEL_FROM_DATABASE=Edge wireless Controller + ++usb:v0E6Fp0008* ++ ID_MODEL_FROM_DATABASE=After Glow Pro Controller ++ ++usb:v0E6Fp0105* ++ ID_MODEL_FROM_DATABASE=Disney's High School Musical 3 Dance Pad for Xbox 360 ++ ++usb:v0E6Fp0113* ++ ID_MODEL_FROM_DATABASE=Afterglow AX.1 Gamepad ++ ++usb:v0E6Fp011F* ++ ID_MODEL_FROM_DATABASE=Rock Candy Wired Controller for Xbox 360 ++ + usb:v0E6Fp0128* + ID_MODEL_FROM_DATABASE=Wireless PS3 Controller + ++usb:v0E6Fp0131* ++ ID_MODEL_FROM_DATABASE=PDP EA Sports Controller ++ ++usb:v0E6Fp0133* ++ ID_MODEL_FROM_DATABASE=Wired Controller ++ ++usb:v0E6Fp0139* ++ ID_MODEL_FROM_DATABASE=Afterglow Prismatic Wired Controller for Xbox One ++ ++usb:v0E6Fp013A* ++ ID_MODEL_FROM_DATABASE=PDP Xbox One Controller ++ ++usb:v0E6Fp0146* ++ ID_MODEL_FROM_DATABASE=Rock Candy Wired Controller for Xbox One ++ ++usb:v0E6Fp0147* ++ ID_MODEL_FROM_DATABASE=PDP Marvel Controller for Xbox One ++ ++usb:v0E6Fp015C* ++ ID_MODEL_FROM_DATABASE=PDP Arcade Stick for Xbox One ++ ++usb:v0E6Fp0161* ++ ID_MODEL_FROM_DATABASE=Camo Wired Controller for Xbox One ++ ++usb:v0E6Fp0162* ++ ID_MODEL_FROM_DATABASE=Xbox One Wired Controller ++ ++usb:v0E6Fp0163* ++ ID_MODEL_FROM_DATABASE=Legendary Collection Deliverer of Truth ++ ++usb:v0E6Fp0164* ++ ID_MODEL_FROM_DATABASE=Battlefield 1 Wired Controller for Xbox One ++ ++usb:v0E6Fp0165* ++ ID_MODEL_FROM_DATABASE=Titanfall 2 Wired Controller for Xbox One ++ ++usb:v0E6Fp0201* ++ ID_MODEL_FROM_DATABASE=Pelican PL-3601 ++ ++usb:v0E6Fp0213* ++ ID_MODEL_FROM_DATABASE=Afterglow Gamepad for Xbox 360 ++ ++usb:v0E6Fp021F* ++ ID_MODEL_FROM_DATABASE=Rock Candy Gamepad for Xbox 360 ++ ++usb:v0E6Fp0246* ++ ID_MODEL_FROM_DATABASE=Rock Candy Gamepad for Xbox One ++ ++usb:v0E6Fp0301* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v0E6Fp0346* ++ ID_MODEL_FROM_DATABASE=Rock Candy Wired Controller for Xbox One ++ ++usb:v0E6Fp0401* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v0E6Fp0413* ++ ID_MODEL_FROM_DATABASE=Afterglow AX.1 Gamepad for Xbox 360 ++ ++usb:v0E6Fp0501* ++ ID_MODEL_FROM_DATABASE=Wired Controller ++ ++usb:v0E6FpF501* ++ ID_MODEL_FROM_DATABASE=Hi-TEC Essentials Wired Gamepad ++ ++usb:v0E6FpF900* ++ ID_MODEL_FROM_DATABASE=Afterglow AX.1 ++ + usb:v0E70* + ID_VENDOR_FROM_DATABASE=Tokyo Electronic Industry Co., Ltd + +@@ -42161,6 +44960,9 @@ usb:v0E8C* + usb:v0E8D* + ID_VENDOR_FROM_DATABASE=MediaTek Inc. + ++usb:v0E8Dp0002* ++ ID_MODEL_FROM_DATABASE=phone (mass storage mode) [Doro Primo 413] ++ + usb:v0E8Dp0003* + ID_MODEL_FROM_DATABASE=MT6227 phone + +@@ -42168,7 +44970,7 @@ usb:v0E8Dp0004* + ID_MODEL_FROM_DATABASE=MT6227 phone + + usb:v0E8Dp0023* +- ID_MODEL_FROM_DATABASE=S103 ++ ID_MODEL_FROM_DATABASE=S103 / Powertel M6200 + + usb:v0E8Dp00A5* + ID_MODEL_FROM_DATABASE=GSM modem [Medion Surfstick Model:S4222] +@@ -42179,18 +44981,30 @@ usb:v0E8Dp1806* + usb:v0E8Dp1836* + ID_MODEL_FROM_DATABASE=Samsung SE-S084 Super WriteMaster Slim External DVD writer + ++usb:v0E8Dp1887* ++ ID_MODEL_FROM_DATABASE=Slim Portable DVD Writer ++ + usb:v0E8Dp1956* + ID_MODEL_FROM_DATABASE=Samsung SE-506 Portable BluRay Disc Writer + + usb:v0E8Dp2000* + ID_MODEL_FROM_DATABASE=MT65xx Preloader + ++usb:v0E8Dp2008* ++ ID_MODEL_FROM_DATABASE=Cyrus Technology CS 24 ++ + usb:v0E8Dp3329* + ID_MODEL_FROM_DATABASE=Qstarz BT-Q1000XT + ++usb:v0E8Dp7612* ++ ID_MODEL_FROM_DATABASE=MT7612U 802.11a/b/g/n/ac Wireless Adapter ++ + usb:v0E8Dp763E* + ID_MODEL_FROM_DATABASE=MT7630e Bluetooth Adapter + ++usb:v0E8Dp7668* ++ ID_MODEL_FROM_DATABASE=MT7668 2x2 Dual Band Dual Concurrent 802.11a/b/g/n/ac WiFi with MU-MIMO and Bluetooth 5.0 Radios ++ + usb:v0E8F* + ID_VENDOR_FROM_DATABASE=GreenAsia Inc. + +@@ -42215,6 +45029,9 @@ usb:v0E8Fp0022* + usb:v0E8Fp0201* + ID_MODEL_FROM_DATABASE=SmartJoy Frag Xpad/PS2 adaptor + ++usb:v0E8Fp3008* ++ ID_MODEL_FROM_DATABASE=Xbox Controller ++ + usb:v0E8Fp300A* + ID_MODEL_FROM_DATABASE=steering Wheel + +@@ -42281,6 +45098,9 @@ usb:v0EA0p2153* + usb:v0EA0p2168* + ID_MODEL_FROM_DATABASE=Transcend JetFlash 2.0 / Astone USB Drive / Intellegent Stick 2.0 + ++usb:v0EA0p2213* ++ ID_MODEL_FROM_DATABASE=WinDroid N287 AH7N2502.013317 ++ + usb:v0EA0p6803* + ID_MODEL_FROM_DATABASE=OTI-6803 Flash Disk + +@@ -42342,7 +45162,7 @@ usb:v0EB8p2200* + ID_MODEL_FROM_DATABASE=Ariva Scale + + usb:v0EB8pF000* +- ID_MODEL_FROM_DATABASE=PS60 Scale ++ ID_MODEL_FROM_DATABASE=BC60 Scale + + usb:v0EBB* + ID_VENDOR_FROM_DATABASE=Thermo Fisher Scientific +@@ -42468,7 +45288,7 @@ usb:v0EEF* + ID_VENDOR_FROM_DATABASE=D-WAV Scientific Co., Ltd + + usb:v0EEFp0001* +- ID_MODEL_FROM_DATABASE=eGalax TouchScreen ++ ID_MODEL_FROM_DATABASE=Titan6001 Surface Acoustic Wave Touchscreen Controller [eGalax] + + usb:v0EEFp0002* + ID_MODEL_FROM_DATABASE=Touchscreen Controller(Professional) +@@ -42476,9 +45296,18 @@ usb:v0EEFp0002* + usb:v0EEFp7200* + ID_MODEL_FROM_DATABASE=Touchscreen Controller + ++usb:v0EEFp7904* ++ ID_MODEL_FROM_DATABASE=Multitouch Capacitive Touchscreen eGalaxTouch EXC7904-21v00_T13 [IIyama Prolite T1932-MSC] ++ + usb:v0EEFpA802* + ID_MODEL_FROM_DATABASE=eGalaxTouch EXC7920 + ++usb:v0EEFpB10E* ++ ID_MODEL_FROM_DATABASE=eGalaxTouch EXC3000 ++ ++usb:v0EEFpC000* ++ ID_MODEL_FROM_DATABASE=Multitouch Capacitive Touchscreen eGalaxTouch EXC3188-4643-08.00.00.00 Sirius_4643 PCAP3188UR Series [IIyama Prolite PLT1932MSC] ++ + usb:v0EF0* + ID_VENDOR_FROM_DATABASE=Hitachi Cable, Ltd + +@@ -42533,9 +45362,39 @@ usb:v0F0C* + usb:v0F0D* + ID_VENDOR_FROM_DATABASE=Hori Co., Ltd + ++usb:v0F0Dp000A* ++ ID_MODEL_FROM_DATABASE=Dead or Alive 4 FightStick for Xbox 360 ++ ++usb:v0F0Dp000C* ++ ID_MODEL_FROM_DATABASE=Horipad EX Turbo for Xbox 360 ++ ++usb:v0F0Dp000D* ++ ID_MODEL_FROM_DATABASE=Fighting Stick EX2 for Xbox 360 ++ + usb:v0F0Dp0011* + ID_MODEL_FROM_DATABASE=Real Arcade Pro 3 + ++usb:v0F0Dp0016* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro.EX for Xbox 360 ++ ++usb:v0F0Dp001B* ++ ID_MODEL_FROM_DATABASE=Real Aracde Pro.VX ++ ++usb:v0F0Dp0063* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro Hayabusa for Xbox One ++ ++usb:v0F0Dp0067* ++ ID_MODEL_FROM_DATABASE=Horipad One ++ ++usb:v0F0Dp0078* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro V Kai for Xbox One / Xbox 360 ++ ++usb:v0F0Dp0090* ++ ID_MODEL_FROM_DATABASE=Horipad Ultimate ++ ++usb:v0F0Dp00C1* ++ ID_MODEL_FROM_DATABASE=HORIPAD for Nintendo Switch ++ + usb:v0F0E* + ID_VENDOR_FROM_DATABASE=Energy Full Corp. + +@@ -42671,15 +45530,24 @@ usb:v0F30* + usb:v0F30p001C* + ID_MODEL_FROM_DATABASE=PS3 Guitar Controller Dongle + ++usb:v0F30p010B* ++ ID_MODEL_FROM_DATABASE=Philips Recoil ++ + usb:v0F30p0110* + ID_MODEL_FROM_DATABASE=Dual Analog Rumble Pad + + usb:v0F30p0111* + ID_MODEL_FROM_DATABASE=Colour Rumble Pad + ++usb:v0F30p0202* ++ ID_MODEL_FROM_DATABASE=Joytech Advanced Controller ++ + usb:v0F30p0208* + ID_MODEL_FROM_DATABASE=Xbox & PC Gamepad + ++usb:v0F30p8888* ++ ID_MODEL_FROM_DATABASE=BigBen XBMiniPad Controller ++ + usb:v0F31* + ID_VENDOR_FROM_DATABASE=Chrysalis Development + +@@ -42695,6 +45563,9 @@ usb:v0F38* + usb:v0F39* + ID_VENDOR_FROM_DATABASE=TG3 Electronics + ++usb:v0F39p0404* ++ ID_MODEL_FROM_DATABASE=Recreated ZX Spectrum Keyboard ++ + usb:v0F39p0876* + ID_MODEL_FROM_DATABASE=Keyboard [87 Francium Pro] + +@@ -42728,6 +45599,12 @@ usb:v0F44pFF11* + usb:v0F44pFF12* + ID_MODEL_FROM_DATABASE=Liberty + ++usb:v0F49* ++ ID_VENDOR_FROM_DATABASE=Evolis SA ++ ++usb:v0F49p0A00* ++ ID_MODEL_FROM_DATABASE=Zenius ++ + usb:v0F4B* + ID_VENDOR_FROM_DATABASE=St. John Technology Co., Ltd + +@@ -42849,31 +45726,37 @@ usb:v0F6E* + ID_VENDOR_FROM_DATABASE=INTELLIGENT SYSTEMS + + usb:v0F6Ep0100* +- ID_MODEL_FROM_DATABASE=GameBoy Color Emulator ++ ID_MODEL_FROM_DATABASE=IS-CGB-EMULATOR + + usb:v0F6Ep0201* + ID_MODEL_FROM_DATABASE=GameBoy Advance Flash Gang Writer + + usb:v0F6Ep0202* +- ID_MODEL_FROM_DATABASE=GameBoy Advance Capture ++ ID_MODEL_FROM_DATABASE=IS-AGB-CAPTURE + + usb:v0F6Ep0300* +- ID_MODEL_FROM_DATABASE=Gamecube DOL Viewer ++ ID_MODEL_FROM_DATABASE=IS-DOL-VIEWER + + usb:v0F6Ep0400* +- ID_MODEL_FROM_DATABASE=NDS Emulator ++ ID_MODEL_FROM_DATABASE=IS-NITRO-EMULATOR + + usb:v0F6Ep0401* +- ID_MODEL_FROM_DATABASE=NDS UIC ++ ID_MODEL_FROM_DATABASE=IS-NITRO-UIC + + usb:v0F6Ep0402* +- ID_MODEL_FROM_DATABASE=NDS Writer ++ ID_MODEL_FROM_DATABASE=IS-NITRO-WRITER + + usb:v0F6Ep0403* +- ID_MODEL_FROM_DATABASE=NDS Capture ++ ID_MODEL_FROM_DATABASE=IS-NITRO-CAPTURE + + usb:v0F6Ep0404* +- ID_MODEL_FROM_DATABASE=NDS Emulator (Lite) ++ ID_MODEL_FROM_DATABASE=IS-NITRO-EMULATOR (DS Lite) ++ ++usb:v0F6Ep0500* ++ ID_MODEL_FROM_DATABASE=IS-TWL-DEBUGGER ++ ++usb:v0F6Ep0501* ++ ID_MODEL_FROM_DATABASE=IS-TWL-CAPTURE + + usb:v0F73* + ID_VENDOR_FROM_DATABASE=DFI +@@ -43028,6 +45911,9 @@ usb:v0FCAp8010* + usb:v0FCAp8011* + ID_MODEL_FROM_DATABASE=Blackberry Playbook (Connect to Mac mode) + ++usb:v0FCAp8014* ++ ID_MODEL_FROM_DATABASE=Blackberry Handheld Z30 ++ + usb:v0FCAp8020* + ID_MODEL_FROM_DATABASE=Blackberry Playbook (CD-Rom mode) + +@@ -43094,8 +45980,14 @@ usb:v0FCEp01BA* + usb:v0FCEp01BB* + ID_MODEL_FROM_DATABASE=D5803 [Xperia Z3 Compact] (MTP mode) + +-usb:v0FCEp0DDE* +- ID_MODEL_FROM_DATABASE=Xperia Mini Pro Bootloader ++usb:v0FCEp01E0* ++ ID_MODEL_FROM_DATABASE=F5122 [Xperia X dual] (MTP mode) ++ ++usb:v0FCEp01E8* ++ ID_MODEL_FROM_DATABASE=F5321 [Xperia X Compact] (MTP mode) ++ ++usb:v0FCEp01F9* ++ ID_MODEL_FROM_DATABASE=H8314 [Xperia XZ2 Compact] + + usb:v0FCEp1010* + ID_MODEL_FROM_DATABASE=WMC Modem +@@ -43145,6 +46037,9 @@ usb:v0FCEp518C* + usb:v0FCEp51A7* + ID_MODEL_FROM_DATABASE=D5503 (Xperia Z1 Compact) + ++usb:v0FCEp51E0* ++ ID_MODEL_FROM_DATABASE=F5122 [Xperia X dual] (developer mode) ++ + usb:v0FCEp614F* + ID_MODEL_FROM_DATABASE=Xperia X12 (debug mode) + +@@ -43163,12 +46058,30 @@ usb:v0FCEp7166* + usb:v0FCEp7177* + ID_MODEL_FROM_DATABASE=Xperia Ion [Tethering] + ++usb:v0FCEp71F4* ++ ID_MODEL_FROM_DATABASE=G8441 (Xperia XZ1 Compact) [Tethering] ++ ++usb:v0FCEp71F9* ++ ID_MODEL_FROM_DATABASE=H8314 [Xperia XZ2 Compact] (Tethering) ++ + usb:v0FCEp8004* + ID_MODEL_FROM_DATABASE=9000 Phone [Mass Storage] + ++usb:v0FCEp81F4* ++ ID_MODEL_FROM_DATABASE=G8441 (Xperia XZ1 Compact) [Tethering] ++ + usb:v0FCEpADDE* + ID_MODEL_FROM_DATABASE=C2005 (Xperia M dual) in service mode + ++usb:v0FCEpC1E0* ++ ID_MODEL_FROM_DATABASE=F5122 [Xperia X dual] (MIDI mode) ++ ++usb:v0FCEpC1E8* ++ ID_MODEL_FROM_DATABASE=F5321 [Xperia X Compact] (MIDI mode) ++ ++usb:v0FCEpC1F9* ++ ID_MODEL_FROM_DATABASE=H8314 [Xperia XZ2 Compact] (MIDI) ++ + usb:v0FCEpD008* + ID_MODEL_FROM_DATABASE=V800-Vodafone 802SE Phone + +@@ -43211,6 +46124,9 @@ usb:v0FCEpD065* + usb:v0FCEpD076* + ID_MODEL_FROM_DATABASE=W910i (Phone mode) + ++usb:v0FCEpD079* ++ ID_MODEL_FROM_DATABASE=K530 Phone ++ + usb:v0FCEpD089* + ID_MODEL_FROM_DATABASE=W580i Phone (mass storage) + +@@ -43415,6 +46331,18 @@ usb:v0FD9p0033* + usb:v0FD9p0037* + ID_MODEL_FROM_DATABASE=Video Capture v2 + ++usb:v0FD9p0060* ++ ID_MODEL_FROM_DATABASE=Stream Deck ++ ++usb:v0FD9p0063* ++ ID_MODEL_FROM_DATABASE=Stream Deck Mini ++ ++usb:v0FD9p006C* ++ ID_MODEL_FROM_DATABASE=Stream Deck XL ++ ++usb:v0FD9p006D* ++ ID_MODEL_FROM_DATABASE=Stream Deck original V2 ++ + usb:v0FDA* + ID_VENDOR_FROM_DATABASE=Quantec Networks GmbH + +@@ -43433,6 +46361,9 @@ usb:v0FDEpCA01* + usb:v0FDEpCA05* + ID_MODEL_FROM_DATABASE=CM160 + ++usb:v0FDEpCA08* ++ ID_MODEL_FROM_DATABASE=WMR300 Professional Weather System ++ + usb:v0FE0* + ID_VENDOR_FROM_DATABASE=Osterhout Design Group + +@@ -43520,6 +46451,9 @@ usb:v0FFC* + usb:v0FFCp0021* + ID_MODEL_FROM_DATABASE=Nord Stage 2 + ++usb:v0FFCp002A* ++ ID_MODEL_FROM_DATABASE=Nord Piano 4 ++ + usb:v0FFD* + ID_VENDOR_FROM_DATABASE=EarlySense + +@@ -43547,6 +46481,9 @@ usb:v1003p0003* + usb:v1003p0100* + ID_MODEL_FROM_DATABASE=SD9/SD10 + ++usb:v1003p8781* ++ ID_MODEL_FROM_DATABASE=Dock UD-01 ++ + usb:v1004* + ID_VENDOR_FROM_DATABASE=LG Electronics, Inc. + +@@ -43599,13 +46536,13 @@ usb:v1004p6300* + ID_MODEL_FROM_DATABASE=G2/Optimus Android Phone [Charge mode] + + usb:v1004p631C* +- ID_MODEL_FROM_DATABASE=G2/Optimus Android Phone [MTP mode] ++ ID_MODEL_FROM_DATABASE=LM-X420xxx/G2/Optimus Android Phone (charge mode) + + usb:v1004p631D* + ID_MODEL_FROM_DATABASE=Optimus Android Phone (Camera/PTP Mode) + + usb:v1004p631E* +- ID_MODEL_FROM_DATABASE=G2/Optimus Android Phone [Camera/PTP mode] ++ ID_MODEL_FROM_DATABASE=LM-X420xxx/G2/Optimus Android Phone (PTP/camera mode) + + usb:v1004p631F* + ID_MODEL_FROM_DATABASE=Optimus Android Phone (Charge Mode) +@@ -43614,10 +46551,13 @@ usb:v1004p633A* + ID_MODEL_FROM_DATABASE=Ultimate 2 Android Phone L41C + + usb:v1004p633E* +- ID_MODEL_FROM_DATABASE=G2/G3 Android Phone [MTP/PTP/Download mode] ++ ID_MODEL_FROM_DATABASE=LM-X420xxx/G2/G3 Android Phone (MTP/download mode) + + usb:v1004p6344* +- ID_MODEL_FROM_DATABASE=G2 Android Phone [tethering mode] ++ ID_MODEL_FROM_DATABASE=LM-X420xxx/G2 Android Phone (USB tethering mode) ++ ++usb:v1004p6348* ++ ID_MODEL_FROM_DATABASE=LM-X420xxx Android Phone (MIDI mode) + + usb:v1004p6356* + ID_MODEL_FROM_DATABASE=Optimus Android Phone [Virtual CD mode] +@@ -43649,6 +46589,9 @@ usb:v1005p1006* + usb:v1005pB113* + ID_MODEL_FROM_DATABASE=Handy Steno/AH123 / Handy Steno 2.0/HT203 + ++usb:v1005pB155* ++ ID_MODEL_FROM_DATABASE=Disk Module ++ + usb:v1005pB223* + ID_MODEL_FROM_DATABASE=CD-RW + 6in1 Card Reader Digital Storage / Converter + +@@ -43751,6 +46694,9 @@ usb:v1016* + usb:v1017* + ID_VENDOR_FROM_DATABASE=Speedy Industrial Supplies, Pte., Ltd + ++usb:v1017p9015* ++ ID_MODEL_FROM_DATABASE=M625 [Vendor: DELUX] ++ + usb:v1019* + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems (ECS) + +@@ -43770,7 +46716,7 @@ usb:v1020p000A* + ID_MODEL_FROM_DATABASE=Wireless Optical Mouse + + usb:v1020p0106* +- ID_MODEL_FROM_DATABASE=Wireless Optical Mouse ++ ID_MODEL_FROM_DATABASE=Wireless Optical Mouse/Keyboard + + usb:v1022* + ID_VENDOR_FROM_DATABASE=Shinko Shoji Co., Ltd +@@ -43817,6 +46763,9 @@ usb:v102Cp6151* + usb:v102Cp6251* + ID_MODEL_FROM_DATABASE=Q-Cam VGA + ++usb:v102CpFF0C* ++ ID_MODEL_FROM_DATABASE=Joytech Wireless Advanced Controller ++ + usb:v102D* + ID_VENDOR_FROM_DATABASE=Winic Corp. + +@@ -43838,9 +46787,18 @@ usb:v1038* + usb:v1038p0100* + ID_MODEL_FROM_DATABASE=Ideazon Zboard + ++usb:v1038p1260* ++ ID_MODEL_FROM_DATABASE=Arctis 7 wireless adapter ++ + usb:v1038p1361* + ID_MODEL_FROM_DATABASE=Ideazon Sensei + ++usb:v1038p1410* ++ ID_MODEL_FROM_DATABASE=SRW-S1 [Simraceway Steering Wheel] ++ ++usb:v1038p1720* ++ ID_MODEL_FROM_DATABASE=Mouse ++ + usb:v1039* + ID_VENDOR_FROM_DATABASE=devolo AG + +@@ -43964,6 +46922,9 @@ usb:v104D* + usb:v104Dp1003* + ID_MODEL_FROM_DATABASE=Model-52 LED Light Source Power Supply and Driver + ++usb:v104Dp3001* ++ ID_MODEL_FROM_DATABASE=ESP301 3 Axis Motion Controller ++ + usb:v104F* + ID_VENDOR_FROM_DATABASE=WB Electronics + +@@ -44028,25 +46989,25 @@ usb:v1050p0211* + ID_MODEL_FROM_DATABASE=Gnubby + + usb:v1050p0401* +- ID_MODEL_FROM_DATABASE=Yubikey 4 OTP ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP + + usb:v1050p0402* +- ID_MODEL_FROM_DATABASE=Yubikey 4 U2F ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 U2F + + usb:v1050p0403* +- ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+U2F ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP+U2F + + usb:v1050p0404* +- ID_MODEL_FROM_DATABASE=Yubikey 4 CCID ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 CCID + + usb:v1050p0405* +- ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+CCID ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP+CCID + + usb:v1050p0406* +- ID_MODEL_FROM_DATABASE=Yubikey 4 U2F+CCID ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 U2F+CCID + + usb:v1050p0407* +- ID_MODEL_FROM_DATABASE=Yubikey 4 OTP+U2F+CCID ++ ID_MODEL_FROM_DATABASE=Yubikey 4/5 OTP+U2F+CCID + + usb:v1050p0410* + ID_MODEL_FROM_DATABASE=Yubikey plus OTP+U2F +@@ -44246,6 +47207,9 @@ usb:v1058p1130* + usb:v1058p1140* + ID_MODEL_FROM_DATABASE=My Book Essential (WDBACW) + ++usb:v1058p1170* ++ ID_MODEL_FROM_DATABASE=My Book Essential 3TB (WDBACW0030HBK) ++ + usb:v1058p1230* + ID_MODEL_FROM_DATABASE=My Book (WDBFJK) + +@@ -44262,7 +47226,7 @@ usb:v1058p259F* + ID_MODEL_FROM_DATABASE=My Passport Ultra (WD10JMVW) + + usb:v1058p25A1* +- ID_MODEL_FROM_DATABASE=Elements / My Passport (WD20NMVW) ++ ID_MODEL_FROM_DATABASE=Elements / My Passport + + usb:v1058p25A2* + ID_MODEL_FROM_DATABASE=Elements 25A2 +@@ -44270,9 +47234,36 @@ usb:v1058p25A2* + usb:v1058p25A3* + ID_MODEL_FROM_DATABASE=Elements Desktop (WDBWLG) + ++usb:v1058p25DA* ++ ID_MODEL_FROM_DATABASE=My Book (WDBFJK) ++ ++usb:v1058p25E1* ++ ID_MODEL_FROM_DATABASE=My Passport (WD20NMVW) ++ + usb:v1058p25E2* + ID_MODEL_FROM_DATABASE=My Passport (WD40NMZW) + ++usb:v1058p25EE* ++ ID_MODEL_FROM_DATABASE=My Book 25EE ++ ++usb:v1058p25F3* ++ ID_MODEL_FROM_DATABASE=My Passport SSD (WDBK3E) ++ ++usb:v1058p25FA* ++ ID_MODEL_FROM_DATABASE=easystore Portable 5TB (WDBKUZ0050) ++ ++usb:v1058p25FB* ++ ID_MODEL_FROM_DATABASE=easystore Desktop (WDBCKA) ++ ++usb:v1058p2603* ++ ID_MODEL_FROM_DATABASE=My Passport Game Storage for PS4 4TB (WDBZGE0040) ++ ++usb:v1058p2624* ++ ID_MODEL_FROM_DATABASE=easystore Portable 5TB (WDBKUZ0050) ++ ++usb:v1058p2626* ++ ID_MODEL_FROM_DATABASE=My Passport (WDBPKJ) ++ + usb:v1058p30A0* + ID_MODEL_FROM_DATABASE=SATA adapter cable + +@@ -44705,6 +47696,9 @@ usb:v108Bp0005* + usb:v108C* + ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH + ++usb:v108Cp017E* ++ ID_MODEL_FROM_DATABASE=GTC 400 C ++ + usb:v108E* + ID_VENDOR_FROM_DATABASE=Lotes Co., Ltd. + +@@ -44723,9 +47717,18 @@ usb:v109A* + usb:v109B* + ID_VENDOR_FROM_DATABASE=Hisense + ++usb:v109Bp9109* ++ ID_MODEL_FROM_DATABASE=CROSSCALL Trekker-M1 Core (MTP-Mode) ++ + usb:v109Bp9118* + ID_MODEL_FROM_DATABASE=Medion P4013 Mobile + ++usb:v109Bp9119* ++ ID_MODEL_FROM_DATABASE=CROSSCALL Trekker-M1 Core (PTP-Mode) ++ ++usb:v109BpF009* ++ ID_MODEL_FROM_DATABASE=CROSSCALL Trekker-M1 Core (CD-ROM-Mode) ++ + usb:v109F* + ID_VENDOR_FROM_DATABASE=eSOL Co., Ltd + +@@ -44952,7 +47955,7 @@ usb:v10C3p00A5* + ID_MODEL_FROM_DATABASE=ULS Print Support + + usb:v10C4* +- ID_VENDOR_FROM_DATABASE=Cygnal Integrated Products, Inc. ++ ID_VENDOR_FROM_DATABASE=Silicon Labs + + usb:v10C4p0002* + ID_MODEL_FROM_DATABASE=F32x USBXpress Device +@@ -45068,17 +48071,65 @@ usb:v10C4p89C6* + usb:v10C4p89E1* + ID_MODEL_FROM_DATABASE=C8051F38x HDMI Extender [UHBX-SW3-WP] + ++usb:v10C4p89FB* ++ ID_MODEL_FROM_DATABASE=Qivicon ZigBee Stick ++ ++usb:v10C4p8A3C* ++ ID_MODEL_FROM_DATABASE=C8051F38x HDBaseT Receiver [UHBX-R-XT] ++ ++usb:v10C4p8A6C* ++ ID_MODEL_FROM_DATABASE=C8051F38x 4K HDMI Audio Extractor [EMX-AMP] ++ ++usb:v10C4p8ACB* ++ ID_MODEL_FROM_DATABASE=C8051F38x HDBaseT Wall Plate Receiver with IR, RS-232, and PoH [UHBX-R-WP] ++ ++usb:v10C4p8AF8* ++ ID_MODEL_FROM_DATABASE=C8051F38x 4K HDMI Audio Extractor w/Audio Amplifier, HDBT Input, Line Audio Input RS-232 Ports and IP Control [VSA-X21] ++ ++usb:v10C4p8B8C* ++ ID_MODEL_FROM_DATABASE=C8051F38x 4K HDMI Audio Extractor w/Audio Amplifier, HDBT Input, Line Audio Input RS-232 Ports and IP Control [SC-3H] ++ ++usb:v10C4p8DB5* ++ ID_MODEL_FROM_DATABASE=C8051F38x CATx HDMI Receiver with USB [EX-HDU-R] ++ ++usb:v10C4p8DB6* ++ ID_MODEL_FROM_DATABASE=C8051F38x CATx HDMI Receiver ++ + usb:v10C4pEA60* +- ID_MODEL_FROM_DATABASE=CP2102/CP2109 UART Bridge Controller [CP210x family] ++ ID_MODEL_FROM_DATABASE=CP210x UART Bridge + + usb:v10C4pEA61* + ID_MODEL_FROM_DATABASE=CP210x UART Bridge + +-usb:v10C4pEA70* ++usb:v10C4pEA63* + ID_MODEL_FROM_DATABASE=CP210x UART Bridge + ++usb:v10C4pEA70* ++ ID_MODEL_FROM_DATABASE=CP2105 Dual UART Bridge ++ ++usb:v10C4pEA71* ++ ID_MODEL_FROM_DATABASE=CP2108 Quad UART Bridge ++ + usb:v10C4pEA80* +- ID_MODEL_FROM_DATABASE=CP210x UART Bridge ++ ID_MODEL_FROM_DATABASE=CP2110 HID UART Bridge ++ ++usb:v10C4pEA90* ++ ID_MODEL_FROM_DATABASE=CP2112 HID I2C Bridge ++ ++usb:v10C4pEA91* ++ ID_MODEL_FROM_DATABASE=CP2112 HID SMBus/I2C Bridge for CP2614 Evaluation Kit ++ ++usb:v10C4pEA93* ++ ID_MODEL_FROM_DATABASE=CP2112 HID SMBus/I2C Bridge for CP2615 Evaluation Kit ++ ++usb:v10C4pEAB0* ++ ID_MODEL_FROM_DATABASE=CP2114 I2S Audio Bridge ++ ++usb:v10C4pEAC0* ++ ID_MODEL_FROM_DATABASE=CP2614 MFi Accessory Digital Audio Bridge ++ ++usb:v10C4pEAC1* ++ ID_MODEL_FROM_DATABASE=CP2615 I2S Audio Bridge + + usb:v10C4pEAC9* + ID_MODEL_FROM_DATABASE=EFM8UB1 Bootloader +@@ -45086,6 +48137,9 @@ usb:v10C4pEAC9* + usb:v10C4pEACA* + ID_MODEL_FROM_DATABASE=EFM8UB2 Bootloader + ++usb:v10C4pEACB* ++ ID_MODEL_FROM_DATABASE=EFM8UB3 Bootloader ++ + usb:v10C5* + ID_VENDOR_FROM_DATABASE=Sanei Electric, Inc. + +@@ -45125,6 +48179,12 @@ usb:v10CEp001D* + usb:v10CEp001E* + ID_MODEL_FROM_DATABASE=Ciaat Brava 21 + ++usb:v10CEp0039* ++ ID_MODEL_FROM_DATABASE=Sinfonia CHC-S2245 ++ ++usb:v10CEp10CE* ++ ID_MODEL_FROM_DATABASE=Sinfonia CHC-S2245 ++ + usb:v10CEpEA6A* + ID_MODEL_FROM_DATABASE=MobiData EDGE USB Modem + +@@ -45179,6 +48239,9 @@ usb:v10D5p5552* + usb:v10D5p55A2* + ID_MODEL_FROM_DATABASE=2Port KVMSwitcher + ++usb:v10D5p5A08* ++ ID_MODEL_FROM_DATABASE=Dual Bay Docking Station ++ + usb:v10D6* + ID_VENDOR_FROM_DATABASE=Actions Semiconductor Co., Ltd + +@@ -45257,6 +48320,90 @@ usb:v10F5* + usb:v10F5p0200* + ID_MODEL_FROM_DATABASE=Audio Advantage Roadie + ++usb:v10F5p0231* ++ ID_MODEL_FROM_DATABASE=Ear Force P11 Headset ++ ++usb:v10F5p10F5* ++ ID_MODEL_FROM_DATABASE=EarForce PX21 Gaming Headset ++ ++usb:v10F8* ++ ID_VENDOR_FROM_DATABASE=Cesys GmbH ++ ++usb:v10F8p3201* ++ ID_MODEL_FROM_DATABASE=CeboLC ++ ++usb:v10F8p3202* ++ ID_MODEL_FROM_DATABASE=CeboStick ++ ++usb:v10F8p3203* ++ ID_MODEL_FROM_DATABASE=CeboMSA64 ++ ++usb:v10F8p3204* ++ ID_MODEL_FROM_DATABASE=CeboDFN ++ ++usb:v10F8p3205* ++ ID_MODEL_FROM_DATABASE=PSAA2304W_CASC ++ ++usb:v10F8pC401* ++ ID_MODEL_FROM_DATABASE=USBV4F unconfigured ++ ++usb:v10F8pC402* ++ ID_MODEL_FROM_DATABASE=EFM01 unconfigured ++ ++usb:v10F8pC403* ++ ID_MODEL_FROM_DATABASE=MISS2 unconfigured ++ ++usb:v10F8pC404* ++ ID_MODEL_FROM_DATABASE=CID unconfigured ++ ++usb:v10F8pC405* ++ ID_MODEL_FROM_DATABASE=USBS6 unconfigured ++ ++usb:v10F8pC406* ++ ID_MODEL_FROM_DATABASE=OP_MISS2 unconfigured ++ ++usb:v10F8pC407* ++ ID_MODEL_FROM_DATABASE=NanoUsb uncofigured ++ ++usb:v10F8pC481* ++ ID_MODEL_FROM_DATABASE=USBV4F ++ ++usb:v10F8pC482* ++ ID_MODEL_FROM_DATABASE=EFM01 ++ ++usb:v10F8pC483* ++ ID_MODEL_FROM_DATABASE=MISS2 ++ ++usb:v10F8pC484* ++ ID_MODEL_FROM_DATABASE=CID ++ ++usb:v10F8pC485* ++ ID_MODEL_FROM_DATABASE=USBS6 ++ ++usb:v10F8pC486* ++ ID_MODEL_FROM_DATABASE=OP_MISS2 ++ ++usb:v10F8pC487* ++ ID_MODEL_FROM_DATABASE=NanoUsb ++ ++usb:v10F8pC501* ++ ID_MODEL_FROM_DATABASE=EFM02 unconfigured ++ ++usb:v10F8pC502* ++ ID_MODEL_FROM_DATABASE=EFM02/B unconfigured ++ ++usb:v10F8pC503* ++ ID_MODEL_FROM_DATABASE=EFM03 unconfigured ++ ++usb:v10F8pC581* ++ ID_MODEL_FROM_DATABASE=EFM02 ++ ++usb:v10F8pC582* ++ ID_MODEL_FROM_DATABASE=EFM02/B ++ ++usb:v10F8pC583* ++ ID_MODEL_FROM_DATABASE=EFM03 ++ + usb:v10FB* + ID_VENDOR_FROM_DATABASE=Pictos Technologies, Inc. + +@@ -45299,6 +48446,12 @@ usb:v1108* + usb:v110A* + ID_VENDOR_FROM_DATABASE=Moxa Technologies Co., Ltd. + ++usb:v110Ap1110* ++ ID_MODEL_FROM_DATABASE=UPort 1110 ++ ++usb:v110Ap1150* ++ ID_MODEL_FROM_DATABASE=UPort 1150 1-Port RS-232/422/485 ++ + usb:v110Ap1250* + ID_MODEL_FROM_DATABASE=UPort 1250 2-Port RS-232/422/485 + +@@ -45407,12 +48560,18 @@ usb:v1130p0001* + usb:v1130p0002* + ID_MODEL_FROM_DATABASE=iBuddy + ++usb:v1130p0004* ++ ID_MODEL_FROM_DATABASE=iBuddy Twins ++ + usb:v1130p0202* + ID_MODEL_FROM_DATABASE=Rocket Launcher + + usb:v1130p6604* + ID_MODEL_FROM_DATABASE=MCE IR-Receiver + ++usb:v1130p6606* ++ ID_MODEL_FROM_DATABASE=U+P Mouse ++ + usb:v1130p660C* + ID_MODEL_FROM_DATABASE=Foot Pedal/Thermometer + +@@ -45788,15 +48947,27 @@ usb:v1199p9009* + usb:v1199p900A* + ID_MODEL_FROM_DATABASE=Gobi 2000 Wireless Modem + ++usb:v1199p9011* ++ ID_MODEL_FROM_DATABASE=MC8305 Modem ++ + usb:v1199p9013* + ID_MODEL_FROM_DATABASE=Sierra Wireless Gobi 3000 Modem device (MC8355) + ++usb:v1199p9041* ++ ID_MODEL_FROM_DATABASE=EM7305 Modem ++ + usb:v1199p9055* + ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (NAT mode) + + usb:v1199p9057* + ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (IP passthrough mode) + ++usb:v1199p9071* ++ ID_MODEL_FROM_DATABASE=AirPrime MC7455 3G/4G LTE Modem ++ ++usb:v1199p9079* ++ ID_MODEL_FROM_DATABASE=EM7455 ++ + usb:v119A* + ID_VENDOR_FROM_DATABASE=ZHAN QI Technology Co., Ltd + +@@ -45842,6 +49013,9 @@ usb:v11B0* + usb:v11B0p6208* + ID_MODEL_FROM_DATABASE=PRO-28U + ++usb:v11B0p6298* ++ ID_MODEL_FROM_DATABASE=Kingston SNA-DC/U ++ + usb:v11BE* + ID_VENDOR_FROM_DATABASE=R&D International NV + +@@ -45860,9 +49034,18 @@ usb:v11C5* + usb:v11C5p0521* + ID_MODEL_FROM_DATABASE=IMT-0521 Smartcard Reader + ++usb:v11C9* ++ ID_VENDOR_FROM_DATABASE=Nacon ++ ++usb:v11C9p55F0* ++ ID_MODEL_FROM_DATABASE=GC-100XF ++ + usb:v11CA* + ID_VENDOR_FROM_DATABASE=VeriFone Inc + ++usb:v11CAp0201* ++ ID_MODEL_FROM_DATABASE=MX870/MX880 ++ + usb:v11CAp0207* + ID_MODEL_FROM_DATABASE=PIN Pad VX 810 + +@@ -45921,59 +49104,314 @@ usb:v1203p0140* + ID_MODEL_FROM_DATABASE=TTP-245C + + usb:v1209* +- ID_VENDOR_FROM_DATABASE=InterBiometrics ++ ID_VENDOR_FROM_DATABASE=Generic ++ ++usb:v1209p0001* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0002* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0003* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0004* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0005* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0006* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0007* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0008* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0009* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000A* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000B* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000C* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000D* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000E* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p000F* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p0010* ++ ID_MODEL_FROM_DATABASE=pid.codes Test PID ++ ++usb:v1209p01C0* ++ ID_MODEL_FROM_DATABASE=Input Club Kiibohd Device ++ ++usb:v1209p01CB* ++ ID_MODEL_FROM_DATABASE=Input Club Kiibohd Device Bootloader ++ ++usb:v1209p0256* ++ ID_MODEL_FROM_DATABASE=Schwalm & Tate LLC pISO Raspberry Pi Hat ++ ++usb:v1209p053A* ++ ID_MODEL_FROM_DATABASE=Hackerspace San Salvador HSSV SAMR21-Mote ++ ++usb:v1209p0CBD* ++ ID_MODEL_FROM_DATABASE=Andrzej Szombierski kuku.eu.org keyboard ++ ++usb:v1209p0D32* ++ ID_MODEL_FROM_DATABASE=ODrive Robotics ODrive v3 + + usb:v1209p1001* +- ID_MODEL_FROM_DATABASE=USB Hub ++ ID_MODEL_FROM_DATABASE=InterBiometrics Hub + + usb:v1209p1002* +- ID_MODEL_FROM_DATABASE=USB Relais ++ ID_MODEL_FROM_DATABASE=InterBiometrics Relais + + usb:v1209p1003* +- ID_MODEL_FROM_DATABASE=IBSecureCam-P ++ ID_MODEL_FROM_DATABASE=InterBiometrics IBSecureCam-P + + usb:v1209p1004* +- ID_MODEL_FROM_DATABASE=IBSecureCam-O ++ ID_MODEL_FROM_DATABASE=InterBiometrics IBSecureCam-O + + usb:v1209p1005* +- ID_MODEL_FROM_DATABASE=IBSecureCam-N ++ ID_MODEL_FROM_DATABASE=InterBiometrics IBSecureCam-N + + usb:v1209p1006* +- ID_MODEL_FROM_DATABASE=Mini IO-Board ++ ID_MODEL_FROM_DATABASE=InterBiometrics Mini IO-Board ++ ++usb:v1209p1007* ++ ID_MODEL_FROM_DATABASE=e-radionica.com Croduino SAMD ++ ++usb:v1209p1986* ++ ID_MODEL_FROM_DATABASE=dgrubb Jaguar Tap + + usb:v1209p1AB5* + ID_MODEL_FROM_DATABASE=Arachnid Labs Tsunami + ++usb:v1209p1AB6* ++ ID_MODEL_FROM_DATABASE=Arachnid Labs Tsunami Bootloader ++ + usb:v1209p2000* + ID_MODEL_FROM_DATABASE=Zygmunt Krynicki Lantern Brightness Sensor + ++usb:v1209p2001* ++ ID_MODEL_FROM_DATABASE=OSHEC Pi-pilot opensource and openhardware autopilot system ++ ++usb:v1209p2002* ++ ID_MODEL_FROM_DATABASE=Peter Lawrence PIC16F1-USB-DFU-Bootloader ++ ++usb:v1209p2003* ++ ID_MODEL_FROM_DATABASE=Peter Lawrence SAMDx1-USB-DFU-Bootloader ++ ++usb:v1209p2004* ++ ID_MODEL_FROM_DATABASE=GCBASIC Serial CDC Stack ++ ++usb:v1209p2005* ++ ID_MODEL_FROM_DATABASE=GCBASIC OakTree Stack ++ ++usb:v1209p2006* ++ ID_MODEL_FROM_DATABASE=GCBASIC Simulation Stack ++ ++usb:v1209p2016* ++ ID_MODEL_FROM_DATABASE=Cupkee ++ ++usb:v1209p2017* ++ ID_MODEL_FROM_DATABASE=Benjamin Shockley Mini SAM ++ ++usb:v1209p2020* ++ ID_MODEL_FROM_DATABASE=Captain Credible Gate Crystal ++ + usb:v1209p2048* +- ID_MODEL_FROM_DATABASE=Housedillon.com MRF49XA Transciever ++ ID_MODEL_FROM_DATABASE=Housedillon.com MRF49XA Transceiver ++ ++usb:v1209p2100* ++ ID_MODEL_FROM_DATABASE=TinyFPGA B1 and B2 Boards ++ ++usb:v1209p2101* ++ ID_MODEL_FROM_DATABASE=TinyFPGA A-Series Programmer ++ ++usb:v1209p2200* ++ ID_MODEL_FROM_DATABASE=Dygma Shortcut Bootloader ++ ++usb:v1209p2201* ++ ID_MODEL_FROM_DATABASE=Dygma Shortcut Keyboard + + usb:v1209p2222* + ID_MODEL_FROM_DATABASE=LabConnect Signalgenerator + + usb:v1209p2300* +- ID_MODEL_FROM_DATABASE=Keyboardio Keyboardio Model 01 Bootloader ++ ID_MODEL_FROM_DATABASE=Keyboardio Model 01 Bootloader + + usb:v1209p2301* +- ID_MODEL_FROM_DATABASE=Keyboardio Keyboardio Model 01 ++ ID_MODEL_FROM_DATABASE=Keyboardio Model 01 ++ ++usb:v1209p2323* ++ ID_MODEL_FROM_DATABASE=bytewerk.org candleLight + + usb:v1209p2327* +- ID_MODEL_FROM_DATABASE=K.T.E.C.Bootloader Device ++ ID_MODEL_FROM_DATABASE=K.T.E.C. Bootloader Device + + usb:v1209p2328* + ID_MODEL_FROM_DATABASE=K.T.E.C. Keyboard Device + ++usb:v1209p2333* ++ ID_MODEL_FROM_DATABASE=Kai Ryu Kimera ++ ++usb:v1209p2334* ++ ID_MODEL_FROM_DATABASE=Kai Ryu Staryu ++ ++usb:v1209p2335* ++ ID_MODEL_FROM_DATABASE=Portwell Sense8 ++ ++usb:v1209p2336* ++ ID_MODEL_FROM_DATABASE=Portwell Sense8 ++ + usb:v1209p2337* +- ID_MODEL_FROM_DATABASE=/Dev or SlashDev /Net ++ ID_MODEL_FROM_DATABASE=/Dev /Net ++ ++usb:v1209p2342* ++ ID_MODEL_FROM_DATABASE=Andreas Bogk Big Red Button ++ ++usb:v1209p2345* ++ ID_MODEL_FROM_DATABASE=VV-Soft Simple Generic HID IO ++ ++usb:v1209p2357* ++ ID_MODEL_FROM_DATABASE=KarolKucza TinyPassword ++ ++usb:v1209p2400* ++ ID_MODEL_FROM_DATABASE=phooky Snap-Pad ++ ++usb:v1209p2488* ++ ID_MODEL_FROM_DATABASE=Peter Lawrence CMSIS-DAP Dapper Miser ++ ++usb:v1209p2552* ++ ID_MODEL_FROM_DATABASE=ProjectIota Electrolink ++ ++usb:v1209p2600* ++ ID_MODEL_FROM_DATABASE=Majenko Technologies chipKIT Lenny ++ ++usb:v1209p2635* ++ ID_MODEL_FROM_DATABASE=Sevinz GameBot ++ ++usb:v1209p2800* ++ ID_MODEL_FROM_DATABASE=Entropic Engineering Triangulation ++ ++usb:v1209p2801* ++ ID_MODEL_FROM_DATABASE=Entropic Engineering Object Manipulation ++ ++usb:v1209p2A00* ++ ID_MODEL_FROM_DATABASE=mooware Wii adapter ++ ++usb:v1209p2A01* ++ ID_MODEL_FROM_DATABASE=mooware SNES adapter + + usb:v1209p3000* + ID_MODEL_FROM_DATABASE=lloyd3000 + ++usb:v1209p3100* ++ ID_MODEL_FROM_DATABASE=OpenSimHardware Pedals & Buttons Controller ++ ++usb:v1209p317E* ++ ID_MODEL_FROM_DATABASE=Codecrete Wirekite ++ ++usb:v1209p3210* ++ ID_MODEL_FROM_DATABASE=OSH Lab, LLC Magic Keys ++ + usb:v1209p3333* + ID_MODEL_FROM_DATABASE=LabConnect Digitalnetzteil + ++usb:v1209p345B* ++ ID_MODEL_FROM_DATABASE=kinX Hub ++ ++usb:v1209p345C* ++ ID_MODEL_FROM_DATABASE=kinX Keyboard Controller ++ ++usb:v1209p3690* ++ ID_MODEL_FROM_DATABASE=Kigakudoh TouchMIDI32 ++ ++usb:v1209p4096* ++ ID_MODEL_FROM_DATABASE=CynaraKrewe Cynara ++ ++usb:v1209p414C* ++ ID_MODEL_FROM_DATABASE=Adi Linden ++ ++usb:v1209p414D* ++ ID_MODEL_FROM_DATABASE=Adi Linden ++ ++usb:v1209p4242* ++ ID_MODEL_FROM_DATABASE=Komakallio Astrophotography Community KomaHub Remote Power Switch ++ ++usb:v1209p4256* ++ ID_MODEL_FROM_DATABASE=CuVoodoo BusVoodoo multi-protocol debugging adapter ++ ++usb:v1209p4321* ++ ID_MODEL_FROM_DATABASE=mooltipass Offline Password Keeper Bootloader ++ ++usb:v1209p4322* ++ ID_MODEL_FROM_DATABASE=mooltipass Arduino Sketch ++ ++usb:v1209p4356* ++ ID_MODEL_FROM_DATABASE=CuVoodoo firmware ++ ++usb:v1209p4443* ++ ID_MODEL_FROM_DATABASE=j1rie IRMP_STM32 Bootloader ++ ++usb:v1209p4444* ++ ID_MODEL_FROM_DATABASE=j1rie IRMP_STM32 ++ ++usb:v1209p4545* ++ ID_MODEL_FROM_DATABASE=SlothCo Enterprises Teletype Adapter ++ ++usb:v1209p4646* ++ ID_MODEL_FROM_DATABASE=SmartPID SPC1000 ++ ++usb:v1209p4748* ++ ID_MODEL_FROM_DATABASE=Kate Gray GHETT-iO Bootloader ++ ++usb:v1209p4750* ++ ID_MODEL_FROM_DATABASE=Chris Pavlina (c4757p) C4-x computer (development interface) ++ ++usb:v1209p4757* ++ ID_MODEL_FROM_DATABASE=Chris Pavlina (c4757p) WCP52 Gain/Phase Analyzer ++ ++usb:v1209p4801* ++ ID_MODEL_FROM_DATABASE=Wojciech Krutnik NVMemProg ++ ++usb:v1209p4C60* ++ ID_MODEL_FROM_DATABASE=MightyPork GEX module ++ ++usb:v1209p4C61* ++ ID_MODEL_FROM_DATABASE=MightyPork GEX wireless dongle ++ ++usb:v1209p4D53* ++ ID_MODEL_FROM_DATABASE=mindsensors.com NXTCam5 ++ ++usb:v1209p5038* ++ ID_MODEL_FROM_DATABASE=frotz.net mdebug rswd protocol ++ ++usb:v1209p5039* ++ ID_MODEL_FROM_DATABASE=frotz.net lpcboot protocol ++ ++usb:v1209p5050* ++ ID_MODEL_FROM_DATABASE=trebb ISO50 ++ ++usb:v1209p5070* ++ ID_MODEL_FROM_DATABASE=SoloHacker security key [SoloKey] ++ ++usb:v1209p50B0* ++ ID_MODEL_FROM_DATABASE=boot for security key [SoloKey] ++ + usb:v1209p5222* + ID_MODEL_FROM_DATABASE=telavivmakers attami + +@@ -45983,54 +49421,498 @@ usb:v1209p53C0* + usb:v1209p53C1* + ID_MODEL_FROM_DATABASE=SatoshiLabs TREZOR + ++usb:v1209p5432* ++ ID_MODEL_FROM_DATABASE=Open Programmer ++ ++usb:v1209p5457* ++ ID_MODEL_FROM_DATABASE=Openlab.Taipei Taiwanduino ++ ++usb:v1209p571C* ++ ID_MODEL_FROM_DATABASE=StreetoArcade PancadariaStick ++ + usb:v1209p5A22* + ID_MODEL_FROM_DATABASE=ikari_01 sd2snes + ++usb:v1209p6000* ++ ID_MODEL_FROM_DATABASE=Pulsar Heavy Industries Cenx4 ++ ++usb:v1209p600D* ++ ID_MODEL_FROM_DATABASE=Makdaam N93 Interface ++ ++usb:v1209p6464* ++ ID_MODEL_FROM_DATABASE=Electric Exploits Shinewave ++ ++usb:v1209p6502* ++ ID_MODEL_FROM_DATABASE=jj1bdx avrhwrng v2rev1 ++ ++usb:v1209p6570* ++ ID_MODEL_FROM_DATABASE=Iowa Scaled Engineering, LLC CKT-AVRPROGRAMMER ++ ++usb:v1209p6666* ++ ID_MODEL_FROM_DATABASE=Talpa Chen VSFLogic ++ ++usb:v1209p6667* ++ ID_MODEL_FROM_DATABASE=SensePost Universal Serial aBUSe - Generic HID ++ ++usb:v1209p6742* ++ ID_MODEL_FROM_DATABASE=NPK Cubitel Atomic Force Microscope ++ ++usb:v1209p6809* ++ ID_MODEL_FROM_DATABASE=Tach Radio Doppelganger ++ ++usb:v1209p6948* ++ ID_MODEL_FROM_DATABASE=MySensors Sensebender Gateway BootLoader ++ ++usb:v1209p6949* ++ ID_MODEL_FROM_DATABASE=MySensors Sensebender Gateway ++ ++usb:v1209p6BCF* ++ ID_MODEL_FROM_DATABASE=blaste Gameboy Cart Flasher ++ ++usb:v1209p7000* ++ ID_MODEL_FROM_DATABASE=Secalot Dongle ++ ++usb:v1209p7001* ++ ID_MODEL_FROM_DATABASE=Secalot Bootloader ++ ++usb:v1209p70B1* ++ ID_MODEL_FROM_DATABASE=Sutajio Ko-Usagi (Kosagi) Tomu ++ ++usb:v1209p7331* ++ ID_MODEL_FROM_DATABASE=Dangerous Prototypes Bus Pirate Next Gen CDC ++ ++usb:v1209p7332* ++ ID_MODEL_FROM_DATABASE=Dangerous Prototypes Bus Pirate Next Gen Logic Analyzer ++ ++usb:v1209p7401* ++ ID_MODEL_FROM_DATABASE=Beststream-jp Tool_CDC ++ + usb:v1209p7530* +- ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Bootloader ++ ID_MODEL_FROM_DATABASE=PotentialLabs Refflion - IoT Development Board - Bootloader + + usb:v1209p7531* +- ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Sketch ++ ID_MODEL_FROM_DATABASE=PotentialLabs Refflion - IoT Development Board - Sketch ++ ++usb:v1209p7551* ++ ID_MODEL_FROM_DATABASE=The Tessel Project Tessel 2 ++ ++usb:v1209p7777* ++ ID_MODEL_FROM_DATABASE=circuitvalley IO Board V3 ++ ++usb:v1209p7778* ++ ID_MODEL_FROM_DATABASE=circuitvalley IO Board V3 Bootloader ++ ++usb:v1209p7950* ++ ID_MODEL_FROM_DATABASE=PIC18F87J94 Bootloader [GenII] ++ ++usb:v1209p7951* ++ ID_MODEL_FROM_DATABASE=PIC18F87J94 Application [GenII] ++ ++usb:v1209p7952* ++ ID_MODEL_FROM_DATABASE=PIC18F87J94 Bootloader [GenIII/IV] ++ ++usb:v1209p7953* ++ ID_MODEL_FROM_DATABASE=PIC18F87J94 Application [GenIII/IV] ++ ++usb:v1209p7954* ++ ID_MODEL_FROM_DATABASE=PIC18F87J94 Application [GenIII/IV] + + usb:v1209p7BD0* + ID_MODEL_FROM_DATABASE=pokey9000 Tiny Bit Dingus + +-usb:v1209pABD0* +- ID_MODEL_FROM_DATABASE=tibounise ADB converter ++usb:v1209p8000* ++ ID_MODEL_FROM_DATABASE=Autonomii NODii 2 ++ ++usb:v1209p8086* ++ ID_MODEL_FROM_DATABASE=MisfitTech Nano Zero Bootloader ++ ++usb:v1209p8087* ++ ID_MODEL_FROM_DATABASE=MisfitTech Nano Zero ++ ++usb:v1209p8123* ++ ID_MODEL_FROM_DATABASE=Danyboard M0 bootloader ++ ++usb:v1209p812A* ++ ID_MODEL_FROM_DATABASE=Danyboard M0 ++ ++usb:v1209p813A* ++ ID_MODEL_FROM_DATABASE=MickMad HACK Bootloader ++ ++usb:v1209p813B* ++ ID_MODEL_FROM_DATABASE=MickMad HACK Sketch ++ ++usb:v1209p8242* ++ ID_MODEL_FROM_DATABASE=Tom Wimmenhove Electronics NBS-DAC 192/24 UAC1 ++ ++usb:v1209p8243* ++ ID_MODEL_FROM_DATABASE=Tom Wimmenhove Electronics NBS-DAC 192/24 UAC2 ++ ++usb:v1209p8472* ++ ID_MODEL_FROM_DATABASE=Shantea Controls OpenDeck ++ ++usb:v1209p8661* ++ ID_MODEL_FROM_DATABASE=ProgHQ TL866 programmer ++ ++usb:v1209p8844* ++ ID_MODEL_FROM_DATABASE=munia.io MUNIA ++ ++usb:v1209p8888* ++ ID_MODEL_FROM_DATABASE=Blinkinlabs POV Pendant ++ ++usb:v1209p8889* ++ ID_MODEL_FROM_DATABASE=Blinkinlabs POV Pendant (bootloader) ++ ++usb:v1209p8B00* ++ ID_MODEL_FROM_DATABASE=ReSwitched Libtransistor Serial Console ++ ++usb:v1209p9021* ++ ID_MODEL_FROM_DATABASE=Connected Community Hackerspace ESPlant ++ ++usb:v1209p9317* ++ ID_MODEL_FROM_DATABASE=Sutajio Ko-Usagi (Kosagi) Palawan-Tx ++ ++usb:v1209p9999* ++ ID_MODEL_FROM_DATABASE=Sandeepan Sengupta CodeBridge Infineo ++ ++usb:v1209p9DB5* ++ ID_MODEL_FROM_DATABASE=PD Buddy Sink ++ ++usb:v1209pA033* ++ ID_MODEL_FROM_DATABASE=area0x33 Memtype ++ ++usb:v1209pA100* ++ ID_MODEL_FROM_DATABASE=KB LES Narsil analog breakout ++ ++usb:v1209pA10C* ++ ID_MODEL_FROM_DATABASE=KB LES Aminoacid Synthesizer ++ ++usb:v1209pA1E5* ++ ID_MODEL_FROM_DATABASE=Atreus Keyboards Atreus Keyboard ++ ++usb:v1209pA3A4* ++ ID_MODEL_FROM_DATABASE=MK::Box MK::Kbd ++ ++usb:v1209pA3A5* ++ ID_MODEL_FROM_DATABASE=MK::Box MK::Kbd Bootloader ++ ++usb:v1209pA55A* ++ ID_MODEL_FROM_DATABASE=Forever Young Software ATTINY2313 ++ ++usb:v1209pA602* ++ ID_MODEL_FROM_DATABASE=Robotips RTBoard ++ ++usb:v1209pA7EA* ++ ID_MODEL_FROM_DATABASE=area3001 Knixx SW04 ++ ++usb:v1209pA800* ++ ID_MODEL_FROM_DATABASE=sowbug.com WebLight ++ ++usb:v1209pA8B0* ++ ID_MODEL_FROM_DATABASE=Intelectron BootWare ++ ++usb:v1209pA8B1* ++ ID_MODEL_FROM_DATABASE=Intelectron FrameWare ++ ++usb:v1209pAA00* ++ ID_MODEL_FROM_DATABASE=Serg Oskin LinuxCNC HID Extender ++ ++usb:v1209pAA0B* ++ ID_MODEL_FROM_DATABASE=Open Bionics ++ ++usb:v1209pAB3D* ++ ID_MODEL_FROM_DATABASE=3DArtists Alligator board ++ ++usb:v1209pABBA* ++ ID_MODEL_FROM_DATABASE=CoinWISE SafeWISE ++ ++usb:v1209pABC0* ++ ID_MODEL_FROM_DATABASE=Omzlo controller ++ ++usb:v1209pABCD* ++ ID_MODEL_FROM_DATABASE=Sandeepan Sengupta CodeBridge ++ ++usb:v1209pABD1* ++ ID_MODEL_FROM_DATABASE=OpenMV Cam ++ ++usb:v1209pACDC* ++ ID_MODEL_FROM_DATABASE=Gediminas Zukaitis midi-grid ++ ++usb:v1209pACE5* ++ ID_MODEL_FROM_DATABASE=SimAces Panel Ace + + usb:v1209pACED* +- ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Device ++ ID_MODEL_FROM_DATABASE=Open Lighting Project Ja Rule Device + + usb:v1209pACEE* +- ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Bootloader ++ ID_MODEL_FROM_DATABASE=Open Lighting Project Ja Rule Bootloader ++ ++usb:v1209pADB0* ++ ID_MODEL_FROM_DATABASE=tibounise ADB converter ++ ++usb:v1209pADDA* ++ ID_MODEL_FROM_DATABASE=MicroPython Boards ++ ++usb:v1209pB007* ++ ID_MODEL_FROM_DATABASE=Konsgn Global_Boot ++ ++usb:v1209pB00B* ++ ID_MODEL_FROM_DATABASE=CrapLab Random Device ++ ++usb:v1209pB010* ++ ID_MODEL_FROM_DATABASE=IObitZ CodeBridge ++ ++usb:v1209pB01D* ++ ID_MODEL_FROM_DATABASE=WyoLum VeloKey ++ ++usb:v1209pB058* ++ ID_MODEL_FROM_DATABASE=Model B, LLC Holoseat ++ ++usb:v1209pB0B0* ++ ID_MODEL_FROM_DATABASE=Monero Hardware Monero Bootloader ++ ++usb:v1209pB100* ++ ID_MODEL_FROM_DATABASE=ptrandem iBizi ++ ++usb:v1209pB101* ++ ID_MODEL_FROM_DATABASE=IObitZ Infineo ++ ++usb:v1209pB195* ++ ID_MODEL_FROM_DATABASE=flehrad Big Switch PCB ++ ++usb:v1209pBAB1* ++ ID_MODEL_FROM_DATABASE=ElectronicCats Meow Meow ++ ++usb:v1209pBABE* ++ ID_MODEL_FROM_DATABASE=brunofreitas.com STM32 HID Bootloader ++ ++usb:v1209pBAD1* ++ ID_MODEL_FROM_DATABASE=Gregory POTEAU CommLinkUSB ++ ++usb:v1209pBAD2* ++ ID_MODEL_FROM_DATABASE=Gregory POTEAU XLinkUSB ++ ++usb:v1209pBADE* ++ ID_MODEL_FROM_DATABASE=Semarme SemarmeHID ++ ++usb:v1209pBB00* ++ ID_MODEL_FROM_DATABASE=keyplus split keyboard firmware ++ ++usb:v1209pBB01* ++ ID_MODEL_FROM_DATABASE=keyplus xusb bootloader ++ ++usb:v1209pBB02* ++ ID_MODEL_FROM_DATABASE=keyplus nRF24 wireless keyboard dongle ++ ++usb:v1209pBB03* ++ ID_MODEL_FROM_DATABASE=keyplus nrf24lu1p-512 bootloader ++ ++usb:v1209pBB05* ++ ID_MODEL_FROM_DATABASE=keyplus kp_boot_32u4 bootloader ++ ++usb:v1209pBEBA* ++ ID_MODEL_FROM_DATABASE=serasidis.gr STM32 HID Bootloader + + usb:v1209pBEEF* + ID_MODEL_FROM_DATABASE=Modal MC-USB + ++usb:v1209pC001* ++ ID_MODEL_FROM_DATABASE=Cynteract Alpha ++ ++usb:v1209pC0C0* ++ ID_MODEL_FROM_DATABASE=Geppetto_Electronics Orthrus ++ ++usb:v1209pC0C1* ++ ID_MODEL_FROM_DATABASE=Michael Bemmerl cookie-mouse ++ ++usb:v1209pC0CA* ++ ID_MODEL_FROM_DATABASE=Jean THOMAS DirtyJTAG ++ ++usb:v1209pC0D3* ++ ID_MODEL_FROM_DATABASE=Samy Kamkar USBdriveby ++ ++usb:v1209pC0DA* ++ ID_MODEL_FROM_DATABASE=Monero Hardware Monero Firmware ++ ++usb:v1209pC0DE* ++ ID_MODEL_FROM_DATABASE=KMRH Labs SBL Brain ++ + usb:v1209pC0F5* + ID_MODEL_FROM_DATABASE=unethi PERswitch + ++usb:v1209pC1AA* ++ ID_MODEL_FROM_DATABASE=Proyecto CIAA Computadora Industrial Abierta Argentina ++ ++usb:v1209pC1B1* ++ ID_MODEL_FROM_DATABASE=Chibitronics Love-to-Code ++ ++usb:v1209pC311* ++ ID_MODEL_FROM_DATABASE=bg nerilex GB-USB-Link ++ + usb:v1209pCA1C* +- ID_MODEL_FROM_DATABASE=KnightOS Hub ++ ID_MODEL_FROM_DATABASE=KnightOS Generic Hub + + usb:v1209pCA1D* + ID_MODEL_FROM_DATABASE=KnightOS MTP Device + ++usb:v1209pCAEA* ++ ID_MODEL_FROM_DATABASE=Open Music Kontrollers Chimaera ++ + usb:v1209pCAFE* + ID_MODEL_FROM_DATABASE=ii iigadget + ++usb:v1209pCC14* ++ ID_MODEL_FROM_DATABASE=trebb NaN-15 ++ ++usb:v1209pCC86* ++ ID_MODEL_FROM_DATABASE=Manfred's Technologies Anastasia Bootloader ++ ++usb:v1209pCEB0* ++ ID_MODEL_FROM_DATABASE=KG4LNE GE-FlashUSB ++ ++usb:v1209pCF20* ++ ID_MODEL_FROM_DATABASE=Smart Citizen SCK 2.0 ++ ++usb:v1209pD00D* ++ ID_MODEL_FROM_DATABASE=Monero Hardware Monero Developer ++ ++usb:v1209pD017* ++ ID_MODEL_FROM_DATABASE=empiriKit empiriKit Controller ++ ++usb:v1209pD11D* ++ ID_MODEL_FROM_DATABASE=Koi Science DI-Lambda AVR ++ ++usb:v1209pD3D8* ++ ID_MODEL_FROM_DATABASE=Duet3d Duet 0.8.5 ++ ++usb:v1209pD706* ++ ID_MODEL_FROM_DATABASE=SkyBean SkyDrop ++ ++usb:v1209pDA42* ++ ID_MODEL_FROM_DATABASE=Devan Lai dap42 debug access probe ++ ++usb:v1209pDAA0* ++ ID_MODEL_FROM_DATABASE=darknao btClubSportWheel ++ + usb:v1209pDADA* + ID_MODEL_FROM_DATABASE=Rebel Technology OWL + ++usb:v1209pDB42* ++ ID_MODEL_FROM_DATABASE=Devan Lai dapboot DFU bootloader ++ ++usb:v1209pDC21* ++ ID_MODEL_FROM_DATABASE=FPGA-Computer Dual Charger ++ ++usb:v1209pDDDD* ++ ID_MODEL_FROM_DATABASE=Stephan Electronics OpenCVMeter ++ + usb:v1209pDEAD* + ID_MODEL_FROM_DATABASE=chaosfield.at AVR-Ruler + ++usb:v1209pDEAF* ++ ID_MODEL_FROM_DATABASE=CrapLab 4chord MIDI ++ ++usb:v1209pDED1* ++ ID_MODEL_FROM_DATABASE=ManCave Made Quark One ++ ++usb:v1209pDEED* ++ ID_MODEL_FROM_DATABASE=Kroneum Time Tracker ++ ++usb:v1209pDF00* ++ ID_MODEL_FROM_DATABASE=D.F.Mac. @TripArts Music mi:muz:tuch ++ ++usb:v1209pDF01* ++ ID_MODEL_FROM_DATABASE=D.F.Mac. @TripArts Music mi:muz:can ++ ++usb:v1209pDF02* ++ ID_MODEL_FROM_DATABASE=D.F.Mac. @TripArts Music mi:muz:can-lite ++ ++usb:v1209pE116* ++ ID_MODEL_FROM_DATABASE=Elijah Motornyy open-oscilloscope-stm32f3 ++ ++usb:v1209pE1EC* ++ ID_MODEL_FROM_DATABASE=FreeSRP ++ ++usb:v1209pE4EE* ++ ID_MODEL_FROM_DATABASE=trebb keytee ++ ++usb:v1209pE500* ++ ID_MODEL_FROM_DATABASE=GitleMikkelsen Helios Laser DAC ++ ++usb:v1209pEAEA* ++ ID_MODEL_FROM_DATABASE=Pinscape Controller ++ ++usb:v1209pEB01* ++ ID_MODEL_FROM_DATABASE=RobotMaker.club EB1 ++ ++usb:v1209pEBA7* ++ ID_MODEL_FROM_DATABASE=VictorGrigoryev USBscope ++ ++usb:v1209pEE00* ++ ID_MODEL_FROM_DATABASE=Explore Embedded SODA(SWD OpenSource Debug Adapter) ++ ++usb:v1209pEE02* ++ ID_MODEL_FROM_DATABASE=Explore Embedded Explore M3 VCOM ++ ++usb:v1209pEE03* ++ ID_MODEL_FROM_DATABASE=Explore Embedded Explore M3 DFU ++ ++usb:v1209pEE2C* ++ ID_MODEL_FROM_DATABASE=jaka USB2RS485 ++ ++usb:v1209pEFFA* ++ ID_MODEL_FROM_DATABASE=EffigyLabs atmega32u4-USB-LUFA-Bootloader ++ ++usb:v1209pEFFE* ++ ID_MODEL_FROM_DATABASE=EffigyLabs Control Pedal ++ ++usb:v1209pF000* ++ ID_MODEL_FROM_DATABASE=Uniti ARC ++ ++usb:v1209pF00D* ++ ID_MODEL_FROM_DATABASE=RomanStepanov Shifter/Pedals Adapter ++ ++usb:v1209pF12E* ++ ID_MODEL_FROM_DATABASE=Michael Bemmerl Feuermelder ++ ++usb:v1209pF16A* ++ ID_MODEL_FROM_DATABASE=uri_ba Cougar TQS adapter ++ ++usb:v1209pF16C* ++ ID_MODEL_FROM_DATABASE=uri_ba adapter for Vipercore's FCC3 Force Sensing Module ++ ++usb:v1209pF380* ++ ID_MODEL_FROM_DATABASE=Windsor Schmidt MD-380 Open Radio Firmware ++ ++usb:v1209pF3FC* ++ ID_MODEL_FROM_DATABASE=dRonin Flight controller-Lumenier Lux ++ ++usb:v1209pF49A* ++ ID_MODEL_FROM_DATABASE=TimVideos.us & HDMI2USB.tv Projects FPGA Programmer & UART Bridge (PIC based Firmware) ++ + usb:v1209pFA11* + ID_MODEL_FROM_DATABASE=moonglow OpenXHC + ++usb:v1209pFA57* ++ ID_MODEL_FROM_DATABASE=3DRacers Pilot Board ++ ++usb:v1209pFA58* ++ ID_MODEL_FROM_DATABASE=3DRacers Pilot Board (Bootloader) ++ ++usb:v1209pFAB1* ++ ID_MODEL_FROM_DATABASE=PAP Mechatronic Technology LamDiNao ++ ++usb:v1209pFACE* ++ ID_MODEL_FROM_DATABASE=Protean Synth Craft ++ ++usb:v1209pFADE* ++ ID_MODEL_FROM_DATABASE=Open Collector dude ++ + usb:v1209pFEED* + ID_MODEL_FROM_DATABASE=ProgramGyar AVR-IR Sender + ++usb:v1209pFFFF* ++ ID_MODEL_FROM_DATABASE=Life2Device Smart House ++ + usb:v120E* + ID_VENDOR_FROM_DATABASE=Hudson Soft Co., Ltd + +@@ -46046,6 +49928,9 @@ usb:v120Fp5260* + usb:v1210* + ID_VENDOR_FROM_DATABASE=DigiTech + ++usb:v1210p000D* ++ ID_MODEL_FROM_DATABASE=RP250 Guitar Multi-Effects Processor ++ + usb:v1210p0016* + ID_MODEL_FROM_DATABASE=RP500 Guitar Multi-Effects Processor + +@@ -46061,6 +49946,33 @@ usb:v121E* + usb:v121Ep3403* + ID_MODEL_FROM_DATABASE=Muzio JM250 Audio Player + ++usb:v121F* ++ ID_VENDOR_FROM_DATABASE=Panini S.p.A. ++ ++usb:v121Fp0001* ++ ID_MODEL_FROM_DATABASE=VisionX without Firmware ++ ++usb:v121Fp0002* ++ ID_MODEL_FROM_DATABASE=VisionX with Firmware ++ ++usb:v121Fp0010* ++ ID_MODEL_FROM_DATABASE=I-Deal ++ ++usb:v121Fp0020* ++ ID_MODEL_FROM_DATABASE=wI-Deal ++ ++usb:v121Fp0021* ++ ID_MODEL_FROM_DATABASE=VisionX Page Scanner Extension ++ ++usb:v121Fp0030* ++ ID_MODEL_FROM_DATABASE=VisionNext ++ ++usb:v121Fp0040* ++ ID_MODEL_FROM_DATABASE=mI:Deal Check Scanner ++ ++usb:v121Fp0041* ++ ID_MODEL_FROM_DATABASE=EverNext Check Scanner ++ + usb:v1220* + ID_VENDOR_FROM_DATABASE=TC Electronic + +@@ -46082,6 +49994,12 @@ usb:v1221* + usb:v1221p3234* + ID_MODEL_FROM_DATABASE=Disk (Thumb drive) + ++usb:v1222* ++ ID_VENDOR_FROM_DATABASE=TiPro ++ ++usb:v1222pFACA* ++ ID_MODEL_FROM_DATABASE=programmable keyboard ++ + usb:v1223* + ID_VENDOR_FROM_DATABASE=SKYCABLE ENTERPRISE. CO., LTD. + +@@ -46193,6 +50111,15 @@ usb:v1235p001A* + usb:v1235p001B* + ID_MODEL_FROM_DATABASE=Impulse 61 + ++usb:v1235p0032* ++ ID_MODEL_FROM_DATABASE=Launchkey 61 ++ ++usb:v1235p0069* ++ ID_MODEL_FROM_DATABASE=Launchpad MK2 ++ ++usb:v1235p0102* ++ ID_MODEL_FROM_DATABASE=LaunchKey Mini MK3 ++ + usb:v1235p4661* + ID_MODEL_FROM_DATABASE=ReMOTE25 + +@@ -46229,12 +50156,27 @@ usb:v1235p8014* + usb:v1235p8016* + ID_MODEL_FROM_DATABASE=Focusrite Scarlett 2i2 + ++usb:v1235p8202* ++ ID_MODEL_FROM_DATABASE=Focusrite Scarlett 2i2 2nd Gen ++ + usb:v1235p8203* + ID_MODEL_FROM_DATABASE=Focusrite Scarlett 6i6 + + usb:v1235p8204* + ID_MODEL_FROM_DATABASE=Scarlett 18i8 2nd Gen + ++usb:v1235p8210* ++ ID_MODEL_FROM_DATABASE=Scarlett 2i2 Camera ++ ++usb:v1235p8211* ++ ID_MODEL_FROM_DATABASE=Scarlett Solo (3rd Gen.) ++ ++usb:v1235p8214* ++ ID_MODEL_FROM_DATABASE=Scarlett 18i8 3rd Gen ++ ++usb:v1235p8215* ++ ID_MODEL_FROM_DATABASE=Scarlett 18i20 3rd Gen ++ + usb:v1241* + ID_VENDOR_FROM_DATABASE=Belkin + +@@ -46265,6 +50207,12 @@ usb:v1241p1603* + usb:v1241pF767* + ID_MODEL_FROM_DATABASE=Keyboard + ++usb:v1243* ++ ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. ++ ++usb:v1243pE000* ++ ID_MODEL_FROM_DATABASE=Unique NFC/RFID reader (keyboard emulation) ++ + usb:v124A* + ID_VENDOR_FROM_DATABASE=AirVast + +@@ -46298,6 +50246,12 @@ usb:v125C* + usb:v125Cp0010* + ID_MODEL_FROM_DATABASE=Alta series CCD + ++usb:v125D* ++ ID_VENDOR_FROM_DATABASE=JMicron ++ ++usb:v125Dp0580* ++ ID_MODEL_FROM_DATABASE=JM580 ++ + usb:v125F* + ID_VENDOR_FROM_DATABASE=A-DATA Technology Co., Ltd. + +@@ -46313,6 +50267,9 @@ usb:v125FpA15A* + usb:v125FpA22A* + ID_MODEL_FROM_DATABASE=DashDrive Elite HE720 500GB + ++usb:v125FpA31A* ++ ID_MODEL_FROM_DATABASE=HV620 Portable HDD ++ + usb:v125FpA91A* + ID_MODEL_FROM_DATABASE=Portable HDD CH91 + +@@ -46403,6 +50360,9 @@ usb:v1275p0002* + usb:v1275p0080* + ID_MODEL_FROM_DATABASE=SkyEye Weather Satellite Receiver + ++usb:v1275p0090* ++ ID_MODEL_FROM_DATABASE=WeatherFax 2000 Demodulator ++ + usb:v1278* + ID_VENDOR_FROM_DATABASE=Starlight Xpress + +@@ -46508,6 +50468,9 @@ usb:v1286p2006* + usb:v1286p203C* + ID_MODEL_FROM_DATABASE=K30326 802.11bgn Wireless Module [Marvell 88W8786U] + ++usb:v1286p204C* ++ ID_MODEL_FROM_DATABASE=Bluetooth and Wireless LAN Composite ++ + usb:v1286p8001* + ID_MODEL_FROM_DATABASE=BLOB boot loader firmware + +@@ -46574,6 +50537,18 @@ usb:v12A7* + usb:v12AB* + ID_VENDOR_FROM_DATABASE=Honey Bee Electronic International Ltd. + ++usb:v12ABp0004* ++ ID_MODEL_FROM_DATABASE=Dance Pad for Xbox 360 ++ ++usb:v12ABp0301* ++ ID_MODEL_FROM_DATABASE=Afterglow Wired Controller for Xbox 360 ++ ++usb:v12ABp0303* ++ ID_MODEL_FROM_DATABASE=Mortal Kombat Klassic FightStick for Xbox 360 ++ ++usb:v12ABp8809* ++ ID_MODEL_FROM_DATABASE=Dance Dance Revolution Dance Pad ++ + usb:v12B8* + ID_VENDOR_FROM_DATABASE=Zhejiang Xinya Electronic Technology Co., Ltd. + +@@ -46665,7 +50640,19 @@ usb:v12D1p1039* + ID_MODEL_FROM_DATABASE=Ideos (tethering mode) + + usb:v12D1p1052* +- ID_MODEL_FROM_DATABASE=MT7-L09 ++ ID_MODEL_FROM_DATABASE=MT7-L09 / P7-L10 / Y330-U01 ++ ++usb:v12D1p1053* ++ ID_MODEL_FROM_DATABASE=P7-L10 (PTP) ++ ++usb:v12D1p1054* ++ ID_MODEL_FROM_DATABASE=P7-L10 (PTP + debug) ++ ++usb:v12D1p1079* ++ ID_MODEL_FROM_DATABASE=GEM-703LT [Honor/MediaPad X2] ++ ++usb:v12D1p107E* ++ ID_MODEL_FROM_DATABASE=P10 smartphone + + usb:v12D1p1404* + ID_MODEL_FROM_DATABASE=EM770W miniPCI WCDMA Modem +@@ -46713,7 +50700,7 @@ usb:v12D1p14DB* + ID_MODEL_FROM_DATABASE=E353/E3131 + + usb:v12D1p14DC* +- ID_MODEL_FROM_DATABASE=E33372 LTE/UMTS/GSM HiLink Modem/Networkcard ++ ID_MODEL_FROM_DATABASE=E3372 LTE/UMTS/GSM HiLink Modem/Networkcard + + usb:v12D1p14F1* + ID_MODEL_FROM_DATABASE=Gobi 3000 HSPA+ Modem +@@ -46742,6 +50729,9 @@ usb:v12D1p1521* + usb:v12D1p155A* + ID_MODEL_FROM_DATABASE=R205 Mobile WiFi (CD-ROM mode) + ++usb:v12D1p1573* ++ ID_MODEL_FROM_DATABASE=ME909u-521 mPCIe LTE/GPS card ++ + usb:v12D1p1575* + ID_MODEL_FROM_DATABASE=K5150 LTE modem + +@@ -46775,12 +50765,21 @@ usb:v12D1p1F01* + usb:v12D1p1F16* + ID_MODEL_FROM_DATABASE=K5150 LTE modem (Mass Storage Mode) + ++usb:v12D1p360E* ++ ID_MODEL_FROM_DATABASE=Y330-U01 (MTP Mode) ++ + usb:v12D1p380B* + ID_MODEL_FROM_DATABASE=WiMAX USB modem(s) + + usb:v12D2* + ID_VENDOR_FROM_DATABASE=LINE TECH INDUSTRIAL CO., LTD. + ++usb:v12D3* ++ ID_VENDOR_FROM_DATABASE=LINAK ++ ++usb:v12D3p0002* ++ ID_MODEL_FROM_DATABASE=DeskLine CBD Control Box ++ + usb:v12D6* + ID_VENDOR_FROM_DATABASE=EMS Dr. Thomas Wuensche + +@@ -46841,6 +50840,9 @@ usb:v12FF* + usb:v12FFp0101* + ID_MODEL_FROM_DATABASE=Advanced RC Servo Controller + ++usb:v1306* ++ ID_VENDOR_FROM_DATABASE=FM20 Barcode Scanner ++ + usb:v1307* + ID_VENDOR_FROM_DATABASE=Transcend Information, Inc. + +@@ -46910,12 +50912,18 @@ usb:v1313p0112* + usb:v1313p8001* + ID_MODEL_FROM_DATABASE=TXP-Series Slot (TXP5001, TXP5004) + ++usb:v1313p8011* ++ ID_MODEL_FROM_DATABASE=BP1 Slit Beam Profiler ++ + usb:v1313p8012* + ID_MODEL_FROM_DATABASE=BC106 Camera Beam Profiler + + usb:v1313p8013* + ID_MODEL_FROM_DATABASE=WFS10 Wavefront Sensor + ++usb:v1313p8016* ++ ID_MODEL_FROM_DATABASE=DMP40 Deformable Mirror ++ + usb:v1313p8017* + ID_MODEL_FROM_DATABASE=BC206 Camera Beam Profiler + +@@ -46931,21 +50939,111 @@ usb:v1313p8021* + usb:v1313p8022* + ID_MODEL_FROM_DATABASE=PM320E Optical Power and Energy Meter + ++usb:v1313p8025* ++ ID_MODEL_FROM_DATABASE=WFS20 Wavefront Sensor ++ + usb:v1313p8030* + ID_MODEL_FROM_DATABASE=ER100 Extinction Ratio Meter + ++usb:v1313p8039* ++ ID_MODEL_FROM_DATABASE=PAX1000 Rotating Waveplate Polarimeter ++ ++usb:v1313p8047* ++ ID_MODEL_FROM_DATABASE=CLD1000 ++ ++usb:v1313p8048* ++ ID_MODEL_FROM_DATABASE=TED4000 ++ ++usb:v1313p8049* ++ ID_MODEL_FROM_DATABASE=LDC4000 ++ ++usb:v1313p804A* ++ ID_MODEL_FROM_DATABASE=ITC4000 ++ ++usb:v1313p8058* ++ ID_MODEL_FROM_DATABASE=LC-100 ++ ++usb:v1313p8060* ++ ID_MODEL_FROM_DATABASE=DC3100 ++ ++usb:v1313p8061* ++ ID_MODEL_FROM_DATABASE=DC4100 ++ ++usb:v1313p8062* ++ ID_MODEL_FROM_DATABASE=DC2100 ++ ++usb:v1313p8065* ++ ID_MODEL_FROM_DATABASE=CS2010 ++ ++usb:v1313p8066* ++ ID_MODEL_FROM_DATABASE=DC4104 ++ + usb:v1313p8070* + ID_MODEL_FROM_DATABASE=PM100D + + usb:v1313p8072* + ID_MODEL_FROM_DATABASE=PM100USB Power and Energy Meter Interface + ++usb:v1313p8073* ++ ID_MODEL_FROM_DATABASE=PM106 Wireless Powermeter Photodiode Sensor ++ ++usb:v1313p8074* ++ ID_MODEL_FROM_DATABASE=PM160T Wireless Powermeter Thermal Sensor ++ ++usb:v1313p8075* ++ ID_MODEL_FROM_DATABASE=PM400 Handheld Optical Power/Energy Meter ++ ++usb:v1313p8076* ++ ID_MODEL_FROM_DATABASE=PM101 Serial PD Power Meter ++ + usb:v1313p8078* + ID_MODEL_FROM_DATABASE=PM100D Compact Power and Energy Meter Console + + usb:v1313p8080* + ID_MODEL_FROM_DATABASE=CCS100 - Compact Spectrometer + ++usb:v1313p8081* ++ ID_MODEL_FROM_DATABASE=CCS100 Compact Spectrometer ++ ++usb:v1313p8083* ++ ID_MODEL_FROM_DATABASE=CCS125 Spectrometer ++ ++usb:v1313p8085* ++ ID_MODEL_FROM_DATABASE=CCS150 UV Spectrometer ++ ++usb:v1313p8087* ++ ID_MODEL_FROM_DATABASE=CCS175 NIR Spectrometer ++ ++usb:v1313p8089* ++ ID_MODEL_FROM_DATABASE=CCS200 Wide Range Spectrometer ++ ++usb:v1313p8090* ++ ID_MODEL_FROM_DATABASE=SPCM Single Photon Counter ++ ++usb:v1313p80A0* ++ ID_MODEL_FROM_DATABASE=LC100 series smart line camera ++ ++usb:v1313p80B0* ++ ID_MODEL_FROM_DATABASE=PM200 Handheld Power and Energy Meter ++ ++usb:v1313p80C0* ++ ID_MODEL_FROM_DATABASE=DC2200 ++ ++usb:v1313p80C9* ++ ID_MODEL_FROM_DATABASE=MTD Series ++ ++usb:v1313p80F0* ++ ID_MODEL_FROM_DATABASE=TSP01 ++ ++usb:v1313p80F1* ++ ID_MODEL_FROM_DATABASE=M2SET Dongle ++ ++usb:v1313p8180* ++ ID_MODEL_FROM_DATABASE=OCT Probe Controller (OCTH-1300) ++ ++usb:v1313p8181* ++ ID_MODEL_FROM_DATABASE=OCT Device ++ + usb:v131D* + ID_VENDOR_FROM_DATABASE=Natural Point + +@@ -46961,6 +51059,12 @@ usb:v131Dp0158* + usb:v1325* + ID_VENDOR_FROM_DATABASE=ams AG + ++usb:v1325p00D6* ++ ID_MODEL_FROM_DATABASE=I2C/SPI InterfaceBoard ++ ++usb:v1325p0C08* ++ ID_MODEL_FROM_DATABASE=Embedded Linux Sensor Bridge ++ + usb:v1325p4002* + ID_MODEL_FROM_DATABASE=I2C Dongle + +@@ -47103,13 +51207,19 @@ usb:v1343p0005* + ID_MODEL_FROM_DATABASE=CY / DNP DSRX1 + + usb:v1343p0006* +- ID_MODEL_FROM_DATABASE=CW-02 ++ ID_MODEL_FROM_DATABASE=CW-02 / OP900ii + + usb:v1343p0007* + ID_MODEL_FROM_DATABASE=DNP DS80DX + + usb:v1343p0008* +- ID_MODEL_FROM_DATABASE=CX2 / DNP DS620 ++ ID_MODEL_FROM_DATABASE=DNP DS620 (old) ++ ++usb:v1343p000A* ++ ID_MODEL_FROM_DATABASE=CX-02 ++ ++usb:v1343p000B* ++ ID_MODEL_FROM_DATABASE=CX-02W + + usb:v1345* + ID_VENDOR_FROM_DATABASE=Sino Lite Technology Corp. +@@ -47201,6 +51311,30 @@ usb:v1357p0503* + usb:v1357p0504* + ID_MODEL_FROM_DATABASE=DEMOJM + ++usb:v1357p1000* ++ ID_MODEL_FROM_DATABASE=Smart Control Touchpad ++ ++usb:v135E* ++ ID_VENDOR_FROM_DATABASE=Insta GmbH ++ ++usb:v135Ep0021* ++ ID_MODEL_FROM_DATABASE=Berker KNX Data Interface ++ ++usb:v135Ep0022* ++ ID_MODEL_FROM_DATABASE=Gira KNX Data Interface ++ ++usb:v135Ep0023* ++ ID_MODEL_FROM_DATABASE=JUNG KNX Data Interface ++ ++usb:v135Ep0024* ++ ID_MODEL_FROM_DATABASE=Merten/Schneider Electric KNX Data Interface ++ ++usb:v135Ep0025* ++ ID_MODEL_FROM_DATABASE=Hager KNX Data Interface ++ ++usb:v135Ep0026* ++ ID_MODEL_FROM_DATABASE=Feller KNX Data Interface ++ + usb:v135F* + ID_VENDOR_FROM_DATABASE=Control Development Inc. + +@@ -47225,6 +51359,9 @@ usb:v1366* + usb:v1366p0101* + ID_MODEL_FROM_DATABASE=J-Link PLUS + ++usb:v1366p1015* ++ ID_MODEL_FROM_DATABASE=J-Link ++ + usb:v136B* + ID_VENDOR_FROM_DATABASE=STEC + +@@ -47288,6 +51425,18 @@ usb:v137B* + usb:v137Bp0002* + ID_MODEL_FROM_DATABASE=SCAPS USC-2 Scanner Controller + ++usb:v137C* ++ ID_VENDOR_FROM_DATABASE=YASKAWA ELECTRIC CORP. ++ ++usb:v137Cp0220* ++ ID_MODEL_FROM_DATABASE=MP Series ++ ++usb:v137Cp0250* ++ ID_MODEL_FROM_DATABASE=SIGMA Series ++ ++usb:v137Cp0401* ++ ID_MODEL_FROM_DATABASE=AC Drive ++ + usb:v1385* + ID_VENDOR_FROM_DATABASE=Netgear, Inc + +@@ -47367,7 +51516,7 @@ usb:v1390* + ID_VENDOR_FROM_DATABASE=TOMTOM B.V. + + usb:v1390p0001* +- ID_MODEL_FROM_DATABASE=GO 520 T/GO 630/ONE XL (v9) ++ ID_MODEL_FROM_DATABASE=GO 520 T / GO 630 / ONE / ONE XL + + usb:v1390p5454* + ID_MODEL_FROM_DATABASE=Blue & Me 2 +@@ -47390,15 +51539,141 @@ usb:v1395* + usb:v1395p0025* + ID_MODEL_FROM_DATABASE=Headset [PC 8] + ++usb:v1395p0026* ++ ID_MODEL_FROM_DATABASE=SC230 ++ ++usb:v1395p0027* ++ ID_MODEL_FROM_DATABASE=SC260 ++ ++usb:v1395p0028* ++ ID_MODEL_FROM_DATABASE=SC230 CTRL ++ ++usb:v1395p0029* ++ ID_MODEL_FROM_DATABASE=SC260 CTRL ++ ++usb:v1395p002A* ++ ID_MODEL_FROM_DATABASE=SC230 for Lync ++ ++usb:v1395p002B* ++ ID_MODEL_FROM_DATABASE=SC260 for Lync ++ ++usb:v1395p002D* ++ ID_MODEL_FROM_DATABASE=BTD-800 ++ ++usb:v1395p002E* ++ ID_MODEL_FROM_DATABASE=Presence ++ ++usb:v1395p0030* ++ ID_MODEL_FROM_DATABASE=CEHS-CI 02 ++ ++usb:v1395p0031* ++ ID_MODEL_FROM_DATABASE=U320 Gaming ++ ++usb:v1395p0032* ++ ID_MODEL_FROM_DATABASE=SC30 for Lync ++ ++usb:v1395p0033* ++ ID_MODEL_FROM_DATABASE=SC60 for Lync ++ ++usb:v1395p0034* ++ ID_MODEL_FROM_DATABASE=SC30 Control ++ ++usb:v1395p0035* ++ ID_MODEL_FROM_DATABASE=SC60 Control ++ ++usb:v1395p0036* ++ ID_MODEL_FROM_DATABASE=SC630 for Lync ++ ++usb:v1395p0037* ++ ID_MODEL_FROM_DATABASE=SC660 for Lync ++ ++usb:v1395p0038* ++ ID_MODEL_FROM_DATABASE=SC630 CTRL ++ ++usb:v1395p0039* ++ ID_MODEL_FROM_DATABASE=SC660 CTRL ++ ++usb:v1395p003F* ++ ID_MODEL_FROM_DATABASE=SP 20 ++ ++usb:v1395p0040* ++ ID_MODEL_FROM_DATABASE=MB Pro 1/2 ++ ++usb:v1395p0041* ++ ID_MODEL_FROM_DATABASE=SP 20 for Lync ++ ++usb:v1395p0042* ++ ID_MODEL_FROM_DATABASE=SP 10 ++ ++usb:v1395p0043* ++ ID_MODEL_FROM_DATABASE=SP 10 for Lync ++ + usb:v1395p0046* + ID_MODEL_FROM_DATABASE=PXC 550 + ++usb:v1395p004A* ++ ID_MODEL_FROM_DATABASE=MOMENTUM M2 OEBT ++ ++usb:v1395p004B* ++ ID_MODEL_FROM_DATABASE=MOMENTUM M2 AEBT ++ ++usb:v1395p004F* ++ ID_MODEL_FROM_DATABASE=SC230 for MS II ++ ++usb:v1395p0050* ++ ID_MODEL_FROM_DATABASE=SC260 for MS II ++ ++usb:v1395p0051* ++ ID_MODEL_FROM_DATABASE=USB-ED CC 01 ++ ++usb:v1395p0058* ++ ID_MODEL_FROM_DATABASE=USB-ED CC 01 for MS ++ ++usb:v1395p0059* ++ ID_MODEL_FROM_DATABASE=SC40 for MS ++ ++usb:v1395p005A* ++ ID_MODEL_FROM_DATABASE=SC70 for MS ++ ++usb:v1395p005B* ++ ID_MODEL_FROM_DATABASE=SC40 CTRL ++ ++usb:v1395p005C* ++ ID_MODEL_FROM_DATABASE=SC70 CTRL ++ ++usb:v1395p0060* ++ ID_MODEL_FROM_DATABASE=SCx5 MS ++ ++usb:v1395p0061* ++ ID_MODEL_FROM_DATABASE=SCx5 CTRL ++ ++usb:v1395p0064* ++ ID_MODEL_FROM_DATABASE=MB 660 MS ++ ++usb:v1395p0065* ++ ID_MODEL_FROM_DATABASE=MB 660 ++ ++usb:v1395p0066* ++ ID_MODEL_FROM_DATABASE=SP 20 D UC ++ ++usb:v1395p0067* ++ ID_MODEL_FROM_DATABASE=SP 20 D MS ++ ++usb:v1395p006B* ++ ID_MODEL_FROM_DATABASE=SC5x5 MS ++ ++usb:v1395p0072* ++ ID_MODEL_FROM_DATABASE=Headset ++ + usb:v1395p3556* + ID_MODEL_FROM_DATABASE=USB Headset + + usb:v1397* + ID_VENDOR_FROM_DATABASE=BEHRINGER International GmbH + ++usb:v1397p0004* ++ ID_MODEL_FROM_DATABASE=FCA1616 ++ + usb:v1397p00BC* + ID_MODEL_FROM_DATABASE=BCF2000 + +@@ -47702,6 +51977,9 @@ usb:v13D3p3394* + usb:v13D3p3474* + ID_MODEL_FROM_DATABASE=Atheros AR3012 Bluetooth + ++usb:v13D3p3526* ++ ID_MODEL_FROM_DATABASE=Bluetooth Radio ++ + usb:v13D3p5070* + ID_MODEL_FROM_DATABASE=Webcam + +@@ -47726,6 +52004,15 @@ usb:v13D3p5130* + usb:v13D3p5134* + ID_MODEL_FROM_DATABASE=Integrated Webcam + ++usb:v13D3p5615* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v13D3p5670* ++ ID_MODEL_FROM_DATABASE=HP TrueVision HD ++ ++usb:v13D3p5682* ++ ID_MODEL_FROM_DATABASE=SunplusIT Integrated Camera ++ + usb:v13D3p5702* + ID_MODEL_FROM_DATABASE=UVC VGA Webcam + +@@ -47735,12 +52022,18 @@ usb:v13D3p5710* + usb:v13D3p5716* + ID_MODEL_FROM_DATABASE=UVC VGA Webcam + ++usb:v13D3p5A07* ++ ID_MODEL_FROM_DATABASE=VGA UVC WebCam ++ + usb:v13D3p7020* + ID_MODEL_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + + usb:v13D3p7022* + ID_MODEL_FROM_DATABASE=DTV-DVB UDST7022BDA DVB-S Box(Without HID) + ++usb:v13D3p784B* ++ ID_MODEL_FROM_DATABASE=XHC Camera ++ + usb:v13D7* + ID_VENDOR_FROM_DATABASE=Guidance Software, Inc. + +@@ -47795,6 +52088,9 @@ usb:v13EEp0003* + usb:v13FD* + ID_VENDOR_FROM_DATABASE=Initio Corporation + ++usb:v13FDp0550* ++ ID_MODEL_FROM_DATABASE=INIC-1530 PATA Bridge ++ + usb:v13FDp0840* + ID_MODEL_FROM_DATABASE=INIC-1618L SATA + +@@ -47828,9 +52124,15 @@ usb:v13FDp1E40* + usb:v13FDp2040* + ID_MODEL_FROM_DATABASE=Samsung Writemaster external DVD writer + ++usb:v13FDp3920* ++ ID_MODEL_FROM_DATABASE=INIC-3619PN SATA Bridge ++ + usb:v13FDp3940* + ID_MODEL_FROM_DATABASE=external DVD burner ECD819-SU3 + ++usb:v13FDp3960* ++ ID_MODEL_FROM_DATABASE=INIC-3639 ++ + usb:v13FDp3E40* + ID_MODEL_FROM_DATABASE=ZALMAN ZM-VE350 + +@@ -47867,18 +52169,27 @@ usb:v13FEp3100* + usb:v13FEp3123* + ID_MODEL_FROM_DATABASE=Verbatim STORE N GO 4GB + ++usb:v13FEp3200* ++ ID_MODEL_FROM_DATABASE=flash drive (2GB, EMTEC) ++ + usb:v13FEp3600* + ID_MODEL_FROM_DATABASE=flash drive (4GB, EMTEC) + + usb:v13FEp3800* + ID_MODEL_FROM_DATABASE=Rage XT Flash Drive + ++usb:v13FEp3D00* ++ ID_MODEL_FROM_DATABASE=Flash Drive ++ + usb:v13FEp3E00* + ID_MODEL_FROM_DATABASE=Flash Drive + + usb:v13FEp4100* + ID_MODEL_FROM_DATABASE=Flash drive + ++usb:v13FEp4200* ++ ID_MODEL_FROM_DATABASE=Platinum USB drive mini ++ + usb:v13FEp5000* + ID_MODEL_FROM_DATABASE=USB flash drive (32 GB SHARKOON Accelerate) + +@@ -47888,6 +52199,12 @@ usb:v13FEp5100* + usb:v13FEp5200* + ID_MODEL_FROM_DATABASE=DataTraveler R3.0 + ++usb:v13FEp5500* ++ ID_MODEL_FROM_DATABASE=Flash drive ++ ++usb:v13FEp6300* ++ ID_MODEL_FROM_DATABASE=SP Mobile C31 (64GB) ++ + usb:v1400* + ID_VENDOR_FROM_DATABASE=Axxion Group Corp. + +@@ -47903,6 +52220,12 @@ usb:v1403p0001* + usb:v1403p0003* + ID_MODEL_FROM_DATABASE=Digital Photo Frame (DPF-1104) + ++usb:v1404* ++ ID_VENDOR_FROM_DATABASE=Fundamental Software, Inc. ++ ++usb:v1404pCDDC* ++ ID_MODEL_FROM_DATABASE=Dongle ++ + usb:v1409* + ID_VENDOR_FROM_DATABASE=IDS Imaging Development Systems GmbH + +@@ -47912,6 +52235,9 @@ usb:v1409p1000* + usb:v1409p1485* + ID_MODEL_FROM_DATABASE=uEye UI1485 + ++usb:v1409p3240* ++ ID_MODEL_FROM_DATABASE=uEye UI3240 ++ + usb:v140E* + ID_VENDOR_FROM_DATABASE=Telechips, Inc. + +@@ -48095,9 +52421,18 @@ usb:v1430p0150* + usb:v1430p4734* + ID_MODEL_FROM_DATABASE=Guitar Hero4 hub + ++usb:v1430p4748* ++ ID_MODEL_FROM_DATABASE=Guitar Hero X-plorer ++ + usb:v1430p474B* + ID_MODEL_FROM_DATABASE=Guitar Hero MIDI interface + ++usb:v1430p8888* ++ ID_MODEL_FROM_DATABASE=TX6500+ Dance Pad ++ ++usb:v1430pF801* ++ ID_MODEL_FROM_DATABASE=Controller ++ + usb:v1431* + ID_VENDOR_FROM_DATABASE=Pertech Resources, Inc. + +@@ -48188,6 +52523,9 @@ usb:v1452* + usb:v1452p8B01* + ID_MODEL_FROM_DATABASE=DS620 + ++usb:v1452p9001* ++ ID_MODEL_FROM_DATABASE=DS820 ++ + usb:v1453* + ID_VENDOR_FROM_DATABASE=Radio Shack + +@@ -48263,6 +52601,18 @@ usb:v145Fp0167* + usb:v145Fp0176* + ID_MODEL_FROM_DATABASE=Isla Keyboard + ++usb:v145Fp019F* ++ ID_MODEL_FROM_DATABASE=17676 Webcam ++ ++usb:v145Fp01E5* ++ ID_MODEL_FROM_DATABASE=Keyboard [GXT 830] ++ ++usb:v145Fp0212* ++ ID_MODEL_FROM_DATABASE=Panora Widescreen Graphic Tablet ++ ++usb:v145Fp023F* ++ ID_MODEL_FROM_DATABASE=Mouse [GXT 168] ++ + usb:v1460* + ID_VENDOR_FROM_DATABASE=Tatung Co. + +@@ -48281,6 +52631,15 @@ usb:v1462p5512* + usb:v1462p8807* + ID_MODEL_FROM_DATABASE=DIGIVOX mini III [af9015] + ++usb:v146B* ++ ID_VENDOR_FROM_DATABASE=BigBen Interactive ++ ++usb:v146Bp0601* ++ ID_MODEL_FROM_DATABASE=Controller for Xbox 360 ++ ++usb:v146Bp0902* ++ ID_MODEL_FROM_DATABASE=Wired Mini PS3 Game Controller ++ + usb:v1472* + ID_VENDOR_FROM_DATABASE=Huawei-3Com + +@@ -48476,6 +52835,9 @@ usb:v1493p001C* + usb:v1493p001D* + ID_MODEL_FROM_DATABASE=Greentit [Ambit2 R] + ++usb:v1493p001E* ++ ID_MODEL_FROM_DATABASE=Ibisbill [Ambit3 Run] ++ + usb:v1497* + ID_VENDOR_FROM_DATABASE=Panstrong Company Ltd. + +@@ -48488,6 +52850,9 @@ usb:v1498pA090* + usb:v149A* + ID_VENDOR_FROM_DATABASE=Imagination Technologies + ++usb:v149Ap069B* ++ ID_MODEL_FROM_DATABASE=PURE Digital Evoke-1XT Tri-band ++ + usb:v149Ap2107* + ID_MODEL_FROM_DATABASE=DBX1 DSP core + +@@ -48524,6 +52889,9 @@ usb:v14AF* + usb:v14B0* + ID_VENDOR_FROM_DATABASE=StarTech.com Ltd. + ++usb:v14B0p3410* ++ ID_MODEL_FROM_DATABASE=Serial Adapter ICUSB2321X [TUSB3410I] ++ + usb:v14B2* + ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp. + +@@ -48614,6 +52982,9 @@ usb:v14CDp125C* + usb:v14CDp127B* + ID_MODEL_FROM_DATABASE=SDXC Reader + ++usb:v14CDp168A* ++ ID_MODEL_FROM_DATABASE=Elecom Co., Ltd MR-K013 Multicard Reader ++ + usb:v14CDp6116* + ID_MODEL_FROM_DATABASE=M6116 SATA Bridge + +@@ -48677,9 +53048,36 @@ usb:v14EApAB13* + usb:v14ED* + ID_VENDOR_FROM_DATABASE=Shure Inc. + ++usb:v14EDp1000* ++ ID_MODEL_FROM_DATABASE=MV5 ++ ++usb:v14EDp1002* ++ ID_MODEL_FROM_DATABASE=MV51 ++ ++usb:v14EDp1003* ++ ID_MODEL_FROM_DATABASE=MVi ++ ++usb:v14EDp1004* ++ ID_MODEL_FROM_DATABASE=SHA900 ++ ++usb:v14EDp1005* ++ ID_MODEL_FROM_DATABASE=KSE1500 ++ ++usb:v14EDp1011* ++ ID_MODEL_FROM_DATABASE=MV88+ ++ ++usb:v14EDp1100* ++ ID_MODEL_FROM_DATABASE=ANIUSB-MATRIX ++ ++usb:v14EDp1101* ++ ID_MODEL_FROM_DATABASE=P300 ++ + usb:v14EDp29B6* + ID_MODEL_FROM_DATABASE=X2u Adapter + ++usb:v14EDp3000* ++ ID_MODEL_FROM_DATABASE=RMCE-USB ++ + usb:v14F7* + ID_VENDOR_FROM_DATABASE=TechniSat Digital GmbH + +@@ -48704,6 +53102,15 @@ usb:v1500* + usb:v1501* + ID_VENDOR_FROM_DATABASE=Pine-Tum Enterprise Co., Ltd. + ++usb:v1504* ++ ID_VENDOR_FROM_DATABASE=Bixolon CO LTD ++ ++usb:v1504p001F* ++ ID_MODEL_FROM_DATABASE=SRP-350II Thermal Receipt Printer ++ ++usb:v1508* ++ ID_VENDOR_FROM_DATABASE=Fibocom ++ + usb:v1509* + ID_VENDOR_FROM_DATABASE=First International Computer, Inc. + +@@ -48965,11 +53372,20 @@ usb:v152Dp0551* + usb:v152Dp0561* + ID_MODEL_FROM_DATABASE=JMS551 - Sharkoon SATA QuickPort Duo + ++usb:v152Dp0562* ++ ID_MODEL_FROM_DATABASE=JMS567 SATA 6Gb/s bridge ++ + usb:v152Dp0567* + ID_MODEL_FROM_DATABASE=JMS567 SATA 6Gb/s bridge + ++usb:v152Dp0576* ++ ID_MODEL_FROM_DATABASE=Gen1 SATA 6Gb/s Bridge ++ + usb:v152Dp0578* +- ID_MODEL_FROM_DATABASE=JMS567 SATA 6Gb/s bridge ++ ID_MODEL_FROM_DATABASE=JMS578 SATA 6Gb/s ++ ++usb:v152Dp0583* ++ ID_MODEL_FROM_DATABASE=JMS583Gen 2 to PCIe Gen3x2 Bridge + + usb:v152Dp0770* + ID_MODEL_FROM_DATABASE=Alienware Integrated Webcam +@@ -48977,6 +53393,9 @@ usb:v152Dp0770* + usb:v152Dp1561* + ID_MODEL_FROM_DATABASE=JMS561U two ports SATA 6Gb/s bridge + ++usb:v152Dp1576* ++ ID_MODEL_FROM_DATABASE=External Disk 3.0 ++ + usb:v152Dp2329* + ID_MODEL_FROM_DATABASE=JM20329 SATA Bridge + +@@ -49019,12 +53438,24 @@ usb:v152Dp3562* + usb:v152Dp3569* + ID_MODEL_FROM_DATABASE=JMS566 SATA 3Gb/s bridge + ++usb:v152Dp578E* ++ ID_MODEL_FROM_DATABASE=JMS578 SATA 6Gb/s bridge ++ ++usb:v152Dp8561* ++ ID_MODEL_FROM_DATABASE=salcar docking station two disks ++ + usb:v152E* + ID_VENDOR_FROM_DATABASE=LG (HLDS) + ++usb:v152Ep1640* ++ ID_MODEL_FROM_DATABASE=INIC-1605 SATA Bridge ++ + usb:v152Ep2507* + ID_MODEL_FROM_DATABASE=PL-2507 IDE Controller + ++usb:v152Ep2571* ++ ID_MODEL_FROM_DATABASE=GP08NU6W DVD-RW ++ + usb:v152EpE001* + ID_MODEL_FROM_DATABASE=GSA-5120D DVD-RW + +@@ -49034,38 +53465,143 @@ usb:v1532* + usb:v1532p0001* + ID_MODEL_FROM_DATABASE=RZ01-020300 Optical Mouse [Diamondback] + ++usb:v1532p0002* ++ ID_MODEL_FROM_DATABASE=Diamondback Optical Mouse ++ + usb:v1532p0003* + ID_MODEL_FROM_DATABASE=Krait Mouse + ++usb:v1532p0005* ++ ID_MODEL_FROM_DATABASE=Boomslang CE ++ + usb:v1532p0007* + ID_MODEL_FROM_DATABASE=DeathAdder Mouse + ++usb:v1532p0009* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Tempest Habu] ++ ++usb:v1532p000A* ++ ID_MODEL_FROM_DATABASE=Mamba (Wired) ++ ++usb:v1532p000C* ++ ID_MODEL_FROM_DATABASE=Lachesis ++ ++usb:v1532p000D* ++ ID_MODEL_FROM_DATABASE=DiamondBack 3G ++ ++usb:v1532p000E* ++ ID_MODEL_FROM_DATABASE=Megalodon ++ ++usb:v1532p000F* ++ ID_MODEL_FROM_DATABASE=Mamba (Wireless) ++ ++usb:v1532p0012* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Salmosa] ++ + usb:v1532p0013* +- ID_MODEL_FROM_DATABASE=Orochi mouse ++ ID_MODEL_FROM_DATABASE=Orochi 2011 + + usb:v1532p0015* + ID_MODEL_FROM_DATABASE=Naga Mouse + + usb:v1532p0016* +- ID_MODEL_FROM_DATABASE=DeathAdder Mouse ++ ID_MODEL_FROM_DATABASE=DeathAdder 3.5G + + usb:v1532p0017* + ID_MODEL_FROM_DATABASE=RZ01-0035 Laser Gaming Mouse [Imperator] + ++usb:v1532p0019* ++ ID_MODEL_FROM_DATABASE=Marauder ++ ++usb:v1532p001A* ++ ID_MODEL_FROM_DATABASE=Spectre ++ ++usb:v1532p001B* ++ ID_MODEL_FROM_DATABASE=Gaming Headset ++ + usb:v1532p001C* + ID_MODEL_FROM_DATABASE=RZ01-0036 Optical Gaming Mouse [Abyssus] + ++usb:v1532p001E* ++ ID_MODEL_FROM_DATABASE=Lachesis (5600 DPI) ++ ++usb:v1532p001F* ++ ID_MODEL_FROM_DATABASE=Naga Epic (Wired) ++ ++usb:v1532p0020* ++ ID_MODEL_FROM_DATABASE=Abyssus 1800 ++ ++usb:v1532p0021* ++ ID_MODEL_FROM_DATABASE=Naga Epic Dock (Wireless, Bluetooth) ++ ++usb:v1532p0022* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [TRON] ++ ++usb:v1532p0023* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [TRON] ++ + usb:v1532p0024* +- ID_MODEL_FROM_DATABASE=Mamba ++ ID_MODEL_FROM_DATABASE=Mamba 2012 (Wired) ++ ++usb:v1532p0025* ++ ID_MODEL_FROM_DATABASE=Mamba 2012 (Wireless) ++ ++usb:v1532p0029* ++ ID_MODEL_FROM_DATABASE=DeathAdder Black Edition ++ ++usb:v1532p002A* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Star Wars: The Old Republic] ++ ++usb:v1532p002B* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [Star Wars: The Old Republic] ++ ++usb:v1532p002C* ++ ID_MODEL_FROM_DATABASE=Gaming Headset [Star Wars: The Old Republic] + + usb:v1532p002E* +- ID_MODEL_FROM_DATABASE=RZ01-0058 Gaming Mouse [Naga] ++ ID_MODEL_FROM_DATABASE=RZ01-0058 Gaming Mouse [Naga 2012] + + usb:v1532p002F* + ID_MODEL_FROM_DATABASE=Imperator 2012 + ++usb:v1532p0031* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse Dock [Star Wars: The Old Republic] ++ ++usb:v1532p0032* ++ ID_MODEL_FROM_DATABASE=Ouroboros 2012 (Wired) ++ ++usb:v1532p0033* ++ ID_MODEL_FROM_DATABASE=Ouroboros 2012 (Wireless) ++ ++usb:v1532p0034* ++ ID_MODEL_FROM_DATABASE=Taipan ++ ++usb:v1532p0035* ++ ID_MODEL_FROM_DATABASE=Krait 2013 Essential ++ + usb:v1532p0036* +- ID_MODEL_FROM_DATABASE=RZ01-0075, Gaming Mouse [Naga Hex] ++ ID_MODEL_FROM_DATABASE=RZ01-0075, Gaming Mouse [Naga Hex (Red)] ++ ++usb:v1532p0037* ++ ID_MODEL_FROM_DATABASE=DeathAdder 2013 ++ ++usb:v1532p0038* ++ ID_MODEL_FROM_DATABASE=DeathAdder 1800 ++ ++usb:v1532p0039* ++ ID_MODEL_FROM_DATABASE=Orochi 2013 ++ ++usb:v1532p003E* ++ ID_MODEL_FROM_DATABASE=Naga Epic Chroma (Wired) ++ ++usb:v1532p003F* ++ ID_MODEL_FROM_DATABASE=Naga Epic Chroma (Wireless) ++ ++usb:v1532p0040* ++ ID_MODEL_FROM_DATABASE=Naga 2014 ++ ++usb:v1532p0041* ++ ID_MODEL_FROM_DATABASE=Naga Hex + + usb:v1532p0042* + ID_MODEL_FROM_DATABASE=Abyssus 2014 +@@ -49083,7 +53619,127 @@ usb:v1532p0046* + ID_MODEL_FROM_DATABASE=Mamba 2015 Tournament Edition [RZ01-01370100-R3] + + usb:v1532p0048* +- ID_MODEL_FROM_DATABASE=Orochi (Wired) ++ ID_MODEL_FROM_DATABASE=Orochi 2015 (Wired) ++ ++usb:v1532p004A* ++ ID_MODEL_FROM_DATABASE=RZ03-0133 Gaming Lapboard, Keyboard Mouse Combo, Dongle [Turret Dongle] ++ ++usb:v1532p004C* ++ ID_MODEL_FROM_DATABASE=Diamondback Chroma ++ ++usb:v1532p004D* ++ ID_MODEL_FROM_DATABASE=DeathAdder 2000 (Cynosa Pro Bundle) ++ ++usb:v1532p004F* ++ ID_MODEL_FROM_DATABASE=RZ01-0145, Gaming Mouse [DeathAdder 2000 (Alternate)] ++ ++usb:v1532p0050* ++ ID_MODEL_FROM_DATABASE=Naga Hex V2 ++ ++usb:v1532p0053* ++ ID_MODEL_FROM_DATABASE=Naga Chroma ++ ++usb:v1532p0054* ++ ID_MODEL_FROM_DATABASE=DeathAdder 3500 ++ ++usb:v1532p0056* ++ ID_MODEL_FROM_DATABASE=Orochi 2015 (Wireless) ++ ++usb:v1532p0059* ++ ID_MODEL_FROM_DATABASE=RZ01-0212 Gaming Mouse [Lancehead (Wired)] ++ ++usb:v1532p005A* ++ ID_MODEL_FROM_DATABASE=RZ01-0212 Gaming Mouse [Lancehead (Wireless)] ++ ++usb:v1532p005B* ++ ID_MODEL_FROM_DATABASE=Abyssus V2 ++ ++usb:v1532p005C* ++ ID_MODEL_FROM_DATABASE=DeathAdder Elite ++ ++usb:v1532p005E* ++ ID_MODEL_FROM_DATABASE=Abyssus 2000 ++ ++usb:v1532p005F* ++ ID_MODEL_FROM_DATABASE=DeathAdder 2000 ++ ++usb:v1532p0060* ++ ID_MODEL_FROM_DATABASE=RZ01-0213 Gaming Mouse [Lancehead Tournament Edition] ++ ++usb:v1532p0062* ++ ID_MODEL_FROM_DATABASE=Atheris ++ ++usb:v1532p0064* ++ ID_MODEL_FROM_DATABASE=Basilisk ++ ++usb:v1532p0065* ++ ID_MODEL_FROM_DATABASE=RZ01-0265, Gaming Mouse [Basilisk Essential] ++ ++usb:v1532p0067* ++ ID_MODEL_FROM_DATABASE=Naga Trinity ++ ++usb:v1532p0068* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse Mat [Firefly Hyperflux] ++ ++usb:v1532p0069* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Mamba Hyperflux] ++ ++usb:v1532p006A* ++ ID_MODEL_FROM_DATABASE=Abyssus Elite (D.Va Edition) ++ ++usb:v1532p006B* ++ ID_MODEL_FROM_DATABASE=Abyssus Essential ++ ++usb:v1532p006C* ++ ID_MODEL_FROM_DATABASE=Mamba Elite (Wired) ++ ++usb:v1532p006E* ++ ID_MODEL_FROM_DATABASE=DeathAdder Essential ++ ++usb:v1532p006F* ++ ID_MODEL_FROM_DATABASE=RZ01-0257 Gaming Mouse [Lancehead Wireless (2019, Wireless, Receiver)] ++ ++usb:v1532p0070* ++ ID_MODEL_FROM_DATABASE=RZ01-0257 Gaming Mouse [Lancehead Wireless (2019, Wired)] ++ ++usb:v1532p0071* ++ ID_MODEL_FROM_DATABASE=RZ01-0254 Gaming Mouse [DeathAdder Essential White Edition] ++ ++usb:v1532p0072* ++ ID_MODEL_FROM_DATABASE=Mamba 2018 (Wireless) ++ ++usb:v1532p0073* ++ ID_MODEL_FROM_DATABASE=Mamba 2018 (Wired) ++ ++usb:v1532p0078* ++ ID_MODEL_FROM_DATABASE=Viper (wired) ++ ++usb:v1532p007A* ++ ID_MODEL_FROM_DATABASE=RC30-0305 Gaming Mouse [Viper Ultimate (Wired)] ++ ++usb:v1532p007B* ++ ID_MODEL_FROM_DATABASE=RC30-0305 Gaming Mouse Dongle [Viper Ultimate (Wireless)] ++ ++usb:v1532p007E* ++ ID_MODEL_FROM_DATABASE=RC30-030502 Mouse Dock ++ ++usb:v1532p0083* ++ ID_MODEL_FROM_DATABASE=RC30-0315, Gaming Mouse [Basilisk X HyperSpeed] ++ ++usb:v1532p0084* ++ ID_MODEL_FROM_DATABASE=RZ01-0321 Gaming Mouse [DeathAdder V2] ++ ++usb:v1532p0085* ++ ID_MODEL_FROM_DATABASE=RZ01-0316 Gaming Mouse [Basilisk V2] ++ ++usb:v1532p0086* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Basilisk Ultimate, Wired] ++ ++usb:v1532p0088* ++ ID_MODEL_FROM_DATABASE=Gaming Mouse [Basilisk Ultimate, Wireless, Receiver] ++ ++usb:v1532p008A* ++ ID_MODEL_FROM_DATABASE=RZ01-0325, Gaming Mouse [Viper Mini] + + usb:v1532p0101* + ID_MODEL_FROM_DATABASE=Copperhead Mouse +@@ -49091,17 +53747,50 @@ usb:v1532p0101* + usb:v1532p0102* + ID_MODEL_FROM_DATABASE=Tarantula Keyboard + ++usb:v1532p0103* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [Reclusa] ++ ++usb:v1532p0105* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [ProType] ++ ++usb:v1532p0106* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [ProType] ++ + usb:v1532p0109* + ID_MODEL_FROM_DATABASE=Lycosa Keyboard + ++usb:v1532p010B* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [Arctosa] ++ + usb:v1532p010D* + ID_MODEL_FROM_DATABASE=BlackWidow Ultimate 2012 + ++usb:v1532p010E* ++ ID_MODEL_FROM_DATABASE=BlackWidow Classic (Alternate) ++ ++usb:v1532p010F* ++ ID_MODEL_FROM_DATABASE=Anansi ++ ++usb:v1532p0110* ++ ID_MODEL_FROM_DATABASE=Cyclosa ++ ++usb:v1532p0111* ++ ID_MODEL_FROM_DATABASE=Nostromo ++ + usb:v1532p0113* + ID_MODEL_FROM_DATABASE=RZ07-0074 Gaming Keypad [Orbweaver] + ++usb:v1532p0114* ++ ID_MODEL_FROM_DATABASE=DeathStalker Ultimate ++ ++usb:v1532p0116* ++ ID_MODEL_FROM_DATABASE=Blade Pro (2015) ++ + usb:v1532p0118* +- ID_MODEL_FROM_DATABASE=RZ03-0080, Gaming Keyboard [Deathstalker] ++ ID_MODEL_FROM_DATABASE=RZ03-0080, Gaming Keyboard [Deathstalker Essential] ++ ++usb:v1532p0119* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [Lycosa] + + usb:v1532p011A* + ID_MODEL_FROM_DATABASE=BlackWidow Ultimate 2013 +@@ -49109,35 +53798,317 @@ usb:v1532p011A* + usb:v1532p011B* + ID_MODEL_FROM_DATABASE=BlackWidow Classic + ++usb:v1532p011C* ++ ID_MODEL_FROM_DATABASE=BlackWidow Tournament Edition Stealth ++ ++usb:v1532p011D* ++ ID_MODEL_FROM_DATABASE=Blade 2013 ++ ++usb:v1532p011E* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard Dock [Edge Keyboard Dock] ++ ++usb:v1532p011F* ++ ID_MODEL_FROM_DATABASE=Deathstalker Essential 2014 ++ ++usb:v1532p0200* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [Reclusa] ++ ++usb:v1532p0201* ++ ID_MODEL_FROM_DATABASE=Tartarus ++ ++usb:v1532p0202* ++ ID_MODEL_FROM_DATABASE=DeathStalker Expert ++ + usb:v1532p0203* + ID_MODEL_FROM_DATABASE=BlackWidow Chroma + ++usb:v1532p0204* ++ ID_MODEL_FROM_DATABASE=DeathStalker Chroma ++ + usb:v1532p0205* + ID_MODEL_FROM_DATABASE=Blade Stealth + ++usb:v1532p0207* ++ ID_MODEL_FROM_DATABASE=Orbweaver Chroma keypad ++ + usb:v1532p0208* +- ID_MODEL_FROM_DATABASE=Tartarus ++ ID_MODEL_FROM_DATABASE=Tartarus Chroma + + usb:v1532p0209* + ID_MODEL_FROM_DATABASE=BlackWidow Tournament Edition Chroma + ++usb:v1532p020D* ++ ID_MODEL_FROM_DATABASE=Cynosa Pro keyboard (Cynosa Pro Bundle) ++ ++usb:v1532p020F* ++ ID_MODEL_FROM_DATABASE=Blade QHD ++ ++usb:v1532p0210* ++ ID_MODEL_FROM_DATABASE=Blade Pro (Late 2016) ++ ++usb:v1532p0211* ++ ID_MODEL_FROM_DATABASE=BlackWidow Chroma (Overwatch) ++ + usb:v1532p0214* + ID_MODEL_FROM_DATABASE=BlackWidow Ultimate 2016 + ++usb:v1532p0215* ++ ID_MODEL_FROM_DATABASE=Core ++ + usb:v1532p0216* + ID_MODEL_FROM_DATABASE=BlackWidow X Chroma + ++usb:v1532p0217* ++ ID_MODEL_FROM_DATABASE=BlackWidow X Ultimate ++ + usb:v1532p021A* + ID_MODEL_FROM_DATABASE=BlackWidow X Tournament Edition Chroma + ++usb:v1532p021B* ++ ID_MODEL_FROM_DATABASE=Gaming Keyboard [BlackWidow X Tournament Edition] ++ ++usb:v1532p021E* ++ ID_MODEL_FROM_DATABASE=Ornata Chroma ++ ++usb:v1532p021F* ++ ID_MODEL_FROM_DATABASE=Ornata ++ + usb:v1532p0220* + ID_MODEL_FROM_DATABASE=Blade Stealth (2016) + ++usb:v1532p0221* ++ ID_MODEL_FROM_DATABASE=RZ03-0203 Gaming Keyboard [BlackWidow Chroma V2] ++ ++usb:v1532p0224* ++ ID_MODEL_FROM_DATABASE=Blade (Late 2016) ++ ++usb:v1532p0225* ++ ID_MODEL_FROM_DATABASE=Blade Pro (2017) ++ ++usb:v1532p0226* ++ ID_MODEL_FROM_DATABASE=Huntsman Elite ++ ++usb:v1532p0227* ++ ID_MODEL_FROM_DATABASE=Huntsman ++ ++usb:v1532p0228* ++ ID_MODEL_FROM_DATABASE=BlackWidow Elite ++ ++usb:v1532p022A* ++ ID_MODEL_FROM_DATABASE=Cynosa Chroma ++ ++usb:v1532p022B* ++ ID_MODEL_FROM_DATABASE=Tartarus V2 ++ ++usb:v1532p022C* ++ ID_MODEL_FROM_DATABASE=Cynosa Chroma Pro ++ ++usb:v1532p022D* ++ ID_MODEL_FROM_DATABASE=Blade Stealth (Mid 2017) ++ ++usb:v1532p022F* ++ ID_MODEL_FROM_DATABASE=Blade Pro FullHD (2017) ++ ++usb:v1532p0232* ++ ID_MODEL_FROM_DATABASE=Blade Stealth (Late 2017) ++ ++usb:v1532p0233* ++ ID_MODEL_FROM_DATABASE=Blade 15 (2018) ++ ++usb:v1532p0234* ++ ID_MODEL_FROM_DATABASE=Blade Pro 17 (2019) ++ ++usb:v1532p0235* ++ ID_MODEL_FROM_DATABASE=BlackWidow Lite (2018) ++ ++usb:v1532p0237* ++ ID_MODEL_FROM_DATABASE=BlackWidow Essential ++ ++usb:v1532p0239* ++ ID_MODEL_FROM_DATABASE=Blade Stealth (2019) ++ ++usb:v1532p023A* ++ ID_MODEL_FROM_DATABASE=Blade 15 (2019) Advanced ++ ++usb:v1532p023B* ++ ID_MODEL_FROM_DATABASE=Blade 15 (2018) Base Model ++ ++usb:v1532p023F* ++ ID_MODEL_FROM_DATABASE=RZ03-0274 Gaming Keyboard [Cynosa Lite] ++ ++usb:v1532p0240* ++ ID_MODEL_FROM_DATABASE=Blade 15 (2018) Mercury ++ ++usb:v1532p0241* ++ ID_MODEL_FROM_DATABASE=BlackWidow (2019) ++ ++usb:v1532p0243* ++ ID_MODEL_FROM_DATABASE=Huntsman Tournament Edition ++ ++usb:v1532p0244* ++ ID_MODEL_FROM_DATABASE=RZ07-0311 Gaming Keypad [Tartarus Pro] ++ ++usb:v1532p0245* ++ ID_MODEL_FROM_DATABASE=Blade 15 (Mid 2019) Mercury ++ ++usb:v1532p0246* ++ ID_MODEL_FROM_DATABASE=Blade 15 (Mid 2019) Base Model ++ ++usb:v1532p024A* ++ ID_MODEL_FROM_DATABASE=Blade Stealth (Late 2019) ++ ++usb:v1532p024B* ++ ID_MODEL_FROM_DATABASE=Gaming Laptop [Blade 15 Advanced (Late 2019)] ++ ++usb:v1532p024C* ++ ID_MODEL_FROM_DATABASE=Gaming Laptop [Blade Pro (Late 2019)] ++ ++usb:v1532p024D* ++ ID_MODEL_FROM_DATABASE=Blade 15 Studio Edition (2019) ++ ++usb:v1532p0253* ++ ID_MODEL_FROM_DATABASE=RZ09-0330, Gaming Laptop [Blade 15 Advanced (Early 2020)] ++ ++usb:v1532p0255* ++ ID_MODEL_FROM_DATABASE=RZ09-0328, Gaming Laptop [Blade 15 Base Model (2020)] ++ ++usb:v1532p0256* ++ ID_MODEL_FROM_DATABASE=RZ09--0329, Gaming Laptop [Blade Pro 17 Full HD (2020)] ++ ++usb:v1532p025D* ++ ID_MODEL_FROM_DATABASE=RZ03-0338, Gaming Keyboard [Ornata V2] ++ + usb:v1532p0300* + ID_MODEL_FROM_DATABASE=RZ06-0063 Motion Sensing Controllers [Hydra] + ++usb:v1532p0401* ++ ID_MODEL_FROM_DATABASE=Gaming Arcade Stick [Panthera] ++ ++usb:v1532p0501* ++ ID_MODEL_FROM_DATABASE=Kraken 7.1 ++ ++usb:v1532p0502* ++ ID_MODEL_FROM_DATABASE=Gaming Headset [Kraken USB] ++ ++usb:v1532p0504* ++ ID_MODEL_FROM_DATABASE=Kraken 7.1 Chroma ++ ++usb:v1532p0506* ++ ID_MODEL_FROM_DATABASE=Kraken 7.1 (Alternate Version) ++ ++usb:v1532p0510* ++ ID_MODEL_FROM_DATABASE=Kraken 7.1 V2 ++ ++usb:v1532p0511* ++ ID_MODEL_FROM_DATABASE=RZ19-0229 Gaming Microphone ++ ++usb:v1532p0514* ++ ID_MODEL_FROM_DATABASE=Electra V2 USB ++ ++usb:v1532p0517* ++ ID_MODEL_FROM_DATABASE=Nommo Chroma ++ ++usb:v1532p0518* ++ ID_MODEL_FROM_DATABASE=Nommo Pro ++ ++usb:v1532p051A* ++ ID_MODEL_FROM_DATABASE=Nari Ultimate ++ ++usb:v1532p051C* ++ ID_MODEL_FROM_DATABASE=Nari (Wireless) ++ ++usb:v1532p051D* ++ ID_MODEL_FROM_DATABASE=Nari (Wired) ++ ++usb:v1532p051E* ++ ID_MODEL_FROM_DATABASE=RC30-026902, Gaming Headset [Nari Essential, Wireless, Receiver] ++ ++usb:v1532p051F* ++ ID_MODEL_FROM_DATABASE=RC30-026901, Gaming Headset [Nari Essential, Wired] ++ ++usb:v1532p0520* ++ ID_MODEL_FROM_DATABASE=Kraken Tournament Edition ++ ++usb:v1532p0521* ++ ID_MODEL_FROM_DATABASE=Kraken Kitty Edition ++ ++usb:v1532p0527* ++ ID_MODEL_FROM_DATABASE=RZ04-0318 Gaming Headset [Kraken Ultimate] ++ ++usb:v1532p0904* ++ ID_MODEL_FROM_DATABASE=R201-0282 Gaming Keyboard, Mouse Combination [Turret For Xbox One] ++ ++usb:v1532p0A00* ++ ID_MODEL_FROM_DATABASE=Atrox Arcade Stick for Xbox One ++ ++usb:v1532p0A02* ++ ID_MODEL_FROM_DATABASE=ManO'War ++ ++usb:v1532p0A03* ++ ID_MODEL_FROM_DATABASE=Wildcat ++ ++usb:v1532p0A15* ++ ID_MODEL_FROM_DATABASE=RZ06-0199, Gaming Controller [Wolverine Tournament Edition] ++ + usb:v1532p0C00* +- ID_MODEL_FROM_DATABASE=Firefly ++ ID_MODEL_FROM_DATABASE=RZ02-0135 Hard Gaming Mouse Mat [Firefly] ++ ++usb:v1532p0C01* ++ ID_MODEL_FROM_DATABASE=Goliathus ++ ++usb:v1532p0C02* ++ ID_MODEL_FROM_DATABASE=Goliathus Extended ++ ++usb:v1532p0C04* ++ ID_MODEL_FROM_DATABASE=Firefly V2 ++ ++usb:v1532p0E03* ++ ID_MODEL_FROM_DATABASE=Gaming Webcam [Kiyo] ++ ++usb:v1532p0F03* ++ ID_MODEL_FROM_DATABASE=Tiamat 7.1 V2 ++ ++usb:v1532p0F07* ++ ID_MODEL_FROM_DATABASE=Chroma Mug Holder ++ ++usb:v1532p0F08* ++ ID_MODEL_FROM_DATABASE=Base Station Chroma ++ ++usb:v1532p0F09* ++ ID_MODEL_FROM_DATABASE=Chroma HDK ++ ++usb:v1532p0F0D* ++ ID_MODEL_FROM_DATABASE=Laptop Stand Chroma ++ ++usb:v1532p0F13* ++ ID_MODEL_FROM_DATABASE=Lian Li O11 Dynamic Razer Edition ++ ++usb:v1532p0F1A* ++ ID_MODEL_FROM_DATABASE=Core X Chroma ++ ++usb:v1532p1000* ++ ID_MODEL_FROM_DATABASE=Gaming Controller [Raiju] ++ ++usb:v1532p1004* ++ ID_MODEL_FROM_DATABASE=Gaming Controller [Raiju Ultimate Wired] ++ ++usb:v1532p1007* ++ ID_MODEL_FROM_DATABASE=Gaming Controller [Raiju 2 Tournament Edition (USB)] ++ ++usb:v1532p1008* ++ ID_MODEL_FROM_DATABASE=Gaming Flightstick [Panthera Evo] ++ ++usb:v1532p1009* ++ ID_MODEL_FROM_DATABASE=Gaming Controller [Raiju 2 Ultimate Edition (BT)] ++ ++usb:v1532p100A* ++ ID_MODEL_FROM_DATABASE=Gaming Controller [Raiju 2 Tournament Edition (BT)] ++ ++usb:v1532p110D* ++ ID_MODEL_FROM_DATABASE=Bootloader (Alternate) ++ ++usb:v1532p800E* ++ ID_MODEL_FROM_DATABASE=Bootloader + + usb:v153B* + ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH +@@ -49184,6 +54155,9 @@ usb:v154Ap8180* + usb:v154B* + ID_VENDOR_FROM_DATABASE=PNY + ++usb:v154Bp000F* ++ ID_MODEL_FROM_DATABASE=Flash Drive ++ + usb:v154Bp0010* + ID_MODEL_FROM_DATABASE=USB 2.0 Flash Drive + +@@ -49208,6 +54182,12 @@ usb:v154Bp0062* + usb:v154Bp007A* + ID_MODEL_FROM_DATABASE=Classic Attache Flash Drive + ++usb:v154Bp5408* ++ ID_MODEL_FROM_DATABASE=2.5in drive enclosure ++ ++usb:v154Bp6000* ++ ID_MODEL_FROM_DATABASE=Flash Drive ++ + usb:v154Bp6545* + ID_MODEL_FROM_DATABASE=FD Device + +@@ -49337,9 +54317,15 @@ usb:v15A2p0038* + usb:v15A2p003B* + ID_MODEL_FROM_DATABASE=USB2CAN Application for ColdFire DEMOJM board + ++usb:v15A2p0041* ++ ID_MODEL_FROM_DATABASE=i.MX51 SystemOnChip in RecoveryMode ++ + usb:v15A2p0042* + ID_MODEL_FROM_DATABASE=OSBDM - Debug Port + ++usb:v15A2p004E* ++ ID_MODEL_FROM_DATABASE=i.MX53 SystemOnChip in RecoveryMode ++ + usb:v15A2p004F* + ID_MODEL_FROM_DATABASE=i.MX28 SystemOnChip in RecoveryMode + +@@ -49352,6 +54338,15 @@ usb:v15A2p0054* + usb:v15A2p0061* + ID_MODEL_FROM_DATABASE=i.MX 6Solo/6DualLite SystemOnChip in RecoveryMode + ++usb:v15A2p006A* ++ ID_MODEL_FROM_DATABASE=Vybrid series SystemOnChip in RecoveryMode ++ ++usb:v15A2p0076* ++ ID_MODEL_FROM_DATABASE=i.MX 7Solo/7Dual SystemOnChip in RecoveryMode ++ ++usb:v15A2p0080* ++ ID_MODEL_FROM_DATABASE=i.MX 6ULL SystemOnChip in RecoveryMode ++ + usb:v15A4* + ID_VENDOR_FROM_DATABASE=Afatech Technologies, Inc. + +@@ -49415,6 +54410,9 @@ usb:v15BAp002A* + usb:v15BAp002B* + ID_MODEL_FROM_DATABASE=ARM-USB-OCD-H JTAG+RS232 + ++usb:v15BAp003C* ++ ID_MODEL_FROM_DATABASE=TERES Keyboard+Touchpad ++ + usb:v15C0* + ID_VENDOR_FROM_DATABASE=XL Imaging + +@@ -49473,10 +54471,10 @@ usb:v15C2pFFDC* + ID_MODEL_FROM_DATABASE=iMON PAD Remote Controller + + usb:v15C5* +- ID_VENDOR_FROM_DATABASE=Advance Multimedia Internet Technology Inc. (AMIT) ++ ID_VENDOR_FROM_DATABASE=Pressure Profile Systems, Inc. + + usb:v15C5p0008* +- ID_MODEL_FROM_DATABASE=WL532U 802.11g Adapter ++ ID_MODEL_FROM_DATABASE=Advance Multimedia Internet Technology Inc. (AMIT) WL532U 802.11g Adapter + + usb:v15C6* + ID_VENDOR_FROM_DATABASE=Laboratoires MXM +@@ -49550,6 +54548,9 @@ usb:v15D9p0A4C* + usb:v15D9p0A4D* + ID_MODEL_FROM_DATABASE=Optical Mouse + ++usb:v15D9p0A4E* ++ ID_MODEL_FROM_DATABASE=AM-5400 [Optical Mouse] ++ + usb:v15D9p0A4F* + ID_MODEL_FROM_DATABASE=Optical Mouse + +@@ -49571,9 +54572,21 @@ usb:v15E4* + usb:v15E4p0024* + ID_MODEL_FROM_DATABASE=Mixtrack + ++usb:v15E4p003C* ++ ID_MODEL_FROM_DATABASE=DJ2GO2 Touch ++ + usb:v15E4p0140* + ID_MODEL_FROM_DATABASE=ION VCR 2 PC / Video 2 PC + ++usb:v15E4p3F00* ++ ID_MODEL_FROM_DATABASE=Power A Mini Pro Elite ++ ++usb:v15E4p3F0A* ++ ID_MODEL_FROM_DATABASE=Airflo Wired Controller for Xbox 360 ++ ++usb:v15E4p3F10* ++ ID_MODEL_FROM_DATABASE=Batarang controller for Xbox 360 ++ + usb:v15E8* + ID_VENDOR_FROM_DATABASE=SohoWare + +@@ -49607,12 +54620,18 @@ usb:v15F4p0001* + usb:v15F4p0025* + ID_MODEL_FROM_DATABASE=HanfTek UMT-010 USB2.0 DVB-T (warm) + ++usb:v15F4p0131* ++ ID_MODEL_FROM_DATABASE=Astrometa DVB-T/T2/C FM & DAB receiver [RTL2832P] ++ + usb:v15F4p0135* + ID_MODEL_FROM_DATABASE=Astrometa T2hybrid + + usb:v1604* + ID_VENDOR_FROM_DATABASE=Tascam + ++usb:v1604p10C0* ++ ID_MODEL_FROM_DATABASE=Dell Integrated Hub ++ + usb:v1604p8000* + ID_MODEL_FROM_DATABASE=US-428 Audio/Midi Controller (without fw) + +@@ -49637,6 +54656,21 @@ usb:v1605* + usb:v1605p0001* + ID_MODEL_FROM_DATABASE=DIO-32 (No Firmware Yet) + ++usb:v1605p0002* ++ ID_MODEL_FROM_DATABASE=USB-DIO-48 (No Firmware Yet) ++ ++usb:v1605p0003* ++ ID_MODEL_FROM_DATABASE=USB-DIO-96 (No Firmware Yet) ++ ++usb:v1605p0004* ++ ID_MODEL_FROM_DATABASE=USB-DIO-32I (No Firmware Yet) ++ ++usb:v1605p0005* ++ ID_MODEL_FROM_DATABASE=USB-DIO24 (based on -CTR6) (No Firmware Yet) ++ ++usb:v1605p0006* ++ ID_MODEL_FROM_DATABASE=USB-DIO24-CTR6 (No Firmware Yet) ++ + usb:v1606* + ID_VENDOR_FROM_DATABASE=Umax + +@@ -49991,6 +55025,18 @@ usb:v1631p6200* + usb:v1631pC019* + ID_MODEL_FROM_DATABASE=RT2573 + ++usb:v1633* ++ ID_VENDOR_FROM_DATABASE=AIM GmbH ++ ++usb:v1633p4510* ++ ID_MODEL_FROM_DATABASE=ASC1553 ++ ++usb:v1633p4520* ++ ID_MODEL_FROM_DATABASE=ASC429 ++ ++usb:v1633p4560* ++ ID_MODEL_FROM_DATABASE=ASC-FDX ++ + usb:v1645* + ID_VENDOR_FROM_DATABASE=Entrega [hex] + +@@ -50222,6 +55268,12 @@ usb:v1679p2001* + usb:v1679p2002* + ID_MODEL_FROM_DATABASE=Cheetah SPI Host Adapter + ++usb:v167B* ++ ID_VENDOR_FROM_DATABASE=Pure Digital Technologies, Inc. ++ ++usb:v167Bp2009* ++ ID_MODEL_FROM_DATABASE=Flip Ultra U1120 ++ + usb:v1680* + ID_VENDOR_FROM_DATABASE=Golden Bridge Electech Inc. + +@@ -50262,7 +55314,16 @@ usb:v1686* + ID_VENDOR_FROM_DATABASE=ZOOM Corporation + + usb:v1686p0045* +- ID_MODEL_FROM_DATABASE=H4 Digital Recorder ++ ID_MODEL_FROM_DATABASE=Handy Recorder stereo mix ++ ++usb:v1686p01C0* ++ ID_MODEL_FROM_DATABASE=Zoom Handy Recorder card reader ++ ++usb:v1686p01C5* ++ ID_MODEL_FROM_DATABASE=Zoom Handy Recorder multi track ++ ++usb:v1686p03D5* ++ ID_MODEL_FROM_DATABASE=LiveTrak L-12 + + usb:v1687* + ID_VENDOR_FROM_DATABASE=Kingmax Digital Inc. +@@ -50285,6 +55346,12 @@ usb:v1689* + usb:v1689pFD00* + ID_MODEL_FROM_DATABASE=Onza Tournament Edition controller + ++usb:v1689pFD01* ++ ID_MODEL_FROM_DATABASE=Onza Classic Edition ++ ++usb:v1689pFE00* ++ ID_MODEL_FROM_DATABASE=Sabertooth Elite ++ + usb:v168C* + ID_VENDOR_FROM_DATABASE=Atheros Communications + +@@ -50531,12 +55598,18 @@ usb:v16C0p0487* + usb:v16C0p0488* + ID_MODEL_FROM_DATABASE=Teensyduino Flight Sim Controls + ++usb:v16C0p05B5* ++ ID_MODEL_FROM_DATABASE=BU0836 ++ + usb:v16C0p05DC* + ID_MODEL_FROM_DATABASE=shared ID for use with libusb + + usb:v16C0p05DD* + ID_MODEL_FROM_DATABASE=BlackcatUSB2 + ++usb:v16C0p05DE* ++ ID_MODEL_FROM_DATABASE=Flashcat ++ + usb:v16C0p05DF* + ID_MODEL_FROM_DATABASE=HID device except mice, keyboards, and joysticks + +@@ -50582,6 +55655,9 @@ usb:v16C0p08CC* + usb:v16C0p08CD* + ID_MODEL_FROM_DATABASE=Alpermann+Velte SAM7X MT Boot Loader + ++usb:v16C0p09CE* ++ ID_MODEL_FROM_DATABASE=LINKUSB ++ + usb:v16C0p0A32* + ID_MODEL_FROM_DATABASE=jbmedia Light-Manager Pro + +@@ -50639,12 +55715,27 @@ usb:v16D0p054B* + usb:v16D0p05BE* + ID_MODEL_FROM_DATABASE=EasyLogic Board + ++usb:v16D0p05F0* ++ ID_MODEL_FROM_DATABASE=Superior Freedom Programmable IR Remote ++ + usb:v16D0p06CC* + ID_MODEL_FROM_DATABASE=Trinamic TMCM-3110 + ++usb:v16D0p06F0* ++ ID_MODEL_FROM_DATABASE=Axium AX-R4C Controller ++ ++usb:v16D0p06F1* ++ ID_MODEL_FROM_DATABASE=Axium AX-R1D Controller ++ + usb:v16D0p06F9* + ID_MODEL_FROM_DATABASE=Gabotronics Xminilab + ++usb:v16D0p0726* ++ ID_MODEL_FROM_DATABASE=Autonomic M400 Amplifier ++ ++usb:v16D0p0727* ++ ID_MODEL_FROM_DATABASE=Autonomic M800 Amplifier ++ + usb:v16D0p0753* + ID_MODEL_FROM_DATABASE=Digistump DigiSpark + +@@ -50654,18 +55745,60 @@ usb:v16D0p075C* + usb:v16D0p075D* + ID_MODEL_FROM_DATABASE=AB-1.x UAC2 [Audio Widget] + ++usb:v16D0p07CC* ++ ID_MODEL_FROM_DATABASE=Xylanta Ltd, Saint3 Device ++ ++usb:v16D0p07F8* ++ ID_MODEL_FROM_DATABASE=Axium AX-R4D Controller ++ + usb:v16D0p080A* + ID_MODEL_FROM_DATABASE=S2E1 Interface + ++usb:v16D0p0830* ++ ID_MODEL_FROM_DATABASE=DMXControl Projects e.V., Nodle U1 ++ ++usb:v16D0p0831* ++ ID_MODEL_FROM_DATABASE=DMXControl Projects e.V., Desklamp ++ ++usb:v16D0p0832* ++ ID_MODEL_FROM_DATABASE=DMXControl Projects e.V., Nodle U2 ++ ++usb:v16D0p0833* ++ ID_MODEL_FROM_DATABASE=DMXControl Projects e.V., Nodle R4S ++ + usb:v16D0p0870* + ID_MODEL_FROM_DATABASE=Kaufmann Automotive GmbH, RKS+CAN Interface + ++usb:v16D0p09F2* ++ ID_MODEL_FROM_DATABASE=Axium AX-1250 Amplifier ++ ++usb:v16D0p09F4* ++ ID_MODEL_FROM_DATABASE=Axium AX-Mini4 Amplifier ++ + usb:v16D0p0B03* + ID_MODEL_FROM_DATABASE=AIS Receiver [dAISy] + ++usb:v16D0p0B7D* ++ ID_MODEL_FROM_DATABASE=Autonomic M801 Amplifier ++ ++usb:v16D0p0B7E* ++ ID_MODEL_FROM_DATABASE=Autonomic M401 Amplifier ++ ++usb:v16D0p0B7F* ++ ID_MODEL_FROM_DATABASE=Autonomic M120e Amplifier ++ + usb:v16D0p0BD4* + ID_MODEL_FROM_DATABASE=codesrc SCSI2SD + ++usb:v16D0p0C9B* ++ ID_MODEL_FROM_DATABASE=Fermium LABS srl/LabTrek srl Hall Effect Apparatus ++ ++usb:v16D0p0D3C* ++ ID_MODEL_FROM_DATABASE=InputStick BT4.0 ++ ++usb:v16D0p0E1E* ++ ID_MODEL_FROM_DATABASE=AtomMiner ++ + usb:v16D1* + ID_VENDOR_FROM_DATABASE=Suprema Inc. + +@@ -50763,7 +55896,7 @@ usb:v16DF* + ID_VENDOR_FROM_DATABASE=King Billion Electronics Co., Ltd. + + usb:v16F0* +- ID_VENDOR_FROM_DATABASE=GN ReSound A/S ++ ID_VENDOR_FROM_DATABASE=GN Hearing A/S + + usb:v16F0p0001* + ID_MODEL_FROM_DATABASE=Speedlink Programming Interface +@@ -50771,9 +55904,18 @@ usb:v16F0p0001* + usb:v16F0p0003* + ID_MODEL_FROM_DATABASE=Airlink Wireless Programming Interface + ++usb:v16F0p0004* ++ ID_MODEL_FROM_DATABASE=Accessory Programming Interface ++ + usb:v16F5* + ID_VENDOR_FROM_DATABASE=Futurelogic Inc. + ++usb:v1702* ++ ID_VENDOR_FROM_DATABASE=FDI-MATELEC ++ ++usb:v1702p0002* ++ ID_MODEL_FROM_DATABASE=Encodeur ++ + usb:v1706* + ID_VENDOR_FROM_DATABASE=BlueView Technologies, Inc. + +@@ -50865,7 +56007,7 @@ usb:v1736* + ID_VENDOR_FROM_DATABASE=CANON IMAGING SYSTEM TECHNOLOGIES INC. + + usb:v1737* +- ID_VENDOR_FROM_DATABASE=Linksys ++ ID_VENDOR_FROM_DATABASE=802.11g Adapter [Linksys WUSB54GC v3] + + usb:v1737p0039* + ID_MODEL_FROM_DATABASE=USB1000 Gigabit Notebook Adapter +@@ -50966,6 +56108,9 @@ usb:v174C* + usb:v174Cp07D1* + ID_MODEL_FROM_DATABASE=Transcend ESD400 Portable SSD (USB 3.0) + ++usb:v174Cp1151* ++ ID_MODEL_FROM_DATABASE=ASM1151W ++ + usb:v174Cp1153* + ID_MODEL_FROM_DATABASE=ASM1153 SATA 3Gb/s bridge + +@@ -50985,7 +56130,7 @@ usb:v174Cp51D6* + ID_MODEL_FROM_DATABASE=ASM1051W SATA 3Gb/s bridge + + usb:v174Cp55AA* +- ID_MODEL_FROM_DATABASE=Name: ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge, ASM1153E SATA 6Gb/s bridge ++ ID_MODEL_FROM_DATABASE=ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge, ASM1153E SATA 6Gb/s bridge + + usb:v174F* + ID_VENDOR_FROM_DATABASE=Syntek +@@ -50996,12 +56141,24 @@ usb:v174Fp1105* + usb:v174Fp110B* + ID_MODEL_FROM_DATABASE=HP Webcam + ++usb:v174Fp1122* ++ ID_MODEL_FROM_DATABASE=HP Webcam ++ ++usb:v174Fp1169* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ + usb:v174Fp1403* + ID_MODEL_FROM_DATABASE=Integrated Webcam + + usb:v174Fp1404* + ID_MODEL_FROM_DATABASE=USB Camera device, 1.3 MPixel Web Cam + ++usb:v174Fp1758* ++ ID_MODEL_FROM_DATABASE=XYZ printing cameraR2 ++ ++usb:v174Fp1759* ++ ID_MODEL_FROM_DATABASE=XYZ printing cameraL2 ++ + usb:v174Fp5212* + ID_MODEL_FROM_DATABASE=USB 2.0 UVC PC Camera + +@@ -51068,6 +56225,12 @@ usb:v1761* + usb:v1761p0B05* + ID_MODEL_FROM_DATABASE=802.11n Network Adapter (wrong ID - swapped vendor and device) + ++usb:v1770* ++ ID_VENDOR_FROM_DATABASE=MSI ++ ++usb:v1770pFF00* ++ ID_MODEL_FROM_DATABASE=steel series rgb keyboard ++ + usb:v1772* + ID_VENDOR_FROM_DATABASE=System Level Solutions, Inc. + +@@ -51077,6 +56240,12 @@ usb:v1776* + usb:v1776p501C* + ID_MODEL_FROM_DATABASE=300K CMOS Camera + ++usb:v1777* ++ ID_VENDOR_FROM_DATABASE=Microscan Systems, Inc. ++ ++usb:v1777p0003* ++ ID_MODEL_FROM_DATABASE=MicroHAWK ID-20 ++ + usb:v177F* + ID_VENDOR_FROM_DATABASE=Sweex + +@@ -51095,6 +56264,18 @@ usb:v177Fp0313* + usb:v1781* + ID_VENDOR_FROM_DATABASE=Multiple Vendors + ++usb:v1781p07DF* ++ ID_MODEL_FROM_DATABASE=Axium AX-800DAV Amplifier ++ ++usb:v1781p07E1* ++ ID_MODEL_FROM_DATABASE=Axium AX-KPC Keypad ++ ++usb:v1781p07E2* ++ ID_MODEL_FROM_DATABASE=Axium AX-KPD Keypad ++ ++usb:v1781p07E3* ++ ID_MODEL_FROM_DATABASE=Axium AX-400DA Amplifier ++ + usb:v1781p083E* + ID_MODEL_FROM_DATABASE=MetaGeek Wi-Spy + +@@ -51104,6 +56285,9 @@ usb:v1781p083F* + usb:v1781p0938* + ID_MODEL_FROM_DATABASE=Iguanaworks USB IR Transceiver + ++usb:v1781p0941* ++ ID_MODEL_FROM_DATABASE=qNimble Quark ++ + usb:v1781p0A96* + ID_MODEL_FROM_DATABASE=raphnet.net usb_game12 + +@@ -51134,6 +56318,9 @@ usb:v1781p0A9E* + usb:v1781p0A9F* + ID_MODEL_FROM_DATABASE=raphnet.net MultiDB9joy + ++usb:v1781p0BAD* ++ ID_MODEL_FROM_DATABASE=Mantracourt Load Cell ++ + usb:v1781p0C30* + ID_MODEL_FROM_DATABASE=Telldus TellStick + +@@ -51152,9 +56339,15 @@ usb:v1781p1EF0* + usb:v1781p1EF1* + ID_MODEL_FROM_DATABASE=E1701 Modular Controller Card + ++usb:v1781p1EF2* ++ ID_MODEL_FROM_DATABASE=E1803 Compact Controller Card ++ + usb:v1782* + ID_VENDOR_FROM_DATABASE=Spreadtrum Communications Inc. + ++usb:v1782p3D00* ++ ID_MODEL_FROM_DATABASE=F200n mobile phone ++ + usb:v1784* + ID_VENDOR_FROM_DATABASE=TopSeed Technology Corp. + +@@ -51185,6 +56378,12 @@ usb:v1787* + usb:v1788* + ID_VENDOR_FROM_DATABASE=ShenZhen Litkconn Technology Co., Ltd. + ++usb:v178E* ++ ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc. (wrong ID) ++ ++usb:v178Ep0B05* ++ ID_MODEL_FROM_DATABASE=CrossLink cable 2GB (wrong ID - swapped vendor and device) ++ + usb:v1796* + ID_VENDOR_FROM_DATABASE=Printrex, Inc. + +@@ -51224,6 +56423,12 @@ usb:v17A0p0101* + usb:v17A0p0120* + ID_MODEL_FROM_DATABASE=Meteorite condenser microphone + ++usb:v17A0p0130* ++ ID_MODEL_FROM_DATABASE=Go Mic Direct ++ ++usb:v17A0p0132* ++ ID_MODEL_FROM_DATABASE=Go Mic Mobile wireless receiver ++ + usb:v17A0p0200* + ID_MODEL_FROM_DATABASE=StudioDock monitors (internal hub) + +@@ -51233,6 +56438,15 @@ usb:v17A0p0201* + usb:v17A0p0210* + ID_MODEL_FROM_DATABASE=StudioGT monitors + ++usb:v17A0p0211* ++ ID_MODEL_FROM_DATABASE=StudioGT monitors [CM6400] ++ ++usb:v17A0p0240* ++ ID_MODEL_FROM_DATABASE=Go Mic Connect ++ ++usb:v17A0p0241* ++ ID_MODEL_FROM_DATABASE=G-Track Pro microphone ++ + usb:v17A0p0301* + ID_MODEL_FROM_DATABASE=Q2U handheld microphone with XLR + +@@ -51251,6 +56465,18 @@ usb:v17A0p0305* + usb:v17A0p0310* + ID_MODEL_FROM_DATABASE=Meteor condenser microphone + ++usb:v17A0p0311* ++ ID_MODEL_FROM_DATABASE=Satellite condenser microphone ++ ++usb:v17A0p1616* ++ ID_MODEL_FROM_DATABASE=RXD1 wireless receiver ++ ++usb:v17A0pB241* ++ ID_MODEL_FROM_DATABASE=G-Track Pro firmware update ++ ++usb:v17A0pB311* ++ ID_MODEL_FROM_DATABASE=Satellite firmware update ++ + usb:v17A4* + ID_VENDOR_FROM_DATABASE=Concept2 + +@@ -51275,6 +56501,18 @@ usb:v17A8p0001* + usb:v17A8p0005* + ID_MODEL_FROM_DATABASE=M-Bus Master MultiPort 250D + ++usb:v17A8p0010* ++ ID_MODEL_FROM_DATABASE=444MHz Radio Mesh Frontend ++ ++usb:v17A8p0011* ++ ID_MODEL_FROM_DATABASE=444MHz RF sniffer ++ ++usb:v17A8p0012* ++ ID_MODEL_FROM_DATABASE=870MHz Radio Mesh Frontend ++ ++usb:v17A8p0013* ++ ID_MODEL_FROM_DATABASE=870MHz RF sniffer ++ + usb:v17B3* + ID_VENDOR_FROM_DATABASE=Grey Innovation + +@@ -51314,6 +56552,9 @@ usb:v17CC* + usb:v17CCp041C* + ID_MODEL_FROM_DATABASE=Audio 2 DJ + ++usb:v17CCp041D* ++ ID_MODEL_FROM_DATABASE=Traktor Audio 2 ++ + usb:v17CCp0808* + ID_MODEL_FROM_DATABASE=Maschine Controller + +@@ -51326,6 +56567,12 @@ usb:v17CCp0839* + usb:v17CCp0D8D* + ID_MODEL_FROM_DATABASE=Guitarrig Mobile + ++usb:v17CCp1001* ++ ID_MODEL_FROM_DATABASE=Komplete Audio 6 ++ ++usb:v17CCp1110* ++ ID_MODEL_FROM_DATABASE=Maschine Mikro ++ + usb:v17CCp1915* + ID_MODEL_FROM_DATABASE=Session I/O + +@@ -51368,6 +56615,15 @@ usb:v17E9* + usb:v17E9p0051* + ID_MODEL_FROM_DATABASE=USB VGA Adaptor + ++usb:v17E9p0198* ++ ID_MODEL_FROM_DATABASE=DisplayLink ++ ++usb:v17E9p019E* ++ ID_MODEL_FROM_DATABASE=Overfly FY-1016A ++ ++usb:v17E9p028F* ++ ID_MODEL_FROM_DATABASE=HIS Multi-View II ++ + usb:v17E9p030B* + ID_MODEL_FROM_DATABASE=HP T100 + +@@ -51398,9 +56654,18 @@ usb:v17E9p410A* + usb:v17E9p430A* + ID_MODEL_FROM_DATABASE=HP Port Replicator (Composite Device) + ++usb:v17E9p430F* ++ ID_MODEL_FROM_DATABASE=Kensington Dock (Composite Device) ++ + usb:v17E9p4312* + ID_MODEL_FROM_DATABASE=S2340T + ++usb:v17E9p436E* ++ ID_MODEL_FROM_DATABASE=Dell D3100 Docking Station ++ ++usb:v17E9pFF10* ++ ID_MODEL_FROM_DATABASE=I1659FWUX {AOC Powered Monitor] ++ + usb:v17EB* + ID_VENDOR_FROM_DATABASE=Cornice, Inc. + +@@ -51408,7 +56673,7 @@ usb:v17EF* + ID_VENDOR_FROM_DATABASE=Lenovo + + usb:v17EFp1000* +- ID_MODEL_FROM_DATABASE=Hub ++ ID_MODEL_FROM_DATABASE=ThinkPad X6 UltraBase + + usb:v17EFp1003* + ID_MODEL_FROM_DATABASE=Integrated Smart Card Reader +@@ -51416,20 +56681,59 @@ usb:v17EFp1003* + usb:v17EFp1004* + ID_MODEL_FROM_DATABASE=Integrated Webcam + ++usb:v17EFp1005* ++ ID_MODEL_FROM_DATABASE=ThinkPad X200 Ultrabase (42X4963 ) ++ + usb:v17EFp1008* + ID_MODEL_FROM_DATABASE=Hub + + usb:v17EFp100A* + ID_MODEL_FROM_DATABASE=ThinkPad Mini Dock Plus Series 3 + ++usb:v17EFp100F* ++ ID_MODEL_FROM_DATABASE=ThinkPad Ultra Dock Hub ++ ++usb:v17EFp1010* ++ ID_MODEL_FROM_DATABASE=ThinkPad Ultra Dock Hub ++ ++usb:v17EFp1020* ++ ID_MODEL_FROM_DATABASE=ThinkPad Dock Hub ++ ++usb:v17EFp1021* ++ ID_MODEL_FROM_DATABASE=ThinkPad Dock Hub [Cypress HX2VL] ++ ++usb:v17EFp3049* ++ ID_MODEL_FROM_DATABASE=ThinkPad OneLink integrated audio ++ + usb:v17EFp304B* + ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [ThinkPad OneLink GigaLAN] + ++usb:v17EFp304F* ++ ID_MODEL_FROM_DATABASE=RTL8153 Gigabit Ethernet [ThinkPad OneLink Pro Dock] ++ ++usb:v17EFp3060* ++ ID_MODEL_FROM_DATABASE=ThinkPad Dock ++ ++usb:v17EFp3062* ++ ID_MODEL_FROM_DATABASE=ThinkPad Dock Ethernet [Realtek RTL8153B] ++ ++usb:v17EFp3063* ++ ID_MODEL_FROM_DATABASE=ThinkPad Dock Audio ++ ++usb:v17EFp3066* ++ ID_MODEL_FROM_DATABASE=ThinkPad Thunderbolt 3 Dock MCU ++ ++usb:v17EFp3069* ++ ID_MODEL_FROM_DATABASE=ThinkPad TBT3 LAN ++ ++usb:v17EFp306A* ++ ID_MODEL_FROM_DATABASE=ThinkPad Thunderbolt 3 Dock Audio ++ + usb:v17EFp3815* + ID_MODEL_FROM_DATABASE=ChipsBnk 2GB USB Stick + + usb:v17EFp4802* +- ID_MODEL_FROM_DATABASE=Lenovo Vc0323+MI1310_SOC Camera ++ ID_MODEL_FROM_DATABASE=Vc0323+MI1310_SOC Camera + + usb:v17EFp4807* + ID_MODEL_FROM_DATABASE=UVC Camera +@@ -51482,15 +56786,54 @@ usb:v17EFp6007* + usb:v17EFp6009* + ID_MODEL_FROM_DATABASE=ThinkPad Keyboard with TrackPoint + ++usb:v17EFp600E* ++ ID_MODEL_FROM_DATABASE=Optical Mouse ++ + usb:v17EFp6014* + ID_MODEL_FROM_DATABASE=Mini Wireless Keyboard N5901 + ++usb:v17EFp6019* ++ ID_MODEL_FROM_DATABASE=M-U0025-O Mouse ++ ++usb:v17EFp6022* ++ ID_MODEL_FROM_DATABASE=Ultraslim Plus Wireless Keyboard and Mouse ++ + usb:v17EFp6025* + ID_MODEL_FROM_DATABASE=ThinkPad Travel Mouse + ++usb:v17EFp602D* ++ ID_MODEL_FROM_DATABASE=Black Silk Keyboard ++ ++usb:v17EFp6032* ++ ID_MODEL_FROM_DATABASE=Wireless Dongle for Keyboard and Mouse ++ ++usb:v17EFp6044* ++ ID_MODEL_FROM_DATABASE=ThinkPad Laser Mouse ++ ++usb:v17EFp6047* ++ ID_MODEL_FROM_DATABASE=ThinkPad Compact Keyboard with TrackPoint ++ ++usb:v17EFp604B* ++ ID_MODEL_FROM_DATABASE=Precision Wireless Mouse ++ ++usb:v17EFp608D* ++ ID_MODEL_FROM_DATABASE=Optical Mouse ++ ++usb:v17EFp609B* ++ ID_MODEL_FROM_DATABASE=Professional Wireless Keyboard and Mouse Combo ++ ++usb:v17EFp609C* ++ ID_MODEL_FROM_DATABASE=Professional Wireless Keyboard ++ + usb:v17EFp7203* + ID_MODEL_FROM_DATABASE=Ethernet adapter [U2L 100P-Y1] + ++usb:v17EFp7205* ++ ID_MODEL_FROM_DATABASE=Thinkpad LAN ++ ++usb:v17EFp7217* ++ ID_MODEL_FROM_DATABASE=VGA adapter ++ + usb:v17EFp7423* + ID_MODEL_FROM_DATABASE=IdeaPad A1 Tablet + +@@ -51512,6 +56855,69 @@ usb:v17EFp749A* + usb:v17EFp749B* + ID_MODEL_FROM_DATABASE=A789 (PTP mode, with debug) + ++usb:v17EFp7604* ++ ID_MODEL_FROM_DATABASE=A760 (Mass Storage mode) ++ ++usb:v17EFp7605* ++ ID_MODEL_FROM_DATABASE=A760 (Mass Storage mode, with debug) ++ ++usb:v17EFp760A* ++ ID_MODEL_FROM_DATABASE=A760 (MTP mode) ++ ++usb:v17EFp760B* ++ ID_MODEL_FROM_DATABASE=A760 (MTP mode, with debug) ++ ++usb:v17EFp760C* ++ ID_MODEL_FROM_DATABASE=A760 (PTP mode) ++ ++usb:v17EFp760D* ++ ID_MODEL_FROM_DATABASE=A760 (PTP mode, with debug) ++ ++usb:v17EFp76FC* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (mass storage) ++ ++usb:v17EFp76FD* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (debug , mass storage) ++ ++usb:v17EFp76FE* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (MTP) ++ ++usb:v17EFp76FF* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (debug , MTP) ++ ++usb:v17EFp7702* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (PTP) ++ ++usb:v17EFp7703* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (debug , PTP) ++ ++usb:v17EFp7704* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (USB tether) ++ ++usb:v17EFp7705* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (debug , USB tether) ++ ++usb:v17EFp7706* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (zerocd) ++ ++usb:v17EFp7707* ++ ID_MODEL_FROM_DATABASE=B8000-H (Yoga Tablet 10) (debug , zerocd) ++ ++usb:v17EFp785F* ++ ID_MODEL_FROM_DATABASE=TAB 2 A7-10 Tablet ++ ++usb:v17EFpB000* ++ ID_MODEL_FROM_DATABASE=Virtual Keyboard and Mouse ++ ++usb:v17EFpB001* ++ ID_MODEL_FROM_DATABASE=Ethernet ++ ++usb:v17EFpB003* ++ ID_MODEL_FROM_DATABASE=Virtual Keyboard and Mouse / Mass Storage ++ ++usb:v17EFpF003* ++ ID_MODEL_FROM_DATABASE=MEDION LIFETAB X10605 MTP mode ++ + usb:v17F4* + ID_VENDOR_FROM_DATABASE=WaveSense + +@@ -51522,11 +56928,14 @@ usb:v17F5* + ID_VENDOR_FROM_DATABASE=K.K. Rocky + + usb:v17F6* +- ID_VENDOR_FROM_DATABASE=Unicomp, Inc ++ ID_VENDOR_FROM_DATABASE=Unicomp, Inc. + + usb:v17F6p0709* + ID_MODEL_FROM_DATABASE=Model M Keyboard + ++usb:v17F6p0822* ++ ID_MODEL_FROM_DATABASE=Ruffian 6 Keyboard v3 [Model M] ++ + usb:v1809* + ID_VENDOR_FROM_DATABASE=Advantech + +@@ -51563,9 +56972,21 @@ usb:v1843* + usb:v1849* + ID_VENDOR_FROM_DATABASE=ASRock Incorporation + ++usb:v184F* ++ ID_VENDOR_FROM_DATABASE=K2L GmbH ++ ++usb:v184Fp0012* ++ ID_MODEL_FROM_DATABASE=MOCCA compact ++ + usb:v1852* + ID_VENDOR_FROM_DATABASE=GYROCOM C&C Co., LTD + ++usb:v1852p7022* ++ ID_MODEL_FROM_DATABASE=Fiio E10 ++ ++usb:v1852p7921* ++ ID_MODEL_FROM_DATABASE=Audiotrak ProDigy CUBE ++ + usb:v1852p7922* + ID_MODEL_FROM_DATABASE=Audiotrak DR.DAC2 DX [GYROCOM C&C] + +@@ -51623,6 +57044,12 @@ usb:v187C* + usb:v187Cp0511* + ID_MODEL_FROM_DATABASE=AlienFX Mobile lighting + ++usb:v187Cp0513* ++ ID_MODEL_FROM_DATABASE=Gaming Desktop [Aurora R4] ++ ++usb:v187Cp0550* ++ ID_MODEL_FROM_DATABASE=LED controller ++ + usb:v187Cp0600* + ID_MODEL_FROM_DATABASE=Dual Compatible Game Pad + +@@ -51704,12 +57131,18 @@ usb:v18A5p0237* + usb:v18A5p0243* + ID_MODEL_FROM_DATABASE=Flash Drive (Store'n'Go) + ++usb:v18A5p0245* ++ ID_MODEL_FROM_DATABASE=Store'n'Stay ++ + usb:v18A5p0302* + ID_MODEL_FROM_DATABASE=Flash Drive + + usb:v18A5p0304* + ID_MODEL_FROM_DATABASE=Store 'n' Go + ++usb:v18A5p0408* ++ ID_MODEL_FROM_DATABASE=Store 'n' Go ++ + usb:v18A5p4123* + ID_MODEL_FROM_DATABASE=Store N Go + +@@ -51780,10 +57213,22 @@ usb:v18D1p0D02* + ID_MODEL_FROM_DATABASE=Celkon A88 + + usb:v18D1p2D00* +- ID_MODEL_FROM_DATABASE=Android-powered device in accessory mode ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (accessory) + + usb:v18D1p2D01* +- ID_MODEL_FROM_DATABASE=Android-powered device in accessory mode with ADB support ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (accessory + ADB) ++ ++usb:v18D1p2D02* ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (audio) ++ ++usb:v18D1p2D03* ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (audio + ADB) ++ ++usb:v18D1p2D04* ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (accessory + audio) ++ ++usb:v18D1p2D05* ++ ID_MODEL_FROM_DATABASE=Android Open Accessory device (accessory + audio + ADB) + + usb:v18D1p4E11* + ID_MODEL_FROM_DATABASE=Nexus One +@@ -51825,25 +57270,37 @@ usb:v18D1p4E44* + ID_MODEL_FROM_DATABASE=Nexus 7 2012 (PTP) + + usb:v18D1p4EE0* +- ID_MODEL_FROM_DATABASE=Nexus 4 (bootloader) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (fastboot) + + usb:v18D1p4EE1* +- ID_MODEL_FROM_DATABASE=Nexus Device (MTP) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (MTP) + + usb:v18D1p4EE2* +- ID_MODEL_FROM_DATABASE=Nexus Device (debug) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (MTP + debug) + + usb:v18D1p4EE3* +- ID_MODEL_FROM_DATABASE=Nexus 4/5/7/10 (tether) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (tether) + + usb:v18D1p4EE4* +- ID_MODEL_FROM_DATABASE=Nexus 4/5/7/10 (debug + tether) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (tether+ debug) + + usb:v18D1p4EE5* +- ID_MODEL_FROM_DATABASE=Nexus 4 (PTP) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (PTP) + + usb:v18D1p4EE6* +- ID_MODEL_FROM_DATABASE=Nexus 4/5 (PTP + debug) ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (PTP + debug) ++ ++usb:v18D1p4EE7* ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (charging + debug) ++ ++usb:v18D1p4EE8* ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (MIDI) ++ ++usb:v18D1p4EE9* ++ ID_MODEL_FROM_DATABASE=Nexus/Pixel Device (MIDI + debug) ++ ++usb:v18D1p5033* ++ ID_MODEL_FROM_DATABASE=Pixel earbuds + + usb:v18D1p7102* + ID_MODEL_FROM_DATABASE=Toshiba Thrive tablet +@@ -51857,6 +57314,9 @@ usb:v18D1pD001* + usb:v18D1pD002* + ID_MODEL_FROM_DATABASE=Nexus 4 (debug) + ++usb:v18D1pD00D* ++ ID_MODEL_FROM_DATABASE=Xiaomi Mi/Redmi 2 (fastboot) ++ + usb:v18D1pD109* + ID_MODEL_FROM_DATABASE=LG G2x MTP + +@@ -51935,12 +57395,36 @@ usb:v18ECp3299* + usb:v18ECp3366* + ID_MODEL_FROM_DATABASE=Bresser Biolux NV + ++usb:v18ECp5850* ++ ID_MODEL_FROM_DATABASE=CVBS / S-Video Capture Device [UVC] ++ ++usb:v18EF* ++ ID_VENDOR_FROM_DATABASE=ELV Elektronik AG ++ ++usb:v18EFpE014* ++ ID_MODEL_FROM_DATABASE=FS20PCE ++ ++usb:v18EFpE015* ++ ID_MODEL_FROM_DATABASE=FS20PCS ++ ++usb:v18EFpE01A* ++ ID_MODEL_FROM_DATABASE=Bedien-Anzeige-Terminal ++ + usb:v18F8* + ID_VENDOR_FROM_DATABASE=[Maxxter] + ++usb:v18F8p0F97* ++ ID_MODEL_FROM_DATABASE=Optical Gaming Mouse [Xtrem] ++ + usb:v18F8p0F99* + ID_MODEL_FROM_DATABASE=Optical gaming mouse + ++usb:v18F8p1142* ++ ID_MODEL_FROM_DATABASE=Optical gaming mouse ++ ++usb:v18F8p1486* ++ ID_MODEL_FROM_DATABASE=X5s ZEUS Macro Pro Gaming Mouse ++ + usb:v18FB* + ID_VENDOR_FROM_DATABASE=Scriptel Corporation + +@@ -52004,8 +57488,26 @@ usb:v1901p0015* + usb:v1908* + ID_VENDOR_FROM_DATABASE=GEMBIRD + ++usb:v1908p0102* ++ ID_MODEL_FROM_DATABASE=Digital Photo Frame ++ ++usb:v1908p0226* ++ ID_MODEL_FROM_DATABASE=MicroSD Card Reader/Writer ++ ++usb:v1908p1315* ++ ID_MODEL_FROM_DATABASE=Digital Photo Frame ++ + usb:v1908p1320* +- ID_MODEL_FROM_DATABASE=PhotoFrame PF-15-1 ++ ID_MODEL_FROM_DATABASE=DM8261 Flashdisc ++ ++usb:v1908p2070* ++ ID_MODEL_FROM_DATABASE=Honk HK-5002 USB Speaker ++ ++usb:v1908p2220* ++ ID_MODEL_FROM_DATABASE=Buildwin Media-Player ++ ++usb:v1908p2311* ++ ID_MODEL_FROM_DATABASE=Generic UVC 1.00 camera [AppoTech AX2311] + + usb:v190D* + ID_VENDOR_FROM_DATABASE=Motorola GSG +@@ -52019,6 +57521,9 @@ usb:v1915* + usb:v1915p000C* + ID_MODEL_FROM_DATABASE=Wireless Desktop nRF24L01 CX-1766 + ++usb:v1915p0101* ++ ID_MODEL_FROM_DATABASE=HP Prime Wireless Kit [FOK65AA] (Flash mode) ++ + usb:v1915p2233* + ID_MODEL_FROM_DATABASE=Linksys WUSB11 v2.8 802.11b Adapter [Atmel AT76C505] + +@@ -52031,6 +57536,9 @@ usb:v1915p2235* + usb:v1915p2236* + ID_MODEL_FROM_DATABASE=Linksys WUSB11 v3.0 802.11b Adapter [Intersil PRISM 3] + ++usb:v1915p7777* ++ ID_MODEL_FROM_DATABASE=Bitcraze Crazyradio (PA) dongle ++ + usb:v191C* + ID_VENDOR_FROM_DATABASE=Innovative Technology LTD + +@@ -52130,9 +57638,18 @@ usb:v1926p0086* + usb:v1926p0087* + ID_MODEL_FROM_DATABASE=1950 HID Touchscreen + ++usb:v1926p0DBF* ++ ID_MODEL_FROM_DATABASE=HID Touchscreen ++ + usb:v1926p0DC2* + ID_MODEL_FROM_DATABASE=HID Touchscreen + ++usb:v1928* ++ ID_VENDOR_FROM_DATABASE=Proceq SA ++ ++usb:v1928p0400* ++ ID_MODEL_FROM_DATABASE=Equotip Piccolo ++ + usb:v192F* + ID_VENDOR_FROM_DATABASE=Avago Technologies, Pte. + +@@ -52145,6 +57662,9 @@ usb:v192Fp0416* + usb:v192Fp0616* + ID_MODEL_FROM_DATABASE=ADNS-5700 Optical Mouse Controller (5-button) + ++usb:v192Fp0916* ++ ID_MODEL_FROM_DATABASE=ADNS-2710 Optical Mouse Controller ++ + usb:v1930* + ID_VENDOR_FROM_DATABASE=Shenzhen Xianhe Technology Co., Ltd. + +@@ -52163,12 +57683,21 @@ usb:v1934p0702* + usb:v1934p5168* + ID_MODEL_FROM_DATABASE=F71610A or F71612A Consumer Infrared Receiver/Transceiver + ++usb:v1935* ++ ID_VENDOR_FROM_DATABASE=Elektron Music Machines ++ ++usb:v1935p000D* ++ ID_MODEL_FROM_DATABASE=Elektron Digitakt ++ + usb:v1938* + ID_VENDOR_FROM_DATABASE=Meinberg Funkuhren GmbH & Co. KG + + usb:v1938p0501* + ID_MODEL_FROM_DATABASE=TCR51USB IRIG Time Code Reader + ++usb:v1938p0502* ++ ID_MODEL_FROM_DATABASE=TCR600USB IRIG Time Code Reader ++ + usb:v1941* + ID_VENDOR_FROM_DATABASE=Dream Link + +@@ -52190,6 +57719,9 @@ usb:v1943p2255* + usb:v1943p2257* + ID_MODEL_FROM_DATABASE=Model 2257 4 Channel Capture Card + ++usb:v1943p2263* ++ ID_MODEL_FROM_DATABASE=Model 2263 UVC HD Audio/Video Codec Card ++ + usb:v1943pA250* + ID_MODEL_FROM_DATABASE=Model 2250 MPEG and JPEG Capture Card (cold) + +@@ -52206,11 +57738,23 @@ usb:v1949p0004* + ID_MODEL_FROM_DATABASE=Amazon Kindle 3/4/Paperwhite + + usb:v1949p0006* +- ID_MODEL_FROM_DATABASE=Kindle Fire ++ ID_MODEL_FROM_DATABASE=Amazon Kindle Fire + + usb:v1949p0008* + ID_MODEL_FROM_DATABASE=Amazon Kindle Fire HD 8.9" + ++usb:v1949p000A* ++ ID_MODEL_FROM_DATABASE=Amazon Kindle Fire 2nd generation (2012) ++ ++usb:v1949p0331* ++ ID_MODEL_FROM_DATABASE=Kindle Fire HD 8 (2018) ++ ++usb:v1949p0417* ++ ID_MODEL_FROM_DATABASE=Amazon Zukey; clone of Yubikey 4 OTP+U2F ++ ++usb:v1949p0800* ++ ID_MODEL_FROM_DATABASE=Fire Phone ++ + usb:v194F* + ID_VENDOR_FROM_DATABASE=PreSonus Audio Electronics, Inc. + +@@ -52223,6 +57767,9 @@ usb:v194Fp0102* + usb:v194Fp0103* + ID_MODEL_FROM_DATABASE=AudioBox 1818 VSL + ++usb:v194Fp0201* ++ ID_MODEL_FROM_DATABASE=FaderPort ++ + usb:v194Fp0301* + ID_MODEL_FROM_DATABASE=AudioBox + +@@ -52241,6 +57788,9 @@ usb:v1954* + usb:v195D* + ID_VENDOR_FROM_DATABASE=Itron Technology iONE + ++usb:v195Dp2030* ++ ID_MODEL_FROM_DATABASE=Func KB-460 Gaming Keyboard ++ + usb:v195Dp7002* + ID_MODEL_FROM_DATABASE=Libra-Q11 IR remote + +@@ -52253,12 +57803,27 @@ usb:v195Dp7777* + usb:v195Dp7779* + ID_MODEL_FROM_DATABASE=Scorpius-P20MT + ++usb:v1963* ++ ID_VENDOR_FROM_DATABASE=IK Multimedia ++ ++usb:v1963p0005* ++ ID_MODEL_FROM_DATABASE=iRig KEYS ++ ++usb:v1963p0046* ++ ID_MODEL_FROM_DATABASE=UNO Synth ++ + usb:v1965* + ID_VENDOR_FROM_DATABASE=Uniden Corporation + + usb:v1965p0016* + ID_MODEL_FROM_DATABASE=HomePatrol-1 + ++usb:v1965p0018* ++ ID_MODEL_FROM_DATABASE=UBC125XLT ++ ++usb:v1965p001A* ++ ID_MODEL_FROM_DATABASE=BCD436HP Scanner ++ + usb:v1967* + ID_VENDOR_FROM_DATABASE=CASIO HITACHI Mobile Communications Co., Ltd. + +@@ -52271,14 +57836,29 @@ usb:v1970* + usb:v1970p0000* + ID_MODEL_FROM_DATABASE=Z Mate 16GB + ++usb:v1973* ++ ID_VENDOR_FROM_DATABASE=Spectralink Corporation ++ ++usb:v1973p0002* ++ ID_MODEL_FROM_DATABASE=Pivot recovery ++ ++usb:v1973p0003* ++ ID_MODEL_FROM_DATABASE=Pivot Media Transfer Protocol ++ ++usb:v1973p0004* ++ ID_MODEL_FROM_DATABASE=Pivot Media Transfer Protocol ++ + usb:v1975* + ID_VENDOR_FROM_DATABASE=Dongguan Guneetal Wire & Cable Co., Ltd. + + usb:v1976* + ID_VENDOR_FROM_DATABASE=Chipsbrand Microelectronics (HK) Co., Ltd. + ++usb:v1976p1307* ++ ID_MODEL_FROM_DATABASE=microSD Card Reader ++ + usb:v1976p6025* +- ID_MODEL_FROM_DATABASE=Flash Drive 512 MB ++ ID_MODEL_FROM_DATABASE=CBM2090 Flash Drive + + usb:v1977* + ID_VENDOR_FROM_DATABASE=T-Logic +@@ -52292,6 +57872,12 @@ usb:v197D* + usb:v197Dp0222* + ID_MODEL_FROM_DATABASE=BCL 508i + ++usb:v1980* ++ ID_VENDOR_FROM_DATABASE=Storage Appliance Corporation ++ ++usb:v1980p0808* ++ ID_MODEL_FROM_DATABASE=Clickfree C2 Slimline (527SE) ++ + usb:v1989* + ID_VENDOR_FROM_DATABASE=Nuconn Technology Corp. + +@@ -52328,6 +57914,15 @@ usb:v1996p3011* + usb:v1996p3012* + ID_MODEL_FROM_DATABASE=e-ImageData Corp. ScanPro + ++usb:v1997* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Riitek Technology Co., Ltd ++ ++usb:v1997p0409* ++ ID_MODEL_FROM_DATABASE=wireless mini keyboard with touchpad ++ ++usb:v1997p2433* ++ ID_MODEL_FROM_DATABASE=wireless mini keyboard with touchpad ++ + usb:v199B* + ID_VENDOR_FROM_DATABASE=MicroStrain, Inc. + +@@ -52340,9 +57935,27 @@ usb:v199E* + usb:v199Ep8101* + ID_MODEL_FROM_DATABASE=DFx 21BU04 Camera + ++usb:v199Ep8457* ++ ID_MODEL_FROM_DATABASE=DFK AFU130-L53 camera ++ + usb:v199F* + ID_VENDOR_FROM_DATABASE=Benica Corporation + ++usb:v19A5* ++ ID_VENDOR_FROM_DATABASE=HARRIS Corp. ++ ++usb:v19A5p0004* ++ ID_MODEL_FROM_DATABASE=Remote NDIS Network Device ++ ++usb:v19A5p0012* ++ ID_MODEL_FROM_DATABASE=RF-7800S Secure Personal Radio ++ ++usb:v19A5p0401* ++ ID_MODEL_FROM_DATABASE=Mass Storage Device ++ ++usb:v19A5p0402* ++ ID_MODEL_FROM_DATABASE=Falcon III RF-7800V family RNDIS ++ + usb:v19A8* + ID_VENDOR_FROM_DATABASE=Biforst Technology Inc. + +@@ -52391,6 +58004,9 @@ usb:v19B6* + usb:v19B9* + ID_VENDOR_FROM_DATABASE=Data Robotics + ++usb:v19B9p4B10* ++ ID_MODEL_FROM_DATABASE=Drobo ++ + usb:v19B9p8D20* + ID_MODEL_FROM_DATABASE=Drobo Elite + +@@ -52409,6 +58025,12 @@ usb:v19CAp0001* + usb:v19CF* + ID_VENDOR_FROM_DATABASE=Parrot SA + ++usb:v19CFp0001* ++ ID_MODEL_FROM_DATABASE=MiniKit Slim handsfree car kit in firmware update mode ++ ++usb:v19D1* ++ ID_VENDOR_FROM_DATABASE=BYD ++ + usb:v19D2* + ID_VENDOR_FROM_DATABASE=ZTE WCDMA Technologies MSM + +@@ -52421,9 +58043,18 @@ usb:v19D2p0002* + usb:v19D2p0007* + ID_MODEL_FROM_DATABASE=TU25 WiMAX Adapter [Beceem BCS200] + ++usb:v19D2p0017* ++ ID_MODEL_FROM_DATABASE=MF669 ++ + usb:v19D2p0031* + ID_MODEL_FROM_DATABASE=MF110/MF627/MF636 + ++usb:v19D2p0037* ++ ID_MODEL_FROM_DATABASE=ONDA MC503HSA ++ ++usb:v19D2p0039* ++ ID_MODEL_FROM_DATABASE=MF100 ++ + usb:v19D2p0063* + ID_MODEL_FROM_DATABASE=K3565-Z HSDPA + +@@ -52439,6 +58070,9 @@ usb:v19D2p0103* + usb:v19D2p0104* + ID_MODEL_FROM_DATABASE=K4505-Z + ++usb:v19D2p0117* ++ ID_MODEL_FROM_DATABASE=MF667 ++ + usb:v19D2p0146* + ID_MODEL_FROM_DATABASE=MF 195E (HSPA+ Modem) + +@@ -52454,6 +58088,15 @@ usb:v19D2p0325* + usb:v19D2p0326* + ID_MODEL_FROM_DATABASE=LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard + ++usb:v19D2p0501* ++ ID_MODEL_FROM_DATABASE=Lever Cell Phone Model Z936L ++ ++usb:v19D2p1001* ++ ID_MODEL_FROM_DATABASE=K3805-Z vodafone WCDMA/GSM Modem - storage mode (made by ZTE) ++ ++usb:v19D2p1002* ++ ID_MODEL_FROM_DATABASE=K3805-Z vodafone WCDMA/GSM Modem/Networkcard (made by ZTE) ++ + usb:v19D2p1008* + ID_MODEL_FROM_DATABASE=K3570-Z + +@@ -52475,6 +58118,9 @@ usb:v19D2p1217* + usb:v19D2p1218* + ID_MODEL_FROM_DATABASE=MF652 + ++usb:v19D2p1270* ++ ID_MODEL_FROM_DATABASE=MF667 ++ + usb:v19D2p2000* + ID_MODEL_FROM_DATABASE=MF627/MF628/MF628+/MF636+ HSDPA/HSUPA + +@@ -52508,9 +58154,15 @@ usb:v19F7p0001* + usb:v19FA* + ID_VENDOR_FROM_DATABASE=Gampaq Co.Ltd + ++usb:v19FAp0607* ++ ID_MODEL_FROM_DATABASE=GAME CONTROLLER ++ + usb:v19FAp0703* + ID_MODEL_FROM_DATABASE=Steering Wheel + ++usb:v19FD* ++ ID_VENDOR_FROM_DATABASE=MTI Instruments Inc. ++ + usb:v19FF* + ID_VENDOR_FROM_DATABASE=Dynex + +@@ -52520,9 +58172,15 @@ usb:v19FFp0102* + usb:v19FFp0201* + ID_MODEL_FROM_DATABASE=Rocketfish Wireless 2.4G Laser Mouse + ++usb:v19FFp0220* ++ ID_MODEL_FROM_DATABASE=RF-HDWEBLT RocketFish HD WebCam ++ + usb:v19FFp0238* + ID_MODEL_FROM_DATABASE=DX-WRM1401 Mouse + ++usb:v19FFp0239* ++ ID_MODEL_FROM_DATABASE=Bluetooth 4.0 Adapter [Broadcom, 1.12, BCM20702A0] ++ + usb:v1A08* + ID_VENDOR_FROM_DATABASE=Bellwood International, Inc. + +@@ -52556,6 +58214,15 @@ usb:v1A2Cp0021* + usb:v1A2Cp0024* + ID_MODEL_FROM_DATABASE=Multimedia Keyboard + ++usb:v1A2Cp2124* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ ++usb:v1A2Cp2D23* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ ++usb:v1A2Cp427C* ++ ID_MODEL_FROM_DATABASE=Backlit Keyboard [Cougar Vantar] ++ + usb:v1A32* + ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc. + +@@ -52604,6 +58271,21 @@ usb:v1A61* + usb:v1A61p3410* + ID_MODEL_FROM_DATABASE=CoPilot System Cable + ++usb:v1A61p3650* ++ ID_MODEL_FROM_DATABASE=FreeStyle Libre ++ ++usb:v1A61p3850* ++ ID_MODEL_FROM_DATABASE=FreeStyle Optium/Precision Neo ++ ++usb:v1A61p3950* ++ ID_MODEL_FROM_DATABASE=FreeStyle Libre 2 ++ ++usb:v1A64* ++ ID_VENDOR_FROM_DATABASE=Mastervolt ++ ++usb:v1A64p0000* ++ ID_MODEL_FROM_DATABASE=MasterBus Link ++ + usb:v1A6A* + ID_VENDOR_FROM_DATABASE=Spansion Inc. + +@@ -52628,9 +58310,18 @@ usb:v1A79* + usb:v1A79p6002* + ID_MODEL_FROM_DATABASE=Contour + ++usb:v1A79p6210* ++ ID_MODEL_FROM_DATABASE=Contour Next Link 2.4 glucometer ++ ++usb:v1A79p6300* ++ ID_MODEL_FROM_DATABASE=Contour next link ++ + usb:v1A79p7410* + ID_MODEL_FROM_DATABASE=Contour Next + ++usb:v1A79p7800* ++ ID_MODEL_FROM_DATABASE=Contour Plus One ++ + usb:v1A7B* + ID_VENDOR_FROM_DATABASE=Lumberg Connect GmbH & Co. KG + +@@ -52646,9 +58337,30 @@ usb:v1A7Cp0168* + usb:v1A7Cp0191* + ID_MODEL_FROM_DATABASE=VerticalMouse 4 + ++usb:v1A7Cp0195* ++ ID_MODEL_FROM_DATABASE=VerticalMouse C Wireless ++ ++usb:v1A7E* ++ ID_VENDOR_FROM_DATABASE=Meltec Systementwicklung ++ ++usb:v1A7Ep1001* ++ ID_MODEL_FROM_DATABASE=UFT75, UT150, UT60 ++ ++usb:v1A7Ep1003* ++ ID_MODEL_FROM_DATABASE=Thermostick ++ + usb:v1A81* + ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. + ++usb:v1A81p1004* ++ ID_MODEL_FROM_DATABASE=Wireless Dongle 2.4 GHZ HT82D40REW ++ ++usb:v1A81p1701* ++ ID_MODEL_FROM_DATABASE=Wireless dongle ++ ++usb:v1A81p2004* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ + usb:v1A81p2203* + ID_MODEL_FROM_DATABASE=Laser Gaming mouse + +@@ -52658,6 +58370,9 @@ usb:v1A81p2204* + usb:v1A81p2205* + ID_MODEL_FROM_DATABASE=Laser Mouse + ++usb:v1A81p4001* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ + usb:v1A86* + ID_VENDOR_FROM_DATABASE=QinHeng Electronics + +@@ -52671,7 +58386,7 @@ usb:v1A86p5584* + ID_MODEL_FROM_DATABASE=CH341 in parallel mode, usb to printer port converter + + usb:v1A86p7523* +- ID_MODEL_FROM_DATABASE=HL-340 USB-Serial adapter ++ ID_MODEL_FROM_DATABASE=CH340 serial converter + + usb:v1A86p752D* + ID_MODEL_FROM_DATABASE=CH345 MIDI adapter +@@ -52712,6 +58427,21 @@ usb:v1AA5* + usb:v1AA6* + ID_VENDOR_FROM_DATABASE=eFortune Technology Corp. + ++usb:v1AAB* ++ ID_VENDOR_FROM_DATABASE=Silvercreations Software AG ++ ++usb:v1AABp7736* ++ ID_MODEL_FROM_DATABASE=sceye (Gen 2) ++ ++usb:v1AABp7737* ++ ID_MODEL_FROM_DATABASE=sceye (Gen 3) ++ ++usb:v1AABp7738* ++ ID_MODEL_FROM_DATABASE=sceye (Gen 4, 3 Mpix) ++ ++usb:v1AABp7750* ++ ID_MODEL_FROM_DATABASE=sceyeS (Gen 5, 5 MPix) ++ + usb:v1AAD* + ID_VENDOR_FROM_DATABASE=KeeTouch + +@@ -52721,9 +58451,24 @@ usb:v1AADp0001* + usb:v1AB1* + ID_VENDOR_FROM_DATABASE=Rigol Technologies + ++usb:v1AB1p04B0* ++ ID_MODEL_FROM_DATABASE=DS6000 SERIES ++ ++usb:v1AB1p04BE* ++ ID_MODEL_FROM_DATABASE=DS4000 SERIES ++ ++usb:v1AB1p04CE* ++ ID_MODEL_FROM_DATABASE=DS1xx4Z/MSO1xxZ series ++ + usb:v1AB1p0588* + ID_MODEL_FROM_DATABASE=DS1000 SERIES + ++usb:v1AB2* ++ ID_VENDOR_FROM_DATABASE=Allied Vision ++ ++usb:v1AB2p0001* ++ ID_MODEL_FROM_DATABASE=Vision device ++ + usb:v1ACB* + ID_VENDOR_FROM_DATABASE=Salcomp Plc + +@@ -52743,7 +58488,13 @@ usb:v1AD4p0002* + ID_MODEL_FROM_DATABASE=KM290-HRS + + usb:v1ADB* +- ID_VENDOR_FROM_DATABASE=SEL C662 Serial Cable ++ ID_VENDOR_FROM_DATABASE=Schweitzer Engineering Laboratories, Inc ++ ++usb:v1ADBp0001* ++ ID_MODEL_FROM_DATABASE=C662 Serial Cable ++ ++usb:v1ADBp0003* ++ ID_MODEL_FROM_DATABASE=CDC Ethernet Gadget + + usb:v1AE4* + ID_VENDOR_FROM_DATABASE=ic-design Reinhard Gottinger GmbH +@@ -52754,6 +58505,9 @@ usb:v1AE7* + usb:v1AE7p0381* + ID_MODEL_FROM_DATABASE=VS-DVB-T 380U (af9015 based) + ++usb:v1AE7p0525* ++ ID_MODEL_FROM_DATABASE=X-Tensions ISDN TA XC-525 [HFC-S USB] ++ + usb:v1AE7p2001* + ID_MODEL_FROM_DATABASE=SpeedLink Snappy Mic webcam (SL-6825-SBK) + +@@ -52772,6 +58526,12 @@ usb:v1AEF* + usb:v1AF1* + ID_VENDOR_FROM_DATABASE=Connect One Ltd. + ++usb:v1AF3* ++ ID_VENDOR_FROM_DATABASE=Kingsis Technology Corporation ++ ++usb:v1AF3p0001* ++ ID_MODEL_FROM_DATABASE=ZOWIE Gaming mouse ++ + usb:v1AFE* + ID_VENDOR_FROM_DATABASE=A. Eberle GmbH & Co. KG + +@@ -53021,6 +58781,12 @@ usb:v1B0Ep1079* + usb:v1B0Ep1080* + ID_MODEL_FROM_DATABASE=WRITECHIP II CCID + ++usb:v1B12* ++ ID_VENDOR_FROM_DATABASE=Eventide ++ ++usb:v1B12p0011* ++ ID_MODEL_FROM_DATABASE=ModFactor ++ + usb:v1B1C* + ID_VENDOR_FROM_DATABASE=Corsair + +@@ -53036,6 +58802,21 @@ usb:v1B1Cp0A60* + usb:v1B1Cp0C04* + ID_MODEL_FROM_DATABASE=Link Cooling Node + ++usb:v1B1Cp0C06* ++ ID_MODEL_FROM_DATABASE=RM-Series C-Link Adapter ++ ++usb:v1B1Cp0C0A* ++ ID_MODEL_FROM_DATABASE=Hydro Series H115i Liquid CPU Cooler ++ ++usb:v1B1Cp0C0B* ++ ID_MODEL_FROM_DATABASE=Lighting Node Pro ++ ++usb:v1B1Cp0C0C* ++ ID_MODEL_FROM_DATABASE=Lighting Node Loader ++ ++usb:v1B1Cp0C22* ++ ID_MODEL_FROM_DATABASE=iCUE H150i RGB PRO XT Liquid CPU Cooler ++ + usb:v1B1Cp1A01* + ID_MODEL_FROM_DATABASE=Flash Voyager GT + +@@ -53051,6 +58832,12 @@ usb:v1B1Cp1A0A* + usb:v1B1Cp1A0B* + ID_MODEL_FROM_DATABASE=Flash Voyager LS + ++usb:v1B1Cp1A0E* ++ ID_MODEL_FROM_DATABASE=Voyager GTX ++ ++usb:v1B1Cp1A14* ++ ID_MODEL_FROM_DATABASE=Voyager Vega ++ + usb:v1B1Cp1A15* + ID_MODEL_FROM_DATABASE=Voyager Slider Flash Drive + +@@ -53078,24 +58865,78 @@ usb:v1B1Cp1B11* + usb:v1B1Cp1B13* + ID_MODEL_FROM_DATABASE=Vengeance K70RGB keyboard + ++usb:v1B1Cp1B20* ++ ID_MODEL_FROM_DATABASE=STRAFE RGB Gaming Keyboard ++ ++usb:v1B1Cp1B2D* ++ ID_MODEL_FROM_DATABASE=K95 RGB Platinum Keyboard [RGP0056] ++ ++usb:v1B1Cp1B2E* ++ ID_MODEL_FROM_DATABASE=Corsair Corsair Gaming M65 Pro RGB Mouse ++ ++usb:v1B1Cp1B2F* ++ ID_MODEL_FROM_DATABASE=Sabre RGB [CH-9303011-XX] ++ ++usb:v1B1Cp1B3D* ++ ID_MODEL_FROM_DATABASE=Corsair Corsair Gaming K55 RGB Keyboard ++ ++usb:v1B1Cp1B5E* ++ ID_MODEL_FROM_DATABASE=Harpoon Wireless Mouse ++ ++usb:v1B1Cp1B65* ++ ID_MODEL_FROM_DATABASE=Harpoon Wireless Dongle ++ + usb:v1B1Cp1C00* + ID_MODEL_FROM_DATABASE=Controller for Corsair Link + ++usb:v1B1Cp1C02* ++ ID_MODEL_FROM_DATABASE=AX1500i Power Supply ++ ++usb:v1B1Cp1C05* ++ ID_MODEL_FROM_DATABASE=HX750i Power Supply ++ ++usb:v1B1Cp1C07* ++ ID_MODEL_FROM_DATABASE=HX1000i Power Supply ++ ++usb:v1B1Cp1C08* ++ ID_MODEL_FROM_DATABASE=HX1200i Power Supply ++ ++usb:v1B1Cp1C0B* ++ ID_MODEL_FROM_DATABASE=RM750i Power Supply ++ + usb:v1B1Cp1C0C* + ID_MODEL_FROM_DATABASE=RM850i Power Supply + ++usb:v1B1Cp1C1A* ++ ID_MODEL_FROM_DATABASE=Corsair CORSAIR Lighting Node CORE ++ ++usb:v1B1E* ++ ID_VENDOR_FROM_DATABASE=General Imaging / General Electric ++ ++usb:v1B1Ep1003* ++ ID_MODEL_FROM_DATABASE=A1250 ++ + usb:v1B1F* + ID_VENDOR_FROM_DATABASE=eQ-3 Entwicklung GmbH + + usb:v1B1FpC00F* + ID_MODEL_FROM_DATABASE=HM-CFG-USB/HM-CFG-USB-2 [HomeMatic Configuration adapter] + ++usb:v1B1FpC020* ++ ID_MODEL_FROM_DATABASE=HmIP-RFUSB ++ + usb:v1B20* + ID_VENDOR_FROM_DATABASE=MStar Semiconductor, Inc. + + usb:v1B22* + ID_VENDOR_FROM_DATABASE=WiLinx Corp. + ++usb:v1B24* ++ ID_VENDOR_FROM_DATABASE=Telegent Systems, Inc. ++ ++usb:v1B24p4001* ++ ID_MODEL_FROM_DATABASE=TLG2300 Hybrid TV Device ++ + usb:v1B26* + ID_VENDOR_FROM_DATABASE=Cellex Power Products, Inc. + +@@ -53198,6 +59039,9 @@ usb:v1B3Fp0C52* + usb:v1B3Fp2002* + ID_MODEL_FROM_DATABASE=808 Camera #9 (web-cam mode) + ++usb:v1B3Fp2003* ++ ID_MODEL_FROM_DATABASE=GPD6000 [Digital MP3 Player] ++ + usb:v1B47* + ID_VENDOR_FROM_DATABASE=Energizer Holdings, Inc. + +@@ -53288,6 +59132,9 @@ usb:v1B65* + usb:v1B71* + ID_VENDOR_FROM_DATABASE=Fushicai + ++usb:v1B71p0050* ++ ID_MODEL_FROM_DATABASE=Encore ENUTV-4 Analog TV Tuner ++ + usb:v1B71p3002* + ID_MODEL_FROM_DATABASE=USBTV007 Video Grabber [EasyCAP] + +@@ -53345,6 +59192,12 @@ usb:v1B80pD700* + usb:v1B80pE297* + ID_MODEL_FROM_DATABASE=Conceptronic DVB-T CTVDIGRCU V3.0 + ++usb:v1B80pE302* ++ ID_MODEL_FROM_DATABASE=CVBS / S-Video Capture Device [Pinnacle Dazzle / UB315-E] ++ ++usb:v1B80pE34C* ++ ID_MODEL_FROM_DATABASE=UB435-Q ATSC TV Stick ++ + usb:v1B80pE383* + ID_MODEL_FROM_DATABASE=DVB-T UB383-T [af9015] + +@@ -53411,6 +59264,9 @@ usb:v1BA4* + usb:v1BA4p0001* + ID_MODEL_FROM_DATABASE=InSight USB Link + ++usb:v1BA4p0002* ++ ID_MODEL_FROM_DATABASE=EM358 Virtual COM Port ++ + usb:v1BA6* + ID_VENDOR_FROM_DATABASE=Abilis Systems + +@@ -53421,10 +59277,121 @@ usb:v1BAD* + ID_VENDOR_FROM_DATABASE=Harmonix Music + + usb:v1BADp0002* +- ID_MODEL_FROM_DATABASE=Guitar for Xbox 360 ++ ID_MODEL_FROM_DATABASE=Rock Band Guitar for Xbox 360 + + usb:v1BADp0003* +- ID_MODEL_FROM_DATABASE=Drum Kit for Xbox 360 ++ ID_MODEL_FROM_DATABASE=Rock Band Drum Kit for Xbox 360 ++ ++usb:v1BADp0130* ++ ID_MODEL_FROM_DATABASE=Ion Drum Rocker for Xbox 360 ++ ++usb:v1BADp028E* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v1BADp3330* ++ ID_MODEL_FROM_DATABASE=Rock Band 3 Keyboard wii interface ++ ++usb:v1BADpF016* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v1BADpF018* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV SE FightStick for Xbox 360 ++ ++usb:v1BADpF019* ++ ID_MODEL_FROM_DATABASE=BrawlStick for Xbox 360 ++ ++usb:v1BADpF021* ++ ID_MODEL_FROM_DATABASE=Ghost Recon Future Soldier Gamepad for Xbox 360 ++ ++usb:v1BADpF023* ++ ID_MODEL_FROM_DATABASE=MLG Pro Circuit Controller for Xbox 360 ++ ++usb:v1BADpF025* ++ ID_MODEL_FROM_DATABASE=Call of Duty Controller for Xbox 360 ++ ++usb:v1BADpF027* ++ ID_MODEL_FROM_DATABASE=FPS Pro Controller for Xbox 360 ++ ++usb:v1BADpF028* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV FightPad for Xbox 360 ++ ++usb:v1BADpF02E* ++ ID_MODEL_FROM_DATABASE=FightPad ++ ++usb:v1BADpF030* ++ ID_MODEL_FROM_DATABASE=MC2 MicroCON Racing Wheel for Xbox 360 ++ ++usb:v1BADpF036* ++ ID_MODEL_FROM_DATABASE=MicroCON Gamepad Pro for Xbox 360 ++ ++usb:v1BADpF038* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV FightStick TE for Xbox 360 ++ ++usb:v1BADpF039* ++ ID_MODEL_FROM_DATABASE=Marvel VS Capcom 2 Tournament Stick for Xbox 360 ++ ++usb:v1BADpF03A* ++ ID_MODEL_FROM_DATABASE=Street Fighter X Tekken FightStick Pro for Xbox 360 ++ ++usb:v1BADpF03D* ++ ID_MODEL_FROM_DATABASE=Street Fighter IV Arcade Stick TE for Xbox 360 ++ ++usb:v1BADpF03E* ++ ID_MODEL_FROM_DATABASE=MLG Arcade FightStick TE for Xbox 360 ++ ++usb:v1BADpF03F* ++ ID_MODEL_FROM_DATABASE=Soulcalibur FightStick for Xbox 360 ++ ++usb:v1BADpF042* ++ ID_MODEL_FROM_DATABASE=Arcade FightStick TE S+ for Xbox 360 ++ ++usb:v1BADpF080* ++ ID_MODEL_FROM_DATABASE=FightStick TE2 for Xbox 360 ++ ++usb:v1BADpF501* ++ ID_MODEL_FROM_DATABASE=Horipad EX2 Turbo for Xbox 360 ++ ++usb:v1BADpF502* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro.VX SA for Xbox 360 ++ ++usb:v1BADpF503* ++ ID_MODEL_FROM_DATABASE=Fighting Stick VX for Xbox 360 ++ ++usb:v1BADpF504* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro.EX ++ ++usb:v1BADpF505* ++ ID_MODEL_FROM_DATABASE=Fighting Stick EX2B for Xbox 360 ++ ++usb:v1BADpF506* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro.EX Premium VLX for Xbox 360 ++ ++usb:v1BADpF900* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v1BADpF901* ++ ID_MODEL_FROM_DATABASE=GameStop Controller ++ ++usb:v1BADpF903* ++ ID_MODEL_FROM_DATABASE=Tron Controller for Xbox 360 ++ ++usb:v1BADpF904* ++ ID_MODEL_FROM_DATABASE=PDP Versus Fighting Pad for Xbox 360 ++ ++usb:v1BADpF906* ++ ID_MODEL_FROM_DATABASE=Mortal Kombat FightStick for Xbox 360 ++ ++usb:v1BADpF907* ++ ID_MODEL_FROM_DATABASE=Afterglow Gamepad ++ ++usb:v1BADpFA01* ++ ID_MODEL_FROM_DATABASE=Gamepad ++ ++usb:v1BADpFD00* ++ ID_MODEL_FROM_DATABASE=Razer Onza Tournament Edition ++ ++usb:v1BADpFD01* ++ ID_MODEL_FROM_DATABASE=Razer Onza Classic Edition + + usb:v1BAE* + ID_VENDOR_FROM_DATABASE=Vuzix Corporation +@@ -53435,12 +59402,69 @@ usb:v1BAEp0002* + usb:v1BBB* + ID_VENDOR_FROM_DATABASE=T & A Mobile Phones + ++usb:v1BBBp0003* ++ ID_MODEL_FROM_DATABASE=Alcatel one touch 4030D modem connection ++ ++usb:v1BBBp0017* ++ ID_MODEL_FROM_DATABASE=HSPA Data Card ++ ++usb:v1BBBp007A* ++ ID_MODEL_FROM_DATABASE=Alcatel OneTouch (firmware upgrade mode) ++ + usb:v1BBBp011E* + ID_MODEL_FROM_DATABASE=Alcatel One Touch L100V / Telekom Speedstick LTE II + ++usb:v1BBBp0169* ++ ID_MODEL_FROM_DATABASE=Alcatel ONE TOUCH Fierce ++ ++usb:v1BBBp0195* ++ ID_MODEL_FROM_DATABASE=Alcatel OneTouch L850V / Telekom Speedstick LTE ++ ++usb:v1BBBpA00E* ++ ID_MODEL_FROM_DATABASE=Vodafone Smart Tab 4G ++ ++usb:v1BBBpF000* ++ ID_MODEL_FROM_DATABASE=Alcatel OneTouch (mass storage mode) ++ + usb:v1BBBpF017* + ID_MODEL_FROM_DATABASE=Alcatel One Touch L100V / Telekom Speedstick LTE II + ++usb:v1BBD* ++ ID_VENDOR_FROM_DATABASE=Videology Imaging Solutions, Inc. ++ ++usb:v1BBDp0060* ++ ID_MODEL_FROM_DATABASE=1.3MP Mono Camera ++ ++usb:v1BBDp0066* ++ ID_MODEL_FROM_DATABASE=1.3MP Mono Camera ++ ++usb:v1BBDp0067* ++ ID_MODEL_FROM_DATABASE=1.3MP Mono Camera ++ ++usb:v1BC0* ++ ID_VENDOR_FROM_DATABASE=Beijing Senseshield Technology Co.,Ltd. ++ ++usb:v1BC0p0013* ++ ID_MODEL_FROM_DATABASE=Elitee-e ++ ++usb:v1BC0p0014* ++ ID_MODEL_FROM_DATABASE=Elite4 ++ ++usb:v1BC0p0020* ++ ID_MODEL_FROM_DATABASE=iToken ++ ++usb:v1BC0p0021* ++ ID_MODEL_FROM_DATABASE=Mikey ++ ++usb:v1BC0p0051* ++ ID_MODEL_FROM_DATABASE=Elite5 ++ ++usb:v1BC0p0055* ++ ID_MODEL_FROM_DATABASE=Elite5 v3.x ++ ++usb:v1BC0p485D* ++ ID_MODEL_FROM_DATABASE=EliteIV ++ + usb:v1BC4* + ID_VENDOR_FROM_DATABASE=Ford Motor Co. + +@@ -53456,9 +59480,15 @@ usb:v1BC7p0020* + usb:v1BC7p0021* + ID_MODEL_FROM_DATABASE=HE910 + ++usb:v1BC7p0022* ++ ID_MODEL_FROM_DATABASE=GE910-QUAD ++ + usb:v1BC7p0023* + ID_MODEL_FROM_DATABASE=HE910-D ECM + ++usb:v1BC7p0032* ++ ID_MODEL_FROM_DATABASE=LE910-EU V2 ++ + usb:v1BC7p1003* + ID_MODEL_FROM_DATABASE=UC864-E + +@@ -53477,8 +59507,20 @@ usb:v1BC7p1010* + usb:v1BC7p1011* + ID_MODEL_FROM_DATABASE=CE910-DUAL + ++usb:v1BC7p1012* ++ ID_MODEL_FROM_DATABASE=UE910 V2 ++ ++usb:v1BC7p1101* ++ ID_MODEL_FROM_DATABASE=ME910C1 ++ ++usb:v1BC7p110A* ++ ID_MODEL_FROM_DATABASE=ME310 ++ + usb:v1BC7p1200* +- ID_MODEL_FROM_DATABASE=LE920 ++ ID_MODEL_FROM_DATABASE=LE920 (old firmware) ++ ++usb:v1BC7p1201* ++ ID_MODEL_FROM_DATABASE=LE910 / LE920 + + usb:v1BCE* + ID_VENDOR_FROM_DATABASE=Contac Cable Industrial Limited +@@ -53501,18 +59543,30 @@ usb:v1BCFp05C5* + usb:v1BCFp05CF* + ID_MODEL_FROM_DATABASE=Micro keyboard & mouse receiver + ++usb:v1BCFp08A0* ++ ID_MODEL_FROM_DATABASE=Gaming mouse [Philips SPK9304] ++ + usb:v1BCFp0C31* + ID_MODEL_FROM_DATABASE=SPIF30x Serial-ATA bridge + ++usb:v1BCFp2281* ++ ID_MODEL_FROM_DATABASE=SPCA2281 Web Camera ++ + usb:v1BCFp2880* + ID_MODEL_FROM_DATABASE=Dell HD Webcam + ++usb:v1BCFp2883* ++ ID_MODEL_FROM_DATABASE=Asus Webcam ++ + usb:v1BCFp2885* + ID_MODEL_FROM_DATABASE=ASUS Webcam + + usb:v1BCFp2888* + ID_MODEL_FROM_DATABASE=HP Universal Camera + ++usb:v1BCFp2895* ++ ID_MODEL_FROM_DATABASE=Dell Integrated Webcam ++ + usb:v1BCFp28A2* + ID_MODEL_FROM_DATABASE=Dell Integrated Webcam + +@@ -53531,12 +59585,30 @@ usb:v1BCFp2985* + usb:v1BCFp2B83* + ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam FHD + ++usb:v1BCFp2B91* ++ ID_MODEL_FROM_DATABASE=Dell E5570 integrated webcam ++ ++usb:v1BCFp2B97* ++ ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam FHD ++ ++usb:v1BCFp2C6E* ++ ID_MODEL_FROM_DATABASE=Laptop Integrated WebCam HD ++ + usb:v1BD0* + ID_VENDOR_FROM_DATABASE=Hangzhou Riyue Electronic Co., Ltd. + + usb:v1BD5* + ID_VENDOR_FROM_DATABASE=BG Systems, Inc. + ++usb:v1BDA* ++ ID_VENDOR_FROM_DATABASE=University Of Southampton ++ ++usb:v1BDAp0010* ++ ID_MODEL_FROM_DATABASE=Power Board v4 Rev B ++ ++usb:v1BDAp0011* ++ ID_MODEL_FROM_DATABASE=Student Robotics SBv4B ++ + usb:v1BDE* + ID_VENDOR_FROM_DATABASE=P-TWO INDUSTRIES, INC. + +@@ -53585,6 +59657,18 @@ usb:v1C02* + usb:v1C04* + ID_VENDOR_FROM_DATABASE=QNAP System Inc. + ++usb:v1C04p2074* ++ ID_MODEL_FROM_DATABASE=ASM1074 High-Speed hub ++ ++usb:v1C04p3074* ++ ID_MODEL_FROM_DATABASE=ASM1074 SuperSpeed hub ++ ++usb:v1C05* ++ ID_VENDOR_FROM_DATABASE=Shenxhen Stager Electric ++ ++usb:v1C05pEA75* ++ ID_MODEL_FROM_DATABASE=G540 Programmer ++ + usb:v1C0C* + ID_VENDOR_FROM_DATABASE=Ionics EMS, Inc. + +@@ -53597,12 +59681,21 @@ usb:v1C0D* + usb:v1C10* + ID_VENDOR_FROM_DATABASE=Lanterra Industrial Co., Ltd. + ++usb:v1C11* ++ ID_VENDOR_FROM_DATABASE=Input Club Inc. ++ ++usb:v1C11pB04D* ++ ID_MODEL_FROM_DATABASE=ErgoDox Infinity ++ + usb:v1C13* + ID_VENDOR_FROM_DATABASE=ALECTRONIC LIMITED + + usb:v1C1A* + ID_VENDOR_FROM_DATABASE=Datel Electronics Ltd. + ++usb:v1C1Ap0100* ++ ID_MODEL_FROM_DATABASE=Action Replay DS "3DS/DSi/DS/Lite Compatible" ++ + usb:v1C1B* + ID_VENDOR_FROM_DATABASE=Volkswagen of America, Inc. + +@@ -53624,6 +59717,39 @@ usb:v1C26* + usb:v1C27* + ID_VENDOR_FROM_DATABASE=HuiYang D & S Cable Co., Ltd. + ++usb:v1C28* ++ ID_VENDOR_FROM_DATABASE=PMD Technologies ++ ++usb:v1C28pC003* ++ ID_MODEL_FROM_DATABASE=CamCube ++ ++usb:v1C28pC004* ++ ID_MODEL_FROM_DATABASE=CamBoard ++ ++usb:v1C28pC005* ++ ID_MODEL_FROM_DATABASE=ConceptCam ++ ++usb:v1C28pC006* ++ ID_MODEL_FROM_DATABASE=CamBoard 22 ++ ++usb:v1C28pC007* ++ ID_MODEL_FROM_DATABASE=CamBoard nano ++ ++usb:v1C28pC008* ++ ID_MODEL_FROM_DATABASE=CamBoard mod ++ ++usb:v1C28pC009* ++ ID_MODEL_FROM_DATABASE=CamBoard plus ++ ++usb:v1C28pC00A* ++ ID_MODEL_FROM_DATABASE=DigiCam ++ ++usb:v1C28pC00D* ++ ID_MODEL_FROM_DATABASE=CamBoard pico LDD ++ ++usb:v1C28pC00F* ++ ID_MODEL_FROM_DATABASE=CamBoard pico ++ + usb:v1C29* + ID_VENDOR_FROM_DATABASE=Elster GmbH + +@@ -53645,6 +59771,9 @@ usb:v1C34p7241* + usb:v1C37* + ID_VENDOR_FROM_DATABASE=Authorizer Technologies, Inc. + ++usb:v1C37p6190* ++ ID_MODEL_FROM_DATABASE=U2F Fido-compliant cryptotoken ++ + usb:v1C3D* + ID_VENDOR_FROM_DATABASE=NONIN MEDICAL INC. + +@@ -53666,9 +59795,18 @@ usb:v1C40p0535* + usb:v1C40p0536* + ID_MODEL_FROM_DATABASE=Swiss ColorPAL + ++usb:v1C40p0537* ++ ID_MODEL_FROM_DATABASE=MIST Board ++ + usb:v1C49* + ID_VENDOR_FROM_DATABASE=Cherng Weei Technology Corp. + ++usb:v1C4B* ++ ID_VENDOR_FROM_DATABASE=Geratherm Medical AG ++ ++usb:v1C4Bp026F* ++ ID_MODEL_FROM_DATABASE=Spirostik ++ + usb:v1C4F* + ID_VENDOR_FROM_DATABASE=SiGma Micro + +@@ -53684,27 +59822,63 @@ usb:v1C4Fp000E* + usb:v1C4Fp0026* + ID_MODEL_FROM_DATABASE=Keyboard + ++usb:v1C4Fp0032* ++ ID_MODEL_FROM_DATABASE=Optical Mouse with Scroll Wheel ++ ++usb:v1C4Fp0034* ++ ID_MODEL_FROM_DATABASE=XM102K Optical Wheel Mouse ++ ++usb:v1C4Fp0063* ++ ID_MODEL_FROM_DATABASE=Touchpad (integrated in detachable keyboard of Chuwi SurBook) ++ ++usb:v1C4Fp0065* ++ ID_MODEL_FROM_DATABASE=Optical Wheel Mouse [Rapoo N1130] ++ + usb:v1C4Fp3000* + ID_MODEL_FROM_DATABASE=Micro USB Web Camera + + usb:v1C4Fp3002* + ID_MODEL_FROM_DATABASE=WebCam SiGma Micro + ++usb:v1C57* ++ ID_VENDOR_FROM_DATABASE=Zalman Tech Co., Ltd. ++ ++usb:v1C57p1E45* ++ ID_MODEL_FROM_DATABASE=FPSGUN FG1000 Mouse ++ + usb:v1C6B* + ID_VENDOR_FROM_DATABASE=Philips & Lite-ON Digital Solutions Corporation + ++usb:v1C6BpA220* ++ ID_MODEL_FROM_DATABASE=DVD Writer Slimtype eSAU108 ++ + usb:v1C6BpA222* + ID_MODEL_FROM_DATABASE=DVD Writer Slimtype eTAU108 + ++usb:v1C6BpA223* ++ ID_MODEL_FROM_DATABASE=DVD Writer Slimtype eUAU108 ++ + usb:v1C6C* + ID_VENDOR_FROM_DATABASE=Skydigital Inc. + ++usb:v1C71* ++ ID_VENDOR_FROM_DATABASE=Humanware Inc ++ ++usb:v1C71pC004* ++ ID_MODEL_FROM_DATABASE=Braille Note Apex (braille terminal mode) ++ + usb:v1C73* + ID_VENDOR_FROM_DATABASE=AMT + + usb:v1C73p861F* + ID_MODEL_FROM_DATABASE=Anysee E30 USB 2.0 DVB-T Receiver + ++usb:v1C75* ++ ID_VENDOR_FROM_DATABASE=Arturia ++ ++usb:v1C75p0288* ++ ID_MODEL_FROM_DATABASE=KeyStep ++ + usb:v1C77* + ID_VENDOR_FROM_DATABASE=Kaetat Industrial Co., Ltd. + +@@ -53717,18 +59891,39 @@ usb:v1C79* + usb:v1C7A* + ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc. + ++usb:v1C7Ap0577* ++ ID_MODEL_FROM_DATABASE=Fingerprint Sensor ++ ++usb:v1C7Ap0603* ++ ID_MODEL_FROM_DATABASE=ES603 Swipe Fingerprint Sensor ++ + usb:v1C7Ap0801* + ID_MODEL_FROM_DATABASE=Fingerprint Reader + + usb:v1C7B* + ID_VENDOR_FROM_DATABASE=LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD. + ++usb:v1C82* ++ ID_VENDOR_FROM_DATABASE=Atracsys ++ ++usb:v1C82p0200* ++ ID_MODEL_FROM_DATABASE=spryTrac ++ + usb:v1C83* + ID_VENDOR_FROM_DATABASE=Schomaecker GmbH + + usb:v1C83p0001* + ID_MODEL_FROM_DATABASE=RS150 V2 + ++usb:v1C83p0002* ++ ID_MODEL_FROM_DATABASE=RFID card reader ++ ++usb:v1C83p0003* ++ ID_MODEL_FROM_DATABASE=Communicator ++ ++usb:v1C83p0005* ++ ID_MODEL_FROM_DATABASE=Mobile RFID Reader ++ + usb:v1C87* + ID_VENDOR_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +@@ -53789,6 +59984,9 @@ usb:v1CB6p6681* + usb:v1CBE* + ID_VENDOR_FROM_DATABASE=Luminary Micro Inc. + ++usb:v1CBEp0002* ++ ID_MODEL_FROM_DATABASE=CDC serial port [TivaWare] ++ + usb:v1CBEp00FD* + ID_MODEL_FROM_DATABASE=In-Circuit Debug Interface + +@@ -53798,6 +59996,9 @@ usb:v1CBEp00FF* + usb:v1CBEp0166* + ID_MODEL_FROM_DATABASE=CANAL USB2CAN + ++usb:v1CBEp0240* ++ ID_MODEL_FROM_DATABASE=McGill Robotics TM4C Microcontroller ++ + usb:v1CBF* + ID_VENDOR_FROM_DATABASE=FORTAT SKYMARK INDUSTRIAL COMPANY + +@@ -53873,6 +60074,9 @@ usb:v1CF1p0025* + usb:v1CF1p0027* + ID_MODEL_FROM_DATABASE=deRFusb13E06 + ++usb:v1CF1p0030* ++ ID_MODEL_FROM_DATABASE=ZigBee gateway [ConBee II] ++ + usb:v1CFC* + ID_VENDOR_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION + +@@ -53903,6 +60107,12 @@ usb:v1D0A* + usb:v1D0B* + ID_VENDOR_FROM_DATABASE=HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD. + ++usb:v1D0D* ++ ID_VENDOR_FROM_DATABASE=TDKMedia ++ ++usb:v1D0Dp0214* ++ ID_MODEL_FROM_DATABASE=Trans-It Drive ++ + usb:v1D0F* + ID_VENDOR_FROM_DATABASE=Sonix Technology Co., Ltd. + +@@ -53927,9 +60137,15 @@ usb:v1D19p1102* + usb:v1D19p1103* + ID_MODEL_FROM_DATABASE=DK 5217 DVB-T Dongle + ++usb:v1D19p1104* ++ ID_MODEL_FROM_DATABASE=MSI DigiVox Micro HD ++ + usb:v1D19p6105* + ID_MODEL_FROM_DATABASE=Video grabber + ++usb:v1D19p610A* ++ ID_MODEL_FROM_DATABASE=Video grabber ++ + usb:v1D19p8202* + ID_MODEL_FROM_DATABASE=DK DVBC/T DONGLE + +@@ -53942,26 +60158,38 @@ usb:v1D20* + usb:v1D27* + ID_VENDOR_FROM_DATABASE=ASUS + ++usb:v1D27p0601* ++ ID_MODEL_FROM_DATABASE=Xtion ++ + usb:v1D34* + ID_VENDOR_FROM_DATABASE=Dream Cheeky + + usb:v1D34p0001* +- ID_MODEL_FROM_DATABASE=Dream Cheeky Fidget ++ ID_MODEL_FROM_DATABASE=Fidget ++ ++usb:v1D34p0002* ++ ID_MODEL_FROM_DATABASE=Fidget (Basketball) ++ ++usb:v1D34p0003* ++ ID_MODEL_FROM_DATABASE=Fidget (Golf Ball) + + usb:v1D34p0004* +- ID_MODEL_FROM_DATABASE=Dream Cheeky Webmail Notifier ++ ID_MODEL_FROM_DATABASE=Webmail Notifier + + usb:v1D34p0008* +- ID_MODEL_FROM_DATABASE=Dream Cheeky button ++ ID_MODEL_FROM_DATABASE=button + + usb:v1D34p000A* +- ID_MODEL_FROM_DATABASE=Dream Cheeky Mailbox Friends Alert ++ ID_MODEL_FROM_DATABASE=Mailbox Friends Alert + + usb:v1D34p000D* +- ID_MODEL_FROM_DATABASE=Dream Cheeky Big Red Button ++ ID_MODEL_FROM_DATABASE=Big Red Button + + usb:v1D34p0013* +- ID_MODEL_FROM_DATABASE=Dream Cheeky LED Message Board ++ ID_MODEL_FROM_DATABASE=LED Message Board ++ ++usb:v1D34p0020* ++ ID_MODEL_FROM_DATABASE=Stress Ball + + usb:v1D45* + ID_VENDOR_FROM_DATABASE=Touch +@@ -53969,6 +60197,12 @@ usb:v1D45* + usb:v1D45p1D45* + ID_MODEL_FROM_DATABASE=Foxlink Optical touch sensor + ++usb:v1D45p459D* ++ ID_MODEL_FROM_DATABASE=BenQ F5 ++ ++usb:v1D45p465C* ++ ID_MODEL_FROM_DATABASE=Harrier Mini by EE ++ + usb:v1D4D* + ID_VENDOR_FROM_DATABASE=PEGATRON CORPORATION + +@@ -54029,6 +60263,171 @@ usb:v1D50p5124* + usb:v1D50p5300* + ID_MODEL_FROM_DATABASE=Rockbox + ++usb:v1D50p530E* ++ ID_MODEL_FROM_DATABASE=iriver H10 20GB (Rockbox) ++ ++usb:v1D50p530F* ++ ID_MODEL_FROM_DATABASE=iriver H10 5/6GB (Rockbox) ++ ++usb:v1D50p5314* ++ ID_MODEL_FROM_DATABASE=Apple iPod Color/Photo (Rockbox) ++ ++usb:v1D50p5315* ++ ID_MODEL_FROM_DATABASE=Apple iPod Nano 1g (Rockbox) ++ ++usb:v1D50p5316* ++ ID_MODEL_FROM_DATABASE=Apple iPod Video (Rockbox) ++ ++usb:v1D50p5318* ++ ID_MODEL_FROM_DATABASE=Apple iPod 4g Grayscale (Rockbox) ++ ++usb:v1D50p5319* ++ ID_MODEL_FROM_DATABASE=Apple iPod Mini 1g (Rockbox) ++ ++usb:v1D50p531A* ++ ID_MODEL_FROM_DATABASE=Apple iPod Mini 2g (Rockbox) ++ ++usb:v1D50p531C* ++ ID_MODEL_FROM_DATABASE=Apple iPod Nano 2g (Rockbox) ++ ++usb:v1D50p531D* ++ ID_MODEL_FROM_DATABASE=Apple iPod Classic/6G (Rockbox) ++ ++usb:v1D50p5321* ++ ID_MODEL_FROM_DATABASE=Cowon D2 (Rockbox) ++ ++usb:v1D50p5329* ++ ID_MODEL_FROM_DATABASE=Toshiba Gigabeat S (Rockbox) ++ ++usb:v1D50p5332* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa e200 series (Rockbox) ++ ++usb:v1D50p5334* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa c200 series (Rockbox) ++ ++usb:v1D50p5337* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Clip (Rockbox) ++ ++usb:v1D50p5338* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa e200v2 series (Rockbox) ++ ++usb:v1D50p5339* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa m200 v4 series (Rockbox) ++ ++usb:v1D50p533A* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Fuze (Rockbox) ++ ++usb:v1D50p533B* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa c200v2 series (Rockbox) ++ ++usb:v1D50p533C* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Clipv2 (Rockbox) ++ ++usb:v1D50p533E* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Clip+ (Rockbox) ++ ++usb:v1D50p533F* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Fuze v2 (Rockbox) ++ ++usb:v1D50p5340* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Fuze+ (Rockbox) ++ ++usb:v1D50p5341* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Zip (Rockbox) ++ ++usb:v1D50p5342* ++ ID_MODEL_FROM_DATABASE=Sandisk Sansa Connect (Rockbox) ++ ++usb:v1D50p5346* ++ ID_MODEL_FROM_DATABASE=Olympus M:Robe 500i (Rockbox) ++ ++usb:v1D50p5347* ++ ID_MODEL_FROM_DATABASE=Olympus m:robe MR-100 (Rockbox) ++ ++usb:v1D50p5359* ++ ID_MODEL_FROM_DATABASE=Creative Zen X-Fi Style (Rockbox) ++ ++usb:v1D50p535D* ++ ID_MODEL_FROM_DATABASE=Creative Zen X-Fi2 (Rockbox) ++ ++usb:v1D50p535E* ++ ID_MODEL_FROM_DATABASE=Creative Zen X-Fi3 (Rockbox) ++ ++usb:v1D50p5360* ++ ID_MODEL_FROM_DATABASE=Creative Zen X-Fi (Rockbox) ++ ++usb:v1D50p5361* ++ ID_MODEL_FROM_DATABASE=Creative ZEN Mozaic (Rockbox) ++ ++usb:v1D50p5362* ++ ID_MODEL_FROM_DATABASE=Creative Zen (Rockbox) ++ ++usb:v1D50p5364* ++ ID_MODEL_FROM_DATABASE=Philips GoGear SA9200 (Rockbox) ++ ++usb:v1D50p5365* ++ ID_MODEL_FROM_DATABASE=Philips GoGear HDD16x0 (Rockbox) ++ ++usb:v1D50p5366* ++ ID_MODEL_FROM_DATABASE=Philips GoGear HDD63x0 (Rockbox) ++ ++usb:v1D50p5378* ++ ID_MODEL_FROM_DATABASE=Onda VX747 (Rockbox) ++ ++usb:v1D50p5379* ++ ID_MODEL_FROM_DATABASE=Onda VX767 (Rockbox) ++ ++usb:v1D50p537B* ++ ID_MODEL_FROM_DATABASE=Onda VX777 (Rockbox) ++ ++usb:v1D50p538C* ++ ID_MODEL_FROM_DATABASE=Samsung YH-820 (Rockbox) ++ ++usb:v1D50p538D* ++ ID_MODEL_FROM_DATABASE=Samsung YH-920 (Rockbox) ++ ++usb:v1D50p538E* ++ ID_MODEL_FROM_DATABASE=Samsung YH-925 (Rockbox) ++ ++usb:v1D50p53A0* ++ ID_MODEL_FROM_DATABASE=Packard Bell Vibe 500 (Rockbox) ++ ++usb:v1D50p53B4* ++ ID_MODEL_FROM_DATABASE=Rockchip 27xx generic (Rockbox) ++ ++usb:v1D50p53BE* ++ ID_MODEL_FROM_DATABASE=HiFiMAN HM-60x (Rockbox) ++ ++usb:v1D50p53BF* ++ ID_MODEL_FROM_DATABASE=HiFiMAN HM-801 (Rockbox) ++ ++usb:v1D50p53D2* ++ ID_MODEL_FROM_DATABASE=HiFi E.T. MA9 (Rockbox) ++ ++usb:v1D50p53D3* ++ ID_MODEL_FROM_DATABASE=HiFi E.T. MA9C (Rockbox) ++ ++usb:v1D50p53D4* ++ ID_MODEL_FROM_DATABASE=HiFi E.T. MA8 (Rockbox) ++ ++usb:v1D50p53D5* ++ ID_MODEL_FROM_DATABASE=HiFi E.T. MA8C (Rockbox) ++ ++usb:v1D50p53DC* ++ ID_MODEL_FROM_DATABASE=Sony NWZ-E370/E380 series (Rockbox) ++ ++usb:v1D50p53DD* ++ ID_MODEL_FROM_DATABASE=Sony NWZ-E360 series (Rockbox) ++ ++usb:v1D50p53E6* ++ ID_MODEL_FROM_DATABASE=IHIFI 760 (Rockbox) ++ ++usb:v1D50p53E7* ++ ID_MODEL_FROM_DATABASE=IHIFI 960 (Rockbox) ++ ++usb:v1D50p53FF* ++ ID_MODEL_FROM_DATABASE=Generic Rockbox device ++ + usb:v1D50p6000* + ID_MODEL_FROM_DATABASE=Ubertooth Zero + +@@ -54116,6 +60515,9 @@ usb:v1D50p601B* + usb:v1D50p601C* + ID_MODEL_FROM_DATABASE=EPOSMote II + ++usb:v1D50p601D* ++ ID_MODEL_FROM_DATABASE=UDS18B20 temperature sensor ++ + usb:v1D50p601E* + ID_MODEL_FROM_DATABASE=5x5 STM32 prototyping board + +@@ -54140,12 +60542,18 @@ usb:v1D50p6024* + usb:v1D50p6025* + ID_MODEL_FROM_DATABASE=Keyglove (HID) + ++usb:v1D50p6026* ++ ID_MODEL_FROM_DATABASE=Keyglove (Serial) ++ + usb:v1D50p6027* + ID_MODEL_FROM_DATABASE=Key64 Keyboard + + usb:v1D50p6028* + ID_MODEL_FROM_DATABASE=Teensy 2.0 Development Board [ErgoDox Keyboard] + ++usb:v1D50p6029* ++ ID_MODEL_FROM_DATABASE=Marlin 2.0 (Serial) ++ + usb:v1D50p602A* + ID_MODEL_FROM_DATABASE=Marlin 2.0 (Mass Storage) + +@@ -54170,6 +60578,9 @@ usb:v1D50p6030* + usb:v1D50p6031* + ID_MODEL_FROM_DATABASE=Handmade GSM GPS tracker + ++usb:v1D50p6032* ++ ID_MODEL_FROM_DATABASE=ncrmnt.org uISP ++ + usb:v1D50p6033* + ID_MODEL_FROM_DATABASE=frobiac / adnw keyboard + +@@ -54272,9 +60683,24 @@ usb:v1D50p6053* + usb:v1D50p6054* + ID_MODEL_FROM_DATABASE=Satlab/AAUSAT3 BlueBox + ++usb:v1D50p6055* ++ ID_MODEL_FROM_DATABASE=RADiuS ER900TRS-02 transciever with SMA Connector ++ + usb:v1D50p6056* + ID_MODEL_FROM_DATABASE=The Glitch + ++usb:v1D50p6057* ++ ID_MODEL_FROM_DATABASE=OpenPipe MIDI Shield ++ ++usb:v1D50p6058* ++ ID_MODEL_FROM_DATABASE=Novena OTG port ++ ++usb:v1D50p6059* ++ ID_MODEL_FROM_DATABASE=xser serial ++ ++usb:v1D50p605A* ++ ID_MODEL_FROM_DATABASE=Daisho test ++ + usb:v1D50p605B* + ID_MODEL_FROM_DATABASE=RfCat YARD Stick One + +@@ -54296,6 +60722,9 @@ usb:v1D50p6060* + usb:v1D50p6061* + ID_MODEL_FROM_DATABASE=Power Manager + ++usb:v1D50p6062* ++ ID_MODEL_FROM_DATABASE=WhiteRabbit console and Wishbone bridge ++ + usb:v1D50p6063* + ID_MODEL_FROM_DATABASE=CPC FPGA + +@@ -54332,6 +60761,9 @@ usb:v1D50p606D* + usb:v1D50p606E* + ID_MODEL_FROM_DATABASE=Reefangel Evolution 1.0 + ++usb:v1D50p606F* ++ ID_MODEL_FROM_DATABASE=Geschwister Schneider CAN adapter ++ + usb:v1D50p6070* + ID_MODEL_FROM_DATABASE=Open Pinball Project + +@@ -54359,6 +60791,9 @@ usb:v1D50p6077* + usb:v1D50p6078* + ID_MODEL_FROM_DATABASE=DTplug + ++usb:v1D50p6079* ++ ID_MODEL_FROM_DATABASE=Mood Light ++ + usb:v1D50p607A* + ID_MODEL_FROM_DATABASE=Fadecandy + +@@ -54371,6 +60806,9 @@ usb:v1D50p607C* + usb:v1D50p607D* + ID_MODEL_FROM_DATABASE=Spark Core Arduino-compatible board with WiFi + ++usb:v1D50p607E* ++ ID_MODEL_FROM_DATABASE=OSHUG Wuthering multi-tool ++ + usb:v1D50p607F* + ID_MODEL_FROM_DATABASE=Spark Core Arduino-compatible board with WiFi (bootloader) + +@@ -54395,6 +60833,9 @@ usb:v1D50p6085* + usb:v1D50p6086* + ID_MODEL_FROM_DATABASE=OneRNG entropy device + ++usb:v1D50p6087* ++ ID_MODEL_FROM_DATABASE=Blinkytape (alternate endpoint config) ++ + usb:v1D50p6088* + ID_MODEL_FROM_DATABASE=picp PIC16F145x based PIC16F145x programmer + +@@ -54506,6 +60947,15 @@ usb:v1D50p60AB* + usb:v1D50p60AC* + ID_MODEL_FROM_DATABASE=OpenBLT generic microcontroller (bootloader) + ++usb:v1D50p60AD* ++ ID_MODEL_FROM_DATABASE=Clasic Gamepad Adapter (NES) ++ ++usb:v1D50p60AE* ++ ID_MODEL_FROM_DATABASE=Clasic Gamepad Adapter (N64) ++ ++usb:v1D50p60AF* ++ ID_MODEL_FROM_DATABASE=Clasic Gamepad Adapter (DB9) ++ + usb:v1D50p60B0* + ID_MODEL_FROM_DATABASE=Waterott Arduino based Clock (caterina bootloader) + +@@ -54551,6 +61001,9 @@ usb:v1D50p60BE* + usb:v1D50p60BF* + ID_MODEL_FROM_DATABASE=Pixelmatix Aurora + ++usb:v1D50p60C0* ++ ID_MODEL_FROM_DATABASE=Nucular Keyboard adapter ++ + usb:v1D50p60C1* + ID_MODEL_FROM_DATABASE=BrewBit Model-T pOSHW temperature controller for homebrewers (bootloader) + +@@ -54560,6 +61013,12 @@ usb:v1D50p60C2* + usb:v1D50p60C3* + ID_MODEL_FROM_DATABASE=X Antenna Tracker arduino board + ++usb:v1D50p60C4* ++ ID_MODEL_FROM_DATABASE=CAN bus communication device ++ ++usb:v1D50p60C5* ++ ID_MODEL_FROM_DATABASE=PIC16F1 bootloader ++ + usb:v1D50p60C6* + ID_MODEL_FROM_DATABASE=USBtrng hardware random number generator + +@@ -54581,6 +61040,9 @@ usb:v1D50p60CB* + usb:v1D50p60CC* + ID_MODEL_FROM_DATABASE=LamDiNao + ++usb:v1D50p60CD* ++ ID_MODEL_FROM_DATABASE=Open Lighting DMX512 / RDM widget ++ + usb:v1D50p60DE* + ID_MODEL_FROM_DATABASE=Cryptech.is random number generator + +@@ -54620,8 +61082,17 @@ usb:v1D50p60E9* + usb:v1D50p60EA* + ID_MODEL_FROM_DATABASE=Wiggleport FPGA-based I/O board + ++usb:v1D50p60EB* ++ ID_MODEL_FROM_DATABASE=candleLight CAN adapter ++ + usb:v1D50p60EC* +- ID_MODEL_FROM_DATABASE=Duet 3D Printer Controller ++ ID_MODEL_FROM_DATABASE=Duet 2 WiFi or Duet 2 Ethernet 3D printer control electronics ++ ++usb:v1D50p60ED* ++ ID_MODEL_FROM_DATABASE=Duet 2 Maestro 3D printer control electronics ++ ++usb:v1D50p60EE* ++ ID_MODEL_FROM_DATABASE=Duet 3 motion control electronics + + usb:v1D50p60F0* + ID_MODEL_FROM_DATABASE=UDAD-T1 data aquisition device (boot) +@@ -54668,11 +61139,23 @@ usb:v1D50p610C* + usb:v1D50p610D* + ID_MODEL_FROM_DATABASE=Magic Keys + ++usb:v1D50p6114* ++ ID_MODEL_FROM_DATABASE=MIDI key ++ ++usb:v1D50p6118* ++ ID_MODEL_FROM_DATABASE=Thomson MO5 keyboard ++ ++usb:v1D50p6122* ++ ID_MODEL_FROM_DATABASE=Ultimate Hacking Keyboard ++ ++usb:v1D50p614C* ++ ID_MODEL_FROM_DATABASE=dwtk In-Circuit Emulator ++ + usb:v1D50p8085* + ID_MODEL_FROM_DATABASE=Box0 (box0-v5) + + usb:v1D50pCC15* +- ID_MODEL_FROM_DATABASE=rad1o badge for CCC congress 2015 ++ ID_MODEL_FROM_DATABASE=rad1o badge for CCC summer camp 2015 + + usb:v1D57* + ID_VENDOR_FROM_DATABASE=Xenta +@@ -54686,6 +61169,9 @@ usb:v1D57p0006* + usb:v1D57p000C* + ID_MODEL_FROM_DATABASE=Optical Mouse + ++usb:v1D57p130F* ++ ID_MODEL_FROM_DATABASE=2.4Ghz wireless optical mouse receiver ++ + usb:v1D57p2400* + ID_MODEL_FROM_DATABASE=Wireless Mouse Receiver + +@@ -54698,15 +61184,36 @@ usb:v1D57p83D0* + usb:v1D57pAC01* + ID_MODEL_FROM_DATABASE=Wireless Receiver (Keyboard and Mouse) + ++usb:v1D57pAC02* ++ ID_MODEL_FROM_DATABASE=ViFit Activity Tracker ++ ++usb:v1D57pAC08* ++ ID_MODEL_FROM_DATABASE=RFID Receiver (Keyboard) ++ + usb:v1D57pAD02* + ID_MODEL_FROM_DATABASE=SE340D PC Remote Control + ++usb:v1D57pAD03* ++ ID_MODEL_FROM_DATABASE=[T3] 2.4GHz and IR Air Mouse Remote Control ++ + usb:v1D57pAF01* + ID_MODEL_FROM_DATABASE=AUVIO Universal Remote Receiver for PlayStation 3 + ++usb:v1D57pAF03* ++ ID_MODEL_FROM_DATABASE=Wireless Receiver ++ ++usb:v1D57pFA20* ++ ID_MODEL_FROM_DATABASE=2.4GHz Wireless Reciever (Mini Keyboard & Mouse) ++ + usb:v1D5B* + ID_VENDOR_FROM_DATABASE=Smartronix, Inc. + ++usb:v1D5C* ++ ID_VENDOR_FROM_DATABASE=Fresco Logic ++ ++usb:v1D5Cp2000* ++ ID_MODEL_FROM_DATABASE=FL2000/FL2000DX VGA/DVI/HDMI Adapter ++ + usb:v1D6B* + ID_VENDOR_FROM_DATABASE=Linux Foundation + +@@ -54740,12 +61247,30 @@ usb:v1D6Bp0105* + usb:v1D6Bp0200* + ID_MODEL_FROM_DATABASE=Qemu Audio Device + ++usb:v1D88* ++ ID_VENDOR_FROM_DATABASE=Mahr GmbH ++ ++usb:v1D88p0001* ++ ID_MODEL_FROM_DATABASE=Measurement Device [MarECon] ++ ++usb:v1D88p0002* ++ ID_MODEL_FROM_DATABASE=Probe ++ ++usb:v1D88p0003* ++ ID_MODEL_FROM_DATABASE=Surface Measurement [PS10] ++ + usb:v1D90* + ID_VENDOR_FROM_DATABASE=Citizen + + usb:v1D90p201E* + ID_MODEL_FROM_DATABASE=PPU-700 + ++usb:v1D90p2037* ++ ID_MODEL_FROM_DATABASE=CL-S631 Barcode Printer ++ ++usb:v1D90p20F0* ++ ID_MODEL_FROM_DATABASE=Thermal Receipt Printer [CT-E351] ++ + usb:v1D9D* + ID_VENDOR_FROM_DATABASE=Sigma Sport + +@@ -54755,6 +61280,18 @@ usb:v1D9Dp1010* + usb:v1D9Dp1011* + ID_MODEL_FROM_DATABASE=Docking Station Topline 2012 + ++usb:v1D9Dp1012* ++ ID_MODEL_FROM_DATABASE=Docking Station Topline 2016 ++ ++usb:v1DD2* ++ ID_VENDOR_FROM_DATABASE=Leo Bodnar Electronics Ltd ++ ++usb:v1DD3* ++ ID_VENDOR_FROM_DATABASE=Dajc Inc. ++ ++usb:v1DD3p0001* ++ ID_MODEL_FROM_DATABASE=Expert I/O 1000 ++ + usb:v1DE1* + ID_VENDOR_FROM_DATABASE=Actions Microelectronics Co. + +@@ -54764,6 +61301,27 @@ usb:v1DE1p1101* + usb:v1DE1pC101* + ID_MODEL_FROM_DATABASE=Generic Display Device + ++usb:v1DE6* ++ ID_VENDOR_FROM_DATABASE=MICRORISC s.r.o. ++ ++usb:v1DF7* ++ ID_VENDOR_FROM_DATABASE=SDRplay ++ ++usb:v1DF7p2500* ++ ID_MODEL_FROM_DATABASE=RSP1 ++ ++usb:v1DF7p3000* ++ ID_MODEL_FROM_DATABASE=RSP1a ++ ++usb:v1DF7p3010* ++ ID_MODEL_FROM_DATABASE=RSP2/RSP2pro ++ ++usb:v1DF7p3020* ++ ID_MODEL_FROM_DATABASE=RSPduo ++ ++usb:v1DF7p3030* ++ ID_MODEL_FROM_DATABASE=RSPdx ++ + usb:v1E0E* + ID_VENDOR_FROM_DATABASE=Qualcomm / Option + +@@ -54783,11 +61341,14 @@ usb:v1E17p0001* + ID_MODEL_FROM_DATABASE=instadose dosimeter + + usb:v1E1D* +- ID_VENDOR_FROM_DATABASE=Lumension Security ++ ID_VENDOR_FROM_DATABASE=Kanguru Solutions + + usb:v1E1Dp0165* + ID_MODEL_FROM_DATABASE=Secure Pen drive + ++usb:v1E1Dp1101* ++ ID_MODEL_FROM_DATABASE=FlashBlu Flash Drive ++ + usb:v1E1F* + ID_VENDOR_FROM_DATABASE=INVIA + +@@ -54842,15 +61403,51 @@ usb:v1E29p040D* + usb:v1E29p040E* + ID_MODEL_FROM_DATABASE=LPC2378 [Robotino 3 Bootloader] + ++usb:v1E29p040F* ++ ID_MODEL_FROM_DATABASE=LPC2148 [Robotino gripper] ++ ++usb:v1E29p0410* ++ ID_MODEL_FROM_DATABASE=LPC2148 [Robotino IR panel] ++ + usb:v1E29p0501* + ID_MODEL_FROM_DATABASE=CP2102 [CMSP] + + usb:v1E29p0601* + ID_MODEL_FROM_DATABASE=CMMP-AS + ++usb:v1E29p0602* ++ ID_MODEL_FROM_DATABASE=FTDI232 [CMMS] ++ ++usb:v1E2D* ++ ID_VENDOR_FROM_DATABASE=Gemalto M2M GmbH ++ ++usb:v1E2Dp004F* ++ ID_MODEL_FROM_DATABASE=EGS3 GSM/GPRS modem ++ ++usb:v1E2Dp0054* ++ ID_MODEL_FROM_DATABASE=PH8 wireless module ++ ++usb:v1E2Dp0058* ++ ID_MODEL_FROM_DATABASE=Wireless Module [Cinterion EHS6] ++ ++usb:v1E2Dp0059* ++ ID_MODEL_FROM_DATABASE=Wireless Module [Cinterion BGx] ++ ++usb:v1E2Dp005B* ++ ID_MODEL_FROM_DATABASE=Zoom 4625 Modem ++ ++usb:v1E2Dp0061* ++ ID_MODEL_FROM_DATABASE=ALSx PLSx LTE modem ++ ++usb:v1E2Dp00A0* ++ ID_MODEL_FROM_DATABASE=Cinterion ELS31-V ++ + usb:v1E3D* + ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd + ++usb:v1E3Dp198A* ++ ID_MODEL_FROM_DATABASE=Flash Disk ++ + usb:v1E3Dp2093* + ID_MODEL_FROM_DATABASE=CBM209x Flash Drive (OEM) + +@@ -54863,6 +61460,15 @@ usb:v1E41* + usb:v1E41p0001* + ID_MODEL_FROM_DATABASE=CS328A PC Oscilloscope + ++usb:v1E41p0004* ++ ID_MODEL_FROM_DATABASE=CS448 ++ ++usb:v1E44* ++ ID_VENDOR_FROM_DATABASE=SHIMANO INC. ++ ++usb:v1E44p7220* ++ ID_MODEL_FROM_DATABASE=SM-BCR2 ++ + usb:v1E4E* + ID_VENDOR_FROM_DATABASE=Cubeternet + +@@ -54872,6 +61478,9 @@ usb:v1E4Ep0100* + usb:v1E4Ep0102* + ID_MODEL_FROM_DATABASE=GL-UPC822 UVC WebCam + ++usb:v1E4Ep0109* ++ ID_MODEL_FROM_DATABASE=EtronTech CMOS based eSP570 WebCam [Onyx Titanium TC101] ++ + usb:v1E54* + ID_VENDOR_FROM_DATABASE=TypeMatrix + +@@ -54884,15 +61493,39 @@ usb:v1E68* + usb:v1E68p001B* + ID_MODEL_FROM_DATABASE=DataStation maxi g.u + ++usb:v1E68p004C* ++ ID_MODEL_FROM_DATABASE=DataStation Pocket Click ++ + usb:v1E68p0050* + ID_MODEL_FROM_DATABASE=DataStation maxi light + ++usb:v1E68p1045* ++ ID_MODEL_FROM_DATABASE=ST70408-3 [SurfTab breeze 7.0 quad 3G] (MTP Mode) ++ ++usb:v1E68p1046* ++ ID_MODEL_FROM_DATABASE=ST70408-3 [SurfTab breeze 7.0 quad 3G] (PTP Mode) ++ + usb:v1E71* + ID_VENDOR_FROM_DATABASE=NZXT + + usb:v1E71p0001* + ID_MODEL_FROM_DATABASE=Avatar Optical Mouse + ++usb:v1E71p170E* ++ ID_MODEL_FROM_DATABASE=Kraken X ++ ++usb:v1E71p1711* ++ ID_MODEL_FROM_DATABASE=Grid+ V3 ++ ++usb:v1E71p1714* ++ ID_MODEL_FROM_DATABASE=Smart Device ++ ++usb:v1E71p1715* ++ ID_MODEL_FROM_DATABASE=Kraken M22 ++ ++usb:v1E71p2006* ++ ID_MODEL_FROM_DATABASE=Smart Device V2 ++ + usb:v1E74* + ID_VENDOR_FROM_DATABASE=Coby Electronics Corporation + +@@ -54917,39 +61550,360 @@ usb:v1E74p6512* + usb:v1E74p7111* + ID_MODEL_FROM_DATABASE=MP957 Music and Video Player + ++usb:v1E7B* ++ ID_VENDOR_FROM_DATABASE=Zurich Instruments ++ ++usb:v1E7Bp0002* ++ ID_MODEL_FROM_DATABASE=HF2 ++ ++usb:v1E7Bp0003* ++ ID_MODEL_FROM_DATABASE=UHF ++ ++usb:v1E7Bp0004* ++ ID_MODEL_FROM_DATABASE=MFLI ++ + usb:v1E7D* + ID_VENDOR_FROM_DATABASE=ROCCAT + + usb:v1E7Dp2C24* + ID_MODEL_FROM_DATABASE=Pyra Mouse (wired) + ++usb:v1E7Dp2C2E* ++ ID_MODEL_FROM_DATABASE=Lua Mouse ++ ++usb:v1E7Dp2C38* ++ ID_MODEL_FROM_DATABASE=Kiro Mouse ++ + usb:v1E7Dp2CED* + ID_MODEL_FROM_DATABASE=Kone Mouse + ++usb:v1E7Dp2CEE* ++ ID_MODEL_FROM_DATABASE=Kova 2016 Gray Mouse ++ ++usb:v1E7Dp2CEF* ++ ID_MODEL_FROM_DATABASE=Kova 2016 White Mouse ++ ++usb:v1E7Dp2CF0* ++ ID_MODEL_FROM_DATABASE=Kova 2016 Black Mouse ++ + usb:v1E7Dp2CF6* + ID_MODEL_FROM_DATABASE=Pyra Mouse (wireless) + + usb:v1E7Dp2D50* +- ID_MODEL_FROM_DATABASE=Kova+ Mouse ++ ID_MODEL_FROM_DATABASE=Kova[+] Mouse + + usb:v1E7Dp2D51* +- ID_MODEL_FROM_DATABASE=Kone+ Mouse ++ ID_MODEL_FROM_DATABASE=Kone[+] Mouse ++ ++usb:v1E7Dp2D5A* ++ ID_MODEL_FROM_DATABASE=Savu Mouse ++ ++usb:v1E7Dp2DB4* ++ ID_MODEL_FROM_DATABASE=Kone Pure Optical Mouse ++ ++usb:v1E7Dp2DBE* ++ ID_MODEL_FROM_DATABASE=Kone Pure Mouse ++ ++usb:v1E7Dp2DBF* ++ ID_MODEL_FROM_DATABASE=Kone Pure Military Mouse ++ ++usb:v1E7Dp2DC2* ++ ID_MODEL_FROM_DATABASE=Kone Pure Optical Black Mouse ++ ++usb:v1E7Dp2DCB* ++ ID_MODEL_FROM_DATABASE=Kone Pure SE(L) Mouse ++ ++usb:v1E7Dp2E22* ++ ID_MODEL_FROM_DATABASE=Kone XTD Mouse ++ ++usb:v1E7Dp2E23* ++ ID_MODEL_FROM_DATABASE=Kone XTD Optical Mouse ++ ++usb:v1E7Dp2E27* ++ ID_MODEL_FROM_DATABASE=Kone AIMO Mouse ++ ++usb:v1E7Dp2E4A* ++ ID_MODEL_FROM_DATABASE=Tyon Black Mouse ++ ++usb:v1E7Dp2E4B* ++ ID_MODEL_FROM_DATABASE=Tyon White Mouse ++ ++usb:v1E7Dp2E7C* ++ ID_MODEL_FROM_DATABASE=Nyth Black Mouse ++ ++usb:v1E7Dp2E7D* ++ ID_MODEL_FROM_DATABASE=Nyth White Mouse ++ ++usb:v1E7Dp2F76* ++ ID_MODEL_FROM_DATABASE=Sova Keyboard ++ ++usb:v1E7Dp2F94* ++ ID_MODEL_FROM_DATABASE=Sova MK Keyboard ++ ++usb:v1E7Dp2FA8* ++ ID_MODEL_FROM_DATABASE=Suora Keyboard ++ ++usb:v1E7Dp2FC6* ++ ID_MODEL_FROM_DATABASE=Skeltr Keyboard ++ ++usb:v1E7Dp2FDA* ++ ID_MODEL_FROM_DATABASE=Ryos MK FX Keyboard + + usb:v1E7Dp30D4* + ID_MODEL_FROM_DATABASE=Arvo Keyboard + ++usb:v1E7Dp3138* ++ ID_MODEL_FROM_DATABASE=Ryos MK Keyboard ++ ++usb:v1E7Dp316A* ++ ID_MODEL_FROM_DATABASE=Ryos TKL Keyboard ++ ++usb:v1E7Dp319C* ++ ID_MODEL_FROM_DATABASE=Isku Keyboard ++ ++usb:v1E7Dp31CE* ++ ID_MODEL_FROM_DATABASE=Ryos MK Glow Keyboard ++ ++usb:v1E7Dp3232* ++ ID_MODEL_FROM_DATABASE=Ryos MK Pro Keyboard ++ ++usb:v1E7Dp3246* ++ ID_MODEL_FROM_DATABASE=Suora FX Keyboard ++ ++usb:v1E7Dp3264* ++ ID_MODEL_FROM_DATABASE=Isku FX Keyboard ++ ++usb:v1E8E* ++ ID_VENDOR_FROM_DATABASE=Airbus Defence and Space ++ ++usb:v1E8Ep6001* ++ ID_MODEL_FROM_DATABASE=P8GR ++ ++usb:v1E91* ++ ID_VENDOR_FROM_DATABASE=Other World Computing ++ ++usb:v1E91pB0B1* ++ ID_MODEL_FROM_DATABASE=miniStack ++ + usb:v1EA7* + ID_VENDOR_FROM_DATABASE=SHARKOON Technologies GmbH + ++usb:v1EA7p0030* ++ ID_MODEL_FROM_DATABASE=Trust GXT 158 Orna Laser Gaming Mouse ++ ++usb:v1EA7p0064* ++ ID_MODEL_FROM_DATABASE=2.4GHz Wireless rechargeable vertical mouse [More&Better] ++ + usb:v1EA7p0066* + ID_MODEL_FROM_DATABASE=[Mediatrack Edge Mini Keyboard] + ++usb:v1EA7p0907* ++ ID_MODEL_FROM_DATABASE=Keyboard ++ ++usb:v1EA7p1002* ++ ID_MODEL_FROM_DATABASE=Vintorez Gaming Mouse ++ + usb:v1EA7p2007* + ID_MODEL_FROM_DATABASE=SHARK ZONE K30 Illuminated Gaming Keyboard + ++usb:v1EAB* ++ ID_VENDOR_FROM_DATABASE=Fujian Newland Computer Co., Ltd ++ ++usb:v1EABp0103* ++ ID_MODEL_FROM_DATABASE=HR200 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp0106* ++ ID_MODEL_FROM_DATABASE=HR200 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp0110* ++ ID_MODEL_FROM_DATABASE=HR200 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp0C03* ++ ID_MODEL_FROM_DATABASE=HR100/HR3260 cordless/HR3290 cordless/BS80 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp0C06* ++ ID_MODEL_FROM_DATABASE=HR100/HR3260 cordless/HR3290 cordless/BS80 Barcode scanner engine (USB Serial CDC) ++ ++usb:v1EABp0C10* ++ ID_MODEL_FROM_DATABASE=HR100/HR3260 cordless/HR3290 cordless/BS80 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp0D03* ++ ID_MODEL_FROM_DATABASE=EM2028 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp0D06* ++ ID_MODEL_FROM_DATABASE=EM2028 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp0D10* ++ ID_MODEL_FROM_DATABASE=EM2028 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1303* ++ ID_MODEL_FROM_DATABASE=EM30xx/EM20xx/HR3260 corded/HR200C Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1306* ++ ID_MODEL_FROM_DATABASE=EM30xx/EM20xx/HR3260 corded/HR200C Barcode scanner engine (USB serial CDC) ++ ++usb:v1EABp1310* ++ ID_MODEL_FROM_DATABASE=EM30xx/EM20xx/HR3260 corded/HR200C Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1403* ++ ID_MODEL_FROM_DATABASE=HR15-xx Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1406* ++ ID_MODEL_FROM_DATABASE=HR15-xx Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1410* ++ ID_MODEL_FROM_DATABASE=HR15-xx Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1603* ++ ID_MODEL_FROM_DATABASE=FM100-M/3250 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1606* ++ ID_MODEL_FROM_DATABASE=FM100-M/3250 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1610* ++ ID_MODEL_FROM_DATABASE=FM100-M/3250 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1903* ++ ID_MODEL_FROM_DATABASE=EM1300 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1906* ++ ID_MODEL_FROM_DATABASE=EM1300 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1910* ++ ID_MODEL_FROM_DATABASE=EM1300 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1A03* ++ ID_MODEL_FROM_DATABASE=HR3290 corded/HR22 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1A06* ++ ID_MODEL_FROM_DATABASE=HR3290 corded/HR22 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1A10* ++ ID_MODEL_FROM_DATABASE=HR3290 corded/HR22 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1C03* ++ ID_MODEL_FROM_DATABASE=HR2150 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1C06* ++ ID_MODEL_FROM_DATABASE=HR2150 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1C10* ++ ID_MODEL_FROM_DATABASE=HR2150 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1D03* ++ ID_MODEL_FROM_DATABASE=FM430 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1D06* ++ ID_MODEL_FROM_DATABASE=FM430 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1D10* ++ ID_MODEL_FROM_DATABASE=FM430 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1E03* ++ ID_MODEL_FROM_DATABASE=HR42 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1E06* ++ ID_MODEL_FROM_DATABASE=HR42 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1E10* ++ ID_MODEL_FROM_DATABASE=HR42 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp1F03* ++ ID_MODEL_FROM_DATABASE=HR11+ Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp1F06* ++ ID_MODEL_FROM_DATABASE=HR11+ Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp1F10* ++ ID_MODEL_FROM_DATABASE=HR11+ Barcode scanner engine (HID Pos) ++ ++usb:v1EABp2003* ++ ID_MODEL_FROM_DATABASE=EM2037v2 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp2006* ++ ID_MODEL_FROM_DATABASE=EM2037v2 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp2010* ++ ID_MODEL_FROM_DATABASE=EM2037v2 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp8003* ++ ID_MODEL_FROM_DATABASE=EM13x5-LD/HR15-70/HR100-70/HR12/HR1150-70 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp8006* ++ ID_MODEL_FROM_DATABASE=EM13x5-LD/HR15-70/HR100-70/HR12/HR1150-70 Barcode scanner engine (USB Serial CDC) ++ ++usb:v1EABp8010* ++ ID_MODEL_FROM_DATABASE=EM13x5-LD/HR15-70/HR100-70/HR12/HR1150-70 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp8203* ++ ID_MODEL_FROM_DATABASE=EM3080-01/EM3095/FR20/FM30 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp8206* ++ ID_MODEL_FROM_DATABASE=EM3080-01/EM3095/FR20/FM30 Barcode scanner engine (USB Serial CDC) ++ ++usb:v1EABp8210* ++ ID_MODEL_FROM_DATABASE=EM3080-01/EM3095/FR20/FM30 Barcode scanner engine (HID Pos) ++ ++usb:v1EABp8303* ++ ID_MODEL_FROM_DATABASE=HR2160 Barcode scanner engine (HID keyboard) ++ ++usb:v1EABp8306* ++ ID_MODEL_FROM_DATABASE=HR2160 Barcode scanner engine (Serial CDC) ++ ++usb:v1EABp8310* ++ ID_MODEL_FROM_DATABASE=HR2160 Barcode scanner engine (HID Pos) ++ ++usb:v1EAF* ++ ID_VENDOR_FROM_DATABASE=Leaflabs ++ ++usb:v1EAFp0003* ++ ID_MODEL_FROM_DATABASE=Maple DFU interface ++ ++usb:v1EAFp0004* ++ ID_MODEL_FROM_DATABASE=Maple serial interface ++ ++usb:v1EB8* ++ ID_VENDOR_FROM_DATABASE=Modacom Co., Ltd. ++ ++usb:v1EB8p7F00* ++ ID_MODEL_FROM_DATABASE=MW-U3500 WiMAX adapter ++ + usb:v1EBB* + ID_VENDOR_FROM_DATABASE=NuCORE Technology, Inc. + ++usb:v1ECB* ++ ID_VENDOR_FROM_DATABASE=AMTelecom ++ ++usb:v1ECBp02E2* ++ ID_MODEL_FROM_DATABASE=JMR1140 [Jiofi] ++ ++usb:v1ED8* ++ ID_VENDOR_FROM_DATABASE=FENDER MUSICAL INSTRUMENTS CORPORATION ++ ++usb:v1ED8p0004* ++ ID_MODEL_FROM_DATABASE=Mustang I/II ++ ++usb:v1ED8p0005* ++ ID_MODEL_FROM_DATABASE=Mustang III/IV/V ++ ++usb:v1ED8p0006* ++ ID_MODEL_FROM_DATABASE=Mustang I/II [Firmware Update] ++ ++usb:v1ED8p0007* ++ ID_MODEL_FROM_DATABASE=Mustang III/IV/V [Firmware Update] ++ ++usb:v1ED8p0010* ++ ID_MODEL_FROM_DATABASE=Mustang Mini ++ ++usb:v1ED8p0011* ++ ID_MODEL_FROM_DATABASE=Mustang Mini [Firmware Update] ++ ++usb:v1ED8p0014* ++ ID_MODEL_FROM_DATABASE=Mustang I (V.2) ++ ++usb:v1ED8p0016* ++ ID_MODEL_FROM_DATABASE=Mustang IV v.2 ++ + usb:v1EDA* + ID_VENDOR_FROM_DATABASE=AirTies Wireless Networks + +@@ -54971,6 +61925,12 @@ usb:v1EDB* + usb:v1EDBpBD3B* + ID_MODEL_FROM_DATABASE=Intensity Shuttle + ++usb:v1EDBpBD46* ++ ID_MODEL_FROM_DATABASE=Mini Converter Analog to SDI ++ ++usb:v1EDBpBD75* ++ ID_MODEL_FROM_DATABASE=2.5K Cinema Camera (BMCC) ++ + usb:v1EE8* + ID_VENDOR_FROM_DATABASE=ONDA COMMUNICATION S.p.a. + +@@ -54998,6 +61958,12 @@ usb:v1EF6p5648* + usb:v1EF6p564A* + ID_MODEL_FROM_DATABASE=Cassidian RIU CSMU/BSD Simulator + ++usb:v1F0C* ++ ID_VENDOR_FROM_DATABASE=CMX Systems ++ ++usb:v1F0Cp2000* ++ ID_MODEL_FROM_DATABASE=HP StreamSmart 410 [NW278AA] ++ + usb:v1F28* + ID_VENDOR_FROM_DATABASE=Cal-Comp + +@@ -55008,10 +61974,19 @@ usb:v1F28p0021* + ID_MODEL_FROM_DATABASE=CD INSTALLER USB Device + + usb:v1F3A* +- ID_VENDOR_FROM_DATABASE=Onda (unverified) ++ ID_VENDOR_FROM_DATABASE=Allwinner Technology ++ ++usb:v1F3Ap1000* ++ ID_MODEL_FROM_DATABASE=Prestigio PER3464B ebook reader (Mass storage mode) ++ ++usb:v1F3Ap1002* ++ ID_MODEL_FROM_DATABASE=mediacom XPRO 415 ++ ++usb:v1F3Ap1010* ++ ID_MODEL_FROM_DATABASE=Android device in fastboot mode + + usb:v1F3ApEFE8* +- ID_MODEL_FROM_DATABASE=V972 tablet in flashing mode ++ ID_MODEL_FROM_DATABASE=sunxi SoC OTG connector in FEL/flashing mode + + usb:v1F44* + ID_VENDOR_FROM_DATABASE=The Neat Company +@@ -55031,12 +62006,33 @@ usb:v1F48p0628* + usb:v1F4D* + ID_VENDOR_FROM_DATABASE=G-Tek Electronics Group + ++usb:v1F4DpA115* ++ ID_MODEL_FROM_DATABASE=EVOLVEO XtraTV stick [DVB-T] ++ + usb:v1F4DpB803* + ID_MODEL_FROM_DATABASE=Lifeview LV5TDLX DVB-T [RTL2832U] + ++usb:v1F4DpC803* ++ ID_MODEL_FROM_DATABASE=NotOnlyTV (Lifeview) LV5TDLX DVB-T [RTL2832U] ++ + usb:v1F4DpD220* + ID_MODEL_FROM_DATABASE=Geniatech T220 DVB-T2 TV Stick + ++usb:v1F52* ++ ID_VENDOR_FROM_DATABASE=Systems & Electronic Development FZCO (SEDCO) ++ ++usb:v1F52p0001* ++ ID_MODEL_FROM_DATABASE=Ultima 49 Printer ++ ++usb:v1F52p0002* ++ ID_MODEL_FROM_DATABASE=Ultima 90 Printer ++ ++usb:v1F52p0003* ++ ID_MODEL_FROM_DATABASE=FormsPro 50 Printer ++ ++usb:v1F52p0004* ++ ID_MODEL_FROM_DATABASE=Ultima 90+ Printer ++ + usb:v1F6F* + ID_VENDOR_FROM_DATABASE=Aliph + +@@ -55049,12 +62045,27 @@ usb:v1F6Fp8000* + usb:v1F75* + ID_VENDOR_FROM_DATABASE=Innostor Technology Corporation + ++usb:v1F75p0611* ++ ID_MODEL_FROM_DATABASE=IS611 SATA/PATA Bridge Controller ++ ++usb:v1F75p0621* ++ ID_MODEL_FROM_DATABASE=IS621 SATA Storage Controller ++ + usb:v1F75p0888* + ID_MODEL_FROM_DATABASE=IS888 SATA Storage Controller + + usb:v1F75p0902* + ID_MODEL_FROM_DATABASE=IS902 UFD controller + ++usb:v1F75p0916* ++ ID_MODEL_FROM_DATABASE=IS916 Flash Drive ++ ++usb:v1F75p0917* ++ ID_MODEL_FROM_DATABASE=IS917 Mass storage ++ ++usb:v1F75p0918* ++ ID_MODEL_FROM_DATABASE=IS918 Flash Drive ++ + usb:v1F82* + ID_VENDOR_FROM_DATABASE=TANDBERG + +@@ -55064,6 +62075,9 @@ usb:v1F82p0001* + usb:v1F84* + ID_VENDOR_FROM_DATABASE=Alere, Inc. + ++usb:v1F84p1F7E* ++ ID_MODEL_FROM_DATABASE=Lateral Flow Engine ++ + usb:v1F87* + ID_VENDOR_FROM_DATABASE=Stantum + +@@ -55076,12 +62090,39 @@ usb:v1F9B* + usb:v1F9Bp0241* + ID_MODEL_FROM_DATABASE=AirView2-EXT + ++usb:v1F9BpB0B1* ++ ID_MODEL_FROM_DATABASE=UniFi VoIP Phone ++ + usb:v1FAB* + ID_VENDOR_FROM_DATABASE=Samsung Opto-Electroncs Co., Ltd. + + usb:v1FABp104D* + ID_MODEL_FROM_DATABASE=ES65 + ++usb:v1FAC* ++ ID_VENDOR_FROM_DATABASE=Franklin Wireless ++ ++usb:v1FACp0232* ++ ID_MODEL_FROM_DATABASE=U770 3G/4G Wimax/4G LTE Modem ++ ++usb:v1FAE* ++ ID_VENDOR_FROM_DATABASE=Lumidigm ++ ++usb:v1FAEp0040* ++ ID_MODEL_FROM_DATABASE=M311 Fingerprint Scanner ++ ++usb:v1FAEp212C* ++ ID_MODEL_FROM_DATABASE=M30x (Mercury) fingerprint sensor ++ ++usb:v1FB2* ++ ID_VENDOR_FROM_DATABASE=Withings ++ ++usb:v1FB2p0001* ++ ID_MODEL_FROM_DATABASE=Wi-Fi Body Scale (WBS01) ++ ++usb:v1FBA* ++ ID_VENDOR_FROM_DATABASE=DERMALOG Identification Systems GmbH ++ + usb:v1FBD* + ID_VENDOR_FROM_DATABASE=Delphin Technology AG + +@@ -55094,9 +62135,30 @@ usb:v1FC9* + usb:v1FC9p0003* + ID_MODEL_FROM_DATABASE=LPC1343 + ++usb:v1FC9p000C* ++ ID_MODEL_FROM_DATABASE=LPC4330FET180 [ARM Cortex M4 + M0] (device firmware upgrade mode) ++ ++usb:v1FC9p0082* ++ ID_MODEL_FROM_DATABASE=LPC4330FET180 [ARM Cortex M4 + M0] (mass storage controller mode) ++ + usb:v1FC9p010B* + ID_MODEL_FROM_DATABASE=PR533 + ++usb:v1FC9p0126* ++ ID_MODEL_FROM_DATABASE=i.MX 7ULP SystemOnChip in RecoveryMode ++ ++usb:v1FC9p012B* ++ ID_MODEL_FROM_DATABASE=i.MX 8M Dual/8M QuadLite/8M Quad Serial Downloader ++ ++usb:v1FC9p5002* ++ ID_MODEL_FROM_DATABASE=PTN5002 [Startech VGA/DVI-D adapter] ++ ++usb:v1FC9p8124* ++ ID_MODEL_FROM_DATABASE=SharkRF Bootloader ++ ++usb:v1FC9p824C* ++ ID_MODEL_FROM_DATABASE=LumiNode1 ++ + usb:v1FDE* + ID_VENDOR_FROM_DATABASE=ILX Lightwave Corporation + +@@ -55118,9 +62180,39 @@ usb:v1FF7p0013* + usb:v1FF7p001A* + ID_MODEL_FROM_DATABASE=Human Interface Device + ++usb:v1FFB* ++ ID_VENDOR_FROM_DATABASE=Pololu Corporation ++ ++usb:v1FFBp0081* ++ ID_MODEL_FROM_DATABASE=AVR Programmer ++ ++usb:v1FFBp0083* ++ ID_MODEL_FROM_DATABASE=Jrk 21v3 Motor Controller ++ ++usb:v1FFBp0089* ++ ID_MODEL_FROM_DATABASE=Micro Maestro 6-Servo Controller ++ ++usb:v1FFBp008A* ++ ID_MODEL_FROM_DATABASE=Mini Maestro 12-Channel Servo Controller ++ ++usb:v1FFBp008B* ++ ID_MODEL_FROM_DATABASE=Mini Maestro 18-Channel Servo Controller ++ ++usb:v1FFBp008C* ++ ID_MODEL_FROM_DATABASE=Mini Maestro 24-Channel Servo Controller ++ ++usb:v1FFBp00B0* ++ ID_MODEL_FROM_DATABASE=AVR Programmer v2 ++ + usb:v1FFF* + ID_VENDOR_FROM_DATABASE=Ideofy Inc. + ++usb:v2000* ++ ID_VENDOR_FROM_DATABASE=CMX Systems ++ ++usb:v2000p1F0C* ++ ID_MODEL_FROM_DATABASE=HP StreamSmart 410 [NW278AA] ++ + usb:v2001* + ID_VENDOR_FROM_DATABASE=D-Link Corp. + +@@ -55139,6 +62231,9 @@ usb:v2001p1A02* + usb:v2001p200C* + ID_MODEL_FROM_DATABASE=10/100 Ethernet + ++usb:v2001p3101* ++ ID_MODEL_FROM_DATABASE=DWA-182 AC1200 DB Wireless Adapter(rev.A1) [Broadcom BCM43526] ++ + usb:v2001p3200* + ID_MODEL_FROM_DATABASE=DWL-120 802.11b Wireless Adapter(rev.E1) [Atmel at76c503a] + +@@ -55157,6 +62252,27 @@ usb:v2001p3309* + usb:v2001p330A* + ID_MODEL_FROM_DATABASE=DWA-133 802.11n Wireless N Adapter [Realtek RTL8192CU] + ++usb:v2001p330D* ++ ID_MODEL_FROM_DATABASE=DWA-131 802.11n Wireless N Nano Adapter (rev.B1) [Realtek RTL8192CU] ++ ++usb:v2001p330F* ++ ID_MODEL_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.D1) [Realtek RTL8188ETV] ++ ++usb:v2001p3310* ++ ID_MODEL_FROM_DATABASE=DWA-123 Wireless N 150 Adapter (rev.D1) ++ ++usb:v2001p3314* ++ ID_MODEL_FROM_DATABASE=DWA-171 AC600 DB Wireless Adapter(rev.A1) [Realtek RTL8811AU] ++ ++usb:v2001p3315* ++ ID_MODEL_FROM_DATABASE=DWA-182 Wireless AC Dualband Adapter(rev.C) [Realtek RTL8812AU] ++ ++usb:v2001p3317* ++ ID_MODEL_FROM_DATABASE=DWA-137 Wireless N High-Gain Adapter [Ralink RT5372] ++ ++usb:v2001p3319* ++ ID_MODEL_FROM_DATABASE=DWA-131 Wireless N Nano Adapter (Rev. E1) [Realtek RTL8192EU] ++ + usb:v2001p3500* + ID_MODEL_FROM_DATABASE=Elitegroup Computer Systems WLAN card WL-162 + +@@ -55244,6 +62360,9 @@ usb:v2001p3C1A* + usb:v2001p3C1B* + ID_MODEL_FROM_DATABASE=DWA-127 Wireless N 150 High-Gain Adapter(rev.A1) [Ralink RT3070] + ++usb:v2001p3C1E* ++ ID_MODEL_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.B1) [Ralink RT5370] ++ + usb:v2001p4000* + ID_MODEL_FROM_DATABASE=DSB-650C Ethernet [klsi] + +@@ -55262,6 +62381,9 @@ usb:v2001p400B* + usb:v2001p4102* + ID_MODEL_FROM_DATABASE=10/100 Ethernet + ++usb:v2001p4A00* ++ ID_MODEL_FROM_DATABASE=DUB-1312 Gigabit Ethernet Adapter ++ + usb:v2001p5100* + ID_MODEL_FROM_DATABASE=DSL-200 ADSL ATM Modem + +@@ -55316,6 +62438,21 @@ usb:v2003* + usb:v2003pEA61* + ID_MODEL_FROM_DATABASE=dc3500 + ++usb:v2006* ++ ID_VENDOR_FROM_DATABASE=LenovoMobile ++ ++usb:v2009* ++ ID_VENDOR_FROM_DATABASE=iStorage ++ ++usb:v2009p5004* ++ ID_MODEL_FROM_DATABASE=datAshur 4GB ++ ++usb:v2009p5016* ++ ID_MODEL_FROM_DATABASE=datAshur 16GB ++ ++usb:v2009p5032* ++ ID_MODEL_FROM_DATABASE=datAshur 32GB ++ + usb:v200C* + ID_VENDOR_FROM_DATABASE=Reloop + +@@ -55325,6 +62462,9 @@ usb:v200Cp100B* + usb:v2013* + ID_VENDOR_FROM_DATABASE=PCTV Systems + ++usb:v2013p0242* ++ ID_MODEL_FROM_DATABASE=QuatroStick 510e ++ + usb:v2013p0245* + ID_MODEL_FROM_DATABASE=PCTV 73ESE + +@@ -55334,9 +62474,36 @@ usb:v2013p0246* + usb:v2013p0248* + ID_MODEL_FROM_DATABASE=PCTV 282E + ++usb:v2013p024C* ++ ID_MODEL_FROM_DATABASE=DVB-S2 Stick 460e ++ + usb:v2013p024F* + ID_MODEL_FROM_DATABASE=nanoStick T2 290e + ++usb:v2013p0251* ++ ID_MODEL_FROM_DATABASE=QuatroStick nano 520e ++ ++usb:v2013p0258* ++ ID_MODEL_FROM_DATABASE=DVB-S2 Stick 461e ++ ++usb:v2013p025A* ++ ID_MODEL_FROM_DATABASE=AndroiDTV 78e ++ ++usb:v2013p025F* ++ ID_MODEL_FROM_DATABASE=tripleStick 292e ++ ++usb:v2013p0262* ++ ID_MODEL_FROM_DATABASE=microStick 79e ++ ++usb:v2018* ++ ID_VENDOR_FROM_DATABASE=Deutsche Telekom AG ++ ++usb:v2018p0406* ++ ID_MODEL_FROM_DATABASE=Eumex 800 ++ ++usb:v2018p0408* ++ ID_MODEL_FROM_DATABASE=Eumex 800 ++ + usb:v2019* + ID_VENDOR_FROM_DATABASE=PLANEX + +@@ -55412,6 +62579,15 @@ usb:v2019pED17* + usb:v2019pED18* + ID_MODEL_FROM_DATABASE=GW-USHyper300 / GW-USH300N 802.11bgn Wireless Adapter [Realtek RTL8191SU] + ++usb:v201E* ++ ID_VENDOR_FROM_DATABASE=Haier ++ ++usb:v201Ep2009* ++ ID_MODEL_FROM_DATABASE=CE100 CDMA EVDO ++ ++usb:v203A* ++ ID_VENDOR_FROM_DATABASE=PARALLELS ++ + usb:v203D* + ID_VENDOR_FROM_DATABASE=Encore Electronics Inc. + +@@ -55421,12 +62597,21 @@ usb:v203Dp1480* + usb:v2040* + ID_VENDOR_FROM_DATABASE=Hauppauge + ++usb:v2040p0265* ++ ID_MODEL_FROM_DATABASE=WinTV-dualHD DVB ++ ++usb:v2040p026D* ++ ID_MODEL_FROM_DATABASE=WinTV-dualHD ATSC ++ + usb:v2040p0C80* + ID_MODEL_FROM_DATABASE=Windham + + usb:v2040p0C90* + ID_MODEL_FROM_DATABASE=Windham + ++usb:v2040p1605* ++ ID_MODEL_FROM_DATABASE=WinTV-HVR 930C HD ++ + usb:v2040p1700* + ID_MODEL_FROM_DATABASE=CataMount + +@@ -55457,6 +62642,9 @@ usb:v2040p2019* + usb:v2040p2400* + ID_MODEL_FROM_DATABASE=WinTV PVR USB2 (Model 24019) + ++usb:v2040p4200* ++ ID_MODEL_FROM_DATABASE=WinTV ++ + usb:v2040p4700* + ID_MODEL_FROM_DATABASE=WinTV Nova-S-USB2 + +@@ -55497,7 +62685,10 @@ usb:v2040p6503* + ID_MODEL_FROM_DATABASE=WinTV HVR-930 + + usb:v2040p6513* +- ID_MODEL_FROM_DATABASE=WinTV HVR-980 ++ ID_MODEL_FROM_DATABASE=WinTV HVR-950/HVR-980 ++ ++usb:v2040p6600* ++ ID_MODEL_FROM_DATABASE=WinTV HVR-900H (Model 660xx) + + usb:v2040p7050* + ID_MODEL_FROM_DATABASE=Nova-T Stick +@@ -55526,6 +62717,12 @@ usb:v2040p9941* + usb:v2040p9950* + ID_MODEL_FROM_DATABASE=WinTV Nova-T-500 + ++usb:v2040pB123* ++ ID_MODEL_FROM_DATABASE=WinTV-HVR-955Q ++ ++usb:v2040pB138* ++ ID_MODEL_FROM_DATABASE=WinTV-HVR-900 model 00246 [WinTV-T Video] ++ + usb:v2040pB910* + ID_MODEL_FROM_DATABASE=Windham + +@@ -55544,15 +62741,177 @@ usb:v2040pC010* + usb:v2047* + ID_VENDOR_FROM_DATABASE=Texas Instruments + ++usb:v2047p0013* ++ ID_MODEL_FROM_DATABASE=MSP eZ-FET lite ++ ++usb:v2047p0014* ++ ID_MODEL_FROM_DATABASE=MSP-FET ++ + usb:v2047p0200* +- ID_MODEL_FROM_DATABASE=MSP430 USB HID Bootstrap Loader ++ ID_MODEL_FROM_DATABASE=MSP430 Bootloader ++ ++usb:v2047p0203* ++ ID_MODEL_FROM_DATABASE=eZ-FET Bootloader ++ ++usb:v2047p0204* ++ ID_MODEL_FROM_DATABASE=MSP-FET Bootloader ++ ++usb:v2047p0300* ++ ID_MODEL_FROM_DATABASE=MSP430 CDC Example ++ ++usb:v2047p0301* ++ ID_MODEL_FROM_DATABASE=MSP430 HID Datapipe Example ++ ++usb:v2047p0302* ++ ID_MODEL_FROM_DATABASE=MSP430 CDC+HID Example ++ ++usb:v2047p0309* ++ ID_MODEL_FROM_DATABASE=MSP430 HID Mouse Example ++ ++usb:v2047p0313* ++ ID_MODEL_FROM_DATABASE=MSP430 CDC+CDC Example ++ ++usb:v2047p0314* ++ ID_MODEL_FROM_DATABASE=MSP430 HID+HID Example ++ ++usb:v2047p0315* ++ ID_MODEL_FROM_DATABASE=MSP430 HID Keyboard Example ++ ++usb:v2047p0316* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC File System Emulation Example ++ ++usb:v2047p0317* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC SD Card Example ++ ++usb:v2047p0318* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC Multiple LUNs Example ++ ++usb:v2047p0319* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC+CDC+HID Example ++ ++usb:v2047p0320* ++ ID_MODEL_FROM_DATABASE=MSP430 SYSBIOS Tasks MSC+CDC+HID Example ++ ++usb:v2047p0321* ++ ID_MODEL_FROM_DATABASE=MSP430 SYSBIOS SWIs MSC+CDC+HID Example ++ ++usb:v2047p0322* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC Double-Buffering Example ++ ++usb:v2047p0323* ++ ID_MODEL_FROM_DATABASE=MSP430 MSC CD-ROM Example ++ ++usb:v2047p03DF* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E0* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E1* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E2* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E3* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E4* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E5* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E6* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E7* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E8* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03E9* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03EA* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03EB* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03EC* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03ED* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03EE* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03EF* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F0* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F1* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F2* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F3* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F4* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F5* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F6* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F7* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F8* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03F9* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03FA* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03FB* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03FC* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p03FD* ++ ID_MODEL_FROM_DATABASE=MSP430 User Experiment ++ ++usb:v2047p0401* ++ ID_MODEL_FROM_DATABASE=MSP430 Keyboard Example + + usb:v2047p0855* + ID_MODEL_FROM_DATABASE=Invensense Embedded MotionApp HID Sensor + ++usb:v2047p08F8* ++ ID_MODEL_FROM_DATABASE=FDC2x14/LDC13xx/LDC16xx EVM ++ + usb:v2047p0964* + ID_MODEL_FROM_DATABASE=Inventio Software MSP430 + ++usb:v2047p0A76* ++ ID_MODEL_FROM_DATABASE=GEOKON S-3810A-5 USB-RS485 CONVERTER ++ ++usb:v2047pFFE7* ++ ID_MODEL_FROM_DATABASE=HID v1.00 Device [Improv Device] ++ + usb:v2058* + ID_VENDOR_FROM_DATABASE=Nano River Technology + +@@ -55580,6 +62939,24 @@ usb:v2080p0003* + usb:v2080p0004* + ID_MODEL_FROM_DATABASE=NOOK Tablet + ++usb:v2080p0005* ++ ID_MODEL_FROM_DATABASE=BNTV600 [Nook HD+] ++ ++usb:v2080p0006* ++ ID_MODEL_FROM_DATABASE=BNTV400 [Nook HD] ++ ++usb:v2080p0007* ++ ID_MODEL_FROM_DATABASE=BNRV500 [Nook Glowlight] ++ ++usb:v2080p000A* ++ ID_MODEL_FROM_DATABASE=BNRV510 [Nook Glowlight Plus] ++ ++usb:v2080p000B* ++ ID_MODEL_FROM_DATABASE=BNRV520 [Nook Glowlight 3] ++ ++usb:v2080p000C* ++ ID_MODEL_FROM_DATABASE=BNRV700 [Nook Glowlight Plus] ++ + usb:v2086* + ID_VENDOR_FROM_DATABASE=SIMPASS + +@@ -55598,6 +62975,12 @@ usb:v2087p0B03* + usb:v20A0* + ID_VENDOR_FROM_DATABASE=Clay Logic + ++usb:v20A0p0006* ++ ID_MODEL_FROM_DATABASE=flirc ++ ++usb:v20A0p4107* ++ ID_MODEL_FROM_DATABASE=GPF Crypto Stick V1.2 ++ + usb:v20A0p4123* + ID_MODEL_FROM_DATABASE=IKALOGIC SCANALOGIC 2 + +@@ -55613,6 +62996,18 @@ usb:v20A0p415B* + usb:v20A0p415C* + ID_MODEL_FROM_DATABASE=PipXtreme + ++usb:v20A0p41E5* ++ ID_MODEL_FROM_DATABASE=BlinkStick ++ ++usb:v20A0p4211* ++ ID_MODEL_FROM_DATABASE=Nitrokey Start ++ ++usb:v20A0p4223* ++ ID_MODEL_FROM_DATABASE=ATSAMD21 [castAR] ++ ++usb:v20A0p428D* ++ ID_MODEL_FROM_DATABASE=Electrosense wideband converter ++ + usb:v20B1* + ID_VENDOR_FROM_DATABASE=XMOS Ltd + +@@ -55643,12 +63038,21 @@ usb:v20B7p1DB5* + usb:v20B7p1DB6* + ID_MODEL_FROM_DATABASE=IDBG in normal mode + ++usb:v20B7p9DB1* ++ ID_MODEL_FROM_DATABASE=Glasgow Debug Tool ++ + usb:v20B7pC25B* + ID_MODEL_FROM_DATABASE=C2 Dongle + + usb:v20B7pCB72* + ID_MODEL_FROM_DATABASE=ben-wpan, cntr + ++usb:v20BC* ++ ID_VENDOR_FROM_DATABASE=ShenZhen ShanWan Technology Co., Ltd. ++ ++usb:v20BCp5500* ++ ID_MODEL_FROM_DATABASE=Frostbite controller ++ + usb:v20CE* + ID_VENDOR_FROM_DATABASE=Minicircuits + +@@ -55667,6 +63071,12 @@ usb:v20DF* + usb:v20DFp0001* + ID_MODEL_FROM_DATABASE=Entropy Key [UDEKEY01] + ++usb:v20F0* ++ ID_VENDOR_FROM_DATABASE=L3Harris Technologies ++ ++usb:v20F0p2102* ++ ID_MODEL_FROM_DATABASE=EWLA V2 Module ++ + usb:v20F1* + ID_VENDOR_FROM_DATABASE=NET New Electronic Technology GmbH + +@@ -55676,9 +63086,24 @@ usb:v20F1p0101* + usb:v20F4* + ID_VENDOR_FROM_DATABASE=TRENDnet + ++usb:v20F4p646B* ++ ID_MODEL_FROM_DATABASE=TEW-646UBH High Power 150Mbps Wireless N Adapter [Realtek RTL8188SU] ++ + usb:v20F4p648B* + ID_MODEL_FROM_DATABASE=TEW-648UBM 802.11n 150Mbps Micro Wireless N Adapter [Realtek RTL8188CUS] + ++usb:v20F4p664B* ++ ID_MODEL_FROM_DATABASE=TEW-664UB H/W:V2.0R ++ ++usb:v20F4p804B* ++ ID_MODEL_FROM_DATABASE=TEW-804UB 802.11a/b/g/n/ac (1x1) Wireless Adapter [Realtek RTL8811AU] ++ ++usb:v20F4p805B* ++ ID_MODEL_FROM_DATABASE=TEW-805UB 300Mbps+867Mbps Wireless AC Adapter [Realtek RTL8812AU] ++ ++usb:v20F4p806B* ++ ID_MODEL_FROM_DATABASE=TEW-806UBH 802.11a/b/g/n/ac (1x1) Wireless Adapter [MediaTek MT7610U] ++ + usb:v20F7* + ID_VENDOR_FROM_DATABASE=XIMEA + +@@ -55700,6 +63125,12 @@ usb:v20F7pA003* + usb:v2100* + ID_VENDOR_FROM_DATABASE=RT Systems + ++usb:v2100p0E56* ++ ID_MODEL_FROM_DATABASE=USB62C Radio Cable [Yaesu 857/D - 897/D] ++ ++usb:v2100p9E50* ++ ID_MODEL_FROM_DATABASE=USB-59 Radio Cable [Yaesu VX-8/D/DR] ++ + usb:v2100p9E52* + ID_MODEL_FROM_DATABASE=Yaesu VX-7 + +@@ -55709,6 +63140,9 @@ usb:v2100p9E54* + usb:v2100p9E57* + ID_MODEL_FROM_DATABASE=RTS01 Radio Cable + ++usb:v2100p9E58* ++ ID_MODEL_FROM_DATABASE=USB63C Radio Cable [Yaesu FTDX-1200] ++ + usb:v2100p9E5D* + ID_MODEL_FROM_DATABASE=K4Y Radio Cable + +@@ -55721,15 +63155,39 @@ usb:v2101* + usb:v2101p0201* + ID_MODEL_FROM_DATABASE=SIIG 4-to-2 Printer Switch + ++usb:v2101p1402* ++ ID_MODEL_FROM_DATABASE=Keyboard/Mouse Switch ++ ++usb:v2104* ++ ID_VENDOR_FROM_DATABASE=Tobii Technology AB ++ ++usb:v2104p0050* ++ ID_MODEL_FROM_DATABASE=Eye tracker [EYEX2] ++ ++usb:v2104p0124* ++ ID_MODEL_FROM_DATABASE=Eyechip ++ ++usb:v2107* ++ ID_VENDOR_FROM_DATABASE=RDING TECH CO.,LTD ++ + usb:v2109* + ID_VENDOR_FROM_DATABASE=VIA Labs, Inc. + ++usb:v2109p0210* ++ ID_MODEL_FROM_DATABASE=Hub ++ + usb:v2109p0700* + ID_MODEL_FROM_DATABASE=VL700 SATA 3Gb/s bridge + + usb:v2109p0701* + ID_MODEL_FROM_DATABASE=VL701 SATA 3Gb/s bridge + ++usb:v2109p0711* ++ ID_MODEL_FROM_DATABASE=VL711 SATA 6Gb/s bridge ++ ++usb:v2109p0715* ++ ID_MODEL_FROM_DATABASE=VL817 SATA Adaptor ++ + usb:v2109p0810* + ID_MODEL_FROM_DATABASE=VL81x Hub + +@@ -55739,15 +63197,33 @@ usb:v2109p0811* + usb:v2109p0812* + ID_MODEL_FROM_DATABASE=VL812 Hub + ++usb:v2109p0813* ++ ID_MODEL_FROM_DATABASE=VL813 Hub ++ ++usb:v2109p0820* ++ ID_MODEL_FROM_DATABASE=VL820 Hub ++ ++usb:v2109p2210* ++ ID_MODEL_FROM_DATABASE=Hub ++ + usb:v2109p2811* + ID_MODEL_FROM_DATABASE=Hub + + usb:v2109p2812* + ID_MODEL_FROM_DATABASE=VL812 Hub + ++usb:v2109p2813* ++ ID_MODEL_FROM_DATABASE=VL813 Hub ++ ++usb:v2109p2820* ++ ID_MODEL_FROM_DATABASE=VL820 Hub ++ + usb:v2109p3431* + ID_MODEL_FROM_DATABASE=Hub + ++usb:v2109p711F* ++ ID_MODEL_FROM_DATABASE=External ++ + usb:v2109p8110* + ID_MODEL_FROM_DATABASE=Hub + +@@ -55763,17 +63239,77 @@ usb:v2113p0145* + usb:v2113p8000* + ID_MODEL_FROM_DATABASE=DepthSense 311 (Color) + ++usb:v2116* ++ ID_VENDOR_FROM_DATABASE=KT Tech ++ ++usb:v2116p000A* ++ ID_MODEL_FROM_DATABASE=IDE Hard Drive Enclosure ++ ++usb:v211F* ++ ID_VENDOR_FROM_DATABASE=CELOT Corporation ++ ++usb:v211Fp6801* ++ ID_MODEL_FROM_DATABASE=CDMA Products ++ ++usb:v2123* ++ ID_VENDOR_FROM_DATABASE=Cheeky Dream ++ ++usb:v2123p1010* ++ ID_MODEL_FROM_DATABASE=Rocket Launcher ++ ++usb:v2125* ++ ID_VENDOR_FROM_DATABASE=Fiberpro Inc. ++ ++usb:v2125p0000* ++ ID_MODEL_FROM_DATABASE=Bootloader ++ ++usb:v2125p0010* ++ ID_MODEL_FROM_DATABASE=MCB-100 Series ++ ++usb:v2133* ++ ID_VENDOR_FROM_DATABASE=signotec GmbH ++ ++usb:v2133p0001* ++ ID_MODEL_FROM_DATABASE=LCD Signature Pad Sigma ++ ++usb:v2133p0018* ++ ID_MODEL_FROM_DATABASE=Delta Pen ++ ++usb:v2133p0019* ++ ID_MODEL_FROM_DATABASE=Delta Touch ++ ++usb:v2133p001C* ++ ID_MODEL_FROM_DATABASE=Kronos Pen ++ ++usb:v2133p0022* ++ ID_MODEL_FROM_DATABASE=Epsilon Pen ++ + usb:v2149* + ID_VENDOR_FROM_DATABASE=Advanced Silicon S.A. + + usb:v2149p211B* + ID_MODEL_FROM_DATABASE=Touchscreen Controller + ++usb:v2149p2306* ++ ID_MODEL_FROM_DATABASE=TS58xxA/TC56xxA [CoolTouch] ++ + usb:v2149p2703* + ID_MODEL_FROM_DATABASE=TS58xxA/TC56xxA [CoolTouch] + ++usb:v214B* ++ ID_VENDOR_FROM_DATABASE=Huasheng Electronics ++ ++usb:v214Bp7000* ++ ID_MODEL_FROM_DATABASE=4-port hub [Maxxter ACT-HUB2-4P, HS8836, iSoul ultra-slim] ++ ++usb:v214E* ++ ID_VENDOR_FROM_DATABASE=Swiftpoint ++ ++usb:v214Ep0005* ++ ID_MODEL_FROM_DATABASE=Z - Gaming mouse [SM700] ++ + usb:v2162* +- ID_VENDOR_FROM_DATABASE=Creative (?) ++ ID_VENDOR_FROM_DATABASE=Broadxent (Creative Labs) + + usb:v2162p2031* + ID_MODEL_FROM_DATABASE=Network Blaster Wireless Adapter +@@ -55784,6 +63320,12 @@ usb:v2162p500C* + usb:v2162p8001* + ID_MODEL_FROM_DATABASE=Broadxent BritePort DSL Bridge 8010U + ++usb:v2166* ++ ID_VENDOR_FROM_DATABASE=JVC Kenwood ++ ++usb:v2166p600B* ++ ID_MODEL_FROM_DATABASE=TH-D74 ++ + usb:v2184* + ID_VENDOR_FROM_DATABASE=GW Instek + +@@ -55796,42 +63338,216 @@ usb:v2184p0006* + usb:v2184p0011* + ID_MODEL_FROM_DATABASE=AFG Function Generator (CDC) + ++usb:v2184p0017* ++ ID_MODEL_FROM_DATABASE=DSO ++ ++usb:v2184p0018* ++ ID_MODEL_FROM_DATABASE=DSO ++ ++usb:v2184p0036* ++ ID_MODEL_FROM_DATABASE=AFG-125 Function Generator (CDC) ++ ++usb:v2188* ++ ID_VENDOR_FROM_DATABASE=No brand ++ ++usb:v2188p0610* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v2188p0611* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v2188p0620* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v2188p0625* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v2188p0754* ++ ID_MODEL_FROM_DATABASE=Card Reader ++ ++usb:v2188p4042* ++ ID_MODEL_FROM_DATABASE=CalDigit Pro Audio ++ ++usb:v219C* ++ ID_VENDOR_FROM_DATABASE=Seal One AG ++ ++usb:v219Cp0010* ++ ID_MODEL_FROM_DATABASE=USB 2200 K Secure Sign Token ++ + usb:v21A1* + ID_VENDOR_FROM_DATABASE=Emotiv Systems Pty. Ltd. + + usb:v21A1p0001* + ID_MODEL_FROM_DATABASE=EPOC Consumer Headset Wireless Dongle + ++usb:v21A4* ++ ID_VENDOR_FROM_DATABASE=Electronic Arts Inc. ++ ++usb:v21A4pAC27* ++ ID_MODEL_FROM_DATABASE=SPORTS Active 2 Wireless Controller for PS3 ++ ++usb:v21A4pAC40* ++ ID_MODEL_FROM_DATABASE=SPORTS Active 2 Wireless Controller for Wii ++ ++usb:v21A9* ++ ID_VENDOR_FROM_DATABASE=Saleae, Inc. ++ ++usb:v21A9p1001* ++ ID_MODEL_FROM_DATABASE=16-channel Logic Analyzer [Logic16] ++ ++usb:v21A9p1003* ++ ID_MODEL_FROM_DATABASE=Logic 4 ++ ++usb:v21A9p1004* ++ ID_MODEL_FROM_DATABASE=Logic8 ++ ++usb:v21A9p1005* ++ ID_MODEL_FROM_DATABASE=Logic Pro 8 ++ ++usb:v21A9p1006* ++ ID_MODEL_FROM_DATABASE=Logic Pro 16 ++ ++usb:v21AB* ++ ID_VENDOR_FROM_DATABASE=Planeta Informatica ++ ++usb:v21ABp0010* ++ ID_MODEL_FROM_DATABASE=RC700 NFC SmartCard Reader ++ ++usb:v21ABp0011* ++ ID_MODEL_FROM_DATABASE=DSR700 SmartCard Reader ++ ++usb:v21B4* ++ ID_VENDOR_FROM_DATABASE=AudioQuest ++ ++usb:v21B4p0081* ++ ID_MODEL_FROM_DATABASE=DragonFly ++ ++usb:v21B4p0082* ++ ID_MODEL_FROM_DATABASE=DragonFly Red ++ + usb:v21D6* + ID_VENDOR_FROM_DATABASE=Agecodagis SARL + + usb:v21D6p0002* + ID_MODEL_FROM_DATABASE=Seismic recorder [Tellus] + ++usb:v2207* ++ ID_VENDOR_FROM_DATABASE=Fuzhou Rockchip Electronics Company ++ ++usb:v2207p0010* ++ ID_MODEL_FROM_DATABASE=GoClever Tab R83 ++ ++usb:v2207p0011* ++ ID_MODEL_FROM_DATABASE=SmartTab ++ ++usb:v2207p281A* ++ ID_MODEL_FROM_DATABASE=RK2818 in Mask ROM mode ++ ++usb:v2207p290A* ++ ID_MODEL_FROM_DATABASE=RK2918 in Mask ROM mode ++ ++usb:v2207p292A* ++ ID_MODEL_FROM_DATABASE=RK2928 in Mask ROM mode ++ ++usb:v2207p292C* ++ ID_MODEL_FROM_DATABASE=RK3026 in Mask ROM mode ++ ++usb:v2207p300A* ++ ID_MODEL_FROM_DATABASE=RK3066 in Mask ROM mode ++ ++usb:v2207p300B* ++ ID_MODEL_FROM_DATABASE=RK3168 in Mask ROM mode ++ ++usb:v2207p301A* ++ ID_MODEL_FROM_DATABASE=RK3036 in Mask ROM mode ++ ++usb:v2207p310A* ++ ID_MODEL_FROM_DATABASE=RK3066B in Mask ROM mode ++ ++usb:v2207p310B* ++ ID_MODEL_FROM_DATABASE=RK3188 in Mask ROM mode ++ ++usb:v2207p310C* ++ ID_MODEL_FROM_DATABASE=RK3126/RK3128 in Mask ROM mode ++ ++usb:v2207p310D* ++ ID_MODEL_FROM_DATABASE=RK3126 in Mask ROM mode ++ ++usb:v2207p320A* ++ ID_MODEL_FROM_DATABASE=RK3288 in Mask ROM mode ++ ++usb:v2207p320B* ++ ID_MODEL_FROM_DATABASE=RK3228/RK3229 in Mask ROM mode ++ ++usb:v2207p320C* ++ ID_MODEL_FROM_DATABASE=RK3328 in Mask ROM mode ++ ++usb:v2207p330A* ++ ID_MODEL_FROM_DATABASE=RK3368 in Mask ROM mode ++ ++usb:v2207p330C* ++ ID_MODEL_FROM_DATABASE=RK3399 in Mask ROM mode ++ ++usb:v221A* ++ ID_VENDOR_FROM_DATABASE=ZTEX GmbH ++ ++usb:v221Ap0100* ++ ID_MODEL_FROM_DATABASE=FPGA Boards ++ + usb:v2222* + ID_VENDOR_FROM_DATABASE=MacAlly + + usb:v2222p0004* + ID_MODEL_FROM_DATABASE=iWebKey Keyboard + ++usb:v2222p0005* ++ ID_MODEL_FROM_DATABASE=ICEKey Keyboard ++ ++usb:v2222p1001* ++ ID_MODEL_FROM_DATABASE=Generic Hub ++ + usb:v2222p2520* + ID_MODEL_FROM_DATABASE=Mini Tablet + + usb:v2222p4050* + ID_MODEL_FROM_DATABASE=AirStick joystick + ++usb:v2226* ++ ID_VENDOR_FROM_DATABASE=Copper Mountain technologies ++ + usb:v2227* + ID_VENDOR_FROM_DATABASE=SAMWOO Enterprise + + usb:v2227p3105* + ID_MODEL_FROM_DATABASE=SKYDATA SKD-U100 + ++usb:v222A* ++ ID_VENDOR_FROM_DATABASE=ILI Technology Corp. ++ ++usb:v222Ap0001* ++ ID_MODEL_FROM_DATABASE=Multi-Touch Screen ++ ++usb:v222Ap0037* ++ ID_MODEL_FROM_DATABASE=Multi-Touch Screen ++ ++usb:v2230* ++ ID_VENDOR_FROM_DATABASE=Plugable ++ ++usb:v2230p0001* ++ ID_MODEL_FROM_DATABASE=UD-160-A / M Integrated Hub ++ ++usb:v2230p0003* ++ ID_MODEL_FROM_DATABASE=DC-125 / M Integrated Hub ++ + usb:v2232* + ID_VENDOR_FROM_DATABASE=Silicon Motion + + usb:v2232p1005* + ID_MODEL_FROM_DATABASE=WebCam SCB-0385N + ++usb:v2232p1024* ++ ID_MODEL_FROM_DATABASE=Webcam SC-13HDL11624N [Namuga Co., Ltd.] ++ + usb:v2232p1028* + ID_MODEL_FROM_DATABASE=WebCam SC-03FFL11939N + +@@ -55841,6 +63557,9 @@ usb:v2232p1029* + usb:v2232p1037* + ID_MODEL_FROM_DATABASE=WebCam SC-03FFM12339N + ++usb:v2232p1045* ++ ID_MODEL_FROM_DATABASE=WebCam SC-10HDP12631N ++ + usb:v2233* + ID_VENDOR_FROM_DATABASE=RadioShack Corporation + +@@ -55853,6 +63572,48 @@ usb:v2237* + usb:v2237p4161* + ID_MODEL_FROM_DATABASE=eReader White + ++usb:v2237p4163* ++ ID_MODEL_FROM_DATABASE=Touch ++ ++usb:v2237p4173* ++ ID_MODEL_FROM_DATABASE=Glo ++ ++usb:v2245* ++ ID_VENDOR_FROM_DATABASE=Aspeed Technology, Inc. ++ ++usb:v2245p1500* ++ ID_MODEL_FROM_DATABASE=AST1500/1510 PC-over-LAN Virtual Hub ++ ++usb:v224F* ++ ID_VENDOR_FROM_DATABASE=APDM ++ ++usb:v224Fp0001* ++ ID_MODEL_FROM_DATABASE=Access Point ++ ++usb:v224Fp0002* ++ ID_MODEL_FROM_DATABASE=Docking Station ++ ++usb:v224Fp0004* ++ ID_MODEL_FROM_DATABASE=V2 Opal ACM ++ ++usb:v224Fp0005* ++ ID_MODEL_FROM_DATABASE=V2 Opal ++ ++usb:v224Fp0006* ++ ID_MODEL_FROM_DATABASE=V2 Docking Station ++ ++usb:v224Fp0007* ++ ID_MODEL_FROM_DATABASE=V2 Access Point ACM ++ ++usb:v224Fp0008* ++ ID_MODEL_FROM_DATABASE=V2 Access Point ++ ++usb:v2256* ++ ID_VENDOR_FROM_DATABASE=Faderfox ++ ++usb:v2256p1007* ++ ID_MODEL_FROM_DATABASE=LV3 MIDI Controller ++ + usb:v225D* + ID_VENDOR_FROM_DATABASE=Morpho + +@@ -55863,35 +63624,86 @@ usb:v225Dp0008* + ID_MODEL_FROM_DATABASE=CBM-E3 Fingerprint Sensor + + usb:v225Dp0009* +- ID_MODEL_FROM_DATABASE=CBM Fingerprint Sensor [CBM-V3] ++ ID_MODEL_FROM_DATABASE=CBM-V3 Fingerprint Sensor + + usb:v225Dp000A* + ID_MODEL_FROM_DATABASE=MSO1300-E3 Fingerprint Sensor + + usb:v225Dp000B* +- ID_MODEL_FROM_DATABASE=MSO1300 Fingerprint Sensor [MSO1300-V3] ++ ID_MODEL_FROM_DATABASE=MSO1300-V3 Fingerprint Sensor + + usb:v225Dp000C* + ID_MODEL_FROM_DATABASE=MSO1350-E3 Fingerprint Sensor & SmartCard Reader + + usb:v225Dp000D* +- ID_MODEL_FROM_DATABASE=MSO1350 Fingerprint Sensor & SmartCard Reader [MSO1350-V3] ++ ID_MODEL_FROM_DATABASE=MSO1350-V3 Fingerprint Sensor & SmartCard Reader + + usb:v225Dp000E* + ID_MODEL_FROM_DATABASE=MorphoAccess SIGMA Biometric Access Control Terminal + ++usb:v225Dp9015* ++ ID_MODEL_FROM_DATABASE=Tablet 2 ++ ++usb:v225Dp9024* ++ ID_MODEL_FROM_DATABASE=Tablet 2 ++ ++usb:v225Dp9039* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225Dp904D* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225Dp904E* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225Dp9091* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225Dp9092* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225DpF000* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225DpF003* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225DpF006* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v225DpF00E* ++ ID_MODEL_FROM_DATABASE=Tablet 2 secure multifunction biometric tablet ++ ++usb:v226E* ++ ID_VENDOR_FROM_DATABASE=DISPLAX ++ + usb:v228D* + ID_VENDOR_FROM_DATABASE=8D Technologies inc. + + usb:v228Dp0001* + ID_MODEL_FROM_DATABASE=Terminal Bike Key Reader + ++usb:v22A4* ++ ID_VENDOR_FROM_DATABASE=VERZO Technology ++ + usb:v22A6* + ID_VENDOR_FROM_DATABASE=Pie Digital, Inc. + + usb:v22A6pFFFF* + ID_MODEL_FROM_DATABASE=PieKey "beta" 4GB model 4E4F41482E4F5247 (SM3251Q BB) + ++usb:v22A7* ++ ID_VENDOR_FROM_DATABASE=Fortinet Technologies ++ ++usb:v22A7p1001* ++ ID_MODEL_FROM_DATABASE=FortiGate Device ++ ++usb:v22B1* ++ ID_VENDOR_FROM_DATABASE=Secret Labs LLC ++ ++usb:v22B1p1000* ++ ID_MODEL_FROM_DATABASE=Netduino MCU pcb ++ + usb:v22B8* + ID_VENDOR_FROM_DATABASE=Motorola PCS + +@@ -55904,6 +63716,9 @@ usb:v22B8p0002* + usb:v22B8p0005* + ID_MODEL_FROM_DATABASE=V.60c/V.60i GSM Phone + ++usb:v22B8p002E* ++ ID_MODEL_FROM_DATABASE=XT1806 ++ + usb:v22B8p0830* + ID_MODEL_FROM_DATABASE=2386C-HT820 + +@@ -55994,6 +63809,12 @@ usb:v22B8p2AC3* + usb:v22B8p2D78* + ID_MODEL_FROM_DATABASE=XT300[SPICE] + ++usb:v22B8p2E82* ++ ID_MODEL_FROM_DATABASE=XT1541 [Moto G 3rd Gen] ++ ++usb:v22B8p2E83* ++ ID_MODEL_FROM_DATABASE=XT1033 [Moto G], PTP mode ++ + usb:v22B8p3001* + ID_MODEL_FROM_DATABASE=A835/E1000 GSM Phone (P2K) + +@@ -56051,6 +63872,9 @@ usb:v22B8p4244* + usb:v22B8p4285* + ID_MODEL_FROM_DATABASE=Droid X (Mass storage) + ++usb:v22B8p42D9* ++ ID_MODEL_FROM_DATABASE=XT910 [Droid RAZR] ++ + usb:v22B8p4801* + ID_MODEL_FROM_DATABASE=Neptune LTS chipset + +@@ -56141,9 +63965,18 @@ usb:v22B8p6401* + usb:v22B8p6403* + ID_MODEL_FROM_DATABASE=Argon chipset flash + ++usb:v22B8p6411* ++ ID_MODEL_FROM_DATABASE=ROKR Z6 (print mode) ++ + usb:v22B8p6415* + ID_MODEL_FROM_DATABASE=ROKR Z6 (MTP mode) + ++usb:v22B8p6422* ++ ID_MODEL_FROM_DATABASE=ROKR Z6 (modem mode) ++ ++usb:v22B8p6426* ++ ID_MODEL_FROM_DATABASE=ROKR Z6 (storage mode) ++ + usb:v22B8p6604* + ID_MODEL_FROM_DATABASE=Washington CDMA Phone + +@@ -56153,6 +63986,12 @@ usb:v22B8p6631* + usb:v22B8p7001* + ID_MODEL_FROM_DATABASE=Q Smartphone + ++usb:v22B8p7086* ++ ID_MODEL_FROM_DATABASE=Atrix ++ ++usb:v22B8p70A8* ++ ID_MODEL_FROM_DATABASE=Xoom Tablet ++ + usb:v22B8pFE01* + ID_MODEL_FROM_DATABASE=StarTAC III MS900 + +@@ -56165,6 +64004,144 @@ usb:v22B9p0006* + usb:v22BA* + ID_VENDOR_FROM_DATABASE=Technology Innovation Holdings, Ltd + ++usb:v22BAp0108* ++ ID_MODEL_FROM_DATABASE=Double Shock Steering Wheel HID ++ ++usb:v22BAp0109* ++ ID_MODEL_FROM_DATABASE=Double Shock Steering Wheel Hub ++ ++usb:v22C9* ++ ID_VENDOR_FROM_DATABASE=StepOver GmbH ++ ++usb:v22C9p0601* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Colour ++ ++usb:v22C9p0701* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Mobile ++ ++usb:v22C9p0801* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Comfort ++ ++usb:v22C9p0881* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Flawless ++ ++usb:v22C9p0901* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Classic ++ ++usb:v22C9p09E1* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Biometric ++ ++usb:v22C9p0CE1* ++ ID_MODEL_FROM_DATABASE=duraSign Pad Brilliance ++ ++usb:v22C9p0CF1* ++ ID_MODEL_FROM_DATABASE=duraSign Pad Biometric 5.0 ++ ++usb:v22C9p0D01* ++ ID_MODEL_FROM_DATABASE=duraSign 10.0 ++ ++usb:v22C9p0DF1* ++ ID_MODEL_FROM_DATABASE=duraSign Pad Biometric 10.0 ++ ++usb:v22CD* ++ ID_VENDOR_FROM_DATABASE=Kinova Robotics Inc. ++ ++usb:v22D4* ++ ID_VENDOR_FROM_DATABASE=Laview Technology ++ ++usb:v22D4p1301* ++ ID_MODEL_FROM_DATABASE=Mionix NAOS 8200 [STM32F103 MCU] ++ ++usb:v22D4p1308* ++ ID_MODEL_FROM_DATABASE=Mionix Avior 7000 ++ ++usb:v22D4p130C* ++ ID_MODEL_FROM_DATABASE=Mionix Naos 7000 ++ ++usb:v22D4p1316* ++ ID_MODEL_FROM_DATABASE=Mionix Castor ++ ++usb:v22D9* ++ ID_VENDOR_FROM_DATABASE=OPPO Electronics Corp. ++ ++usb:v22D9p2765* ++ ID_MODEL_FROM_DATABASE=Oppo N1 ++ ++usb:v22D9p2767* ++ ID_MODEL_FROM_DATABASE=Oppo Find 5 (X909) ++ ++usb:v22DB* ++ ID_VENDOR_FROM_DATABASE=Phase One ++ ++usb:v22DBp0003* ++ ID_MODEL_FROM_DATABASE=IQ3 100MP IG030372 ++ ++usb:v22DC* ++ ID_VENDOR_FROM_DATABASE=Mellanox Technologies ++ ++usb:v22DCp0004* ++ ID_MODEL_FROM_DATABASE=BlueField SOC ++ ++usb:v22DE* ++ ID_VENDOR_FROM_DATABASE=WeTelecom Incorporated ++ ++usb:v22DF* ++ ID_VENDOR_FROM_DATABASE=Medicom MTD, Ltd ++ ++usb:v22E0* ++ ID_VENDOR_FROM_DATABASE=secunet Security Networks AG ++ ++usb:v22E0p0002* ++ ID_MODEL_FROM_DATABASE=SINA Flash Drive ++ ++usb:v22E0p0003* ++ ID_MODEL_FROM_DATABASE=SINA ID Token A ++ ++usb:v22E8* ++ ID_VENDOR_FROM_DATABASE=Cambridge Audio ++ ++usb:v22E8p6512* ++ ID_MODEL_FROM_DATABASE=651N Audio ++ ++usb:v22E8p6969* ++ ID_MODEL_FROM_DATABASE=Audio Prototype ++ ++usb:v22E8p7512* ++ ID_MODEL_FROM_DATABASE=751R Audio ++ ++usb:v22E8p770A* ++ ID_MODEL_FROM_DATABASE=X70A Audio ++ ++usb:v22E8p850C* ++ ID_MODEL_FROM_DATABASE=851C Audio [Azur 850C] ++ ++usb:v22E8p851D* ++ ID_MODEL_FROM_DATABASE=851D Audio [Azur 851D] ++ ++usb:v22E8pCA02* ++ ID_MODEL_FROM_DATABASE=Audio ++ ++usb:v22E8pCA04* ++ ID_MODEL_FROM_DATABASE=Audio ++ ++usb:v22E8pCA06* ++ ID_MODEL_FROM_DATABASE=AmpMagic ++ ++usb:v22E8pDAC2* ++ ID_MODEL_FROM_DATABASE=DacMagic Plus ++ ++usb:v22E8pDAC3* ++ ID_MODEL_FROM_DATABASE=Azur DacMagic 100 ++ ++usb:v22E8pDAC4* ++ ID_MODEL_FROM_DATABASE=Azur DacMagic 100 ++ ++usb:v22E8pDAC6* ++ ID_MODEL_FROM_DATABASE=DacMagicXS 2.0 ++ ++usb:v22E8pDAC8* ++ ID_MODEL_FROM_DATABASE=Audio ++ + usb:v2304* + ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc. + +@@ -56303,12 +64280,45 @@ usb:v2304p061D* + usb:v2304p061E* + ID_MODEL_FROM_DATABASE=PCTV Deluxe (PAL) Device + ++usb:v2304p2304* ++ ID_MODEL_FROM_DATABASE=1689 ++ ++usb:v230D* ++ ID_VENDOR_FROM_DATABASE=Teracom ++ ++usb:v230Dp0103* ++ ID_MODEL_FROM_DATABASE=Huwaii 3g wireless modem ++ ++usb:v2314* ++ ID_VENDOR_FROM_DATABASE=INQ Mobile ++ + usb:v2318* + ID_VENDOR_FROM_DATABASE=Shining Technologies, Inc. [hex] + + usb:v2318p0011* + ID_MODEL_FROM_DATABASE=CitiDISK Jr. IDE Enclosure + ++usb:v2319* ++ ID_VENDOR_FROM_DATABASE=Tronsmart ++ ++usb:v2319p0014* ++ ID_MODEL_FROM_DATABASE=TSM01 Air Mouse + Keyboard ++ ++usb:v232B* ++ ID_VENDOR_FROM_DATABASE=Pantum Ltd. ++ ++usb:v232Bp0810* ++ ID_MODEL_FROM_DATABASE=P2000 ++ ++usb:v232E* ++ ID_VENDOR_FROM_DATABASE=EA Elektro-Automatik GmbH & Co. KG ++ ++usb:v232Ep0010* ++ ID_MODEL_FROM_DATABASE=EA-PS-2000 B Series Power Supply ++ ++usb:v2340* ++ ID_VENDOR_FROM_DATABASE=Teleepoch ++ + usb:v2341* + ID_VENDOR_FROM_DATABASE=Arduino SA + +@@ -56318,9 +64328,18 @@ usb:v2341p0001* + usb:v2341p0010* + ID_MODEL_FROM_DATABASE=Mega 2560 (CDC ACM) + ++usb:v2341p0036* ++ ID_MODEL_FROM_DATABASE=Leonardo Bootloader ++ + usb:v2341p003B* + ID_MODEL_FROM_DATABASE=Serial Adapter (CDC ACM) + ++usb:v2341p003D* ++ ID_MODEL_FROM_DATABASE=Due Programming Port ++ ++usb:v2341p003E* ++ ID_MODEL_FROM_DATABASE=Due ++ + usb:v2341p003F* + ID_MODEL_FROM_DATABASE=Mega ADK (CDC ACM) + +@@ -56336,12 +64355,36 @@ usb:v2341p0044* + usb:v2341p0045* + ID_MODEL_FROM_DATABASE=Serial R3 (CDC ACM) + ++usb:v2341p0049* ++ ID_MODEL_FROM_DATABASE=ISP ++ + usb:v2341p8036* + ID_MODEL_FROM_DATABASE=Leonardo (CDC ACM, HID) + ++usb:v2341p8038* ++ ID_MODEL_FROM_DATABASE=Robot Control Board (CDC ACM, HID) ++ ++usb:v2341p8039* ++ ID_MODEL_FROM_DATABASE=Robot Motor Board (CDC ACM, HID) ++ ++usb:v2349* ++ ID_VENDOR_FROM_DATABASE=P2 Engineering Group, LLC ++ ++usb:v234B* ++ ID_VENDOR_FROM_DATABASE=Free Software Initiative of Japan ++ ++usb:v234Bp0000* ++ ID_MODEL_FROM_DATABASE=Gnuk Token ++ ++usb:v234Bp0001* ++ ID_MODEL_FROM_DATABASE=NeuG True RNG ++ + usb:v2357* + ID_VENDOR_FROM_DATABASE=TP-Link + ++usb:v2357p0005* ++ ID_MODEL_FROM_DATABASE=M7350 4G Mi-Fi Router ++ + usb:v2357p0100* + ID_MODEL_FROM_DATABASE=TL-WN8200ND [Realtek RTL8192CU] + +@@ -56354,20 +64397,44 @@ usb:v2357p0103* + usb:v2357p0105* + ID_MODEL_FROM_DATABASE=Archer T1U 802.11a/n/ac Wireless Adapter [MediaTek MT7610U] + ++usb:v2357p0106* ++ ID_MODEL_FROM_DATABASE=Archer T9UH v1 [Realtek RTL8814AU] ++ + usb:v2357p0107* +- ID_MODEL_FROM_DATABASE=TL-WN821N Version 5 RTL8192EU ++ ID_MODEL_FROM_DATABASE=TL-WN821N v5/v6 [RTL8192EU] + + usb:v2357p0108* + ID_MODEL_FROM_DATABASE=TL-WN822N Version 4 RTL8192EU + + usb:v2357p0109* +- ID_MODEL_FROM_DATABASE=TL WN823N RTL8192EU ++ ID_MODEL_FROM_DATABASE=TL-WN823N v2/v3 [Realtek RTL8192EU] ++ ++usb:v2357p010B* ++ ID_MODEL_FROM_DATABASE=Archer T2UHP [MediaTek MT7610U] + + usb:v2357p010C* +- ID_MODEL_FROM_DATABASE=TL-WN722N v2 ++ ID_MODEL_FROM_DATABASE=TL-WN722N v2/v3 [Realtek RTL8188EUS] ++ ++usb:v2357p010D* ++ ID_MODEL_FROM_DATABASE=Archer T4U v2 [Realtek RTL8812AU] + + usb:v2357p010E* +- ID_MODEL_FROM_DATABASE=TL-WN722N v2 ++ ID_MODEL_FROM_DATABASE=Archer T4UH v2 [Realtek RTL8812AU] ++ ++usb:v2357p010F* ++ ID_MODEL_FROM_DATABASE=Archer T4UHP [Realtek RTL8812AU] ++ ++usb:v2357p0115* ++ ID_MODEL_FROM_DATABASE=Archer T4U ver.3 ++ ++usb:v2357p011E* ++ ID_MODEL_FROM_DATABASE=AC600 wireless Realtek RTL8811AU [Archer T2U Nano] ++ ++usb:v2357p0120* ++ ID_MODEL_FROM_DATABASE=Archer T2U PLUS [RTL8821AU] ++ ++usb:v2357p012D* ++ ID_MODEL_FROM_DATABASE=Archer T3U [Realtek RTL8812BU] + + usb:v2357p0200* + ID_MODEL_FROM_DATABASE=MA 180 Zero CD +@@ -56375,6 +64442,66 @@ usb:v2357p0200* + usb:v2357p0201* + ID_MODEL_FROM_DATABASE=HSUPA Modem MA180 + ++usb:v2357p0600* ++ ID_MODEL_FROM_DATABASE=UE300 10/100/1000 LAN (mass storage CD-ROM mode) [Realtek RTL8153] ++ ++usb:v2357p0601* ++ ID_MODEL_FROM_DATABASE=UE300 10/100/1000 LAN (ethernet mode) [Realtek RTL8153] ++ ++usb:v2366* ++ ID_VENDOR_FROM_DATABASE=Bitmanufaktur GmbH ++ ++usb:v2366p0001* ++ ID_MODEL_FROM_DATABASE=Reserved Prototyping PID ++ ++usb:v2366p0002* ++ ID_MODEL_FROM_DATABASE=OpenBeacon USB 2 ++ ++usb:v2366p0003* ++ ID_MODEL_FROM_DATABASE=OpenPCD 2 RFID Reader for 13.56MHz ++ ++usb:v2366p0004* ++ ID_MODEL_FROM_DATABASE=OpenBeacon ++ ++usb:v2366p0005* ++ ID_MODEL_FROM_DATABASE=Blinkenlights WDIM ++ ++usb:v2366p0006* ++ ID_MODEL_FROM_DATABASE=Blinkenlights WMCU ++ ++usb:v2366p0007* ++ ID_MODEL_FROM_DATABASE=OpenBeacon Ethernet EasyReader PoE II - Active 2.4GHz RFID Reader ++ ++usb:v2366p0008* ++ ID_MODEL_FROM_DATABASE=OpenBeacon WLAN ++ ++usb:v2366p0009* ++ ID_MODEL_FROM_DATABASE=OpenPCD 2 RFID Reader for 13.56MHz ++ ++usb:v2366p000A* ++ ID_MODEL_FROM_DATABASE=OpenPCD 2 Audio & LCD Display ++ ++usb:v2367* ++ ID_VENDOR_FROM_DATABASE=Teenage Engineering ++ ++usb:v2367p0002* ++ ID_MODEL_FROM_DATABASE=OP-1 Portable synthesizer ++ ++usb:v2367p000C* ++ ID_MODEL_FROM_DATABASE=OP-Z Portable synthesizer ++ ++usb:v2368* ++ ID_VENDOR_FROM_DATABASE=Peterson Electro-Musical Products Inc. ++ ++usb:v2368p0001* ++ ID_MODEL_FROM_DATABASE=BBS-1 [BodyBeat Sync] ++ ++usb:v236A* ++ ID_VENDOR_FROM_DATABASE=SiBEAM ++ ++usb:v236Ap1965* ++ ID_MODEL_FROM_DATABASE=SB6501 802.11ad Wireless Network Adapter ++ + usb:v2373* + ID_VENDOR_FROM_DATABASE=Pumatronix Ltda + +@@ -56387,18 +64514,195 @@ usb:v2375* + usb:v2375p0001* + ID_MODEL_FROM_DATABASE=Digital Audio Player + ++usb:v2378* ++ ID_VENDOR_FROM_DATABASE=OnLive ++ ++usb:v2378p100A* ++ ID_MODEL_FROM_DATABASE=Universal Wireless Controller ++ ++usb:v237D* ++ ID_VENDOR_FROM_DATABASE=Cradlepoint ++ ++usb:v237Dp0400* ++ ID_MODEL_FROM_DATABASE=MC400 ++ ++usb:v2386* ++ ID_VENDOR_FROM_DATABASE=Raydium Corporation ++ ++usb:v2386p3125* ++ ID_MODEL_FROM_DATABASE=Touch System ++ ++usb:v2386p4328* ++ ID_MODEL_FROM_DATABASE=Touch System ++ ++usb:v2386p432F* ++ ID_MODEL_FROM_DATABASE=Touch System ++ ++usb:v238B* ++ ID_VENDOR_FROM_DATABASE=Hytera Communications ++ ++usb:v238Bp0A11* ++ ID_MODEL_FROM_DATABASE=DMR Radio ++ ++usb:v239A* ++ ID_VENDOR_FROM_DATABASE=Adafruit ++ ++usb:v239Ap0001* ++ ID_MODEL_FROM_DATABASE=CDC Bootloader ++ ++usb:v239Ap801E* ++ ID_MODEL_FROM_DATABASE=Trinket M0 ++ ++usb:v23A0* ++ ID_VENDOR_FROM_DATABASE=BIFIT ++ ++usb:v23A0p0001* ++ ID_MODEL_FROM_DATABASE=Token iBank2key ++ ++usb:v23A0p0002* ++ ID_MODEL_FROM_DATABASE=iBank2Key Type M Token ++ ++usb:v23A0p0003* ++ ID_MODEL_FROM_DATABASE=iToken ++ ++usb:v23A0p0008* ++ ID_MODEL_FROM_DATABASE=MS_KEY K - Angara ++ ++usb:v23A6* ++ ID_VENDOR_FROM_DATABASE=Tronical Components GmbH ++ ++usb:v23A6p2000* ++ ID_MODEL_FROM_DATABASE=Gibson Firebird X Pedal Board ++ ++usb:v23A6p2001* ++ ID_MODEL_FROM_DATABASE=Gibson Firebird X Switch Board ++ ++usb:v23B4* ++ ID_VENDOR_FROM_DATABASE=Dental Wings Inc. ++ ++usb:v23B4p0200* ++ ID_MODEL_FROM_DATABASE=DW0200 Color Camera ++ ++usb:v23B4p0300* ++ ID_MODEL_FROM_DATABASE=DW0300 Hight Speed Monochrome Camera ++ ++usb:v23C7* ++ ID_VENDOR_FROM_DATABASE=Gemini ++ ++usb:v23C7p1021* ++ ID_MODEL_FROM_DATABASE=FirstMix ++ ++usb:v23FC* ++ ID_VENDOR_FROM_DATABASE=SesKion GmbH ++ ++usb:v23FCp0201* ++ ID_MODEL_FROM_DATABASE=SPI-Simulyzer box for SPI data communication ++ ++usb:v23FCp0202* ++ ID_MODEL_FROM_DATABASE=PSI5-Simulyzer box for PSI5 (Peripheral-Sensor-Interfacs) data communication ++ ++usb:v23FCp0203* ++ ID_MODEL_FROM_DATABASE=SENT-Simulyzer box for SENT data communication ++ ++usb:v23FCp0204* ++ ID_MODEL_FROM_DATABASE=DSI-Simulyzer box for DSI3 data communication ++ ++usb:v2405* ++ ID_VENDOR_FROM_DATABASE=Custom Computer Services, Inc ++ ++usb:v2405p0002* ++ ID_MODEL_FROM_DATABASE=West Mountain Radio RIGblaster Advantage Audio ++ ++usb:v2405p0003* ++ ID_MODEL_FROM_DATABASE=West Mountain Radio RIGblaster Advantage ++ + usb:v2406* + ID_VENDOR_FROM_DATABASE=SANHO Digital Electronics Co., Ltd. + + usb:v2406p6688* + ID_MODEL_FROM_DATABASE=PD7X Portable Storage + ++usb:v2420* ++ ID_VENDOR_FROM_DATABASE=IRiver ++ ++usb:v242E* ++ ID_VENDOR_FROM_DATABASE=Vossloh-Schwabe Deutschland GmbH ++ ++usb:v242Ep0001* ++ ID_MODEL_FROM_DATABASE=DALI Master ++ ++usb:v242Ep0002* ++ ID_MODEL_FROM_DATABASE=LiCS Bootloader Mode ++ ++usb:v242Ep0003* ++ ID_MODEL_FROM_DATABASE=LiCS Running Mode ++ ++usb:v242Ep0004* ++ ID_MODEL_FROM_DATABASE=iProgrammer ++ ++usb:v242Ep0005* ++ ID_MODEL_FROM_DATABASE=NFC programming device ++ ++usb:v2433* ++ ID_VENDOR_FROM_DATABASE=ASETEK ++ ++usb:v2433pB200* ++ ID_MODEL_FROM_DATABASE=[NZXT Kraken X60] ++ + usb:v2443* + ID_VENDOR_FROM_DATABASE=Aessent Technology Ltd + + usb:v2443p00DC* + ID_MODEL_FROM_DATABASE=aes220 FPGA Mini-Module + ++usb:v2457* ++ ID_VENDOR_FROM_DATABASE=Ocean Optics Inc. ++ ++usb:v2457p100A* ++ ID_MODEL_FROM_DATABASE=HR2000 Spectrometer 1.00.0 ++ ++usb:v2457p1012* ++ ID_MODEL_FROM_DATABASE=HR4000 Spectrometer ++ ++usb:v2458* ++ ID_VENDOR_FROM_DATABASE=Bluegiga Technologies ++ ++usb:v2458p0001* ++ ID_MODEL_FROM_DATABASE=BLED112 Bluetooth 4.0 Single Mode Dongle ++ ++usb:v245F* ++ ID_VENDOR_FROM_DATABASE=Chord Electronics Limited ++ ++usb:v2464* ++ ID_VENDOR_FROM_DATABASE=Nest ++ ++usb:v2464p0001* ++ ID_MODEL_FROM_DATABASE=Learning Thermostat ++ ++usb:v2464p0002* ++ ID_MODEL_FROM_DATABASE=Learning Thermostat (2nd Generation) ++ ++usb:v2464p0010* ++ ID_MODEL_FROM_DATABASE=Protect : Smoke + Carbon Monoxide ++ ++usb:v2464p0020* ++ ID_MODEL_FROM_DATABASE=Heat Link ++ ++usb:v2466* ++ ID_VENDOR_FROM_DATABASE=Fractal Audio Systems ++ ++usb:v2466p8003* ++ ID_MODEL_FROM_DATABASE=Axe-Fx II ++ ++usb:v2466p8010* ++ ID_MODEL_FROM_DATABASE=Axe-FX III ++ ++usb:v2476* ++ ID_VENDOR_FROM_DATABASE=YEI Technology ++ ++usb:v2476p1040* ++ ID_MODEL_FROM_DATABASE=3-Space Embedded Sensor ++ + usb:v2478* + ID_VENDOR_FROM_DATABASE=Tripp-Lite + +@@ -56411,9 +64715,144 @@ usb:v248A* + usb:v248Ap8366* + ID_MODEL_FROM_DATABASE=Wireless Optical Mouse ACT-MUSW-002 + ++usb:v248Ap8367* ++ ID_MODEL_FROM_DATABASE=Telink Wireless Receiver ++ + usb:v249C* + ID_VENDOR_FROM_DATABASE=M2Tech s.r.l. + ++usb:v24A4* ++ ID_VENDOR_FROM_DATABASE=Primare AB ++ ++usb:v24A4p0002* ++ ID_MODEL_FROM_DATABASE=I15_v1.06 [Primare Audio DAC] ++ ++usb:v24AE* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Rapoo Technology Co., Ltd. ++ ++usb:v24AEp0001* ++ ID_MODEL_FROM_DATABASE=KX Keyboard ++ ++usb:v24AEp0197* ++ ID_MODEL_FROM_DATABASE=meva Barcode Scanner ++ ++usb:v24AEp1813* ++ ID_MODEL_FROM_DATABASE=E9260 Wireless Multi-mode Keyboard ++ ++usb:v24AEp2000* ++ ID_MODEL_FROM_DATABASE=2.4G Wireless Device Serial ++ ++usb:v24AEp2001* ++ ID_MODEL_FROM_DATABASE=5 GHz Wireless Receiver ++ ++usb:v24AEp2003* ++ ID_MODEL_FROM_DATABASE=5GHz Wireless Transceiver ++ ++usb:v24AEp4110* ++ ID_MODEL_FROM_DATABASE=Optical Gaming Mouse [V280] ++ ++usb:v24AEp6000* ++ ID_MODEL_FROM_DATABASE=Wireless Audio ++ ++usb:v24C0* ++ ID_VENDOR_FROM_DATABASE=Chaney Instrument ++ ++usb:v24C0p0003* ++ ID_MODEL_FROM_DATABASE=Model 01036 weather center ++ ++usb:v24C6* ++ ID_VENDOR_FROM_DATABASE=ThrustMaster, Inc. ++ ++usb:v24C6p5000* ++ ID_MODEL_FROM_DATABASE=Razer Atrox Gaming Arcade Stick ++ ++usb:v24C6p5300* ++ ID_MODEL_FROM_DATABASE=PowerA Mini ProEX Controller for Xbox 360 ++ ++usb:v24C6p5303* ++ ID_MODEL_FROM_DATABASE=Airflo Wired Controller for Xbox 360 ++ ++usb:v24C6p530A* ++ ID_MODEL_FROM_DATABASE=ProEX Controller for Xbox 360 ++ ++usb:v24C6p531A* ++ ID_MODEL_FROM_DATABASE=Pro Ex mini for XBOX ++ ++usb:v24C6p5397* ++ ID_MODEL_FROM_DATABASE=FUS1ON Tournament Controller ++ ++usb:v24C6p541A* ++ ID_MODEL_FROM_DATABASE=PowerA CPFA115320-01 [Mini Controller for Xbox One] ++ ++usb:v24C6p542A* ++ ID_MODEL_FROM_DATABASE=Spectra for Xbox One ++ ++usb:v24C6p543A* ++ ID_MODEL_FROM_DATABASE=PowerA Wired Controller for Xbox One ++ ++usb:v24C6p5500* ++ ID_MODEL_FROM_DATABASE=Horipad EX2 Turbo ++ ++usb:v24C6p5501* ++ ID_MODEL_FROM_DATABASE=Hori Real Arcade Pro.VX-SA for Xbox 360 ++ ++usb:v24C6p5502* ++ ID_MODEL_FROM_DATABASE=Hori Fighting Stick VX Alt for Xbox 360 ++ ++usb:v24C6p5503* ++ ID_MODEL_FROM_DATABASE=Hori Fighting Edge for Xbox 360 ++ ++usb:v24C6p5506* ++ ID_MODEL_FROM_DATABASE=Hori Soulcalibur V Stick for Xbox 360 ++ ++usb:v24C6p550D* ++ ID_MODEL_FROM_DATABASE=Hori Gem Controller for Xbox 360 ++ ++usb:v24C6p550E* ++ ID_MODEL_FROM_DATABASE=Real Arcade Pro V Kai for Xbox One / Xbox 360 ++ ++usb:v24C6p551A* ++ ID_MODEL_FROM_DATABASE=Fusion Pro Controller ++ ++usb:v24C6p561A* ++ ID_MODEL_FROM_DATABASE=Fusion Controller for Xbox One ++ ++usb:v24C6p5B00* ++ ID_MODEL_FROM_DATABASE=Ferrari 458 Italia Racing Wheel ++ ++usb:v24C6p5B02* ++ ID_MODEL_FROM_DATABASE=GPX Controller ++ ++usb:v24C6p5D04* ++ ID_MODEL_FROM_DATABASE=Sabertooth Elite ++ ++usb:v24C6pFA00* ++ ID_MODEL_FROM_DATABASE=INF-8032385 Disney Infinity Reader ++ ++usb:v24C6pFAFB* ++ ID_MODEL_FROM_DATABASE=Aplay Controller ++ ++usb:v24C6pFAFD* ++ ID_MODEL_FROM_DATABASE=Afterglow Gamepad for Xbox 360 ++ ++usb:v24C6pFAFE* ++ ID_MODEL_FROM_DATABASE=Rock Candy Gamepad for Xbox 360 ++ ++usb:v24CF* ++ ID_VENDOR_FROM_DATABASE=Lytro, Inc. ++ ++usb:v24CFp00A1* ++ ID_MODEL_FROM_DATABASE=Light Field Camera ++ ++usb:v24DC* ++ ID_VENDOR_FROM_DATABASE=Aladdin R.D. ++ ++usb:v24DCp0406* ++ ID_MODEL_FROM_DATABASE=JaCarta SF GOST ++ ++usb:v24E0* ++ ID_VENDOR_FROM_DATABASE=Yoctopuce Sarl ++ + usb:v24E1* + ID_VENDOR_FROM_DATABASE=Paratronic + +@@ -56423,6 +64862,51 @@ usb:v24E1p3001* + usb:v24E1p3005* + ID_MODEL_FROM_DATABASE=Radius + ++usb:v24E3* ++ ID_VENDOR_FROM_DATABASE=K-Touch ++ ++usb:v24EA* ++ ID_VENDOR_FROM_DATABASE=Meva ++ ++usb:v24EAp0197* ++ ID_MODEL_FROM_DATABASE=Barcode Scanner ++ ++usb:v24ED* ++ ID_VENDOR_FROM_DATABASE=Zen Group ++ ++usb:v24EDp044D* ++ ID_MODEL_FROM_DATABASE=Chat Headset ++ ++usb:v24F0* ++ ID_VENDOR_FROM_DATABASE=Metadot ++ ++usb:v24F0p0105* ++ ID_MODEL_FROM_DATABASE=Das Keyboard 4 ++ ++usb:v24F0p0140* ++ ID_MODEL_FROM_DATABASE=Das Keyboard 4 ++ ++usb:v24F0p2020* ++ ID_MODEL_FROM_DATABASE=Das Keyboard 5Q ++ ++usb:v24FF* ++ ID_VENDOR_FROM_DATABASE=Acroname Inc. ++ ++usb:v2500* ++ ID_VENDOR_FROM_DATABASE=Ettus Research LLC ++ ++usb:v2500p0020* ++ ID_MODEL_FROM_DATABASE=USRP B210 ++ ++usb:v2500p0021* ++ ID_MODEL_FROM_DATABASE=USRP B200-mini ++ ++usb:v2500p0022* ++ ID_MODEL_FROM_DATABASE=USRP B205-mini ++ ++usb:v2500p0200* ++ ID_MODEL_FROM_DATABASE=USRP B200 ++ + usb:v2516* + ID_VENDOR_FROM_DATABASE=Cooler Master Co., Ltd. + +@@ -56442,11 +64926,20 @@ usb:v2516p0009* + ID_MODEL_FROM_DATABASE=Storm Quick Fire PRO + + usb:v2516p0011* +- ID_MODEL_FROM_DATABASE=Storm Quick Fire TK ++ ID_MODEL_FROM_DATABASE=Storm Quick Fire TK 6keys ++ ++usb:v2516p0014* ++ ID_MODEL_FROM_DATABASE=Storm Quick Fire TK Nkeys ++ ++usb:v2516p0015* ++ ID_MODEL_FROM_DATABASE=Storm QuickFire Pro/Ultimate keyboard + + usb:v2516p0017* + ID_MODEL_FROM_DATABASE=CM Storm Quick Fire Stealth + ++usb:v2516p001A* ++ ID_MODEL_FROM_DATABASE=Storm Quick Fire XT ++ + usb:v2516p0020* + ID_MODEL_FROM_DATABASE=QuickFire Rapid-i Keyboard + +@@ -56456,12 +64949,357 @@ usb:v2516p0027* + usb:v2516p002D* + ID_MODEL_FROM_DATABASE=Alcor mouse + ++usb:v2516p0042* ++ ID_MODEL_FROM_DATABASE=Masterkeys Lite L Combo RGB Keyboard ++ ++usb:v2516p0044* ++ ID_MODEL_FROM_DATABASE=Masterkeys Lite L Combo RGB Mouse ++ ++usb:v2516p0046* ++ ID_MODEL_FROM_DATABASE=Masterkeys PRO L ++ + usb:v2516p0047* + ID_MODEL_FROM_DATABASE=MasterKeys Pro L + ++usb:v2516p0055* ++ ID_MODEL_FROM_DATABASE=MasterKeys L ++ ++usb:v2516p1006* ++ ID_MODEL_FROM_DATABASE=MasterCase SL600M ++ + usb:v2516p9494* + ID_MODEL_FROM_DATABASE=Sirus Headset + ++usb:v2520* ++ ID_VENDOR_FROM_DATABASE=ANA-U GmbH ++ ++usb:v2520p0001* ++ ID_MODEL_FROM_DATABASE=EasyPrinter S3 ++ ++usb:v2527* ++ ID_VENDOR_FROM_DATABASE=Software Bisque ++ ++usb:v2527p1388* ++ ID_MODEL_FROM_DATABASE=Paramount 5 ++ ++usb:v2537* ++ ID_VENDOR_FROM_DATABASE=Norelsys ++ ++usb:v2537p1066* ++ ID_MODEL_FROM_DATABASE=NS1066 ++ ++usb:v2537p1068* ++ ID_MODEL_FROM_DATABASE=NS1068/NS1068X SATA Bridge Controller ++ ++usb:v2544* ++ ID_VENDOR_FROM_DATABASE=Energy Micro AS ++ ++usb:v2546* ++ ID_VENDOR_FROM_DATABASE=Ravensburger ++ ++usb:v2546pE301* ++ ID_MODEL_FROM_DATABASE=TipToi Pen ++ ++usb:v2548* ++ ID_VENDOR_FROM_DATABASE=Pulse-Eight ++ ++usb:v2548p1001* ++ ID_MODEL_FROM_DATABASE=CEC Adapter ++ ++usb:v2548p1002* ++ ID_MODEL_FROM_DATABASE=CEC Adapter ++ ++usb:v254E* ++ ID_VENDOR_FROM_DATABASE=SHF Communication Technologies AG ++ ++usb:v254EpE2B3* ++ ID_MODEL_FROM_DATABASE=SHF 58035 A BiasBoard ++ ++usb:v2554* ++ ID_VENDOR_FROM_DATABASE=ASSA ABLOY AB ++ ++usb:v2555* ++ ID_VENDOR_FROM_DATABASE=Basis Science Inc. ++ ++usb:v2555p0001* ++ ID_MODEL_FROM_DATABASE=B1 Fitness Band ++ ++usb:v255E* ++ ID_VENDOR_FROM_DATABASE=Beijing Bonxeon Technology Co., Ltd. ++ ++usb:v255Ep0001* ++ ID_MODEL_FROM_DATABASE=Device ++ ++usb:v255Ep0002* ++ ID_MODEL_FROM_DATABASE=Dual ++ ++usb:v2560* ++ ID_VENDOR_FROM_DATABASE=e-con Systems ++ ++usb:v2560pC152* ++ ID_MODEL_FROM_DATABASE=See3CAM_CU51 5 Mpx monochrome camera ++ ++usb:v2563* ++ ID_VENDOR_FROM_DATABASE=ShenZhen ShanWan Technology Co., Ltd. ++ ++usb:v2563p031D* ++ ID_MODEL_FROM_DATABASE=DXT Mouse ++ ++usb:v2563p0523* ++ ID_MODEL_FROM_DATABASE=BM0523 WirelessGamepad ++ ++usb:v2563p0575* ++ ID_MODEL_FROM_DATABASE=ZD-V+ Wired Gaming Controller ++ ++usb:v256B* ++ ID_VENDOR_FROM_DATABASE=Perreaux Industries Ltd ++ ++usb:v256Bp0121* ++ ID_MODEL_FROM_DATABASE=Audiant 80i ++ ++usb:v256F* ++ ID_VENDOR_FROM_DATABASE=3Dconnexion ++ ++usb:v256FpC62E* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Wireless (cabled) ++ ++usb:v256FpC62F* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Wireless Receiver ++ ++usb:v256FpC631* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Pro Wireless (cabled) ++ ++usb:v256FpC632* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Pro Wireless Receiver ++ ++usb:v256FpC633* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Enterprise ++ ++usb:v256FpC635* ++ ID_MODEL_FROM_DATABASE=SpaceMouse Compact ++ ++usb:v256FpC651* ++ ID_MODEL_FROM_DATABASE=CadMouse Wireless ++ ++usb:v256FpC652* ++ ID_MODEL_FROM_DATABASE=Universal Receiver ++ ++usb:v256FpC654* ++ ID_MODEL_FROM_DATABASE=CadMouse Pro Wireless ++ ++usb:v256FpC657* ++ ID_MODEL_FROM_DATABASE=CadMouse Pro Wireless Left ++ ++usb:v2573* ++ ID_VENDOR_FROM_DATABASE=ESI Audiotechnik GmbH ++ ++usb:v2573p0017* ++ ID_MODEL_FROM_DATABASE=MAYA22 ++ ++usb:v2574* ++ ID_VENDOR_FROM_DATABASE=AVer Information, Inc. ++ ++usb:v2574p0901* ++ ID_MODEL_FROM_DATABASE=VC520 ++ ++usb:v2574p0910* ++ ID_MODEL_FROM_DATABASE=CAM520 ++ ++usb:v2574p0920* ++ ID_MODEL_FROM_DATABASE=VC320 ++ ++usb:v2574p0930* ++ ID_MODEL_FROM_DATABASE=CAM530 ++ ++usb:v2574p0940* ++ ID_MODEL_FROM_DATABASE=CAM340 ++ ++usb:v2574p0950* ++ ID_MODEL_FROM_DATABASE=VC322 ++ ++usb:v2574p0960* ++ ID_MODEL_FROM_DATABASE=VB342 ++ ++usb:v2575* ++ ID_VENDOR_FROM_DATABASE=Weida Hi-Tech Co., Ltd. ++ ++usb:v2576* ++ ID_VENDOR_FROM_DATABASE=AFO Co., Ltd. ++ ++usb:v2576p0003* ++ ID_MODEL_FROM_DATABASE=TCM ++ ++usb:v2576p0005* ++ ID_MODEL_FROM_DATABASE=BL [Boot Loader] ++ ++usb:v2576p0011* ++ ID_MODEL_FROM_DATABASE=THM ++ ++usb:v2578* ++ ID_VENDOR_FROM_DATABASE=Pluscom ++ ++usb:v2578p4168* ++ ID_MODEL_FROM_DATABASE=2.4GHZ Wireless Arc Folding Mouse ++ ++usb:v2581* ++ ID_VENDOR_FROM_DATABASE=Plug-up ++ ++usb:v2581p1807* ++ ID_MODEL_FROM_DATABASE=Generic HID Smartcard ++ ++usb:v2581p1808* ++ ID_MODEL_FROM_DATABASE=WinUSB Smartcard ++ ++usb:v2581pF1D0* ++ ID_MODEL_FROM_DATABASE=FIDO U2F Security Key ++ ++usb:v258D* ++ ID_VENDOR_FROM_DATABASE=Sequans Communications ++ ++usb:v259A* ++ ID_VENDOR_FROM_DATABASE=TriQuint Semiconductor ++ ++usb:v25A7* ++ ID_VENDOR_FROM_DATABASE=Areson Technology Corp ++ ++usb:v25A7p2410* ++ ID_MODEL_FROM_DATABASE=Laser mouse ++ ++usb:v25A7pFA23* ++ ID_MODEL_FROM_DATABASE=2.4G Receiver ++ ++usb:v25A7pFA61* ++ ID_MODEL_FROM_DATABASE=Elecom Co., Ltd MR-K013 Multicard Reader ++ ++usb:v25B5* ++ ID_VENDOR_FROM_DATABASE=FlatFrog ++ ++usb:v25B5p0002* ++ ID_MODEL_FROM_DATABASE=Multitouch 3200 ++ ++usb:v25BB* ++ ID_VENDOR_FROM_DATABASE=Brunner Elektronik AG ++ ++usb:v25BBp0063* ++ ID_MODEL_FROM_DATABASE=PRT.5105 [Yoke] ++ ++usb:v25BBp0064* ++ ID_MODEL_FROM_DATABASE=PRT.5105 [reserved] ++ ++usb:v25BBp0065* ++ ID_MODEL_FROM_DATABASE=PRT.5096 [Battery Management System] ++ ++usb:v25BBp0066* ++ ID_MODEL_FROM_DATABASE=PRT.5096 [Battery Management System] ++ ++usb:v25BBp0067* ++ ID_MODEL_FROM_DATABASE=PRT.5094 ++ ++usb:v25BBp0068* ++ ID_MODEL_FROM_DATABASE=PRT.5094 ++ ++usb:v25BBp0069* ++ ID_MODEL_FROM_DATABASE=PRT.5119 [Ethernet2CAN LC Gateway] ++ ++usb:v25BBp006A* ++ ID_MODEL_FROM_DATABASE=PRT.5113 [CLS CANaerospace Gateway] ++ ++usb:v25BBp006B* ++ ID_MODEL_FROM_DATABASE=PRT.5123 ++ ++usb:v25BBp006C* ++ ID_MODEL_FROM_DATABASE=PRT.5123 [reserved] ++ ++usb:v25BBp006D* ++ ID_MODEL_FROM_DATABASE=PRT.5127 ++ ++usb:v25BBp00FF* ++ ID_MODEL_FROM_DATABASE=MSP430 HID Update Agent ++ ++usb:v25BF* ++ ID_VENDOR_FROM_DATABASE=Elegant Invention ++ ++usb:v25BFp0001* ++ ID_MODEL_FROM_DATABASE=Isostick ++ ++usb:v25BFp0002* ++ ID_MODEL_FROM_DATABASE=Isostick updater ++ ++usb:v25C4* ++ ID_VENDOR_FROM_DATABASE=ARCAM ++ ++usb:v25C6* ++ ID_VENDOR_FROM_DATABASE=Vitus Audio (AVA Group A/S) ++ ++usb:v25C8* ++ ID_VENDOR_FROM_DATABASE=Visual Planet Ltd ++ ++usb:v25C8p0014* ++ ID_MODEL_FROM_DATABASE=Single User touchfoil(tm) (SU2-80) ++ ++usb:v25DA* ++ ID_VENDOR_FROM_DATABASE=Netatmo ++ ++usb:v25DAp0001* ++ ID_MODEL_FROM_DATABASE=Weather Station ++ ++usb:v25E3* ++ ID_VENDOR_FROM_DATABASE=Lumigon ++ ++usb:v25F0* ++ ID_VENDOR_FROM_DATABASE=ShanWan ++ ++usb:v25F0pC131* ++ ID_MODEL_FROM_DATABASE=Gioteck PS3 2.4G Wireless Controller ++ ++usb:v25FB* ++ ID_VENDOR_FROM_DATABASE=Pentax Ricoh Imaging Co., Ltd ++ ++usb:v25FBp0102* ++ ID_MODEL_FROM_DATABASE=K-5 ++ ++usb:v2604* ++ ID_VENDOR_FROM_DATABASE=Tenda ++ ++usb:v2604p0012* ++ ID_MODEL_FROM_DATABASE=U12 ++ ++usb:v2625* ++ ID_VENDOR_FROM_DATABASE=MilDef AB ++ ++usb:v2626* ++ ID_VENDOR_FROM_DATABASE=Aruba Networks ++ ++usb:v2626pEA60* ++ ID_MODEL_FROM_DATABASE=UART Bridge Controller [cp210x] ++ ++usb:v262A* ++ ID_VENDOR_FROM_DATABASE=SAVITECH Corp. ++ ++usb:v262Ap100E* ++ ID_MODEL_FROM_DATABASE=SA9027 Audio Streaming Controller ++ ++usb:v262Ap10E0* ++ ID_MODEL_FROM_DATABASE=SA9023 Audio Streaming Controller ++ ++usb:v262Ap9020* ++ ID_MODEL_FROM_DATABASE=SA9020 audio controller ++ ++usb:v262Ap9023* ++ ID_MODEL_FROM_DATABASE=SA9023 audio controller ++ ++usb:v262Ap9027* ++ ID_MODEL_FROM_DATABASE=SA9027 audio controller ++ ++usb:v262Ap9226* ++ ID_MODEL_FROM_DATABASE=SA9226 192KHz audio controller ++ ++usb:v262Ap9227* ++ ID_MODEL_FROM_DATABASE=SA9227 384KHz audio controller ++ ++usb:v262Ap9228* ++ ID_MODEL_FROM_DATABASE=SA9228 384KHz/DSD audio controller ++ + usb:v2632* + ID_VENDOR_FROM_DATABASE=TwinMOS + +@@ -56507,12 +65345,27 @@ usb:v2639p0103* + usb:v2639p0200* + ID_MODEL_FROM_DATABASE=MTw + ++usb:v2639p0300* ++ ID_MODEL_FROM_DATABASE=Motion Tracker Development Board ++ ++usb:v2639p0301* ++ ID_MODEL_FROM_DATABASE=MTi Converter ++ + usb:v2639pD00D* + ID_MODEL_FROM_DATABASE=Wireless Receiver + ++usb:v264A* ++ ID_VENDOR_FROM_DATABASE=Thermaltake ++ ++usb:v264Ap1004* ++ ID_MODEL_FROM_DATABASE=Ventus ++ + usb:v2650* + ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc. [hex] + ++usb:v2650p1311* ++ ID_MODEL_FROM_DATABASE=eBeam Classic [Luidia] ++ + usb:v2659* + ID_VENDOR_FROM_DATABASE=Sundtek + +@@ -56558,15 +65411,345 @@ usb:v2659p1212* + usb:v2659p1213* + ID_MODEL_FROM_DATABASE=MediaTV Pro III MiniPCIe (US) + ++usb:v2662* ++ ID_VENDOR_FROM_DATABASE=Moog Music Inc. ++ ++usb:v266E* ++ ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems ++ ++usb:v2672* ++ ID_VENDOR_FROM_DATABASE=GoPro ++ ++usb:v2672p0004* ++ ID_MODEL_FROM_DATABASE=Hero 3 ++ ++usb:v2672p0006* ++ ID_MODEL_FROM_DATABASE=HERO 3+ Silver Edition ++ ++usb:v2672p0007* ++ ID_MODEL_FROM_DATABASE=HERO 3+ Black ++ ++usb:v2672p000E* ++ ID_MODEL_FROM_DATABASE=HERO4 Black ++ ++usb:v2672p0011* ++ ID_MODEL_FROM_DATABASE=Hero 3+ Black ++ + usb:v2676* + ID_VENDOR_FROM_DATABASE=Basler AG + + usb:v2676pBA02* + ID_MODEL_FROM_DATABASE=ace + ++usb:v2676pBA03* ++ ID_MODEL_FROM_DATABASE=ba03 dart Vision Caera ++ ++usb:v2676pBA04* ++ ID_MODEL_FROM_DATABASE=ba04 pulse Vision Camera ++ ++usb:v2676pBA05* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA06* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA07* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA08* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA09* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0A* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0B* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0C* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0D* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0E* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2676pBA0F* ++ ID_MODEL_FROM_DATABASE=Vision Camera ++ ++usb:v2685* ++ ID_VENDOR_FROM_DATABASE=Cardo Peripheral Systems LTD ++ ++usb:v2685p0900* ++ ID_MODEL_FROM_DATABASE=[Packtalk Bold Bluetooth Motorcycle Intercom] ++ ++usb:v2687* ++ ID_VENDOR_FROM_DATABASE=Fitbit Inc. ++ ++usb:v2687pFB01* ++ ID_MODEL_FROM_DATABASE=Base Station ++ ++usb:v2689* ++ ID_VENDOR_FROM_DATABASE=StepOver International GmbH ++ ++usb:v2689p0601* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad POS ++ ++usb:v2689p0901* ++ ID_MODEL_FROM_DATABASE=naturaSign Pad Light ++ ++usb:v2689p0CE1* ++ ID_MODEL_FROM_DATABASE=Pad Vivid US ++ ++usb:v2689p0CF1* ++ ID_MODEL_FROM_DATABASE=Pad Biometric US 5.0 ++ ++usb:v2689p0D01* ++ ID_MODEL_FROM_DATABASE=duraSign Pad US 10.0 ++ ++usb:v2689p0DF1* ++ ID_MODEL_FROM_DATABASE=duraSign Pad Biometric US 10.0 ++ ++usb:v268B* ++ ID_VENDOR_FROM_DATABASE=Dimension Engineering ++ ++usb:v268Bp0101* ++ ID_MODEL_FROM_DATABASE=DELink 2 ++ ++usb:v268Bp0201* ++ ID_MODEL_FROM_DATABASE=Sabertooth 2x32 ++ ++usb:v268Bp0405* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 ++ ++usb:v268Bp0406* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 ++ ++usb:v268Bp0407* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 ++ ++usb:v268Bp0408* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 ++ ++usb:v268Bp0409* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 ++ ++usb:v268Bp0412* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 ++ ++usb:v268Bp0413* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 ++ ++usb:v268Bp0414* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 ++ ++usb:v268Bp0415* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 ++ ++usb:v268Bp0416* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 ++ ++usb:v268Bp0417* ++ ID_MODEL_FROM_DATABASE=Evolv DNA Go ++ ++usb:v268Bp0419* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 Color ++ ++usb:v268Bp0423* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 ++ ++usb:v268Bp0424* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 ++ ++usb:v268Bp0425* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 ++ ++usb:v268Bp0426* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 ++ ++usb:v268Bp8405* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 (recovery mode) ++ ++usb:v268Bp8406* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 (recovery mode) ++ ++usb:v268Bp8407* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 (recovery mode) ++ ++usb:v268Bp8408* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 (recovery mode) ++ ++usb:v268Bp8409* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 (recovery mode) ++ ++usb:v268Bp8412* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 (recovery mode) ++ ++usb:v268Bp8413* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 (recovery mode) ++ ++usb:v268Bp8414* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 (recovery mode) ++ ++usb:v268Bp8415* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 (recovery mode) ++ ++usb:v268Bp8416* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 (recovery mode) ++ ++usb:v268Bp8423* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 200 (recovery mode) ++ ++usb:v268Bp8424* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 250 (recovery mode) ++ ++usb:v268Bp8425* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 75 (recovery mode) ++ ++usb:v268Bp8426* ++ ID_MODEL_FROM_DATABASE=Evolv DNA 60 (recovery mode) ++ ++usb:v26A9* ++ ID_VENDOR_FROM_DATABASE=Research Industrial Systems Engineering ++ ++usb:v26A9p0001* ++ ID_MODEL_FROM_DATABASE=Payment Terminal v1.0 ++ ++usb:v26AA* ++ ID_VENDOR_FROM_DATABASE=Yaesu Musen ++ ++usb:v26AAp0001* ++ ID_MODEL_FROM_DATABASE=FT-1D ++ ++usb:v26AAp000E* ++ ID_MODEL_FROM_DATABASE=FTA-550 ++ ++usb:v26AAp000F* ++ ID_MODEL_FROM_DATABASE=FTA-750 ++ ++usb:v26B5* ++ ID_VENDOR_FROM_DATABASE=Electrocompaniet ++ ++usb:v26B5p0002* ++ ID_MODEL_FROM_DATABASE=ECD 2 ++ ++usb:v26B5p0003* ++ ID_MODEL_FROM_DATABASE=ECD 2 (Audio Class 1) ++ ++usb:v26B5p0004* ++ ID_MODEL_FROM_DATABASE=PI 2D ++ ++usb:v26B5p0005* ++ ID_MODEL_FROM_DATABASE=PI 2D (Audio Class 1) ++ ++usb:v26B5p0006* ++ ID_MODEL_FROM_DATABASE=ECI 6 ++ ++usb:v26B5p0007* ++ ID_MODEL_FROM_DATABASE=ECI 6 (Audio Class 1) ++ ++usb:v26B5p0020* ++ ID_MODEL_FROM_DATABASE=ECI 80 ++ ++usb:v26BD* ++ ID_VENDOR_FROM_DATABASE=Integral Memory ++ ++usb:v26BDp9917* ++ ID_MODEL_FROM_DATABASE=Fusion Flash Drive ++ ++usb:v26E2* ++ ID_VENDOR_FROM_DATABASE=Ingenieurbuero Dietzsch und Thiele, PartG ++ ++usb:v26F2* ++ ID_VENDOR_FROM_DATABASE=Micromega ++ ++usb:v26F2p0200* ++ ID_MODEL_FROM_DATABASE=MyDac ++ ++usb:v2707* ++ ID_VENDOR_FROM_DATABASE=Bardac Corporation ++ ++usb:v2707p0005* ++ ID_MODEL_FROM_DATABASE=drive.web ++ ++usb:v270D* ++ ID_VENDOR_FROM_DATABASE=Rosand Technologies ++ ++usb:v270Dp1001* ++ ID_MODEL_FROM_DATABASE=R-Idge Bootloader ++ ++usb:v270Dp1002* ++ ID_MODEL_FROM_DATABASE=R-Idge Router ++ ++usb:v2717* ++ ID_VENDOR_FROM_DATABASE=Xiaomi Inc. ++ ++usb:v2717p0011* ++ ID_MODEL_FROM_DATABASE=100Mbps Network Card Adapter ++ ++usb:v2717p0360* ++ ID_MODEL_FROM_DATABASE=Mi3W ++ ++usb:v2717p0368* ++ ID_MODEL_FROM_DATABASE=Mi4 LTE ++ ++usb:v2717p3801* ++ ID_MODEL_FROM_DATABASE=Mi ANC & Type-C In-Ear Earphones ++ ++usb:v2717p4106* ++ ID_MODEL_FROM_DATABASE=MediaTek MT7601U [MI WiFi] ++ ++usb:v2717pFF08* ++ ID_MODEL_FROM_DATABASE=Redmi Note 3 (ADB Interface) ++ ++usb:v2717pFF10* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (PTP) ++ ++usb:v2717pFF18* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (PTP + ADB) ++ ++usb:v2717pFF40* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (MTP) ++ ++usb:v2717pFF48* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (MTP + ADB) ++ ++usb:v2717pFF60* ++ ID_MODEL_FROM_DATABASE=redmi prime 2 ++ ++usb:v2717pFF68* ++ ID_MODEL_FROM_DATABASE=Mi-4c ++ ++usb:v2717pFF80* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (RNDIS) ++ ++usb:v2717pFF88* ++ ID_MODEL_FROM_DATABASE=Mi/Redmi series (RNDIS + ADB) ++ ++usb:v272A* ++ ID_VENDOR_FROM_DATABASE=StarLeaf Ltd. ++ ++usb:v272C* ++ ID_VENDOR_FROM_DATABASE=Signum Systems ++ ++usb:v272Cp7D13* ++ ID_MODEL_FROM_DATABASE=I-jet ++ + usb:v2730* + ID_VENDOR_FROM_DATABASE=Citizen + ++usb:v2730p0FFF* ++ ID_MODEL_FROM_DATABASE=CT-S2000/4000/310/CLP-521/621/631/CL-S700 Series ++ ++usb:v2730p1004* ++ ID_MODEL_FROM_DATABASE=PPU-700 ++ ++usb:v2730p2002* ++ ID_MODEL_FROM_DATABASE=CT-S2000 Thermal Printer (Parallel mode) ++ + usb:v2730p200F* + ID_MODEL_FROM_DATABASE=CT-S310 Label printer + +@@ -56693,6 +65876,30 @@ usb:v273Fp1004* + usb:v273Fp1005* + ID_MODEL_FROM_DATABASE=ColorHug2 bootloader + ++usb:v2756* ++ ID_VENDOR_FROM_DATABASE=Victor Hasselblad AB ++ ++usb:v2756p0002* ++ ID_MODEL_FROM_DATABASE=X1D Camera ++ ++usb:v2759* ++ ID_VENDOR_FROM_DATABASE=Philip Morris Products S.A. ++ ++usb:v2759p0003* ++ ID_MODEL_FROM_DATABASE=IQOS Pocket Charger 2.4 ++ ++usb:v2765* ++ ID_VENDOR_FROM_DATABASE=Firstbeat Technologies, Ltd. ++ ++usb:v2765p0004* ++ ID_MODEL_FROM_DATABASE=Bodyguard 2 ++ ++usb:v2766* ++ ID_VENDOR_FROM_DATABASE=LifeScan ++ ++usb:v2766p0000* ++ ID_MODEL_FROM_DATABASE=OneTouch Verio ++ + usb:v2770* + ID_VENDOR_FROM_DATABASE=NHJ, Ltd + +@@ -56729,12 +65936,111 @@ usb:v2770p930B* + usb:v2770p930C* + ID_MODEL_FROM_DATABASE=CCD Webcam(PC370R) + ++usb:v27A8* ++ ID_VENDOR_FROM_DATABASE=Square, Inc. ++ ++usb:v27A8pA120* ++ ID_MODEL_FROM_DATABASE=Contactless + Chip Reader ++ + usb:v27B8* + ID_VENDOR_FROM_DATABASE=ThingM + + usb:v27B8p01ED* + ID_MODEL_FROM_DATABASE=blink(1) + ++usb:v27BD* ++ ID_VENDOR_FROM_DATABASE=Codethink Ltd. ++ ++usb:v27BDp0001* ++ ID_MODEL_FROM_DATABASE=Slab Node Manager ++ ++usb:v27BDp0002* ++ ID_MODEL_FROM_DATABASE=Slab Node Manager JTAG ++ ++usb:v27C0* ++ ID_VENDOR_FROM_DATABASE=Cadwell Laboratories, Inc. ++ ++usb:v27C0p0818* ++ ID_MODEL_FROM_DATABASE=Paperlike HD-FT ++ ++usb:v27C6* ++ ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. ++ ++usb:v27C6p5117* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5201* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5301* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p530C* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p532D* ++ ID_MODEL_FROM_DATABASE=Fingerprint ++ ++usb:v27C6p5381* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5385* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p538C* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5395* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5584* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p55B4* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27C6p5740* ++ ID_MODEL_FROM_DATABASE=Fingerprint Reader ++ ++usb:v27D4* ++ ID_VENDOR_FROM_DATABASE=Blackstar Amplification Limited ++ ++usb:v27DD* ++ ID_VENDOR_FROM_DATABASE=Mindeo ++ ++usb:v27DDp0002* ++ ID_MODEL_FROM_DATABASE=Mindeo Virtual COM Port ++ ++usb:v27F2* ++ ID_VENDOR_FROM_DATABASE=Softnautics LLP ++ ++usb:v2803* ++ ID_VENDOR_FROM_DATABASE=StarLine LLC. ++ ++usb:v2803p0001* ++ ID_MODEL_FROM_DATABASE=Controller Area Network car alarm module [SLCAN-2] ++ ++usb:v2806* ++ ID_VENDOR_FROM_DATABASE=SIMPASS ++ ++usb:v2806p0001* ++ ID_MODEL_FROM_DATABASE=N-PASS X1 ++ ++usb:v2817* ++ ID_VENDOR_FROM_DATABASE=Signal Hound, Inc. ++ ++usb:v2817p0002* ++ ID_MODEL_FROM_DATABASE=BB60C Spectrum Analyzer ++ ++usb:v2817p0004* ++ ID_MODEL_FROM_DATABASE=SM200A Spectrum Analyzer ++ ++usb:v2818* ++ ID_VENDOR_FROM_DATABASE=Codex Digital Limited ++ ++usb:v2818p0001* ++ ID_MODEL_FROM_DATABASE=Transfer Drive Dock ++ + usb:v2821* + ID_VENDOR_FROM_DATABASE=ASUSTek Computer Inc. + +@@ -56747,6 +66053,69 @@ usb:v2821p160F* + usb:v2821p3300* + ID_MODEL_FROM_DATABASE=WL-140 / Hawking HWU36D 802.11b Wireless Adapter [Intersil PRISM 3] + ++usb:v2822* ++ ID_VENDOR_FROM_DATABASE=REFLEXdigital ++ ++usb:v2833* ++ ID_VENDOR_FROM_DATABASE=Oculus VR, Inc. ++ ++usb:v2833p0001* ++ ID_MODEL_FROM_DATABASE=Rift Developer Kit 1 ++ ++usb:v2833p0021* ++ ID_MODEL_FROM_DATABASE=Rift DK2 ++ ++usb:v2833p0031* ++ ID_MODEL_FROM_DATABASE=Rift CV1 ++ ++usb:v2833p0101* ++ ID_MODEL_FROM_DATABASE=Latency Tester ++ ++usb:v2833p0137* ++ ID_MODEL_FROM_DATABASE=Quest Headset ++ ++usb:v2833p0201* ++ ID_MODEL_FROM_DATABASE=Camera DK2 ++ ++usb:v2833p0211* ++ ID_MODEL_FROM_DATABASE=Rift CV1 Sensor ++ ++usb:v2833p0330* ++ ID_MODEL_FROM_DATABASE=Rift CV1 Audio ++ ++usb:v2833p1031* ++ ID_MODEL_FROM_DATABASE=Rift CV1 ++ ++usb:v2833p2021* ++ ID_MODEL_FROM_DATABASE=Rift DK2 ++ ++usb:v2833p2031* ++ ID_MODEL_FROM_DATABASE=Rift CV1 ++ ++usb:v2833p3031* ++ ID_MODEL_FROM_DATABASE=Rift CV1 ++ ++usb:v2836* ++ ID_VENDOR_FROM_DATABASE=OUYA ++ ++usb:v286B* ++ ID_VENDOR_FROM_DATABASE=STANEO SAS ++ ++usb:v286Bp0003* ++ ID_MODEL_FROM_DATABASE=D6BB/D9 seismic digitizer ++ ++usb:v2886* ++ ID_VENDOR_FROM_DATABASE=Seeed Technology Co., Ltd. ++ ++usb:v2886p0002* ++ ID_MODEL_FROM_DATABASE=Seeeduino Lite ++ ++usb:v2890* ++ ID_VENDOR_FROM_DATABASE=Teknic, Inc ++ ++usb:v2890p0213* ++ ID_MODEL_FROM_DATABASE=ClearPath 4-axis Comm Hub ++ + usb:v2899* + ID_VENDOR_FROM_DATABASE=Toptronic Industrial Co., Ltd + +@@ -56792,6 +66161,42 @@ usb:v289Bp000B* + usb:v289Bp000C* + ID_MODEL_FROM_DATABASE=Gamecube/N64 controller v2.9 (Joystick mode) + ++usb:v289Bp000E* ++ ID_MODEL_FROM_DATABASE=VirtualBoy controller ++ ++usb:v289Bp0010* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.2 (Joystick mode) ++ ++usb:v289Bp0011* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.2 (Mouse mode) ++ ++usb:v289Bp0012* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.2.1 (Joystick mode) ++ ++usb:v289Bp0013* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.2.1 (Mouse mode) ++ ++usb:v289Bp0014* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.3 (Joystick mode) ++ ++usb:v289Bp0015* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.3 (Mouse mode) ++ ++usb:v289Bp0016* ++ ID_MODEL_FROM_DATABASE=WUSBMote v1.3 (I2C interface mode) ++ ++usb:v289Bp0017* ++ ID_MODEL_FROM_DATABASE=Gamecube/N64 controller v3.0 ++ ++usb:v289Bp0018* ++ ID_MODEL_FROM_DATABASE=Atari Jaguar controller ++ ++usb:v289Bp0019* ++ ID_MODEL_FROM_DATABASE=MultiDB9joy v3 ++ ++usb:v289Bp001A* ++ ID_MODEL_FROM_DATABASE=MultiDB9joy v3 (multitap mode) ++ + usb:v289Bp0100* + ID_MODEL_FROM_DATABASE=Dual-relay board + +@@ -56801,6 +66206,117 @@ usb:v289Bp0500* + usb:v289Bp0502* + ID_MODEL_FROM_DATABASE=Precision barometer + ++usb:v289D* ++ ID_VENDOR_FROM_DATABASE=Seek Thermal, Inc. ++ ++usb:v289Dp0010* ++ ID_MODEL_FROM_DATABASE=PIR206 Thermal Camera [Seek Compact] ++ ++usb:v28BD* ++ ID_VENDOR_FROM_DATABASE=XP-Pen ++ ++usb:v28BDp0920* ++ ID_MODEL_FROM_DATABASE=Star G960 Graphic Tablet ++ ++usb:v28C7* ++ ID_VENDOR_FROM_DATABASE=Ultimaker B.V. ++ ++usb:v28C7p0001* ++ ID_MODEL_FROM_DATABASE=3D printer serial interface ++ ++usb:v28D4* ++ ID_VENDOR_FROM_DATABASE=Devialet ++ ++usb:v28D4p0008* ++ ID_MODEL_FROM_DATABASE=120/200/250/400/800/D-Premier ++ ++usb:v28DE* ++ ID_VENDOR_FROM_DATABASE=Valve Software ++ ++usb:v28DEp1102* ++ ID_MODEL_FROM_DATABASE=Wired Controller ++ ++usb:v28DEp1142* ++ ID_MODEL_FROM_DATABASE=Wireless Steam Controller ++ ++usb:v28DEp2000* ++ ID_MODEL_FROM_DATABASE=Lighthouse FPGA RX ++ ++usb:v28DEp2012* ++ ID_MODEL_FROM_DATABASE=Virtual Reality Controller [VRC] ++ ++usb:v28DEp2101* ++ ID_MODEL_FROM_DATABASE=Watchman Dongle ++ ++usb:v28DEp2500* ++ ID_MODEL_FROM_DATABASE=Lighthouse Base Station ++ ++usb:v28E0* ++ ID_VENDOR_FROM_DATABASE=PT. Prasimax Inovasi Teknologi ++ ++usb:v28E0p1001* ++ ID_MODEL_FROM_DATABASE=BTS Monitoring Config for Prototype ++ ++usb:v28E0p5740* ++ ID_MODEL_FROM_DATABASE=TRUMON TS-107 ++ ++usb:v28E0p5741* ++ ID_MODEL_FROM_DATABASE=TRUMON TS-108 ++ ++usb:v28E9* ++ ID_VENDOR_FROM_DATABASE=GDMicroelectronics ++ ++usb:v28E9p0189* ++ ID_MODEL_FROM_DATABASE=GD32 DFU Bootloader (Longan Nano) ++ ++usb:v28F3* ++ ID_VENDOR_FROM_DATABASE=Clover Network, Inc. ++ ++usb:v28F3p2000* ++ ID_MODEL_FROM_DATABASE=Mobile Wi-Fi (C200) ++ ++usb:v28F3p3000* ++ ID_MODEL_FROM_DATABASE=Mini ++ ++usb:v28F3p4000* ++ ID_MODEL_FROM_DATABASE=Flex ++ ++usb:v28F9* ++ ID_VENDOR_FROM_DATABASE=Profitap HQ BV ++ ++usb:v28F9p0001* ++ ID_MODEL_FROM_DATABASE=Profishark 1G Black ++ ++usb:v28F9p0003* ++ ID_MODEL_FROM_DATABASE=Profishark 1G+ ++ ++usb:v28F9p0004* ++ ID_MODEL_FROM_DATABASE=Profishark 1G ++ ++usb:v28F9p0005* ++ ID_MODEL_FROM_DATABASE=Profishark 10G ++ ++usb:v28F9p0006* ++ ID_MODEL_FROM_DATABASE=Profishark 100M ++ ++usb:v290C* ++ ID_VENDOR_FROM_DATABASE=R. Hamilton & Co. Ltd. ++ ++usb:v290Cp4B4D* ++ ID_MODEL_FROM_DATABASE=Mercury iPod Dock ++ ++usb:v2912* ++ ID_VENDOR_FROM_DATABASE=Audioengine ++ ++usb:v2912p20C8* ++ ID_MODEL_FROM_DATABASE=D1 24-bit DAC ++ ++usb:v2912p30C8* ++ ID_MODEL_FROM_DATABASE=D1 24-bit DAC ++ ++usb:v2916* ++ ID_VENDOR_FROM_DATABASE=Yota Devices ++ + usb:v2931* + ID_VENDOR_FROM_DATABASE=Jolla Oy + +@@ -56813,6 +66329,9 @@ usb:v2931p0A02* + usb:v2931p0A05* + ID_MODEL_FROM_DATABASE=Jolla PC connection + ++usb:v2931p0A07* ++ ID_MODEL_FROM_DATABASE=Phone MTP ++ + usb:v2931p0AFE* + ID_MODEL_FROM_DATABASE=Jolla charging only + +@@ -56828,6 +66347,117 @@ usb:v2939p495A* + usb:v2939p495B* + ID_MODEL_FROM_DATABASE=X-MCB2 + ++usb:v2939p49B1* ++ ID_MODEL_FROM_DATABASE=X-MCB1 ++ ++usb:v2939p49B2* ++ ID_MODEL_FROM_DATABASE=X-MCB2 ++ ++usb:v2939p49C1* ++ ID_MODEL_FROM_DATABASE=X-MCC1 ++ ++usb:v2939p49C2* ++ ID_MODEL_FROM_DATABASE=X-MCC2 ++ ++usb:v2939p49C3* ++ ID_MODEL_FROM_DATABASE=X-MCC3 ++ ++usb:v2939p49C4* ++ ID_MODEL_FROM_DATABASE=X-MCC4 ++ ++usb:v2957* ++ ID_VENDOR_FROM_DATABASE=Obsidian Research Corporation ++ ++usb:v2957p0001* ++ ID_MODEL_FROM_DATABASE=Management Console ++ ++usb:v2961* ++ ID_VENDOR_FROM_DATABASE=Miselu ++ ++usb:v2961p0001* ++ ID_MODEL_FROM_DATABASE=C.24 keyboard ++ ++usb:v296B* ++ ID_VENDOR_FROM_DATABASE=Xacti Corporation ++ ++usb:v296Bp3917* ++ ID_MODEL_FROM_DATABASE=CX-WE100 Camera ++ ++usb:v2972* ++ ID_VENDOR_FROM_DATABASE=FiiO Electronics Technology ++ ++usb:v2972p0007* ++ ID_MODEL_FROM_DATABASE=X3 2nd gen audio player / DAC ++ ++usb:v298D* ++ ID_VENDOR_FROM_DATABASE=Next Biometrics ++ ++usb:v298Dp2020* ++ ID_MODEL_FROM_DATABASE=NB-2020-U Fingerprint Reader ++ ++usb:v29BD* ++ ID_VENDOR_FROM_DATABASE=Silicon Works ++ ++usb:v29BDp4101* ++ ID_MODEL_FROM_DATABASE=Multi-touch Device ++ ++usb:v29C1* ++ ID_VENDOR_FROM_DATABASE=Taztag ++ ++usb:v29C1p1105* ++ ID_MODEL_FROM_DATABASE=M17-G903-1 [Tazpad] ++ ++usb:v29C1p1107* ++ ID_MODEL_FROM_DATABASE=M17-G903-A [Tazpad] (CCID) ++ ++usb:v29C2* ++ ID_VENDOR_FROM_DATABASE=Lewitt GmbH ++ ++usb:v29C2p0001* ++ ID_MODEL_FROM_DATABASE=DGT 650 ++ ++usb:v29C2p0003* ++ ID_MODEL_FROM_DATABASE=DGT 450 ++ ++usb:v29C2p0009* ++ ID_MODEL_FROM_DATABASE=DGT 260 ++ ++usb:v29C2p0011* ++ ID_MODEL_FROM_DATABASE=Stream 4x5 ++ ++usb:v29C3* ++ ID_VENDOR_FROM_DATABASE=Noviga ++ ++usb:v29E2* ++ ID_VENDOR_FROM_DATABASE=Huatune Technology (Shanghai) Co., Ltd. ++ ++usb:v29E7* ++ ID_VENDOR_FROM_DATABASE=Brunel University ++ ++usb:v29E8* ++ ID_VENDOR_FROM_DATABASE=4Links Limited ++ ++usb:v29EA* ++ ID_VENDOR_FROM_DATABASE=Kinesis Corporation ++ ++usb:v29EAp0102* ++ ID_MODEL_FROM_DATABASE=Advantage2 Keyboard ++ ++usb:v29F1* ++ ID_VENDOR_FROM_DATABASE=Canaan Creative Co., Ltd ++ ++usb:v29F1p33F1* ++ ID_MODEL_FROM_DATABASE=Avalon nano 1.0 ++ ++usb:v29F1p33F2* ++ ID_MODEL_FROM_DATABASE=Avalon USB2IIC Converter ++ ++usb:v29F1p33F3* ++ ID_MODEL_FROM_DATABASE=Avalon nano 2.0 ++ ++usb:v29F1p40F1* ++ ID_MODEL_FROM_DATABASE=Avalon4 mini ++ + usb:v2A03* + ID_VENDOR_FROM_DATABASE=dog hunter AG + +@@ -56850,7 +66480,7 @@ usb:v2A03p003A* + ID_MODEL_FROM_DATABASE=Arduino Micro ADK rev3 (bootloader) + + usb:v2A03p003B* +- ID_MODEL_FROM_DATABASE=Arduino Serial ++ ID_MODEL_FROM_DATABASE=Arduino usb2serial + + usb:v2A03p003C* + ID_MODEL_FROM_DATABASE=Arduino Explora (bootloader) +@@ -56900,12 +66530,105 @@ usb:v2A03p8041* + usb:v2A03p804D* + ID_MODEL_FROM_DATABASE=Arduino Zero Pro (CDC ACM) + ++usb:v2A0E* ++ ID_VENDOR_FROM_DATABASE=Shenzhen DreamSource Technology Co., Ltd. ++ ++usb:v2A13* ++ ID_VENDOR_FROM_DATABASE=Grabba International ++ ++usb:v2A13p0000* ++ ID_MODEL_FROM_DATABASE=S-Series data capture device ++ ++usb:v2A19* ++ ID_VENDOR_FROM_DATABASE=Numato Systems Pvt. Ltd ++ ++usb:v2A19p1002* ++ ID_MODEL_FROM_DATABASE=Mimas V2 Spartan6 FPGA Development Board ++ ++usb:v2A19p5440* ++ ID_MODEL_FROM_DATABASE=TimVideos' HDMI2USB Opsis (FX2) - Unconfigured device ++ ++usb:v2A19p5441* ++ ID_MODEL_FROM_DATABASE=TimVideos' HDMI2USB Opsis (FX2) - Firmware load/upgrade ++ ++usb:v2A19p5442* ++ ID_MODEL_FROM_DATABASE=TimVideos' HDMI2USB Opsis (FX2) - HDMI/DVI Capture Device ++ ++usb:v2A1D* ++ ID_VENDOR_FROM_DATABASE=Oxford Nanopore Technologies, Ltd ++ ++usb:v2A1Dp0000* ++ ID_MODEL_FROM_DATABASE=MinION ++ ++usb:v2A1Dp0001* ++ ID_MODEL_FROM_DATABASE=MinION ++ ++usb:v2A1Dp0010* ++ ID_MODEL_FROM_DATABASE=VolTRAX ++ ++usb:v2A1Dp0011* ++ ID_MODEL_FROM_DATABASE=VolTRAX ++ ++usb:v2A1Dp0020* ++ ID_MODEL_FROM_DATABASE=GridION ++ ++usb:v2A1Dp0021* ++ ID_MODEL_FROM_DATABASE=GridION ++ + usb:v2A37* + ID_VENDOR_FROM_DATABASE=RTD Embedded Technologies, Inc. + + usb:v2A37p5110* + ID_MODEL_FROM_DATABASE=UPS35110/UPS25110 + ++usb:v2A39* ++ ID_VENDOR_FROM_DATABASE=RME ++ ++usb:v2A39p3FB0* ++ ID_MODEL_FROM_DATABASE=Babyface Pro (Class Compliant Mode) ++ ++usb:v2A39p3FC0* ++ ID_MODEL_FROM_DATABASE=Babyface Pro ++ ++usb:v2A39p3FC1* ++ ID_MODEL_FROM_DATABASE=Fireface UFX+ ++ ++usb:v2A39p3FC2* ++ ID_MODEL_FROM_DATABASE=Fireface UFX+ ++ ++usb:v2A39p3FD1* ++ ID_MODEL_FROM_DATABASE=Fireface UFX+ ++ ++usb:v2A3C* ++ ID_VENDOR_FROM_DATABASE=Trinamic Motion Control GmbH & Co KG ++ ++usb:v2A3Cp0100* ++ ID_MODEL_FROM_DATABASE=Stepper Device ++ ++usb:v2A3Cp0200* ++ ID_MODEL_FROM_DATABASE=BLDC/PMSM Device ++ ++usb:v2A3Cp0300* ++ ID_MODEL_FROM_DATABASE=Motor Control Device ++ ++usb:v2A3Cp0400* ++ ID_MODEL_FROM_DATABASE=Motor Control Device ++ ++usb:v2A3Cp0500* ++ ID_MODEL_FROM_DATABASE=PANdrive(TM) ++ ++usb:v2A3Cp0600* ++ ID_MODEL_FROM_DATABASE=motionCookie(TM) ++ ++usb:v2A3Cp0700* ++ ID_MODEL_FROM_DATABASE=Evaluation Device ++ ++usb:v2A3Cp0800* ++ ID_MODEL_FROM_DATABASE=Interface Device ++ ++usb:v2A3Cp0900* ++ ID_MODEL_FROM_DATABASE=Generic Device ++ + usb:v2A45* + ID_VENDOR_FROM_DATABASE=Meizu Corp. + +@@ -56933,11 +66656,269 @@ usb:v2A45p200C* + usb:v2A45p2012* + ID_MODEL_FROM_DATABASE=MX Phone (MTP & ACM) + ++usb:v2A47* ++ ID_VENDOR_FROM_DATABASE=Mundo Reader, S.L. ++ ++usb:v2A47p0C02* ++ ID_MODEL_FROM_DATABASE=bq Aquaris E4.5 ++ ++usb:v2A47p201D* ++ ID_MODEL_FROM_DATABASE=Tablet Edison 3 ++ ++usb:v2A47p903A* ++ ID_MODEL_FROM_DATABASE=bq Aquaris U ++ ++usb:v2A4B* ++ ID_VENDOR_FROM_DATABASE=EMULEX Corporation ++ ++usb:v2A4Bp0400* ++ ID_MODEL_FROM_DATABASE=Pilot4 Integrated Hub ++ ++usb:v2A62* ++ ID_VENDOR_FROM_DATABASE=Flymaster Avionics ++ ++usb:v2A62pB301* ++ ID_MODEL_FROM_DATABASE=LiveSD ++ ++usb:v2A62pB302* ++ ID_MODEL_FROM_DATABASE=NavSD ++ ++usb:v2A6E* ++ ID_VENDOR_FROM_DATABASE=Bare Conductive ++ ++usb:v2A6Ep0003* ++ ID_MODEL_FROM_DATABASE=Touch Board ++ ++usb:v2A6Ep8003* ++ ID_MODEL_FROM_DATABASE=Touch Board ++ ++usb:v2A70* ++ ID_VENDOR_FROM_DATABASE=OnePlus Technology (Shenzhen) Co., Ltd. ++ ++usb:v2A70p4EE7* ++ ID_MODEL_FROM_DATABASE=ONEPLUS A3010 [OnePlus 3T] / A5010 [OnePlus 5T] / A6003 [OnePlus 6] (Charging + USB debugging modes) ++ ++usb:v2A70p904D* ++ ID_MODEL_FROM_DATABASE=A3000 phone (PTP mode) [3T] ++ ++usb:v2A70p904E* ++ ID_MODEL_FROM_DATABASE=A3000 phone (PTP mode, with debug) [3T] ++ ++usb:v2A88* ++ ID_VENDOR_FROM_DATABASE=DFU Technology Ltd ++ ++usb:v2A88pFFFF* ++ ID_MODEL_FROM_DATABASE=DFU ++ ++usb:v2A8D* ++ ID_VENDOR_FROM_DATABASE=Keysight Technologies, Inc. ++ ++usb:v2AB6* ++ ID_VENDOR_FROM_DATABASE=T+A elektroakustik GmbH & Co KG, Germany ++ ++usb:v2AB6p0001* ++ ID_MODEL_FROM_DATABASE=PDP3000HV DAC ++ ++usb:v2AB6p0002* ++ ID_MODEL_FROM_DATABASE=MP1000E, MP2000R, MP2500R, MP3100HV ++ ++usb:v2AB6p0003* ++ ID_MODEL_FROM_DATABASE=TA HD AUDIO V2 ++ ++usb:v2AC7* ++ ID_VENDOR_FROM_DATABASE=Ultrahaptics Ltd. ++ ++usb:v2AC7p0101* ++ ID_MODEL_FROM_DATABASE=Evaluation Kit [Dragonfly] ++ ++usb:v2AC7p0102* ++ ID_MODEL_FROM_DATABASE=UHDK5 ++ ++usb:v2AC7p0104* ++ ID_MODEL_FROM_DATABASE=Touchbase ++ ++usb:v2AC7p0110* ++ ID_MODEL_FROM_DATABASE=STRATOS Explore ++ ++usb:v2AC7p0111* ++ ID_MODEL_FROM_DATABASE=STRATOS Explore DFU ++ ++usb:v2AC7p0112* ++ ID_MODEL_FROM_DATABASE=STRATOS Inspire ++ ++usb:v2AC7p0113* ++ ID_MODEL_FROM_DATABASE=STRATOS Inspire DFU ++ ++usb:v2AC7pFFFF* ++ ID_MODEL_FROM_DATABASE=DFU ++ ++usb:v2AD1* ++ ID_VENDOR_FROM_DATABASE=Picotronic GmbH ++ ++usb:v2AD1p7AB8* ++ ID_MODEL_FROM_DATABASE=Turningtable ++ ++usb:v2AE5* ++ ID_VENDOR_FROM_DATABASE=Fairphone B.V. ++ ++usb:v2AE5p9015* ++ ID_MODEL_FROM_DATABASE=2 (Mass storage & ADB) ++ ++usb:v2AE5p9024* ++ ID_MODEL_FROM_DATABASE=2 (RNDIS & ADB) ++ ++usb:v2AE5p9039* ++ ID_MODEL_FROM_DATABASE=2 (MTP & ADB) ++ ++usb:v2AE5p904D* ++ ID_MODEL_FROM_DATABASE=2 (PTP) ++ ++usb:v2AE5p904E* ++ ID_MODEL_FROM_DATABASE=2 (PTP & ADB) ++ ++usb:v2AE5p90DE* ++ ID_MODEL_FROM_DATABASE=2 (Charging) ++ ++usb:v2AE5pF000* ++ ID_MODEL_FROM_DATABASE=2 (Mass storage) ++ ++usb:v2AE5pF003* ++ ID_MODEL_FROM_DATABASE=2 (MTP) ++ ++usb:v2AE5pF005* ++ ID_MODEL_FROM_DATABASE=2 (tethering) ++ ++usb:v2AE5pF00E* ++ ID_MODEL_FROM_DATABASE=2 (RNDIS) ++ ++usb:v2AEC* ++ ID_VENDOR_FROM_DATABASE=Ambiq Micro, Inc. ++ ++usb:v2AECp6011* ++ ID_MODEL_FROM_DATABASE=Converter ++ ++usb:v2AF4* ++ ID_VENDOR_FROM_DATABASE=ROLI Ltd. ++ ++usb:v2AF4p0100* ++ ID_MODEL_FROM_DATABASE=Seaboard GRAND ++ ++usb:v2AF4p0200* ++ ID_MODEL_FROM_DATABASE=Seaboard RISE ++ ++usb:v2AF4p0300* ++ ID_MODEL_FROM_DATABASE=BlueWing Proto ++ ++usb:v2AF4p0400* ++ ID_MODEL_FROM_DATABASE=VOICE ++ ++usb:v2AF4p0500* ++ ID_MODEL_FROM_DATABASE=BLOCKS ++ ++usb:v2B03* ++ ID_VENDOR_FROM_DATABASE=STEREOLABS ++ ++usb:v2B03pF580* ++ ID_MODEL_FROM_DATABASE=ZED camera ++ ++usb:v2B03pF582* ++ ID_MODEL_FROM_DATABASE=ZED camera ++ ++usb:v2B03pF680* ++ ID_MODEL_FROM_DATABASE=ZED-M camera ++ ++usb:v2B03pF681* ++ ID_MODEL_FROM_DATABASE=ZED-M HID Interface ++ ++usb:v2B03pF682* ++ ID_MODEL_FROM_DATABASE=ZED-M camera ++ ++usb:v2B03pF683* ++ ID_MODEL_FROM_DATABASE=ZED-M HID Interface ++ ++usb:v2B03pF684* ++ ID_MODEL_FROM_DATABASE=ZED-M camera ++ ++usb:v2B0E* ++ ID_VENDOR_FROM_DATABASE=LeEco ++ ++usb:v2B0Ep171B* ++ ID_MODEL_FROM_DATABASE=Le2 ++ ++usb:v2B0Ep171E* ++ ID_MODEL_FROM_DATABASE=Le2 in USB tethering mode ++ ++usb:v2B0Ep1830* ++ ID_MODEL_FROM_DATABASE=Le1 Pro ++ ++usb:v2B0Ep1844* ++ ID_MODEL_FROM_DATABASE=Le Max2 ++ ++usb:v2B0Ep2B0E* ++ ID_MODEL_FROM_DATABASE=LeEco ++ ++usb:v2B0Ep6108* ++ ID_MODEL_FROM_DATABASE=Lex720 [LePro 3] in connection sharing usb ++ ++usb:v2B0Ep610B* ++ ID_MODEL_FROM_DATABASE=Lex720 [LePro 3] in Camera mode ++ ++usb:v2B0Ep610C* ++ ID_MODEL_FROM_DATABASE=Lex720 [LePro 3] ++ ++usb:v2B0Ep610D* ++ ID_MODEL_FROM_DATABASE=Lex720 [LePro 3] in debug ++ ++usb:v2B23* ++ ID_VENDOR_FROM_DATABASE=Red Hat, Inc. ++ ++usb:v2B23pCAFE* ++ ID_MODEL_FROM_DATABASE=UsbDk (USB Development Kit) ++ + usb:v2B24* + ID_VENDOR_FROM_DATABASE=KeepKey LLC + + usb:v2B24p0001* +- ID_MODEL_FROM_DATABASE=Bitcoin hardware wallet ++ ID_MODEL_FROM_DATABASE=Bitcoin Wallet [KeepKey] ++ ++usb:v2B24p0002* ++ ID_MODEL_FROM_DATABASE=Bitcoin Wallet ++ ++usb:v2B3E* ++ ID_VENDOR_FROM_DATABASE=NewAE Technology Inc. ++ ++usb:v2B3EpACE2* ++ ID_MODEL_FROM_DATABASE=CW1173 [ChipWhisperer-Lite] ++ ++usb:v2B4C* ++ ID_VENDOR_FROM_DATABASE=ZUK ++ ++usb:v2B4Cp1004* ++ ID_MODEL_FROM_DATABASE=Z1 MTP ++ ++usb:v2BC5* ++ ID_VENDOR_FROM_DATABASE=Orbbec 3D Technology International, Inc ++ ++usb:v2BC5p0401* ++ ID_MODEL_FROM_DATABASE=Astra ++ ++usb:v2BC5p0403* ++ ID_MODEL_FROM_DATABASE=Astra Pro ++ ++usb:v2BC5p0407* ++ ID_MODEL_FROM_DATABASE=Astra Mini S ++ ++usb:v2BCC* ++ ID_VENDOR_FROM_DATABASE=InoTec GmbH Organisationssysteme ++ ++usb:v2BD6* ++ ID_VENDOR_FROM_DATABASE=Coroware, Inc. ++ ++usb:v2BD6p4201* ++ ID_MODEL_FROM_DATABASE=RS-485 Controller and Interface [Cypress Semiconductor] ++ ++usb:v2BD8* ++ ID_VENDOR_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH + + usb:v2C02* + ID_VENDOR_FROM_DATABASE=Planex Communications +@@ -56951,6 +66932,39 @@ usb:v2C1A* + usb:v2C1Ap0000* + ID_MODEL_FROM_DATABASE=Wireless Optical Mouse + ++usb:v2C23* ++ ID_VENDOR_FROM_DATABASE=Supermicro Computer Incorporated ++ ++usb:v2C23p1B83* ++ ID_MODEL_FROM_DATABASE=NIC ++ ++usb:v2C4E* ++ ID_VENDOR_FROM_DATABASE=Mercucys INC ++ ++usb:v2C4Ep0100* ++ ID_MODEL_FROM_DATABASE=MW300UM RTL8192EU wifi ++ ++usb:v2C4F* ++ ID_VENDOR_FROM_DATABASE=Canon Electronic Business Machines Co., Ltd. ++ ++usb:v2C4Fp3003* ++ ID_MODEL_FROM_DATABASE=PR Wireless Presenter ++ ++usb:v2C55* ++ ID_VENDOR_FROM_DATABASE=Magic Leap, Inc. ++ ++usb:v2C55pA100* ++ ID_MODEL_FROM_DATABASE=ML1 Lightpack (MLDB) ++ ++usb:v2C55pB100* ++ ID_MODEL_FROM_DATABASE=ML1 Lightpack (fastboot) ++ ++usb:v2C55pC001* ++ ID_MODEL_FROM_DATABASE=ML1 Control (COM) ++ ++usb:v2C55pC002* ++ ID_MODEL_FROM_DATABASE=ML1 Control (Bootloader) ++ + usb:v2C7C* + ID_VENDOR_FROM_DATABASE=Quectel Wireless Solutions Co., Ltd. + +@@ -56975,15 +66989,501 @@ usb:v2C7Cp0306* + usb:v2C7Cp0435* + ID_MODEL_FROM_DATABASE=AG35 LTE modem + ++usb:v2C97* ++ ID_VENDOR_FROM_DATABASE=Ledger ++ ++usb:v2C97p0000* ++ ID_MODEL_FROM_DATABASE=Blue ++ ++usb:v2C97p0001* ++ ID_MODEL_FROM_DATABASE=Nano S ++ ++usb:v2C97p0004* ++ ID_MODEL_FROM_DATABASE=Nano X ++ ++usb:v2C99* ++ ID_VENDOR_FROM_DATABASE=Prusa ++ ++usb:v2C99p0001* ++ ID_MODEL_FROM_DATABASE=i3 MK2S ++ ++usb:v2C9C* ++ ID_VENDOR_FROM_DATABASE=Vayyar Imaging Ltd. ++ ++usb:v2C9Cp1000* ++ ID_MODEL_FROM_DATABASE=Walabot Makers Series ++ ++usb:v2C9Cp1020* ++ ID_MODEL_FROM_DATABASE=Walabot DIY ++ ++usb:v2C9Cp1022* ++ ID_MODEL_FROM_DATABASE=Walabot DIY Plus ++ ++usb:v2C9Cp1030* ++ ID_MODEL_FROM_DATABASE=Walabot Home (vHC) ++ ++usb:v2C9Cp9100* ++ ID_MODEL_FROM_DATABASE=VNAKit ++ ++usb:v2C9D* ++ ID_VENDOR_FROM_DATABASE=Nod Inc ++ ++usb:v2C9Dp90A0* ++ ID_MODEL_FROM_DATABASE=Goa ++ ++usb:v2C9DpBAC5* ++ ID_MODEL_FROM_DATABASE=Backspin ++ ++usb:v2CA3* ++ ID_VENDOR_FROM_DATABASE=DJI Technology Co., Ltd. ++ ++usb:v2CA3p0008* ++ ID_MODEL_FROM_DATABASE=Mavic Mini MR1SD25 Remote controller ++ ++usb:v2CB7* ++ ID_VENDOR_FROM_DATABASE=Fibocom ++ ++usb:v2CB7p0210* ++ ID_MODEL_FROM_DATABASE=L830-EB-00 LTE WWAN Modem ++ ++usb:v2CC0* ++ ID_VENDOR_FROM_DATABASE=Hangzhou Zero Zero Infinity Technology Co., Ltd. ++ ++usb:v2CC2* ++ ID_VENDOR_FROM_DATABASE=Lautsprecher Teufel GmbH ++ ++usb:v2CCF* ++ ID_VENDOR_FROM_DATABASE=Hypersecu ++ ++usb:v2CCFp0880* ++ ID_MODEL_FROM_DATABASE=HyperFIDO ++ ++usb:v2CD9* ++ ID_VENDOR_FROM_DATABASE=Cambrionix Ltd ++ ++usb:v2CD9p0804* ++ ID_MODEL_FROM_DATABASE=PowerSync4 USBPD Hub ++ ++usb:v2CDC* ++ ID_VENDOR_FROM_DATABASE=Sea & Sun Technology GmbH ++ ++usb:v2CDCpF232* ++ ID_MODEL_FROM_DATABASE=CTD48Mc CTD Probe ++ ++usb:v2CE5* ++ ID_VENDOR_FROM_DATABASE=InX8 Inc [AKiTiO] ++ ++usb:v2CE5p0014* ++ ID_MODEL_FROM_DATABASE=Mass Storage [NT2 U31C] ++ ++usb:v2CF0* ++ ID_VENDOR_FROM_DATABASE=Nuand LLC ++ ++usb:v2CF0p5246* ++ ID_MODEL_FROM_DATABASE=bladeRF ++ ++usb:v2CF0p5250* ++ ID_MODEL_FROM_DATABASE=bladeRF 2.0 micro ++ ++usb:v2D1F* ++ ID_VENDOR_FROM_DATABASE=Wacom Taiwan Information Co. Ltd. ++ ++usb:v2D25* ++ ID_VENDOR_FROM_DATABASE=Kronegger GmbH. ++ ++usb:v2D2D* ++ ID_VENDOR_FROM_DATABASE=proxmark.org ++ ++usb:v2D2Dp504D* ++ ID_MODEL_FROM_DATABASE=Proxmark3 ++ ++usb:v2D37* ++ ID_VENDOR_FROM_DATABASE=Zhuhai Poskey Technology Co.,Ltd ++ ++usb:v2D6B* ++ ID_VENDOR_FROM_DATABASE=NetUP Inc. ++ ++usb:v2D6Bp7777* ++ ID_MODEL_FROM_DATABASE=Joker TV universal DTV receiver ++ ++usb:v2D81* ++ ID_VENDOR_FROM_DATABASE=Evollve Inc. ++ ++usb:v2D81p4F01* ++ ID_MODEL_FROM_DATABASE=Ozobot Evo ++ ++usb:v2D84* ++ ID_VENDOR_FROM_DATABASE=Zhuhai Poskey Technology Co.,Ltd ++ ++usb:v2D84pB806* ++ ID_MODEL_FROM_DATABASE=DT-108B Thermal Label Printer ++ ++usb:v2DC8* ++ ID_VENDOR_FROM_DATABASE=8BitDo ++ ++usb:v2DC8p5006* ++ ID_MODEL_FROM_DATABASE=M30 Bluetooth gamepad ++ ++usb:v2DC8p5750* ++ ID_MODEL_FROM_DATABASE=Bootloader ++ ++usb:v2DC8p6000* ++ ID_MODEL_FROM_DATABASE=SF30 Pro gamepad ++ ++usb:v2DC8p6001* ++ ID_MODEL_FROM_DATABASE=SN30/SF30 Pro gamepad ++ ++usb:v2DC8pAB11* ++ ID_MODEL_FROM_DATABASE=F30 gamepad ++ ++usb:v2DC8pAB12* ++ ID_MODEL_FROM_DATABASE=N30 gamepad ++ ++usb:v2DC8pAB20* ++ ID_MODEL_FROM_DATABASE=SN30/SF30 gamepad ++ ++usb:v2DC8pAB21* ++ ID_MODEL_FROM_DATABASE=SF30 gamepad ++ + usb:v2DCF* + ID_VENDOR_FROM_DATABASE=Dialog Semiconductor + ++usb:v2DCFpC951* ++ ID_MODEL_FROM_DATABASE=Audio Class 1.0 Devices ++ + usb:v2DCFpC952* + ID_MODEL_FROM_DATABASE=Audio Class 2.0 Devices + ++usb:v2DEF* ++ ID_VENDOR_FROM_DATABASE=Kirale Technologies ++ ++usb:v2DEFp0000* ++ ID_MODEL_FROM_DATABASE=KiNOS Boot DFU ++ ++usb:v2DEFp0102* ++ ID_MODEL_FROM_DATABASE=KTWM102 Module ++ ++usb:v2DF2* ++ ID_VENDOR_FROM_DATABASE=LIPS Corporation ++ ++usb:v2DF2p0213* ++ ID_MODEL_FROM_DATABASE=LIPSedge DL 3D ToF Camera ++ ++usb:v2DF2p0215* ++ ID_MODEL_FROM_DATABASE=LIPSedge DL RGB Camera ++ ++usb:v2DF2p2102* ++ ID_MODEL_FROM_DATABASE=LIPSedge 5 Megapixel RGB Camera ++ ++usb:v2E04* ++ ID_VENDOR_FROM_DATABASE=HMD Global ++ ++usb:v2E04p0001* ++ ID_MODEL_FROM_DATABASE=Nokia 3310 3G ++ ++usb:v2E04p0002* ++ ID_MODEL_FROM_DATABASE=Nokia 3310 3G ++ ++usb:v2E04p0A14* ++ ID_MODEL_FROM_DATABASE=Nokia 3310 3G ++ ++usb:v2E04pC008* ++ ID_MODEL_FROM_DATABASE=Tethering Network Interface ++ ++usb:v2E04pC009* ++ ID_MODEL_FROM_DATABASE=Nokia 1 (bootloader) ++ ++usb:v2E04pC025* ++ ID_MODEL_FROM_DATABASE=Nokia 8 (MTP mode) ++ ++usb:v2E04pC026* ++ ID_MODEL_FROM_DATABASE=Nokia Smartphone ++ ++usb:v2E04pC029* ++ ID_MODEL_FROM_DATABASE=Nokia 8 (PTP mode) ++ ++usb:v2E04pC031* ++ ID_MODEL_FROM_DATABASE=Nokia 1 (PTP) ++ ++usb:v2E04pC03F* ++ ID_MODEL_FROM_DATABASE=Nokia 8 (MIDI mode) ++ ++usb:v2E0E* ++ ID_VENDOR_FROM_DATABASE=Hatteland Display AS ++ ++usb:v2E0Ep0001* ++ ID_MODEL_FROM_DATABASE=CAN Gateway ++ ++usb:v2E24* ++ ID_VENDOR_FROM_DATABASE=Hyperkin ++ ++usb:v2E24p0652* ++ ID_MODEL_FROM_DATABASE=Duke Xbox One controller ++ ++usb:v2E24p1688* ++ ID_MODEL_FROM_DATABASE=X91 Xbox One controller ++ ++usb:v2E3B* ++ ID_VENDOR_FROM_DATABASE=uSens Inc. ++ ++usb:v2E57* ++ ID_VENDOR_FROM_DATABASE=MEGWARE Computer Vertrieb und Service GmbH ++ ++usb:v2E57p454D* ++ ID_MODEL_FROM_DATABASE=SlideSX EnergyMeter ++ ++usb:v2E57p454E* ++ ID_MODEL_FROM_DATABASE=SlideSX EnergyMeter DFU ++ ++usb:v2E57p5CBA* ++ ID_MODEL_FROM_DATABASE=SlideSX / ClustSafe Bus Adapter ++ ++usb:v2E69* ++ ID_VENDOR_FROM_DATABASE=Swift Navigation ++ ++usb:v2E69p1001* ++ ID_MODEL_FROM_DATABASE=Piksi Multi ++ ++usb:v2E95* ++ ID_VENDOR_FROM_DATABASE=SCUF Gaming ++ ++usb:v2E95p7725* ++ ID_MODEL_FROM_DATABASE=Controller ++ ++usb:v2F76* ++ ID_VENDOR_FROM_DATABASE=KeyXentic Inc. ++ ++usb:v2F76p0905* ++ ID_MODEL_FROM_DATABASE=KX905 Smart Terminal ++ ++usb:v2F76p0906* ++ ID_MODEL_FROM_DATABASE=KX906 Smart Card Reader ++ ++usb:v2F76p1906* ++ ID_MODEL_FROM_DATABASE=KX906 Smart Token (Mass Storage) ++ ++usb:v2FAD* ++ ID_VENDOR_FROM_DATABASE=Definium Technologies ++ ++usb:v2FB0* ++ ID_VENDOR_FROM_DATABASE=Infocrypt ++ + usb:v2FB2* + ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd + ++usb:v2FC0* ++ ID_VENDOR_FROM_DATABASE=Sensidyne, LP ++ ++usb:v2FC0p0001* ++ ID_MODEL_FROM_DATABASE=Project Archer ++ ++usb:v2FC6* ++ ID_VENDOR_FROM_DATABASE=Comtrue Inc. ++ ++usb:v2FC6p6012* ++ ID_MODEL_FROM_DATABASE=UAC2 Device GB ++ ++usb:v2FE0* ++ ID_VENDOR_FROM_DATABASE=Xaptum, Inc. ++ ++usb:v2FE0p8B01* ++ ID_MODEL_FROM_DATABASE=XAP-RC-001 ENF Router Card ++ ++usb:v2FE0p8B02* ++ ID_MODEL_FROM_DATABASE=XAP-RW-001 ENF Router Card with WiFi ++ ++usb:v2FE0p8BDE* ++ ID_MODEL_FROM_DATABASE=XAP-EA-002 ENF Access Card ++ ++usb:v2FE0p8BEE* ++ ID_MODEL_FROM_DATABASE=XAP-EA-003 ENF Access Card ++ ++usb:v2FE3* ++ ID_VENDOR_FROM_DATABASE=NordicSemiconductor ++ ++usb:v2FE7* ++ ID_VENDOR_FROM_DATABASE=ELGIN S.A. ++ ++usb:v2FE7p0001* ++ ID_MODEL_FROM_DATABASE=SMART S@T ++ ++usb:v2FEB* ++ ID_VENDOR_FROM_DATABASE=Beijing Veikk E-Commerce Co., Ltd. ++ ++usb:v2FEBp0004* ++ ID_MODEL_FROM_DATABASE=Veikk A15 Pen Tablet ++ ++usb:v2FF4* ++ ID_VENDOR_FROM_DATABASE=Quixant Plc ++ ++usb:v3016* ++ ID_VENDOR_FROM_DATABASE=Boundary Devices, LLC ++ ++usb:v3016p0001* ++ ID_MODEL_FROM_DATABASE=Nitrogen Bootloader ++ ++usb:v3036* ++ ID_VENDOR_FROM_DATABASE=Control iD ++ ++usb:v3036p0001* ++ ID_MODEL_FROM_DATABASE=Print iD ++ ++usb:v3036p0002* ++ ID_MODEL_FROM_DATABASE=iDBio ++ ++usb:v3037* ++ ID_VENDOR_FROM_DATABASE=Beijing Chushifengmang Technology Development Co.,Ltd. ++ ++usb:v3057* ++ ID_VENDOR_FROM_DATABASE=Kingsis Corporation ++ ++usb:v3057p0002* ++ ID_MODEL_FROM_DATABASE=ZOWIE Gaming mouse ++ ++usb:v308F* ++ ID_VENDOR_FROM_DATABASE=Input Club ++ ++usb:v308Fp0000* ++ ID_MODEL_FROM_DATABASE=Infinity 60% Bootloader ++ ++usb:v308Fp0001* ++ ID_MODEL_FROM_DATABASE=Infinity 60% - Standard ++ ++usb:v308Fp0002* ++ ID_MODEL_FROM_DATABASE=Infinity 60% - Hacker ++ ++usb:v308Fp0003* ++ ID_MODEL_FROM_DATABASE=Infinity Ergodox Bootloader ++ ++usb:v308Fp0004* ++ ID_MODEL_FROM_DATABASE=Infinity Ergodox ++ ++usb:v308Fp0005* ++ ID_MODEL_FROM_DATABASE=WhiteFox Bootloader ++ ++usb:v308Fp0006* ++ ID_MODEL_FROM_DATABASE=WhiteFox - Vanilla ++ ++usb:v308Fp0007* ++ ID_MODEL_FROM_DATABASE=WhiteFox - ISO ++ ++usb:v308Fp0008* ++ ID_MODEL_FROM_DATABASE=WhiteFox - Aria ++ ++usb:v308Fp0009* ++ ID_MODEL_FROM_DATABASE=WhiteFox - Winkeyless ++ ++usb:v308Fp000A* ++ ID_MODEL_FROM_DATABASE=WhiteFox - True Fox ++ ++usb:v308Fp000B* ++ ID_MODEL_FROM_DATABASE=WhiteFox - Jack of All Trades ++ ++usb:v308Fp000C* ++ ID_MODEL_FROM_DATABASE=Infinity 60% LED Bootloader ++ ++usb:v308Fp000D* ++ ID_MODEL_FROM_DATABASE=Infinity 60% LED - Standard ++ ++usb:v308Fp000E* ++ ID_MODEL_FROM_DATABASE=Infinity 60% LED - Hacker ++ ++usb:v308Fp000F* ++ ID_MODEL_FROM_DATABASE=Infinity 60% LED - Alphabet ++ ++usb:v308Fp0010* ++ ID_MODEL_FROM_DATABASE=K-Type Bootloader ++ ++usb:v308Fp0011* ++ ID_MODEL_FROM_DATABASE=K-Type ++ ++usb:v308Fp0012* ++ ID_MODEL_FROM_DATABASE=Kira Bootloader ++ ++usb:v308Fp0013* ++ ID_MODEL_FROM_DATABASE=Kira ++ ++usb:v308Fp0014* ++ ID_MODEL_FROM_DATABASE=Gemini Dawn/Dusk Bootloader ++ ++usb:v308Fp0015* ++ ID_MODEL_FROM_DATABASE=Gemini Dawn/Dusk ++ ++usb:v308Fp0016* ++ ID_MODEL_FROM_DATABASE=Re:Type Bootloader ++ ++usb:v308Fp0017* ++ ID_MODEL_FROM_DATABASE=Re:Type ++ ++usb:v308Fp0018* ++ ID_MODEL_FROM_DATABASE=Re:Type USB Hub ++ ++usb:v308Fp0019* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) Bootloader ++ ++usb:v308Fp001A* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - Vanilla ++ ++usb:v308Fp001B* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - ISO ++ ++usb:v308Fp001C* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - Aria ++ ++usb:v308Fp001D* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - Winkeyless ++ ++usb:v308Fp001E* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - True Fox ++ ++usb:v308Fp001F* ++ ID_MODEL_FROM_DATABASE=WhiteFox (SAM4S) - Jack of All Trades ++ ++usb:v30A4* ++ ID_VENDOR_FROM_DATABASE=Blues Wireless ++ ++usb:v30A4p0001* ++ ID_MODEL_FROM_DATABASE=Notecard ++ ++usb:v30C2* ++ ID_VENDOR_FROM_DATABASE=UNPARALLEL Innovation, Lda ++ ++usb:v30C2p1388* ++ ID_MODEL_FROM_DATABASE=SPL Meter ++ ++usb:v30C9* ++ ID_VENDOR_FROM_DATABASE=Luxvisions Innotech Limited ++ ++usb:v30EE* ++ ID_VENDOR_FROM_DATABASE=Fujitsu Connected Technologies Limited ++ ++usb:v30EEp1001* ++ ID_MODEL_FROM_DATABASE=F-01L ++ ++usb:v30F2* ++ ID_VENDOR_FROM_DATABASE=Varex Imaging ++ ++usb:v3111* ++ ID_VENDOR_FROM_DATABASE=Hiperscan GmbH ++ ++usb:v3111p0000* ++ ID_MODEL_FROM_DATABASE=SGS-NT Microspectrometer ++ ++usb:v3112* ++ ID_VENDOR_FROM_DATABASE=Meteca SA ++ ++usb:v3112p0001* ++ ID_MODEL_FROM_DATABASE=MBC-WB01 (CDC-ACM) ++ ++usb:v3112p0002* ++ ID_MODEL_FROM_DATABASE=MBC-WB01 (Bootloader) ++ ++usb:v3112p0003* ++ ID_MODEL_FROM_DATABASE=ABC (CDC ACM) ++ ++usb:v3112p0004* ++ ID_MODEL_FROM_DATABASE=ABC (Bootloader) ++ + usb:v3125* + ID_VENDOR_FROM_DATABASE=Eagletron + +@@ -56993,6 +67493,45 @@ usb:v3125p0001* + usb:v3136* + ID_VENDOR_FROM_DATABASE=Navini Networks + ++usb:v3145* ++ ID_VENDOR_FROM_DATABASE=SafeLogic Inc. ++ ++usb:v3147* ++ ID_VENDOR_FROM_DATABASE=Tanvas, Inc. ++ ++usb:v316C* ++ ID_VENDOR_FROM_DATABASE=SigmaSense, LLC ++ ++usb:v316D* ++ ID_VENDOR_FROM_DATABASE=Purism, SPC ++ ++usb:v316Dp4C4B* ++ ID_MODEL_FROM_DATABASE=Librem Key ++ ++usb:v316E* ++ ID_VENDOR_FROM_DATABASE=SPECINFOSYSTEMS ++ ++usb:v316Ep0001* ++ ID_MODEL_FROM_DATABASE=DIAMOND token ++ ++usb:v3171* ++ ID_VENDOR_FROM_DATABASE=8086 Consultancy ++ ++usb:v3171p0011* ++ ID_MODEL_FROM_DATABASE=ClusterCTRL DA ++ ++usb:v3171p0012* ++ ID_MODEL_FROM_DATABASE=ClusterCTRL pHAT ++ ++usb:v3171p0013* ++ ID_MODEL_FROM_DATABASE=ClusterCTRL A+6 ++ ++usb:v3171p0014* ++ ID_MODEL_FROM_DATABASE=ClusterCTRL Triple ++ ++usb:v3171p0015* ++ ID_MODEL_FROM_DATABASE=ClusterCTRL Single ++ + usb:v3176* + ID_VENDOR_FROM_DATABASE=Whanam Electronics Co., Ltd + +@@ -57008,12 +67547,75 @@ usb:v3195pF280* + usb:v3195pF281* + ID_MODEL_FROM_DATABASE=MSO-28 + ++usb:v31C9* ++ ID_VENDOR_FROM_DATABASE=BeiJing LanXum Computer Technology Co., Ltd. ++ ++usb:v31C9p1001* ++ ID_MODEL_FROM_DATABASE=Printer ++ ++usb:v31C9p1301* ++ ID_MODEL_FROM_DATABASE=Black and White Laser Printer ++ ++usb:v31C9p1501* ++ ID_MODEL_FROM_DATABASE=LaserPrint GA50 series ++ ++usb:v3200* ++ ID_VENDOR_FROM_DATABASE=Alcatel-Lucent Enterprise ++ ++usb:v3200p2100* ++ ID_MODEL_FROM_DATABASE=ALE 8058s ++ ++usb:v3200p2101* ++ ID_MODEL_FROM_DATABASE=ALE 8068s ++ ++usb:v3200p2102* ++ ID_MODEL_FROM_DATABASE=8078s ++ ++usb:v3219* ++ ID_VENDOR_FROM_DATABASE=Smak Tecnologia e Automacao LTDA ++ ++usb:v3219p0044* ++ ID_MODEL_FROM_DATABASE=SKO44 Optical Keyboard ++ ++usb:v321C* ++ ID_VENDOR_FROM_DATABASE=Premio, Inc. ++ ++usb:v324C* ++ ID_VENDOR_FROM_DATABASE=CUPRIS Ltd. ++ ++usb:v326D* ++ ID_VENDOR_FROM_DATABASE=Agile Display Solutions Co., Ltd ++ ++usb:v326Dp0001* ++ ID_MODEL_FROM_DATABASE=Avocor USB Camera ++ + usb:v3275* + ID_VENDOR_FROM_DATABASE=VidzMedia Pte Ltd + + usb:v3275p4FB1* + ID_MODEL_FROM_DATABASE=MonsterTV P2H + ++usb:v3293* ++ ID_VENDOR_FROM_DATABASE=Unhuman Inc. ++ ++usb:v32B3* ++ ID_VENDOR_FROM_DATABASE=TEXA ++ ++usb:v32B3pD1A6* ++ ID_MODEL_FROM_DATABASE=TXT Multihub ++ ++usb:v32B3pD1A7* ++ ID_MODEL_FROM_DATABASE=TXT Multihub ++ ++usb:v3310* ++ ID_VENDOR_FROM_DATABASE=MUDITA Sp. z o.o. ++ ++usb:v3310p0100* ++ ID_MODEL_FROM_DATABASE=Pure ++ ++usb:v3310p0101* ++ ID_MODEL_FROM_DATABASE=Pure tethering ++ + usb:v3333* + ID_VENDOR_FROM_DATABASE=InLine + +@@ -57038,12 +67640,30 @@ usb:v3340p0E3A* + usb:v3340pA0A3* + ID_MODEL_FROM_DATABASE=deltaX 5 BT (D) PDA + ++usb:v3340pFFFF* ++ ID_MODEL_FROM_DATABASE=Mio DigiWalker Sync ++ + usb:v3344* + ID_VENDOR_FROM_DATABASE=Leaguer Microelectronics (LME) + + usb:v3344p3744* + ID_MODEL_FROM_DATABASE=OEM PC Remote + ++usb:v3384* ++ ID_VENDOR_FROM_DATABASE=System76 ++ ++usb:v3384p0000* ++ ID_MODEL_FROM_DATABASE=Thelio Io (thelio-io) ++ ++usb:v3384p0001* ++ ID_MODEL_FROM_DATABASE=Launch Configurable Keyboard (launch_1) ++ ++usb:v348F* ++ ID_VENDOR_FROM_DATABASE=ISY ++ ++usb:v348Fp2322* ++ ID_MODEL_FROM_DATABASE=Wireless Presenter ++ + usb:v3504* + ID_VENDOR_FROM_DATABASE=Micro Star + +@@ -57068,6 +67688,9 @@ usb:v3538p0042* + usb:v3538p0054* + ID_MODEL_FROM_DATABASE=Flash Drive (2GB) + ++usb:v3538p0901* ++ ID_MODEL_FROM_DATABASE=Traveling Disk U273 (4GB) ++ + usb:v3579* + ID_VENDOR_FROM_DATABASE=DIVA + +@@ -57078,17 +67701,26 @@ usb:v357D* + ID_VENDOR_FROM_DATABASE=Sharkoon + + usb:v357Dp7788* +- ID_MODEL_FROM_DATABASE=QuickPort XT ++ ID_MODEL_FROM_DATABASE=JMicron JMS567 ATA/ATAPI Bridge + + usb:v3636* + ID_VENDOR_FROM_DATABASE=InVibro + ++usb:v3767* ++ ID_VENDOR_FROM_DATABASE=Fanatec ++ ++usb:v3767p0101* ++ ID_MODEL_FROM_DATABASE=Speedster 3 Forceshock Wheel ++ + usb:v3838* + ID_VENDOR_FROM_DATABASE=WEM + + usb:v3838p0001* + ID_MODEL_FROM_DATABASE=5-in-1 Card Reader + ++usb:v3838p1031* ++ ID_MODEL_FROM_DATABASE=2.4G Wireless Mouse ++ + usb:v3923* + ID_VENDOR_FROM_DATABASE=National Instruments Corp. + +@@ -57140,21 +67772,75 @@ usb:v3923p2F80* + usb:v3923p2F90* + ID_MODEL_FROM_DATABASE=DAQPad-6052E + +-usb:v3923p702B* ++usb:v3923p702A* + ID_MODEL_FROM_DATABASE=GPIB-USB-B + ++usb:v3923p702B* ++ ID_MODEL_FROM_DATABASE=GPIB-USB-B Initialization ++ + usb:v3923p703C* + ID_MODEL_FROM_DATABASE=USB-485 RS485 Cable + + usb:v3923p709B* + ID_MODEL_FROM_DATABASE=GPIB-USB-HS + ++usb:v3923p7166* ++ ID_MODEL_FROM_DATABASE=USB-8451 ++ ++usb:v3923p716E* ++ ID_MODEL_FROM_DATABASE=USB-8451 Firmware Loader ++ ++usb:v3923p717A* ++ ID_MODEL_FROM_DATABASE=USB-6008 ++ ++usb:v3923p717B* ++ ID_MODEL_FROM_DATABASE=USB-6009 ++ ++usb:v3923p71D6* ++ ID_MODEL_FROM_DATABASE=USB-6008 OEM ++ ++usb:v3923p71D7* ++ ID_MODEL_FROM_DATABASE=USB-6009 OEM ++ ++usb:v3923p71D8* ++ ID_MODEL_FROM_DATABASE=USB-6009 OEM ++ + usb:v3923p7254* + ID_MODEL_FROM_DATABASE=NI MIO (data acquisition card) firmware updater + + usb:v3923p729E* + ID_MODEL_FROM_DATABASE=USB-6251 (OEM) data acquisition card + ++usb:v3923p7346* ++ ID_MODEL_FROM_DATABASE=USB-6229 ++ ++usb:v3923p755B* ++ ID_MODEL_FROM_DATABASE=myDAQ ++ ++usb:v3923p76AF* ++ ID_MODEL_FROM_DATABASE=USB-6000 ++ ++usb:v3923p76B0* ++ ID_MODEL_FROM_DATABASE=USB-6000 OEM ++ ++usb:v3923p76BF* ++ ID_MODEL_FROM_DATABASE=USB-6001 ++ ++usb:v3923p76C0* ++ ID_MODEL_FROM_DATABASE=USB-6001 OEM ++ ++usb:v3923p76C4* ++ ID_MODEL_FROM_DATABASE=USB-6002 ++ ++usb:v3923p76C5* ++ ID_MODEL_FROM_DATABASE=USB-6002 OEM ++ ++usb:v3923p76C6* ++ ID_MODEL_FROM_DATABASE=USB-6003 ++ ++usb:v3923p76C7* ++ ID_MODEL_FROM_DATABASE=USB-6003 OEM ++ + usb:v40BB* + ID_VENDOR_FROM_DATABASE=I-O Data + +@@ -57267,7 +67953,7 @@ usb:v413Cp2002* + ID_MODEL_FROM_DATABASE=SK-8125 Keyboard + + usb:v413Cp2003* +- ID_MODEL_FROM_DATABASE=Keyboard ++ ID_MODEL_FROM_DATABASE=Keyboard SK-8115 + + usb:v413Cp2005* + ID_MODEL_FROM_DATABASE=RT7D50 Keyboard +@@ -57282,17 +67968,32 @@ usb:v413Cp2100* + ID_MODEL_FROM_DATABASE=SK-3106 Keyboard + + usb:v413Cp2101* +- ID_MODEL_FROM_DATABASE=SmartCard Reader Keyboard ++ ID_MODEL_FROM_DATABASE=SK-3205 SmartCard Reader Keyboard + + usb:v413Cp2105* + ID_MODEL_FROM_DATABASE=Model L100 Keyboard + + usb:v413Cp2106* +- ID_MODEL_FROM_DATABASE=Dell QuietKey Keyboard ++ ID_MODEL_FROM_DATABASE=QuietKey Keyboard ++ ++usb:v413Cp2107* ++ ID_MODEL_FROM_DATABASE=KB212-B Quiet Key Keyboard ++ ++usb:v413Cp2113* ++ ID_MODEL_FROM_DATABASE=KB216 Wired Keyboard ++ ++usb:v413Cp2134* ++ ID_MODEL_FROM_DATABASE=Hub of E-Port Replicator ++ ++usb:v413Cp21D7* ++ ID_MODEL_FROM_DATABASE=Dell Wireless 5560 HSPA+ Mobile Broadband Modem + + usb:v413Cp2500* + ID_MODEL_FROM_DATABASE=DRAC4 Remote Access Card + ++usb:v413Cp2501* ++ ID_MODEL_FROM_DATABASE=Keyboard and mouse dongle ++ + usb:v413Cp2513* + ID_MODEL_FROM_DATABASE=internal USB Hub of E-Port Replicator + +@@ -57305,6 +68006,12 @@ usb:v413Cp3012* + usb:v413Cp3016* + ID_MODEL_FROM_DATABASE=Optical 5-Button Wheel Mouse + ++usb:v413Cp301A* ++ ID_MODEL_FROM_DATABASE=Dell MS116 Optical Mouse ++ ++usb:v413Cp301B* ++ ID_MODEL_FROM_DATABASE=Universal Bluetooth Receiver ++ + usb:v413Cp3200* + ID_MODEL_FROM_DATABASE=Mouse + +@@ -57383,6 +68090,9 @@ usb:v413Cp5124* + usb:v413Cp5128* + ID_MODEL_FROM_DATABASE=Photo AIO 928 + ++usb:v413Cp5133* ++ ID_MODEL_FROM_DATABASE=968 AIO Printer ++ + usb:v413Cp5200* + ID_MODEL_FROM_DATABASE=Laser Printer + +@@ -57407,6 +68117,9 @@ usb:v413Cp5225* + usb:v413Cp5226* + ID_MODEL_FROM_DATABASE=Printing Support + ++usb:v413Cp5228* ++ ID_MODEL_FROM_DATABASE=Laser Printer 1720dn ++ + usb:v413Cp5300* + ID_MODEL_FROM_DATABASE=Laser Printer + +@@ -57416,18 +68129,30 @@ usb:v413Cp5400* + usb:v413Cp5401* + ID_MODEL_FROM_DATABASE=Laser Printer + ++usb:v413Cp5404* ++ ID_MODEL_FROM_DATABASE=1250c Color Printer ++ + usb:v413Cp5513* + ID_MODEL_FROM_DATABASE=WLA3310 Wireless Adapter [Intersil ISL3887] + ++usb:v413Cp5534* ++ ID_MODEL_FROM_DATABASE=Hub of E-Port Replicator ++ + usb:v413Cp5601* + ID_MODEL_FROM_DATABASE=Laser Printer 3100cn + + usb:v413Cp5602* + ID_MODEL_FROM_DATABASE=Laser Printer 3000cn + ++usb:v413Cp5607* ++ ID_MODEL_FROM_DATABASE=MFP Color Laser Printer 3115cn ++ + usb:v413Cp5631* + ID_MODEL_FROM_DATABASE=Laser Printer 5100cn + ++usb:v413Cp564A* ++ ID_MODEL_FROM_DATABASE=C1765 series Multifunction Color LaserPrinter, Scanner & Copier ++ + usb:v413Cp5905* + ID_MODEL_FROM_DATABASE=Printing Support + +@@ -57530,6 +68255,9 @@ usb:v413Cp8140* + usb:v413Cp8142* + ID_MODEL_FROM_DATABASE=Mobile 360 in DFU + ++usb:v413Cp8143* ++ ID_MODEL_FROM_DATABASE=Broadcom BCM20702A0 Bluetooth ++ + usb:v413Cp8147* + ID_MODEL_FROM_DATABASE=F3507g Mobile Broadband Module + +@@ -57572,9 +68300,30 @@ usb:v413Cp8186* + usb:v413Cp8187* + ID_MODEL_FROM_DATABASE=DW375 Bluetooth Module + ++usb:v413Cp818E* ++ ID_MODEL_FROM_DATABASE=DW5560 miniPCIe HSPA+ Mobile Broadband Modem ++ ++usb:v413Cp8197* ++ ID_MODEL_FROM_DATABASE=BCM20702A0 Bluetooth Module ++ ++usb:v413Cp81A0* ++ ID_MODEL_FROM_DATABASE=Wireless 5808 Mobile Broadband (Sierra Wireless MC7355 Mini PCIE, 4G UMTS,HSDPA,HSPA+,LTE,1xRTT,EVDO Rev A,GSM,GPRS) ++ ++usb:v413Cp81A3* ++ ID_MODEL_FROM_DATABASE=Hub of E-Port Replicator ++ ++usb:v413Cp81A8* ++ ID_MODEL_FROM_DATABASE=Wireless 5808 Mobile Broadband (Sierra Wireless Mini PCIE, 4G UMTS,HSDPA,HSPA+,LTE,1xRTT,EVDO Rev A,GSM,GPRS) ++ + usb:v413Cp8501* + ID_MODEL_FROM_DATABASE=Bluetooth Adapter + ++usb:v413Cp9001* ++ ID_MODEL_FROM_DATABASE=ATA Bridge ++ ++usb:v413Cp9009* ++ ID_MODEL_FROM_DATABASE=Portable Device ++ + usb:v413Cp9500* + ID_MODEL_FROM_DATABASE=USB CP210x UART Bridge Controller [DW700] + +@@ -57584,9 +68333,21 @@ usb:v413CpA001* + usb:v413CpA005* + ID_MODEL_FROM_DATABASE=Internal 2.0 Hub + ++usb:v413CpA101* ++ ID_MODEL_FROM_DATABASE=Internal Dual SD Card module ++ ++usb:v413CpA102* ++ ID_MODEL_FROM_DATABASE=iDRAC Virtual NIC ++ ++usb:v413CpA503* ++ ID_MODEL_FROM_DATABASE=AC511 Sound Bar ++ + usb:v413CpA700* + ID_MODEL_FROM_DATABASE=Hub (in 1905FP LCD Monitor) + ++usb:v413CpB007* ++ ID_MODEL_FROM_DATABASE=Streak 5 Android Tablet ++ + usb:v4146* + ID_VENDOR_FROM_DATABASE=USBest Technology + +@@ -57635,11 +68396,14 @@ usb:v4317p0711* + usb:v4317p0720* + ID_MODEL_FROM_DATABASE=Dynex DX-BUSB + ++usb:v4317p0721* ++ ID_MODEL_FROM_DATABASE=Dynex DX-EBUSB ++ + usb:v4348* + ID_VENDOR_FROM_DATABASE=WinChipHead + + usb:v4348p5523* +- ID_MODEL_FROM_DATABASE=USB->RS 232 adapter with Prolifec PL 2303 chipset ++ ID_MODEL_FROM_DATABASE=USB->RS 232 adapter with Prolific PL 2303 chipset + + usb:v4348p5537* + ID_MODEL_FROM_DATABASE=13.56Mhz RFID Card Reader and Writer +@@ -57665,6 +68429,9 @@ usb:v4670* + usb:v4670p9394* + ID_MODEL_FROM_DATABASE=Game Cube USB Memory Adaptor 64M + ++usb:v46F4* ++ ID_VENDOR_FROM_DATABASE=QEMU ++ + usb:v4752* + ID_VENDOR_FROM_DATABASE=Miditech + +@@ -57695,12 +68462,42 @@ usb:v4855p7288* + usb:v4971* + ID_VENDOR_FROM_DATABASE=SimpleTech + ++usb:v4971p1004* ++ ID_MODEL_FROM_DATABASE=Hitachi LifeStudio Desk (3.5" HDD) [w/o flash key] ++ ++usb:v4971p1013* ++ ID_MODEL_FROM_DATABASE=Touro Desk Pro ++ ++usb:v4971p1015* ++ ID_MODEL_FROM_DATABASE=Touro Desk 3.0 ++ ++usb:v4971p8001* ++ ID_MODEL_FROM_DATABASE=G-Tech G-DRIVE Mobile ++ + usb:v4971pCB01* + ID_MODEL_FROM_DATABASE=SP-U25/120G + ++usb:v4971pCD15* ++ ID_MODEL_FROM_DATABASE=Simple Drive Mini (2.5" HDD) ++ ++usb:v4971pCE07* ++ ID_MODEL_FROM_DATABASE=SimpleDrive (3.5" HDD) ++ ++usb:v4971pCE12* ++ ID_MODEL_FROM_DATABASE=FV-U35 ++ + usb:v4971pCE17* + ID_MODEL_FROM_DATABASE=1TB SimpleDrive II USB External Hard Drive + ++usb:v4971pCE18* ++ ID_MODEL_FROM_DATABASE=(re)Drive ++ ++usb:v4971pCE21* ++ ID_MODEL_FROM_DATABASE=JMicron JM20329 SATA Bridge [eg. HITACHI SimpleDrive mini] ++ ++usb:v4971pCE22* ++ ID_MODEL_FROM_DATABASE=Hitachi SimpleTough (3.5" HDD) ++ + usb:v4D46* + ID_VENDOR_FROM_DATABASE=Musical Fidelity + +@@ -57725,21 +68522,18 @@ usb:v5032p0FA0* + usb:v5032p0FA1* + ID_MODEL_FROM_DATABASE=Grandtec USB1.1 DVB-T (warm) + +-usb:v5041* +- ID_VENDOR_FROM_DATABASE=Linksys (?) +- +-usb:v5041p2234* +- ID_MODEL_FROM_DATABASE=WUSB54G v1 802.11g Adapter [Intersil ISL3886] +- +-usb:v5041p2235* +- ID_MODEL_FROM_DATABASE=WUSB54GP v1 802.11g Adapter [Intersil ISL3886] +- + usb:v50C2* + ID_VENDOR_FROM_DATABASE=Averatec (?) + + usb:v50C2p4013* + ID_MODEL_FROM_DATABASE=WLAN Adapter + ++usb:v5131* ++ ID_VENDOR_FROM_DATABASE=MSR ++ ++usb:v5131p2007* ++ ID_MODEL_FROM_DATABASE=MSR-101U Mini HID magnetic card reader ++ + usb:v5173* + ID_VENDOR_FROM_DATABASE=Sweex + +@@ -57752,6 +68546,12 @@ usb:v5219* + usb:v5219p1001* + ID_MODEL_FROM_DATABASE=Cetus CDC Device + ++usb:v5332* ++ ID_VENDOR_FROM_DATABASE=Clearly Superior Technologies, Inc. ++ ++usb:v5332p1300* ++ ID_MODEL_FROM_DATABASE=CST2545-5W (L-Trac) ++ + usb:v5345* + ID_VENDOR_FROM_DATABASE=Owon + +@@ -57764,6 +68564,18 @@ usb:v534C* + usb:v534Cp0001* + ID_MODEL_FROM_DATABASE=Bitcoin Wallet [TREZOR] + ++usb:v534Cp0002* ++ ID_MODEL_FROM_DATABASE=Bitcoin Wallet [TREZOR v2] ++ ++usb:v534D* ++ ID_VENDOR_FROM_DATABASE=MacroSilicon ++ ++usb:v534Dp0021* ++ ID_MODEL_FROM_DATABASE=MS210x Video Grabber [EasierCAP] ++ ++usb:v534Dp6021* ++ ID_MODEL_FROM_DATABASE=VGA Display Adapter ++ + usb:v5354* + ID_VENDOR_FROM_DATABASE=Meyer Instruments (MIS) + +@@ -57794,9 +68606,18 @@ usb:v5543p0041* + usb:v5543p0042* + ID_MODEL_FROM_DATABASE=Tablet PF1209 + ++usb:v5543p004A* ++ ID_MODEL_FROM_DATABASE=XP-Pen Artist 10S tablet ++ ++usb:v5543p004D* ++ ID_MODEL_FROM_DATABASE=Tablet Monitor MSP19U ++ + usb:v5543p0064* + ID_MODEL_FROM_DATABASE=Aiptek HyperPen 10000U + ++usb:v5543p3031* ++ ID_MODEL_FROM_DATABASE=Graphics tablet [DrawImage G3, Ugee G3] ++ + usb:v5555* + ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc. + +@@ -57827,6 +68648,18 @@ usb:v5555p3411* + usb:v5555p3422* + ID_MODEL_FROM_DATABASE=DVI2USB Duo + ++usb:v5555p3500* ++ ID_MODEL_FROM_DATABASE=DVI2USB3 ++ ++usb:v5555p3501* ++ ID_MODEL_FROM_DATABASE=DVI2USB3 Rev3 ++ ++usb:v5555p3510* ++ ID_MODEL_FROM_DATABASE=DVI2USB3_ET ++ ++usb:v5555p3520* ++ ID_MODEL_FROM_DATABASE=SDI2USB3 ++ + usb:v55AA* + ID_VENDOR_FROM_DATABASE=OnSpec Electronic, Inc. + +@@ -57902,6 +68735,18 @@ usb:v5986p0101* + usb:v5986p0102* + ID_MODEL_FROM_DATABASE=Crystal Eye Webcam + ++usb:v5986p0137* ++ ID_MODEL_FROM_DATABASE=HP Webcam ++ ++usb:v5986p0141* ++ ID_MODEL_FROM_DATABASE=BisonCam, NB Pro ++ ++usb:v5986p0149* ++ ID_MODEL_FROM_DATABASE=HP Webcam-101 ++ ++usb:v5986p014C* ++ ID_MODEL_FROM_DATABASE=MSI Integrated Webcam ++ + usb:v5986p01A6* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam + +@@ -57914,18 +68759,87 @@ usb:v5986p01A9* + usb:v5986p0200* + ID_MODEL_FROM_DATABASE=OrbiCam + ++usb:v5986p0202* ++ ID_MODEL_FROM_DATABASE=Fujitsu Webcam ++ + usb:v5986p0203* + ID_MODEL_FROM_DATABASE=BisonCam NB Pro 1300 + ++usb:v5986p0205* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v5986p0217* ++ ID_MODEL_FROM_DATABASE=Integrated Webcam ++ + usb:v5986p0241* + ID_MODEL_FROM_DATABASE=BisonCam, NB Pro + ++usb:v5986p0268* ++ ID_MODEL_FROM_DATABASE=SunplusIT INC. Integrated Camera ++ ++usb:v5986p026A* ++ ID_MODEL_FROM_DATABASE=Integrated Camera ++ ++usb:v5986p0292* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ ++usb:v5986p0294* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ ++usb:v5986p0295* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ ++usb:v5986p0299* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ ++usb:v5986p029C* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v5986p02AC* ++ ID_MODEL_FROM_DATABASE=HP TrueVision HD Webcam ++ + usb:v5986p02D0* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + ++usb:v5986p02D2* ++ ID_MODEL_FROM_DATABASE=ThinkPad Integrated Camera ++ ++usb:v5986p02D5* ++ ID_MODEL_FROM_DATABASE=Integrated Camera ++ ++usb:v5986p03B3* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ + usb:v5986p03D0* + ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + ++usb:v5986p0400* ++ ID_MODEL_FROM_DATABASE=BisonCam, NB Pro ++ ++usb:v5986p0535* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera integrated webcam ++ ++usb:v5986p055A* ++ ID_MODEL_FROM_DATABASE=Lenovo Integrated Webcam ++ ++usb:v5986p0652* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v5986p0670* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v5986p0671* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera ++ ++usb:v5986p0706* ++ ID_MODEL_FROM_DATABASE=ThinkPad P50 Integrated Camera ++ ++usb:v5986p2113* ++ ID_MODEL_FROM_DATABASE=SunplusIT Integrated Camera ++ ++usb:v5986pA002* ++ ID_MODEL_FROM_DATABASE=Lenovo EasyCamera Integrated Webcam ++ + usb:v59E3* + ID_VENDOR_FROM_DATABASE=Nonolith Labs + +@@ -57948,7 +68862,7 @@ usb:v5A57p0284* + ID_MODEL_FROM_DATABASE=802.11a/b/g/n USB Wireless LAN Card + + usb:v5A57p0290* +- ID_MODEL_FROM_DATABASE=ZW-N290 802.11n [Realtek RTL8192SU] ++ ID_MODEL_FROM_DATABASE=ZW-N290 802.11n [Realtek RTL8192U] + + usb:v5A57p5257* + ID_MODEL_FROM_DATABASE=Metronic 495257 wifi 802.11ng +@@ -57956,6 +68870,9 @@ usb:v5A57p5257* + usb:v6000* + ID_VENDOR_FROM_DATABASE=Beholder International Ltd. + ++usb:v6000p0001* ++ ID_MODEL_FROM_DATABASE=Trident TVBOX Video Grabber ++ + usb:v6000pDEC0* + ID_MODEL_FROM_DATABASE=TV Wander + +@@ -57968,11 +68885,20 @@ usb:v601A* + usb:v601Ap4740* + ID_MODEL_FROM_DATABASE=XBurst Jz4740 boot mode + ++usb:v601Ap4760* ++ ID_MODEL_FROM_DATABASE=JZ4760 Boot Device ++ ++usb:v6022* ++ ID_VENDOR_FROM_DATABASE=Xektek ++ ++usb:v6022p0500* ++ ID_MODEL_FROM_DATABASE=SuperPro Universal Device Programmer ++ + usb:v6189* + ID_VENDOR_FROM_DATABASE=Sitecom + + usb:v6189p182D* +- ID_MODEL_FROM_DATABASE=USB 2.0 Ethernet ++ ID_MODEL_FROM_DATABASE=LN-029 10/100 Ethernet Adapter + + usb:v6189p2068* + ID_MODEL_FROM_DATABASE=USB to serial cable (v2) +@@ -58064,6 +68990,48 @@ usb:v6244p0500* + usb:v6244p0501* + ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad STICK2B + ++usb:v6244p0520* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK2C Firmware download, 32/64bits ++ ++usb:v6244p0521* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK2C, 32/64bits) ++ ++usb:v6244p0540* ++ ID_MODEL_FROM_DATABASE=Sunlite Universal Smart Handy Interface (SUSHI1A Firmware download, 32/64bits) ++ ++usb:v6244p0541* ++ ID_MODEL_FROM_DATABASE=Sunlite Universal Smart Handy Interface (SUSHI1A, 32/64bits) ++ ++usb:v6244p0570* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK4A Firmware download, 32/64bits) ++ ++usb:v6244p0571* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK4A, 32/64bits) ++ ++usb:v6244p0580* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK5A Firmware download, 32/64bits) ++ ++usb:v6244p0581* ++ ID_MODEL_FROM_DATABASE=Touch Sensitive Intelligent Control Keypad (STICK5A, 32/64bits) ++ ++usb:v6244p0590* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface (SIUDI9S Firmware Download, 32/64bits) ++ ++usb:v6244p0591* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface (SIUDI9S, 32/64bits) ++ ++usb:v6244p0600* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface (SIUDI9M Firmware Download, 32/64bits) ++ ++usb:v6244p0601* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface (SIUDI9M, 32/64bits) ++ ++usb:v6244p0610* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface SIUDI10A Firmware Download ++ ++usb:v6244p0611* ++ ID_MODEL_FROM_DATABASE=Intelligent Dmx Interface SIUDI10A ++ + usb:v6253* + ID_VENDOR_FROM_DATABASE=TwinHan Technology Co., Ltd + +@@ -58074,7 +69042,7 @@ usb:v636C* + ID_VENDOR_FROM_DATABASE=CoreLogic, Inc. + + usb:v6472* +- ID_VENDOR_FROM_DATABASE=Unknown (Sony?) ++ ID_VENDOR_FROM_DATABASE=Sony Corp. + + usb:v6472p01C8* + ID_MODEL_FROM_DATABASE=PlayStation Portable [Mass Storage] +@@ -58085,18 +69053,39 @@ usb:v6547* + usb:v6547p0232* + ID_MODEL_FROM_DATABASE=ARK3116 Serial + ++usb:v6557* ++ ID_VENDOR_FROM_DATABASE=Emtec ++ ++usb:v6557p5500* ++ ID_MODEL_FROM_DATABASE=Mass Storage Device ++ ++usb:v6557p8005* ++ ID_MODEL_FROM_DATABASE=Car Key ++ + usb:v6615* + ID_VENDOR_FROM_DATABASE=IRTOUCHSYSTEMS Co. Ltd. + + usb:v6615p0001* + ID_MODEL_FROM_DATABASE=Touchscreen + ++usb:v6615p0020* ++ ID_MODEL_FROM_DATABASE=IRTOUCH InfraRed TouchScreen ++ ++usb:v6615p0081* ++ ID_MODEL_FROM_DATABASE=TouchScreen ++ + usb:v6666* + ID_VENDOR_FROM_DATABASE=Prototype product Vendor ID + + usb:v6666p0667* + ID_MODEL_FROM_DATABASE=WiseGroup Smart Joy PSX, PS-PC Smart JoyPad + ++usb:v6666p1C40* ++ ID_MODEL_FROM_DATABASE=TELEMIC 802.15.4 Sensor node (Bootloader) ++ ++usb:v6666p1C41* ++ ID_MODEL_FROM_DATABASE=TELEMIC 802.15.4 Sensor node ++ + usb:v6666p2667* + ID_MODEL_FROM_DATABASE=JCOP BlueZ Smartcard reader + +@@ -58115,6 +69104,12 @@ usb:v6677p8802* + usb:v6677p8811* + ID_MODEL_FROM_DATABASE=Deluxe Dance Mat + ++usb:v675D* ++ ID_VENDOR_FROM_DATABASE=Humanscale ++ ++usb:v675Dp062A* ++ ID_MODEL_FROM_DATABASE=Switch Mouse ++ + usb:v6891* + ID_VENDOR_FROM_DATABASE=3Com + +@@ -58148,6 +69143,12 @@ usb:v726C* + usb:v726Cp2149* + ID_MODEL_FROM_DATABASE=EntropyKing Random Number Generator + ++usb:v7302* ++ ID_VENDOR_FROM_DATABASE=Solinftec ++ ++usb:v7302p0001* ++ ID_MODEL_FROM_DATABASE=HUB 4X232 ++ + usb:v734C* + ID_VENDOR_FROM_DATABASE=TBS Technologies China + +@@ -58167,20 +69168,104 @@ usb:v7392* + ID_VENDOR_FROM_DATABASE=Edimax Technology Co., Ltd + + usb:v7392p7711* +- ID_MODEL_FROM_DATABASE=EW-7711UTn nLite Wireless Adapter [Ralink RT2870] ++ ID_MODEL_FROM_DATABASE=EW-7711UTn nLite Wireless Adapter [Ralink RT3070] + + usb:v7392p7717* +- ID_MODEL_FROM_DATABASE=EW-7717UN 802.11n Wireless Adapter [Ralink RT2870] ++ ID_MODEL_FROM_DATABASE=EW-7717UN 802.11n Wireless Adapter [Ralink RT2770] + + usb:v7392p7718* + ID_MODEL_FROM_DATABASE=EW-7718UN 802.11n Wireless Adapter [Ralink RT2870] + + usb:v7392p7722* +- ID_MODEL_FROM_DATABASE=EW-7722UTn 802.11n Wireless Adapter [Ralink RT307x] ++ ID_MODEL_FROM_DATABASE=EW-7722UTn 802.11n Wireless Adapter [Ralink RT3072] ++ ++usb:v7392p7733* ++ ID_MODEL_FROM_DATABASE=EW-7733UnD 802.11abgn 3x3:3 [Ralink RT3573] + + usb:v7392p7811* + ID_MODEL_FROM_DATABASE=EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS] + ++usb:v7392p7822* ++ ID_MODEL_FROM_DATABASE=EW-7612UAn V2 802.11n Wireless Adapter [Realtek RTL8192CU] ++ ++usb:v7392pA611* ++ ID_MODEL_FROM_DATABASE=EW-7611ULB 802.11b/g/n and Bluetooth 4.0 Adapter ++ ++usb:v7392pA711* ++ ID_MODEL_FROM_DATABASE=EW-7711MAC 802.11ac Wireless Adapter ++ ++usb:v7392pA811* ++ ID_MODEL_FROM_DATABASE=EW-7811UTC 802.11ac Wireless Adapter ++ ++usb:v7392pB711* ++ ID_MODEL_FROM_DATABASE=EW-7722UAC 802.11a/b/g/n/ac (2x2) Wireless Adapter [MediaTek MT7612U] ++ ++usb:v7392pB822* ++ ID_MODEL_FROM_DATABASE=EW-7822ULC 802.11ac Wireless Adapter [Realtek RTL8812AU] ++ ++usb:v73D8* ++ ID_VENDOR_FROM_DATABASE=Progeny Dental Equipment Specialists ++ ++usb:v73D8p0104* ++ ID_MODEL_FROM_DATABASE=VetPro DR, Size 1 ++ ++usb:v73D8p0105* ++ ID_MODEL_FROM_DATABASE=VetPro DR, Size 2 ++ ++usb:v7669* ++ ID_VENDOR_FROM_DATABASE=Venable Instruments ++ ++usb:v7669p350C* ++ ID_MODEL_FROM_DATABASE=Model 350c, Frequency Response Analyzer ++ ++usb:v7669p5140* ++ ID_MODEL_FROM_DATABASE=Model 5140, Frequency Response Analyzer ++ ++usb:v7669p6305* ++ ID_MODEL_FROM_DATABASE=Model 6305, Frequency Response Analyzer ++ ++usb:v7669p6320* ++ ID_MODEL_FROM_DATABASE=Model 6320, Frequency Response Analyzer ++ ++usb:v7669p6340* ++ ID_MODEL_FROM_DATABASE=Model 6340, Frequency Response Analyzer ++ ++usb:v7669p7405* ++ ID_MODEL_FROM_DATABASE=Model 7405, Frequency Response Analyzer ++ ++usb:v7669p7420* ++ ID_MODEL_FROM_DATABASE=Model 7420, Frequency Response Analyzer ++ ++usb:v7669p7440* ++ ID_MODEL_FROM_DATABASE=Model 7440, Frequency Response Analyzer ++ ++usb:v7669p8805* ++ ID_MODEL_FROM_DATABASE=Model 8805, Frequency Response Analyzer ++ ++usb:v7669p8820* ++ ID_MODEL_FROM_DATABASE=Model 8820, Frequency Response Analyzer ++ ++usb:v7669p8840* ++ ID_MODEL_FROM_DATABASE=Model 8840, Frequency Response Analyzer ++ ++usb:v7825* ++ ID_VENDOR_FROM_DATABASE=Other World Computing ++ ++usb:v7825pA2A4* ++ ID_MODEL_FROM_DATABASE=External SATA Hard Drive Adapter cable PA023U3 ++ ++usb:v7825pB0B3* ++ ID_MODEL_FROM_DATABASE=miniStack MAX ++ ++usb:v8070* ++ ID_VENDOR_FROM_DATABASE=ACCES I/O Products, Inc. ++ ++usb:v8070p8003* ++ ID_MODEL_FROM_DATABASE=USB-DIO-96 ++ ++usb:v8070p8070* ++ ID_MODEL_FROM_DATABASE=USB-AO16-16A ++ + usb:v8086* + ID_VENDOR_FROM_DATABASE=Intel Corp. + +@@ -58220,11 +69305,14 @@ usb:v8086p0186* + usb:v8086p0188* + ID_MODEL_FROM_DATABASE=WiMAX Connection 2400m + ++usb:v8086p0189* ++ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 Bluetooth adapter ++ + usb:v8086p0200* + ID_MODEL_FROM_DATABASE=AnyPoint(TM) Wireless II Network 11Mbps Adapter [Atmel AT76C503A] + + usb:v8086p0431* +- ID_MODEL_FROM_DATABASE=Intel Pro Video PC Camera ++ ID_MODEL_FROM_DATABASE=Pro Video PC Camera + + usb:v8086p0510* + ID_MODEL_FROM_DATABASE=Digital Movie Creator +@@ -58238,6 +69326,12 @@ usb:v8086p0780* + usb:v8086p07D3* + ID_MODEL_FROM_DATABASE=BLOB boot loader firmware + ++usb:v8086p07DC* ++ ID_MODEL_FROM_DATABASE=Bluetooth 4.0* Smart Ready (low energy) ++ ++usb:v8086p0B07* ++ ID_MODEL_FROM_DATABASE=RealSense D435 ++ + usb:v8086p0DAD* + ID_MODEL_FROM_DATABASE=Cherry MiniatureCard Keyboard + +@@ -58256,6 +69350,9 @@ usb:v8086p1110* + usb:v8086p1111* + ID_MODEL_FROM_DATABASE=PRO/Wireless 2011B 802.11b Adapter [Intersil PRISM 2.5] + ++usb:v8086p1122* ++ ID_MODEL_FROM_DATABASE=Integrated Hub ++ + usb:v8086p1134* + ID_MODEL_FROM_DATABASE=Hollister Mobile Monitor + +@@ -58292,8 +69389,17 @@ usb:v8086p3241* + usb:v8086p8602* + ID_MODEL_FROM_DATABASE=Miniature Card Slot + ++usb:v8086p8C26* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series EHCI #1 ++ ++usb:v8086p8C2D* ++ ID_MODEL_FROM_DATABASE=8 Series/C220 Series EHCI #2 ++ ++usb:v8086p8C31* ++ ID_MODEL_FROM_DATABASE=eXtensible Host Controller ++ + usb:v8086p9303* +- ID_MODEL_FROM_DATABASE=Intel 8x930Hx Hub ++ ID_MODEL_FROM_DATABASE=8x930Hx Hub + + usb:v8086p9500* + ID_MODEL_FROM_DATABASE=CE 9500 DVB-T +@@ -58307,6 +69413,9 @@ usb:v8086pBEEF* + usb:v8086pC013* + ID_MODEL_FROM_DATABASE=Wireless HID Station + ++usb:v8086pDEAD* ++ ID_MODEL_FROM_DATABASE=Galileo ++ + usb:v8086pF001* + ID_MODEL_FROM_DATABASE=XScale PXA27x Bulverde flash + +@@ -58322,12 +69431,78 @@ usb:v8087p0020* + usb:v8087p0024* + ID_MODEL_FROM_DATABASE=Integrated Rate Matching Hub + ++usb:v8087p0025* ++ ID_MODEL_FROM_DATABASE=Wireless-AC 9260 Bluetooth Adapter ++ ++usb:v8087p0026* ++ ID_MODEL_FROM_DATABASE=AX201 Bluetooth ++ ++usb:v8087p0029* ++ ID_MODEL_FROM_DATABASE=AX200 Bluetooth ++ ++usb:v8087p0032* ++ ID_MODEL_FROM_DATABASE=AX210 Bluetooth ++ ++usb:v8087p0716* ++ ID_MODEL_FROM_DATABASE=Modem Flashloader ++ ++usb:v8087p07DA* ++ ID_MODEL_FROM_DATABASE=Centrino Bluetooth Wireless Transceiver ++ ++usb:v8087p07DB* ++ ID_MODEL_FROM_DATABASE=Atom C2000 Root Hub ++ ++usb:v8087p07DC* ++ ID_MODEL_FROM_DATABASE=Bluetooth wireless interface ++ ++usb:v8087p07EB* ++ ID_MODEL_FROM_DATABASE=Oaktrail tablet ++ ++usb:v8087p0A2A* ++ ID_MODEL_FROM_DATABASE=Bluetooth wireless interface ++ ++usb:v8087p0A2B* ++ ID_MODEL_FROM_DATABASE=Bluetooth wireless interface ++ ++usb:v8087p0A9E* ++ ID_MODEL_FROM_DATABASE=Edison ++ ++usb:v8087p0AA7* ++ ID_MODEL_FROM_DATABASE=Wireless-AC 3168 Bluetooth ++ ++usb:v8087p0AAA* ++ ID_MODEL_FROM_DATABASE=Bluetooth 9460/9560 Jefferson Peak (JfP) ++ ++usb:v8087p0FFF* ++ ID_MODEL_FROM_DATABASE=Intel Android Bootloader Interface ++ ++usb:v8087p8000* ++ ID_MODEL_FROM_DATABASE=Integrated Rate Matching Hub ++ ++usb:v8087p8001* ++ ID_MODEL_FROM_DATABASE=Integrated Hub ++ ++usb:v8087p8002* ++ ID_MODEL_FROM_DATABASE=8 channel internal hub ++ ++usb:v8087p8008* ++ ID_MODEL_FROM_DATABASE=Integrated Rate Matching Hub ++ ++usb:v8087p800A* ++ ID_MODEL_FROM_DATABASE=Hub ++ ++usb:v8087p8087* ++ ID_MODEL_FROM_DATABASE=07da Centrino Advanced-N 6235 ++ + usb:v80EE* + ID_VENDOR_FROM_DATABASE=VirtualBox + + usb:v80EEp0021* + ID_MODEL_FROM_DATABASE=USB Tablet + ++usb:v80EEp0022* ++ ID_MODEL_FROM_DATABASE=multitouch tablet ++ + usb:v8282* + ID_VENDOR_FROM_DATABASE=Keio + +@@ -58337,6 +69512,12 @@ usb:v8282p3201* + usb:v8282p3301* + ID_MODEL_FROM_DATABASE=Retro Adapter Mouse + ++usb:v8301* ++ ID_VENDOR_FROM_DATABASE=Hapurs ++ ++usb:v8301p0089* ++ ID_MODEL_FROM_DATABASE=HPBT05R 2.4 G Mini Wireless Touchpad Keyboard ++ + usb:v8341* + ID_VENDOR_FROM_DATABASE=EGO Systems, Inc. + +@@ -58350,7 +69531,16 @@ usb:v8564p1000* + ID_MODEL_FROM_DATABASE=JetFlash + + usb:v8564p4000* +- ID_MODEL_FROM_DATABASE=RDF8 ++ ID_MODEL_FROM_DATABASE=microSD/SD/CF UHS-II Card Reader [RDF8, RDF9] ++ ++usb:v8564p6000* ++ ID_MODEL_FROM_DATABASE=digital photo frame PF830 ++ ++usb:v8564p6002* ++ ID_MODEL_FROM_DATABASE=digital photo frame PF830 ++ ++usb:v8564p7000* ++ ID_MODEL_FROM_DATABASE=StoreJet 25H3 + + usb:v8644* + ID_VENDOR_FROM_DATABASE=Intenso GmbG +@@ -58367,6 +69557,12 @@ usb:v8E06* + usb:v8E06pF700* + ID_MODEL_FROM_DATABASE=DT225 Trackball + ++usb:v8EA3* ++ ID_VENDOR_FROM_DATABASE=Doosl ++ ++usb:v8EA3pA02C* ++ ID_MODEL_FROM_DATABASE=Wireless Presenter Receiver ++ + usb:v9016* + ID_VENDOR_FROM_DATABASE=Sitecom + +@@ -58391,6 +69587,9 @@ usb:v9148* + usb:v9148p0004* + ID_MODEL_FROM_DATABASE=R3 Compatible Device + ++usb:v9516* ++ ID_VENDOR_FROM_DATABASE=Studiologic ++ + usb:v9710* + ID_VENDOR_FROM_DATABASE=MosChip Semiconductor + +@@ -58415,6 +69614,15 @@ usb:v9710p7730* + usb:v9710p7780* + ID_MODEL_FROM_DATABASE=MCS7780 4Mbps Fast IrDA Adapter + ++usb:v9710p7784* ++ ID_MODEL_FROM_DATABASE=MCS7784 115.2Kb IrDA Adapter ++ ++usb:v9710p7810* ++ ID_MODEL_FROM_DATABASE=MCS7810 Serial Port Adapter ++ ++usb:v9710p7820* ++ ID_MODEL_FROM_DATABASE=MCS7820 Dual Serial Port Adapter ++ + usb:v9710p7830* + ID_MODEL_FROM_DATABASE=MCS7830 10/100 Mbps Ethernet adapter + +@@ -58424,12 +69632,21 @@ usb:v9710p7832* + usb:v9710p7840* + ID_MODEL_FROM_DATABASE=MCS7820/MCS7840 2/4 port serial adapter + ++usb:v9710p9990* ++ ID_MODEL_FROM_DATABASE=MCS9990 PCIe Host Controller ++ + usb:v9849* + ID_VENDOR_FROM_DATABASE=Bestmedia CD Recordable GmbH & Co. KG + + usb:v9849p0701* + ID_MODEL_FROM_DATABASE=Platinum MyDrive HP + ++usb:v9886* ++ ID_VENDOR_FROM_DATABASE=Astro Gaming ++ ++usb:v9886p0015* ++ ID_MODEL_FROM_DATABASE=A50 ++ + usb:v9999* + ID_VENDOR_FROM_DATABASE=Odeon + +@@ -58454,6 +69671,21 @@ usb:v9E88* + usb:v9E88p9E8F* + ID_MODEL_FROM_DATABASE=Plug Computer Basic [SheevaPlug] + ++usb:vA014* ++ ID_VENDOR_FROM_DATABASE=Insignia (Best Buy) ++ ++usb:vA014pB014* ++ ID_MODEL_FROM_DATABASE=Desktop Microphone NS-PAUM50 ++ ++usb:vA108* ++ ID_VENDOR_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd ++ ++usb:vA108p1000* ++ ID_MODEL_FROM_DATABASE=X1000 ++ ++usb:vA108p4775* ++ ID_MODEL_FROM_DATABASE=JZ4775 Boot Device ++ + usb:vA128* + ID_VENDOR_FROM_DATABASE=AnMo Electronics Corp. / Dino-Lite (?) + +@@ -58508,12 +69740,51 @@ usb:vA168p0617* + usb:vA168p0618* + ID_MODEL_FROM_DATABASE=Dino-Lite Digital Microscope + ++usb:vA466* ++ ID_VENDOR_FROM_DATABASE=Haikou Xingong Electronics Co.,Ltd ++ ++usb:vA466p0A53* ++ ID_MODEL_FROM_DATABASE=TL866II Plus Device Programmer [MiniPRO] ++ + usb:vA600* +- ID_VENDOR_FROM_DATABASE=Asix ++ ID_VENDOR_FROM_DATABASE=ASIX s.r.o. ++ ++usb:vA600p5500* ++ ID_MODEL_FROM_DATABASE=zuban H2OPS - GPS for canoeing ++ ++usb:vA600pA000* ++ ID_MODEL_FROM_DATABASE=SIGMA Logic Analyzer ++ ++usb:vA600pA002* ++ ID_MODEL_FROM_DATABASE=EMUSB interface pro MU Beta ++ ++usb:vA600pC000* ++ ID_MODEL_FROM_DATABASE=MREL Data Trap II ++ ++usb:vA600pC001* ++ ID_MODEL_FROM_DATABASE=VUTS DMU4 ++ ++usb:vA600pC002* ++ ID_MODEL_FROM_DATABASE=Electrone MASH ++ ++usb:vA600pC005* ++ ID_MODEL_FROM_DATABASE=MREL HTU HandiTrap cable ++ ++usb:vA600pC006* ++ ID_MODEL_FROM_DATABASE=JRC COmeter + + usb:vA600pE110* + ID_MODEL_FROM_DATABASE=OK1ZIA Davac 4.x + ++usb:vA600pE112* ++ ID_MODEL_FROM_DATABASE=OK1ZIA Antenna rotator ++ ++usb:vA600pE113* ++ ID_MODEL_FROM_DATABASE=OK1ZIA GPIO ++ ++usb:vA600pE114* ++ ID_MODEL_FROM_DATABASE=OK1ZIA HD&Keyb ++ + usb:vA727* + ID_VENDOR_FROM_DATABASE=3Com + +@@ -58526,14 +69797,35 @@ usb:vA727p6895* + usb:vA727p6897* + ID_MODEL_FROM_DATABASE=AR5523 + ++usb:vA88A* ++ ID_VENDOR_FROM_DATABASE=Clas Ohlsson ++ ++usb:vA88Ap3003* ++ ID_MODEL_FROM_DATABASE=PCFree Multimedia Remote Control PC ++ + usb:vAAAA* + ID_VENDOR_FROM_DATABASE=MXT + + usb:vAAAAp8815* + ID_MODEL_FROM_DATABASE=microSD CardReader + ++usb:vAAAAp8816* ++ ID_MODEL_FROM_DATABASE=microSD CardReader ++ ++usb:vAB12* ++ ID_VENDOR_FROM_DATABASE=aplic ++ ++usb:vAB12p34CD* ++ ID_MODEL_FROM_DATABASE=JMICRON JMS578 SATA 6Gb/s bridge ++ + usb:vABCD* +- ID_VENDOR_FROM_DATABASE=Unknown ++ ID_VENDOR_FROM_DATABASE=LogiLink ++ ++usb:vABCDp1234* ++ ID_MODEL_FROM_DATABASE=UDisk flash drive ++ ++usb:vABCDp6104* ++ ID_MODEL_FROM_DATABASE=PCCloneEX Lite+ SATA docking station [QP0017] + + usb:vABCDpCDEE* + ID_MODEL_FROM_DATABASE=Petcam +@@ -58544,6 +69836,12 @@ usb:vB58E* + usb:vB58Ep9E84* + ID_MODEL_FROM_DATABASE=Yeti Stereo Microphone + ++usb:vBA77* ++ ID_VENDOR_FROM_DATABASE=Clockmaker ++ ++usb:vBA77p7147* ++ ID_MODEL_FROM_DATABASE=Agterbosch ++ + usb:vC216* + ID_VENDOR_FROM_DATABASE=Card Device Expert Co., LTD + +@@ -58553,9 +69851,21 @@ usb:vC216p0180* + usb:vC251* + ID_VENDOR_FROM_DATABASE=Keil Software, Inc. + ++usb:vC251p1705* ++ ID_MODEL_FROM_DATABASE=MCB2300 ++ + usb:vC251p2710* + ID_MODEL_FROM_DATABASE=ULink + ++usb:vC251p2723* ++ ID_MODEL_FROM_DATABASE=ULink-ME ++ ++usb:vC502* ++ ID_VENDOR_FROM_DATABASE=AGPTek ++ ++usb:vC502p0029* ++ ID_MODEL_FROM_DATABASE=Rocker ++ + usb:vCACE* + ID_VENDOR_FROM_DATABASE=CACE Technologies Inc. + +@@ -58563,7 +69873,7 @@ usb:vCACEp0002* + ID_MODEL_FROM_DATABASE=AirPCAP Classic 802.11 packet capture adapter + + usb:vCACEp0300* +- ID_MODEL_FROM_DATABASE=AirPcap NX [Atheros AR9001U-(2)NG] ++ ID_MODEL_FROM_DATABASE=AirPcap NX [Atheros AR9170+AR9104] + + usb:vCD12* + ID_VENDOR_FROM_DATABASE=SMART TECHNOLOGY INDUSTRIAL LTD. +@@ -58583,12 +69893,24 @@ usb:vD209p0301* + usb:vD209p0501* + ID_MODEL_FROM_DATABASE=Ultra-Stik Ultimarc Ultra-Stik Player 1 + ++usb:vD209p1571* ++ ID_MODEL_FROM_DATABASE=A-PAC Arcade Control Interface ++ + usb:vD904* + ID_VENDOR_FROM_DATABASE=LogiLink + + usb:vD904p0003* + ID_MODEL_FROM_DATABASE=Laser Mouse (ID0009A) + ++usb:vE2B7* ++ ID_VENDOR_FROM_DATABASE=Jie Li ++ ++usb:vE2B7p0811* ++ ID_MODEL_FROM_DATABASE=CD002 ++ ++usb:vE2B7p0812* ++ ID_MODEL_FROM_DATABASE=CD005 MP3 Player ++ + usb:vE4E4* + ID_VENDOR_FROM_DATABASE=Xorcom Ltd. + +@@ -58659,10 +69981,25 @@ usb:vEB1Ap2776* + ID_MODEL_FROM_DATABASE=Combined audio and video input device + + usb:vEB1Ap2800* +- ID_MODEL_FROM_DATABASE=Terratec Cinergy 200 ++ ID_MODEL_FROM_DATABASE=EM2800 Video Capture + + usb:vEB1Ap2801* +- ID_MODEL_FROM_DATABASE=GrabBeeX+ Video Encoder ++ ID_MODEL_FROM_DATABASE=EM2801 Video Capture ++ ++usb:vEB1Ap2820* ++ ID_MODEL_FROM_DATABASE=EM2820 Video Capture ++ ++usb:vEB1Ap2821* ++ ID_MODEL_FROM_DATABASE=EM2820 Video Capture ++ ++usb:vEB1Ap2840* ++ ID_MODEL_FROM_DATABASE=EM2840 Video Capture ++ ++usb:vEB1Ap2841* ++ ID_MODEL_FROM_DATABASE=EM2840 Video Capture ++ ++usb:vEB1Ap2861* ++ ID_MODEL_FROM_DATABASE=EasyCAP DC60+ [EM2861] + + usb:vEB1Ap2863* + ID_MODEL_FROM_DATABASE=Video Grabber +@@ -58679,6 +70016,18 @@ usb:vEB1Ap50A3* + usb:vEB1Ap50A6* + ID_MODEL_FROM_DATABASE=Gadmei UTV330 TV Box + ++usb:vEB1Ap5166* ++ ID_MODEL_FROM_DATABASE=video grabber 28282 ++ ++usb:vEB1Ap5184* ++ ID_MODEL_FROM_DATABASE=VIDBOX NW06 [EM28281] ++ ++usb:vEB1Ap8179* ++ ID_MODEL_FROM_DATABASE=Terratec Cinergy T2 Stick HD ++ ++usb:vEB1ApE305* ++ ID_MODEL_FROM_DATABASE=KWorld PlusTV Analog Stick ++ + usb:vEB1ApE355* + ID_MODEL_FROM_DATABASE=KWorld DVB-T 355U Digital TV Dongle + +@@ -58694,12 +70043,36 @@ usb:vF003* + usb:vF003p6002* + ID_MODEL_FROM_DATABASE=PhotoSmart C500 + ++usb:vF007* ++ ID_VENDOR_FROM_DATABASE=Teslong ++ ++usb:vF007pA999* ++ ID_MODEL_FROM_DATABASE=Endoscope Camera ++ ++usb:vF007pB999* ++ ID_MODEL_FROM_DATABASE=Otoscope Camera ++ + usb:vF182* + ID_VENDOR_FROM_DATABASE=Leap Motion + + usb:vF182p0003* + ID_MODEL_FROM_DATABASE=Controller + ++usb:vF3F0* ++ ID_VENDOR_FROM_DATABASE=CCT, Inc ++ ++usb:vF3F0p0740* ++ ID_MODEL_FROM_DATABASE=multi-function device ++ ++usb:vF3F0p1340* ++ ID_MODEL_FROM_DATABASE=multi-function printer ++ ++usb:vF3F0p1440* ++ ID_MODEL_FROM_DATABASE=printer device ++ ++usb:vF3F0p1921* ++ ID_MODEL_FROM_DATABASE=printer ++ + usb:vF4EC* + ID_VENDOR_FROM_DATABASE=Atten Electronics / Siglent Technologies + +@@ -58721,12 +70094,21 @@ usb:vF766* + usb:vF766p0001* + ID_MODEL_FROM_DATABASE=PC-Gamepad "Greystorm" + ++usb:vFA11* ++ ID_VENDOR_FROM_DATABASE=DyingLight ++ ++usb:vFA11p5AFE* ++ ID_MODEL_FROM_DATABASE=DyingLight ++ + usb:vFC08* + ID_VENDOR_FROM_DATABASE=Conrad Electronic SE + + usb:vFC08p0101* + ID_MODEL_FROM_DATABASE=MIDI Cable UA0037 + ++usb:vFF00* ++ ID_VENDOR_FROM_DATABASE=Power Delivery ++ + usb:vFFEE* + ID_VENDOR_FROM_DATABASE=FNK Tech + +diff --git a/hwdb/60-autosuspend-fingerprint-reader.hwdb b/hwdb/60-autosuspend-fingerprint-reader.hwdb +new file mode 100644 +index 0000000000..c1485e1256 +--- /dev/null ++++ b/hwdb/60-autosuspend-fingerprint-reader.hwdb +@@ -0,0 +1,300 @@ ++# This file is part of systemd. ++# ++# Rules to autosuspend known fingerprint readers (pulled from libfprint). ++# ++# SPDX-License-Identifier: LGPL-2.1-or-later ++# This file has been generated using fprint-list-udev-hwdb with all drivers enabled ++ ++# Supported by libfprint driver aes1610 ++usb:v08FFp1600* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes1660 ++usb:v08FFp1660* ++usb:v08FFp1680* ++usb:v08FFp1681* ++usb:v08FFp1682* ++usb:v08FFp1683* ++usb:v08FFp1684* ++usb:v08FFp1685* ++usb:v08FFp1686* ++usb:v08FFp1687* ++usb:v08FFp1688* ++usb:v08FFp1689* ++usb:v08FFp168A* ++usb:v08FFp168B* ++usb:v08FFp168C* ++usb:v08FFp168D* ++usb:v08FFp168E* ++usb:v08FFp168F* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes2501 ++usb:v08FFp2500* ++usb:v08FFp2580* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes2550 ++usb:v08FFp2550* ++usb:v08FFp2810* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes2660 ++usb:v08FFp2660* ++usb:v08FFp2680* ++usb:v08FFp2681* ++usb:v08FFp2682* ++usb:v08FFp2683* ++usb:v08FFp2684* ++usb:v08FFp2685* ++usb:v08FFp2686* ++usb:v08FFp2687* ++usb:v08FFp2688* ++usb:v08FFp2689* ++usb:v08FFp268A* ++usb:v08FFp268B* ++usb:v08FFp268C* ++usb:v08FFp268D* ++usb:v08FFp268E* ++usb:v08FFp268F* ++usb:v08FFp2691* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes3500 ++usb:v08FFp5731* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver aes4000 ++usb:v5501p08FF* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver egis0570 ++usb:v1C7Ap0570* ++usb:v1C7Ap0571* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver elan ++usb:v04F3p0903* ++usb:v04F3p0907* ++usb:v04F3p0C01* ++usb:v04F3p0C02* ++usb:v04F3p0C03* ++usb:v04F3p0C04* ++usb:v04F3p0C05* ++usb:v04F3p0C06* ++usb:v04F3p0C07* ++usb:v04F3p0C08* ++usb:v04F3p0C09* ++usb:v04F3p0C0A* ++usb:v04F3p0C0B* ++usb:v04F3p0C0C* ++usb:v04F3p0C0D* ++usb:v04F3p0C0E* ++usb:v04F3p0C0F* ++usb:v04F3p0C10* ++usb:v04F3p0C11* ++usb:v04F3p0C12* ++usb:v04F3p0C13* ++usb:v04F3p0C14* ++usb:v04F3p0C15* ++usb:v04F3p0C16* ++usb:v04F3p0C17* ++usb:v04F3p0C18* ++usb:v04F3p0C19* ++usb:v04F3p0C1A* ++usb:v04F3p0C1B* ++usb:v04F3p0C1C* ++usb:v04F3p0C1D* ++usb:v04F3p0C1E* ++usb:v04F3p0C1F* ++usb:v04F3p0C20* ++usb:v04F3p0C21* ++usb:v04F3p0C22* ++usb:v04F3p0C23* ++usb:v04F3p0C24* ++usb:v04F3p0C25* ++usb:v04F3p0C26* ++usb:v04F3p0C27* ++usb:v04F3p0C28* ++usb:v04F3p0C29* ++usb:v04F3p0C2A* ++usb:v04F3p0C2B* ++usb:v04F3p0C2C* ++usb:v04F3p0C2D* ++usb:v04F3p0C2E* ++usb:v04F3p0C2F* ++usb:v04F3p0C30* ++usb:v04F3p0C31* ++usb:v04F3p0C32* ++usb:v04F3p0C33* ++usb:v04F3p0C3D* ++usb:v04F3p0C42* ++usb:v04F3p0C4D* ++usb:v04F3p0C4F* ++usb:v04F3p0C63* ++usb:v04F3p0C6E* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver elanmoc ++usb:v04F3p0C7E* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver etes603 ++usb:v1C7Ap0603* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver goodixmoc ++usb:v27C6p5840* ++usb:v27C6p609C* ++usb:v27C6p60A2* ++usb:v27C6p639C* ++usb:v27C6p63AC* ++usb:v27C6p6496* ++usb:v27C6p6584* ++usb:v27C6p658C* ++usb:v27C6p6592* ++usb:v27C6p6594* ++usb:v27C6p659C* ++usb:v27C6p6A94* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver nb1010 ++usb:v298Dp1010* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver synaptics ++usb:v06CBp00BD* ++usb:v06CBp00DF* ++usb:v06CBp00F9* ++usb:v06CBp00FC* ++usb:v06CBp00C2* ++usb:v06CBp00C9* ++usb:v06CBp0100* ++usb:v06CBp00F0* ++usb:v06CBp0103* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver upeksonly ++usb:v147Ep2016* ++usb:v147Ep1000* ++usb:v147Ep1001* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver upektc ++usb:v0483p2015* ++usb:v147Ep3001* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver upektc_img ++usb:v147Ep2020* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver uru4000 ++usb:v045Ep00BC* ++usb:v045Ep00BD* ++usb:v045Ep00CA* ++usb:v05BAp0007* ++usb:v05BAp0008* ++usb:v05BAp000A* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vcom5s ++usb:v061Ap0110* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vfs0050 ++usb:v138Ap0050* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vfs101 ++usb:v138Ap0001* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vfs301 ++usb:v138Ap0005* ++usb:v138Ap0008* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vfs5011 ++usb:v138Ap0010* ++usb:v138Ap0011* ++usb:v138Ap0015* ++usb:v138Ap0017* ++usb:v138Ap0018* ++ ID_AUTOSUSPEND=1 ++ ++# Supported by libfprint driver vfs7552 ++usb:v138Ap0091* ++ ID_AUTOSUSPEND=1 ++ ++# Known unsupported devices ++usb:v04F3p036B* ++usb:v04F3p0C00* ++usb:v04F3p0C4B* ++usb:v04F3p0C4C* ++usb:v04F3p0C57* ++usb:v04F3p0C5E* ++usb:v04F3p2706* ++usb:v06CBp0081* ++usb:v06CBp0088* ++usb:v06CBp008A* ++usb:v06CBp009A* ++usb:v06CBp009B* ++usb:v06CBp00A2* ++usb:v06CBp00B7* ++usb:v06CBp00BB* ++usb:v06CBp00BE* ++usb:v06CBp00C4* ++usb:v06CBp00CB* ++usb:v06CBp00D8* ++usb:v06CBp00DA* ++usb:v06CBp00E9* ++usb:v0A5Cp5801* ++usb:v0A5Cp5805* ++usb:v0A5Cp5834* ++usb:v0A5Cp5840* ++usb:v0A5Cp5841* ++usb:v0A5Cp5842* ++usb:v0A5Cp5843* ++usb:v0A5Cp5845* ++usb:v10A5p0007* ++usb:v1188p9545* ++usb:v138Ap0007* ++usb:v138Ap003A* ++usb:v138Ap003C* ++usb:v138Ap003D* ++usb:v138Ap003F* ++usb:v138Ap0090* ++usb:v138Ap0092* ++usb:v138Ap0094* ++usb:v138Ap0097* ++usb:v138Ap009D* ++usb:v138Ap00AB* ++usb:v147Ep1002* ++usb:v1491p0088* ++usb:v16D1p1027* ++usb:v1C7Ap0300* ++usb:v1C7Ap0575* ++usb:v27C6p5042* ++usb:v27C6p5110* ++usb:v27C6p5117* ++usb:v27C6p5201* ++usb:v27C6p521D* ++usb:v27C6p5301* ++usb:v27C6p530C* ++usb:v27C6p532D* ++usb:v27C6p533C* ++usb:v27C6p5381* ++usb:v27C6p5385* ++usb:v27C6p538C* ++usb:v27C6p538D* ++usb:v27C6p5395* ++usb:v27C6p5584* ++usb:v27C6p55A2* ++usb:v27C6p55A4* ++usb:v27C6p55B4* ++usb:v27C6p5740* ++usb:v2808p9338* ++usb:v298Dp2033* ++usb:v3538p0930* ++ ID_AUTOSUSPEND=1 +diff --git a/hwdb/60-autosuspend.hwdb b/hwdb/60-autosuspend.hwdb +new file mode 100644 +index 0000000000..15dcc2f1ee +--- /dev/null ++++ b/hwdb/60-autosuspend.hwdb +@@ -0,0 +1,71 @@ ++# This file is part of systemd. ++# ++# The lookup keys are $MODALIAS strings, see udev's hwdb builtin. ++# ++# Match string formats: ++# : ++# ++# pci:vd ++# usb:vp ++# ++# To add local entries, create a new file ++# /etc/udev/hwdb.d/61-autosuspend-local.hwdb ++# and add your rules there. To load the new rules execute (as root): ++# systemd-hwdb update ++# udevadm trigger /dev/… ++# ++# If your changes are generally applicable, preferably send them as a pull ++# request to ++# https://github.com/systemd/systemd ++# or create a bug report on https://github.com/systemd/systemd/issues and ++# include your new rules, a description of the device, and the output of ++# udevadm info ++# the device. ++# ++# Allowed properties are: ++# ID_AUTOSUSPEND=1 ++ ++# Sort by brand, model ++ ++######################################### ++# Alcor ++######################################### ++ ++# AU9540 Smartcard Reader ++usb:v058Fp9540* ++ ID_AUTOSUSPEND=1 ++ ++######################################### ++# Lenovo ++######################################### ++ ++# X1C8 Touchscreen ++usb:v04F3p2B7C* ++# T14 Gen 1 Touchscreen ++usb:v04F3p2ACC* ++ ID_AUTOSUSPEND=1 ++ ++######################################### ++# QEMU ++######################################### ++ ++# Emulated USB HID devices ++usb:v0627p0001:*QEMU USB Keyboard* ++usb:v0627p0001:*QEMU USB Mouse* ++usb:v0627p0001:*QEMU USB Tablet* ++ ID_AUTOSUSPEND=1 ++ ++######################################### ++# Sierra Wireless ++######################################### ++ ++# Sierra Wireless EM7345 4G LTE modem ++usb:v1199pA001* ++ ID_AUTOSUSPEND=1 ++ ++######################################### ++# Wacom ++######################################### ++ ++usb:v056Ap51A0* ++ ID_AUTOSUSPEND=1 +diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb +index ab4b3068e6..bd463a4215 100644 +--- a/hwdb/60-evdev.hwdb ++++ b/hwdb/60-evdev.hwdb +@@ -3,10 +3,10 @@ + # The lookup keys are composed in: + # 60-evdev.rules + # +-# Note: The format of the "evdev:" prefix match key is a +-# contract between the rules file and the hardware data, it might +-# change in later revisions to support more or better matches, it +-# is not necessarily expected to be a stable ABI. ++# Note: The format of the "evdev:" prefix match key is a contract between the ++# rules file and the hardware data, it might change in later revisions to ++# support more or better matches, it is not necessarily expected to be a stable ++# ABI. + # + # Match string formats: + # evdev: +@@ -17,8 +17,8 @@ + # and add your rules there. To load the new rules execute (as root): + # systemd-hwdb update + # udevadm trigger /dev/input/eventXX +-# where /dev/input/eventXX is the device in question. If in +-# doubt, simply use /dev/input/event* to reload all input rules. ++# where /dev/input/eventXX is the device in question. If in doubt, simply use ++# /dev/input/event* to reload all input rules. + # + # If your changes are generally applicable, preferably send them as a pull + # request to +@@ -30,20 +30,39 @@ + # Allowed properties are: + # EVDEV_ABS_=:::: + # +-# where is the hexadecimal EV_ABS code as listed in linux/input.h +-# and min, max, res, fuzz, flat are the decimal values to the respective +-# fields of the struct input_absinfo as listed in linux/input.h. +-# If a field is missing the field will be left as-is. Not all fields need to +-# be present. e.g. ::45 sets the resolution to 45 units/mm. ++# where is the hexadecimal EV_ABS code as listed in linux/input.h and ++# min, max, res, fuzz, flat are the decimal values to the respective fields of ++# the struct input_absinfo as listed in linux/input.h. If a field is missing ++# the field will be left as-is. Not all fields need to be present. e.g. ::45 ++# sets the resolution to 45 units/mm. + +-# + # Sort by brand, model + ++######################################### ++# ACECAD ++######################################### ++ ++# Acecad Flair / Pentagram Quadpen ++evdev:input:b0003v0460p0004* ++ EVDEV_ABS_00=::40 ++ EVDEV_ABS_01=::40 ++ ++######################################### ++# AIPTEK ++######################################### ++ ++# Hyperpen 12000U ++evdev:input:b0003v08CAp0010* ++# Hyperpen 6000U ++evdev:input:b0003v08CAp0020* ++ EVDEV_ABS_00=::20 ++ EVDEV_ABS_01=::20 ++ + ######################################### + # Apple + ######################################### + +-# Macbook2,1 (late 2006), single-button touchpad ++# Macbook2,1 (late 2006), single-button touchpad + evdev:input:b0003v05ACp021B* + # Macbook4,1 + evdev:input:b0003v05ACp0229* +@@ -91,17 +110,50 @@ evdev:input:b0003v05ACp025B* + EVDEV_ABS_35=::94 + EVDEV_ABS_36=::92 + ++# MacBook8,1 (2015), MacBook9,1 (2016), MacBook10,1 (2017) ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBook8,1:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBook9,1:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBook10,1:* ++ EVDEV_ABS_00=::95 ++ EVDEV_ABS_01=::90 ++ EVDEV_ABS_35=::95 ++ EVDEV_ABS_36=::90 ++ ++# MacBookPro13,* (Late 2016), MacBookPro14,* (Mid 2017) ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro13,1:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro13,2:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro14,1:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro14,2:* ++ EVDEV_ABS_00=::96 ++ EVDEV_ABS_01=::94 ++ EVDEV_ABS_35=::96 ++ EVDEV_ABS_36=::94 ++ ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro13,3:* ++evdev:name:Apple SPI Touchpad:dmi:*:svnAppleInc.:pnMacBookPro14,3:* ++ EVDEV_ABS_00=::96 ++ EVDEV_ABS_01=::95 ++ EVDEV_ABS_35=::96 ++ EVDEV_ABS_36=::95 ++ + ######################################### + # ASUS + ######################################### + ++# Asus N53SV ++evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnASUSTeKComputerInc.:pnN53SV:* ++ EVDEV_ABS_00=0:1152:14 ++ EVDEV_ABS_01=0:576:10 ++ EVDEV_ABS_35=0:1152:14 ++ EVDEV_ABS_36=0:576:10 ++ + # Asus F3Sg + evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnASUSTeKComputerInc.:pnF3Sg:* + EVDEV_ABS_00=0:6143:136 + EVDEV_ABS_01=1103:5856:61 + + # Asus VivoBook E402SA +-evdev:name:Elan Touchpad:dmi:*svnASUSTeKCOMPUTERINC.:pnE402SA* ++evdev:name:Elan Touchpad:dmi:*svnASUSTeKCOMPUTERINC.:pnE402SA:* + EVDEV_ABS_00=::29 + EVDEV_ABS_01=::29 + EVDEV_ABS_35=::29 +@@ -137,31 +189,42 @@ evdev:name:Elan Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnUX305UA:* + EVDEV_ABS_35=0:3097:32 + EVDEV_ABS_36=0:2119:33 + ++######################################### ++# Bangho ++######################################### ++ ++# Bangho Cloud Pro ++evdev:name:SYNA3602:00 0911:5288 Touchpad:dmi:*svnBANGHO:pnCLOUDPRO:* ++ EVDEV_ABS_00=52:1747:17 ++ EVDEV_ABS_01=45:954:14 ++ EVDEV_ABS_35=52:1747:17 ++ EVDEV_ABS_36=45:954:14 ++ + ######################################### + # Dell + ######################################### + + # Dell Vostro 1510 +-evdev:name:AlpsPS/2 ALPS GlidePoint*:dmi:bvn*:bvr*:bd*:svnDellInc.:pnVostro1510* ++evdev:name:AlpsPS/2 ALPS GlidePoint*:dmi:bvn*:bvr*:bd*:svnDellInc.:pnVostro1510:* + EVDEV_ABS_00=::14 + EVDEV_ABS_01=::18 + + # Dell Inspiron 3537 - PS/2 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnDellInc.:pnInspiron3537* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnDellInc.:pnInspiron3537:* + EVDEV_ABS_00=1268:5675:41 + EVDEV_ABS_01=1101:4792:61 + EVDEV_ABS_35=1268:5675:41 + EVDEV_ABS_36=1101:4792:61 + + # Dell Inspiron 3537 - RMI4 +-evdev:name:Synaptics TM2382-001:dmi:*svnDellInc.:pnInspiron3537* ++evdev:name:Synaptics TM2382-001:dmi:*svnDellInc.:pnInspiron3537:* + EVDEV_ABS_00=::24 + EVDEV_ABS_01=::34 + EVDEV_ABS_35=::24 + EVDEV_ABS_36=::34 + + # Dell Inspiron N5040 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnInspironN5040* ++evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnInspironN5040:* + EVDEV_ABS_00=25:2000:22 + EVDEV_ABS_01=0:1351:28 + EVDEV_ABS_35=25:2000:22 +@@ -172,50 +235,71 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*bvn*:bvr*:bd*:svnDellInc.:pnMM061:* + EVDEV_ABS_00=1008:5793:66 + EVDEV_ABS_01=687:5176:107 + ++# Dell Latitude E5510 ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnDellInc.:pnLatitudeE5510:* ++ EVDEV_ABS_00=73:1828:26 ++ EVDEV_ABS_01=101:1319:27 ++ EVDEV_ABS_35=73:1828:26 ++ EVDEV_ABS_36=101:1319:27 ++ + # Dell Latitude E6220 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6220* ++evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6220:* + EVDEV_ABS_00=76:1815:22 + EVDEV_ABS_01=131:1330:30 + EVDEV_ABS_35=76:1815:22 + EVDEV_ABS_36=131:1330:30 + + # Dell Latitude E6320 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320* ++evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320:* + EVDEV_ABS_00=79:1841:22 + EVDEV_ABS_01=140:1325:29 + EVDEV_ABS_35=79:1841:22 + EVDEV_ABS_36=140:1325:29 + ++# Dell Latitude E7250 ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7250:* ++ EVDEV_ABS_00=179:3903:38 ++ EVDEV_ABS_01=277:1916:32 ++ EVDEV_ABS_35=179:3903:38 ++ EVDEV_ABS_36=277:1916:32 ++ + # Dell Latitude E7470 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470* +- EVDEV_ABS_00=29:2930:30 +- EVDEV_ABS_01=26:1533:29 +- EVDEV_ABS_35=29:2930:30 +- EVDEV_ABS_36=26:1533:29 ++evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470:* ++ EVDEV_ABS_00=29:2930:30:16 ++ EVDEV_ABS_01=26:1533:29:16 ++ EVDEV_ABS_35=29:2930:30:16 ++ EVDEV_ABS_36=26:1533:29:16 + + # Dell Precision 5510 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510:* + EVDEV_ABS_00=::42 + EVDEV_ABS_01=::43 + EVDEV_ABS_35=::42 + EVDEV_ABS_36=::43 + + # Dell Precision M4700 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnDellInc.:pnPrecisionM4700* ++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 XPS13 9360 ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnDellInc.:pnXPS139360:cvr:* ++ EVDEV_ABS_00=::42 ++ EVDEV_ABS_01=::60 ++ EVDEV_ABS_35=::42 ++ EVDEV_ABS_36=::60 ++ + # Dell XPS15 9550 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPS159550* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPS159550:* + EVDEV_ABS_00=::41 + EVDEV_ABS_01=::43 + EVDEV_ABS_35=::41 + EVDEV_ABS_36=::43 + + # Dell XPS M1530 +-evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPSM1530* ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPSM1530:* + EVDEV_ABS_00=85:947:15 + EVDEV_ABS_01=154:726:18 + +@@ -233,7 +317,7 @@ evdev:input:b0003v0430p0530* + ######################################### + + # Chromebook Pixel (2015) - Samus +-evdev:name:Atmel maXTouch Touch*:dmi:bvn*:bvr*:bd*:svnGOOGLE:pnSamus* ++evdev:name:Atmel maXTouch Touch*:dmi:bvn*:bvr*:bd*:svnGOOGLE:pnSamus:* + EVDEV_ABS_00=::10 + EVDEV_ABS_01=::10 + EVDEV_ABS_35=::10 +@@ -243,15 +327,29 @@ evdev:name:Atmel maXTouch Touch*:dmi:bvn*:bvr*:bd*:svnGOOGLE:pnSamus* + # HP + ######################################### + ++# HP Chromebook 14 (Falco) ++evdev:name:Cypress APA Trackpad ?cyapa?:dmi:*:svnHewlett-Packard*:pnFalco*:* ++ EVDEV_ABS_00=:::8 ++ EVDEV_ABS_01=:::8 ++ EVDEV_ABS_35=:::8 ++ EVDEV_ABS_36=:::8 ++ + # HP Pavilion dm4 +-evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondm4* ++evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondm4:* + EVDEV_ABS_00=1360:5563:47 + EVDEV_ABS_01=1269:4618:61 + EVDEV_ABS_35=1360:5563:47 + EVDEV_ABS_36=1269:4618:61 + ++# HP Pavilion g6 ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvnHewlett-Packard:*svnHewlett-Packard:pnHPPaviliong6:* ++ EVDEV_ABS_00=1255:5728:50 ++ EVDEV_ABS_01=1215:4761:71 ++ EVDEV_ABS_35=1255:5728:50 ++ EVDEV_ABS_36=1215:4761:71 ++ + # HP Pavilion dv7 +-evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondv7* ++evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondv7:* + EVDEV_ABS_00=1068:5805:44 + EVDEV_ABS_01=1197:4890:57 + EVDEV_ABS_35=1068:5805:44 +@@ -265,39 +363,46 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnHP:pnHPLaptop15-bs0xx:* + EVDEV_ABS_36=1029:4916:78 + + # HP Spectre +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:i*svnHP:pnHPSpectreNotebook* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnHP:pnHPSpectreNotebook:* + EVDEV_ABS_00=1205:5691:47 + EVDEV_ABS_01=1083:4808:65 + EVDEV_ABS_35=1205:5691:47 + EVDEV_ABS_36=1083:4808:65 + ++# HP Envy x360 ++evdev:name:SynPS/2 Synaptics TouchPad:*svnHP:pnHPENVYx360Convertible15m-cn0xxx:* ++ EVDEV_ABS_00=1302:5640:36 ++ EVDEV_ABS_01=1119:4741:61 ++ EVDEV_ABS_35=1302:5640:36 ++ EVDEV_ABS_36=1119:4741:61 ++ + ######################################### + # Lenovo + ######################################### + + # Lenovo B590 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrLenovoB590* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrLenovoB590:* + EVDEV_ABS_00=1243:5759:48 + EVDEV_ABS_01=1130:4832:65 + EVDEV_ABS_35=1243:5759:48 + EVDEV_ABS_36=1130:4832:65 + + # Lenovo E530 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:pn*ThinkPadEdgeE530* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:pn*ThinkPadEdgeE530:* + EVDEV_ABS_00=1241:5703:49 + EVDEV_ABS_01=1105:4820:68 + EVDEV_ABS_35=1241:5703:49 + EVDEV_ABS_36=1105:4820:68 + + # Lenovo L430 +-evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnLENOVO*:pvrThinkPadL430* ++evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnLENOVO*:pvrThinkPadL430:* + EVDEV_ABS_00=19:2197:29 + EVDEV_ABS_01=12:1151:25 + EVDEV_ABS_35=19:2197:29 + EVDEV_ABS_36=12:1151:25 + + # Lenovo P50 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*P50* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*P50:* + EVDEV_ABS_00=::44 + EVDEV_ABS_01=::67 + EVDEV_ABS_35=::44 +@@ -311,120 +416,207 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPad??40?:* + EVDEV_ABS_35=::41 + EVDEV_ABS_36=::37 + ++# Lenovo X240 series ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX240:* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX240?:* ++ EVDEV_ABS_00=1232:5711:51:13 ++ EVDEV_ABS_01=1159:4700:53:13 ++ EVDEV_ABS_35=1232:5711:51:13 ++ EVDEV_ABS_36=1159:4700:53:13 ++ ++# Lenovo ThinkPad X140e ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX140e:* ++ EVDEV_ABS_00=1176:5767:62 ++ EVDEV_ABS_01=416:5534:160 ++ EVDEV_ABS_35=1176:5767:62 ++ EVDEV_ABS_36=416:5534:160 ++ + # Lenovo ThinkPad T430 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadT430* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadT430:* + EVDEV_ABS_00=1250:5631:58 + EVDEV_ABS_01=1309:4826:78 + EVDEV_ABS_35=1250:5631:58 + EVDEV_ABS_36=1309:4826:78 + ++# Lenovo Thinkpad X1 Carbon Extreme 3rd gen. ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*pvrThinkPadX1ExtremeGen3* ++ EVDEV_ABS_00=1354:5678:43 ++ EVDEV_ABS_01=1169:4695:51 ++ EVDEV_ABS_35=1354:5678:43 ++ EVDEV_ABS_36=1169:4695:51 ++ + # Lenovo Thinkpad Carbon X1 4th gen. and X1 Yoga 1st gen. +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon4th* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon4th:* + EVDEV_ABS_00=1262:5679:44 + EVDEV_ABS_01=1101:4824:65 + EVDEV_ABS_35=1262:5679:44 + EVDEV_ABS_36=1101:4824:65 + + # Lenovo Thinkpad Carbon X1 5th gen. +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th:* + EVDEV_ABS_00=::44 + EVDEV_ABS_01=::65 + EVDEV_ABS_35=::44 + EVDEV_ABS_36=::65 + + # Lenovo Thinkpad Carbon X1 5th gen. (rmi4) +-evdev:name:Synaptics TM3289-002:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th* ++evdev:name:Synaptics TM3289-002:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th:* + EVDEV_ABS_00=::19 + EVDEV_ABS_01=::19 + EVDEV_ABS_35=::19 + EVDEV_ABS_36=::19 + ++# Lenovo Thinkpad X1 Tablet Gen3 ++evdev:input:b0003v17EFp60B5* ++ EVDEV_ABS_00=::12 ++ EVDEV_ABS_01=::11 ++ EVDEV_ABS_35=::12 ++ EVDEV_ABS_36=::11 ++ + # Lenovo T460 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460:* + EVDEV_ABS_00=1266:5677:44 + EVDEV_ABS_01=1093:4832:65 + EVDEV_ABS_35=1266:5677:44 + EVDEV_ABS_36=1093:4832:65 + + # Lenovo T510 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T510* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T510:* + EVDEV_ABS_00=778:6239:72 + EVDEV_ABS_01=841:5330:100 + EVDEV_ABS_35=778:6239:72 + EVDEV_ABS_36=841:5330:100 + + # Lenovo V360 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrLenovoV360* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrLenovoV360:* + EVDEV_ABS_00=1243:5927:60 + EVDEV_ABS_01=902:5330:108 + + # Lenovo W530 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadW530* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadW530:* + EVDEV_ABS_00=1250:5631:59 + EVDEV_ABS_01=1205:4834:81 + EVDEV_ABS_35=1250:5631:59 + EVDEV_ABS_36=1205:4834:81 + + # Lenovo X220 series +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadX220* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadX220:* + EVDEV_ABS_00=1316:5627:58 + EVDEV_ABS_01=1355:4826:81 + EVDEV_ABS_35=1316:5627:58 + EVDEV_ABS_36=1355:4826:81 + + # Lenovo X230 series +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*X230* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*X230:* + EVDEV_ABS_01=::100 + EVDEV_ABS_36=::100 + + # Lenovo Y700-14ISK +-evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoideapadY700-14ISK* ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoideapadY700-14ISK:* + EVDEV_ABS_00=::27 + EVDEV_ABS_01=::29 + EVDEV_ABS_35=::27 + EVDEV_ABS_36=::29 + ++# Lenovo Ideapad 310S-14ISK ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoideapad310S-14ISK:* ++ EVDEV_ABS_00=113:3960:37 ++ EVDEV_ABS_01=100:1959:27 ++ EVDEV_ABS_35=113:3960:37 ++ EVDEV_ABS_36=100:1959:27 ++ + # Lenovo Ideapad 500S-13ISK +-evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoideapad500S-13ISK* ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoideapad500S-13ISK:* + EVDEV_ABS_00=125:3955:37 + EVDEV_ABS_01=104:1959:27 + EVDEV_ABS_35=125:3954:37 + EVDEV_ABS_36=104:1959:27 + + # Lenovo Yoga 500-14ISK +-evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoYoga500-14ISK* ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoYoga500-14ISK:* + EVDEV_ABS_00=124:3955:36 + EVDEV_ABS_01=103:1959:26 + EVDEV_ABS_35=124:3955:36 + EVDEV_ABS_36=103:1959:26 + + # Lenovo Flex 3 15-inch +-evdev:name:AlpsPS/2 ALPS GlidePoint*:dmi:bvn*:bvr*:bd*:svnLENOVO*:pvrFlex3-15* ++evdev:name:AlpsPS/2 ALPS GlidePoint*:dmi:bvn*:bvr*:bd*:svnLENOVO*:pvrFlex3-15:* + EVDEV_ABS_00=::38 + EVDEV_ABS_01=::28 + EVDEV_ABS_35=::38 + EVDEV_ABS_36=::28 + + # Lenovo ThinkPad Edge 13 (02173BG) +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*02173BG*:*pvrThinkPadEdge* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*02173BG*:*pvrThinkPadEdge:* + EVDEV_ABS_00=916:6077:55 + EVDEV_ABS_01=653:5395:116 + EVDEV_ABS_35=916:6077:55 + EVDEV_ABS_36=653:5395:116 + ++# Lenovo Yoga 500-14IBD, 80N4 ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoYoga500-14IBD:* ++ EVDEV_ABS_00=117:3952:36 ++ EVDEV_ABS_01=105:1960:26 ++ EVDEV_ABS_35=117:3952:36 ++ EVDEV_ABS_36=105:1960:26 ++ ++# Lenovo U41-70 (80JV) ++evdev:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnLENOVO:*pvrLenovoU41-70:* ++ EVDEV_ABS_00=117:3958:36 ++ EVDEV_ABS_01=104:1960:26 ++ EVDEV_ABS_35=117:3958:36 ++ EVDEV_ABS_36=104:1960:26 ++ ++# Lenovo Thinkpad T490 and T14/P14s Gen1/2 ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*:svnLENOVO:*pvrThinkPadT490:* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*:svnLENOVO:*pvrThinkPadT14Gen1:* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*:svnLENOVO:*pvrThinkPadP14sGen1:* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*:svnLENOVO:*pvrThinkPadP14sGen2a:* ++ EVDEV_ABS_00=::44 ++ EVDEV_ABS_01=::52 ++ EVDEV_ABS_35=::44 ++ EVDEV_ABS_36=::52 ++ ++# Lenovo Legion Y9000X2020 ++evdev:name:MSFT0001:02 04F3:304B Touchpad:dmi:*svnLENOVO:*pvrLenovoLegionY9000X2020:* ++ EVDEV_ABS_00=::31 ++ EVDEV_ABS_01=::30 ++ EVDEV_ABS_35=::31 ++ EVDEV_ABS_36=::30 ++ ++######################################### ++# NEWYES ++######################################### ++ ++# NEWYES 10" LCD writing tablet ++evdev:input:b0003v6161p4D15* ++ EVDEV_ABS_00=::152 ++ EVDEV_ABS_01=::244 ++ ++########################################################### ++# Pine64 ++########################################################### ++ ++# Pinebook Pro ++evdev:input:b0003v258Ap001E* ++ EVDEV_ABS_00=::15 ++ EVDEV_ABS_01=::15 ++ EVDEV_ABS_35=::15 ++ EVDEV_ABS_36=::15 ++ + ######################################### + # Razer + ######################################### + + # Razer Blade Stealth +-evdev:name:1A586753:00 06CB:8323 Touchpad:dmi:*svnRazer:pnBladeStealth:* ++evdev:name:1A58675*:00 06CB:8323 Touchpad:dmi:*svnRazer:pnBladeStealth:* + EVDEV_ABS_00=::12:8 + EVDEV_ABS_01=::11:8 + EVDEV_ABS_35=::12:8 + EVDEV_ABS_36=::11:8 + + # Razer Blade Stealth (2016) +-evdev:name:Synaptics TM2438-005:dmi:*svnRazer:pnBladeStealth* ++evdev:name:Synaptics TM2438-005:dmi:*svnRazer:pnBladeStealth:* + EVDEV_ABS_00=0:4064:29 + EVDEV_ABS_01=0:2405:37 + EVDEV_ABS_35=0:4064:29 +@@ -435,19 +627,37 @@ evdev:name:Synaptics TM2438-005:dmi:*svnRazer:pnBladeStealth* + ######################################### + + # Samsung 305V4 +-evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn305V4A/305V5A* ++evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn305V4A/305V5A:* + EVDEV_ABS_00=0:2480:28 + EVDEV_ABS_01=0:1116:24 + EVDEV_ABS_35=0:2480:28 + EVDEV_ABS_36=0:1116:24 + + # Samsung 880Z5E +-evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/880Z5E/680Z5E* ++evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/880Z5E/680Z5E:* + EVDEV_ABS_00=::30 + EVDEV_ABS_01=::29 + EVDEV_ABS_35=::30 + EVDEV_ABS_36=::29 + ++######################################### ++# Star Labs ++######################################### ++ ++# Star LabTop Mk III ++evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLabTop:* ++ EVDEV_ABS_00=0:2627:25 ++ EVDEV_ABS_01=0:1331:20 ++ EVDEV_ABS_35=0:2627:25 ++ EVDEV_ABS_36=0:1331:20 ++ ++# Star Lite Mk II ++evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLite:* ++ EVDEV_ABS_00=55:1750:16 ++ EVDEV_ABS_01=51:950:15 ++ EVDEV_ABS_35=55:1750:16 ++ EVDEV_ABS_36=51:950:15 ++ + ######################################### + # System76 + ######################################### +@@ -464,17 +674,26 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnSystem76:pnGalagoPro:pvrgalp2:* + ######################################### + + # Toshiba Tecra M11 +-evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnTOSHIBA:pnTECRAM11* ++evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnTOSHIBA:pnTECRAM11:* + EVDEV_ABS_00=90:962:11 + EVDEV_ABS_01=51:681:14 + + # Toshiba Satellite R830 +-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnTOSHIBA:pnSATELLITER830* ++evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnTOSHIBA:pnSATELLITER830:* + EVDEV_ABS_00=1238:5785:53 + EVDEV_ABS_01=1045:4826:76 + EVDEV_ABS_35=1238:5785:53 + EVDEV_ABS_36=1045:4826:76 + ++######################################### ++# UGTablet ++######################################### ++ ++# Trust Flex Graphics Tablet ++evdev:input:b0003v2179p0004* ++ EVDEV_ABS_00=::234 ++ EVDEV_ABS_01=::328 ++ + ######################################### + # Waltop + ######################################### +@@ -483,3 +702,13 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnTOSHIBA:pnSATELLITER830* + evdev:input:b0003v172Fp0031* + EVDEV_ABS_00=0:10000:400 + EVDEV_ABS_01=0:6250:400 ++ ++# WALTOP International Corp. Graphics Tablet ++evdev:input:b0003v172Fp0047* ++ EVDEV_ABS_00=0:20000:80 ++ EVDEV_ABS_01=0:12500:80 ++ ++# WALTOP International Corp. Batteryless Tablet ++evdev:input:b0003v172Fp0505* ++ EVDEV_ABS_00=::160 ++ EVDEV_ABS_01=::160 +diff --git a/hwdb/60-input-id.hwdb b/hwdb/60-input-id.hwdb +index b05b402d74..2b1aa4579a 100644 +--- a/hwdb/60-input-id.hwdb ++++ b/hwdb/60-input-id.hwdb +@@ -3,10 +3,10 @@ + # The lookup keys are composed in: + # 60-input-id.rules + # +-# Note: The format of the "input-id:" prefix match key is a +-# contract between the rules file and the hardware data, it might +-# change in later revisions to support more or better matches, it +-# is not necessarily expected to be a stable ABI. ++# Note: The format of the "input-id:" prefix match key is a contract between ++# the rules file and the hardware data, it might change in later revisions to ++# support more or better matches, it is not necessarily expected to be a stable ++# ABI. + # + # Match string formats: + # id-input:modalias: +@@ -27,16 +27,14 @@ + # udevadm info /dev/input/eventXX. + # + # This file must only be used where the input_id builtin assigns the wrong +-# properties or lacks the assignment of some properties. This is almost +-# always caused by a device not adhering to the standard of the device's +-# type. ++# properties or lacks the assignment of some properties. This is almost always ++# caused by a device not adhering to the standard of the device's type. + # + # Allowed properties are: +-# ID_INPUT +-# ID_INPUT_ACCELEROMETER, ID_INPUT_MOUSE, +-# ID_INPUT_POINTINGSTICK, ID_INPUT_TOUCHSCREEN, ID_INPUT_TOUCHPAD, +-# ID_INPUT_TABLET, ID_INPUT_TABLET_PAD, ID_INPUT_JOYSTICK, ID_INPUT_KEY, +-# ID_INPUT_KEYBOARD, ID_INPUT_SWITCH, ID_INPUT_TRACKBALL ++# ID_INPUT, ID_INPUT_ACCELEROMETER, ID_INPUT_MOUSE, ID_INPUT_POINTINGSTICK, ++# ID_INPUT_TOUCHSCREEN, ID_INPUT_TOUCHPAD, ID_INPUT_TABLET, ++# ID_INPUT_TABLET_PAD, ID_INPUT_JOYSTICK, ID_INPUT_KEY, ID_INPUT_KEYBOARD, ++# ID_INPUT_SWITCH, ID_INPUT_TRACKBALL + # + # ID_INPUT + # * MUST be set when ANY of ID_INPUT_* is set +@@ -45,7 +43,7 @@ + # ID_INPUT_TABLET + # * MUST be set when setting ID_INPUT_TABLET_PAD + # +-# Allowed values are 1 and 0 to set or unset, repsectively. ++# Allowed values are 1 and 0 to set or unset, respectively. + # + # NOT allowed in this file are: + # ID_INPUT_WIDTH_MM, ID_INPUT_HEIGHT_MM, ID_INPUT_TOUCHPAD_INTEGRATION +@@ -62,3 +60,19 @@ + id-input:modalias:input:b0003v5543p0081* + ID_INPUT_TABLET=1 + ID_INPUT_TABLET_PAD=1 ++ ++# XP-PEN STAR 06 ++id-input:modalias:input:b0003v28bdp0078* ++ ID_INPUT_TABLET=1 ++ ++# Lite-On Tech IBM USB Travel Keyboard with Ultra Nav Mouse ++id-input:modalias:input:b0003v04B3p301Ee0100-e0,1,2,4* ++ ID_INPUT_POINTINGSTICK=1 ++ ++# Logitech Ultrathin Touch Mouse ++id-input:modalias:input:b0005v046DpB00De0700* ++ ID_INPUT_MOUSE=1 ++ ++# Logitech MX Keys ++id-input:modalias:input:b0003v046Dp408Ae0111* ++ ID_INPUT_MOUSE=0 +diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb +index ae3ec3ca15..2e06143697 100644 +--- a/hwdb/60-keyboard.hwdb ++++ b/hwdb/60-keyboard.hwdb +@@ -13,17 +13,17 @@ + # The lookup keys are composed in: + # 60-evdev.rules + # +-# Note: The format of the "evdev:" prefix match key is a +-# contract between the rules file and the hardware data, it might +-# change in later revisions to support more or better matches, it +-# is not necessarily expected to be a stable ABI. ++# Note: The format of the "evdev:" prefix match key is a contract between the ++# rules file and the hardware data, it might change in later revisions to ++# support more or better matches, it is not necessarily expected to be a stable ++# ABI. + # + # Supported hardware matches are: + # - Generic input devices match: + # evdev:input:bZZZZvYYYYpXXXXeWWWW-VVVV + # This matches on the kernel modalias of the input-device, mainly: + # ZZZZ is the bus-id (see /usr/include/linux/input.h BUS_*), YYYY, XXXX and +-# WWW are the 4-digit hex uppercase vendor, product and version ID and VVVV ++# WWWW are the 4-digit hex uppercase vendor, product and version ID and VVVV + # is an arbitrary length input-modalias describing the device capabilities. + # The vendor, product and version ID for a device node "eventX" is listed + # in /sys/class/input/eventX/device/id. +@@ -48,7 +48,6 @@ + # firmware-provided string exported by the kernel DMI modalias, + # see /sys/class/dmi/id/modalias + +- + # ######################### KEY MAPPING ###################################### + # + # Keyboard mapping of scan codes to key codes, and +@@ -71,11 +70,17 @@ + + # A device with a fixed keyboard layout that must not be changed by + # the desktop environment may specify that layout as: +-# XKB_FIXED_LAYOUT="us" +-# XKB_FIXED_VARIANT="" ++# XKB_FIXED_LAYOUT=us ++# XKB_FIXED_VARIANT= + # Examples of such devices: the Yubikey or other key-code generating + # devices. +-# ++ ++# A device where the scan code to key code mapping is insufficient and ++# requires a special key code to symbol configuration may specify that with: ++# XKB_FIXED_MODEL=xkbmodel ++# Examples of such devices: Chromebooks where the top row is used for both ++# media and F1-F10 keys. ++ + # To update this file, create a new file + # /etc/udev/hwdb.d/70-keyboard.hwdb + # and add your rules there. To load the new rules execute (as root): +@@ -97,9 +102,9 @@ + ########################################## + + # common keys +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:* + KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings +@@ -127,17 +132,17 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr* + KEYBOARD_KEY_f9=prog1 # Launch NTI shadow + + # Acer kernel driver +-evdev:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:pvr* ++evdev:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:* + KEYBOARD_KEY_82=f21 # Touchpad toggle + + # Aspire models +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*:* + KEYBOARD_KEY_84=bluetooth # sent when bluetooth module missing, and key pressed + KEYBOARD_KEY_d9=bluetooth # Bluetooth off + KEYBOARD_KEY_92=media # Acer arcade + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*5720*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*5720*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnZG8*:* + KEYBOARD_KEY_f4=prog3 # e-key + + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*5920G:* +@@ -151,74 +156,98 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*8930:* + KEYBOARD_KEY_89=fastforward + KEYBOARD_KEY_9e=back + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*7750G:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*7750G:* + KEYBOARD_KEY_e0=!pageup + ++# Predator PH 315-52 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredator*PH*315-52:* ++ KEYBOARD_KEY_ef=kbdillumup # Fn+F10 ++ KEYBOARD_KEY_f0=kbdillumdown # Fn+F9 ++ + # Travelmate C300 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:* + KEYBOARD_KEY_67=f24 # FIXME: rotate screen + KEYBOARD_KEY_68=up + KEYBOARD_KEY_69=down + KEYBOARD_KEY_6b=fn + KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons + +-# Travelmate P648-G2-MG and P645-S +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P645-S*:pvr* ++# Travelmate P648-G2-MG, P648-G3-M and P645-S ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G3-M*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P645-S*:* + KEYBOARD_KEY_8a=f20 # Microphone mute button; should be micmute + + # on some models this isn't brightnessup +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5610*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5620*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5720*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5610*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5620*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5720*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*4720*:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*6593:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*1640:* + KEYBOARD_KEY_ee=screenlock + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAOA*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAOA*:* + KEYBOARD_KEY_a9=!switchvideomode # Fn+F5 + +-# Easynote models +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pnEasynote*:pvr* ++# Packard Bell and Gateway models ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGateway*:pn*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pn*:* + KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key + + ########################################################### + # Alienware + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn* ++# Alienware/Dell reserves these keys; safe to apply on all their devices ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn*:* ++ KEYBOARD_KEY_81=f21 # Touchpad toggle + KEYBOARD_KEY_8a=ejectcd ++ KEYBOARD_KEY_bf=!prog1 # graphics amplifier, cable plug-in event ++ KEYBOARD_KEY_c1=!prog2 # graphics amplifier, undock-button event ++ KEYBOARD_KEY_c2=!power # graphics amplifier, surprise undock event + +-# Alienware/Dell reserves these keys; safe to apply on all their devices +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn*:pvr* +- KEYBOARD_KEY_bf=!prog1 #graphics amplifier, cable plug-in event +- KEYBOARD_KEY_c1=!prog2 #graphics amplifier, undock-button event +- KEYBOARD_KEY_c2=!power #graphics amplifier, surprise undock event ++# Alienware M17xR3 laptops ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pnM17xR3:* ++ KEYBOARD_KEY_89=ejectcd + + ########################################################### + # Asus + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnASUS:pn* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnASUS:pn*:* + KEYBOARD_KEY_ed=volumeup + KEYBOARD_KEY_ee=volumedown + KEYBOARD_KEY_ef=mute + +-evdev:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr* +-evdev:name:Eee PC WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr* +-evdev:name:Asus Laptop extra buttons:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr* ++evdev:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* ++evdev:name:Eee PC WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* ++evdev:name:Asus Laptop extra buttons:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* + KEYBOARD_KEY_6b=f21 # Touchpad Toggle + ++# USB keyboard in Asus FX503VD ++evdev:input:b0003v0B05p1869* ++ KEYBOARD_KEY_ff31007c=f20 # Remap micmute to f20 ++ + ########################################################### + # BenQ + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook*R22*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*BenQ*:pn*Joybook*R22*:* + KEYBOARD_KEY_6e=wlan + ++########################################################### ++# Clevo ++########################################################### ++ ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnNotebook:pnW65_67SZ:* ++ KEYBOARD_KEY_a0=!mute ++ KEYBOARD_KEY_a2=!playpause ++ KEYBOARD_KEY_ae=!volumedown ++ KEYBOARD_KEY_b0=!volumeup ++ + ########################################################### + # Compal + ########################################################### +@@ -230,8 +259,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCOMPAL:pnHEL80I:* + # COMPAQ + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo*N*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*E500*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo*N*:* + KEYBOARD_KEY_a3=www # I key + KEYBOARD_KEY_9a=search + KEYBOARD_KEY_9e=email +@@ -256,7 +285,7 @@ evdev:name:gpio-keys:phys:gpio-keys/input0:ev:3:dmi:bvn*:bvr*:bd*:svncube:pni1-T + # Dell + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pn* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pn*:* + KEYBOARD_KEY_81=playpause # Play/Pause + KEYBOARD_KEY_82=stopcd # Stop + KEYBOARD_KEY_83=previoussong # Previous song +@@ -264,7 +293,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pn* + KEYBOARD_KEY_85=brightnessdown # Fn+Down Brightness Down + KEYBOARD_KEY_86=brightnessup # Fn+Up Brightness Up + KEYBOARD_KEY_87=battery # Fn+F3 battery icon +- KEYBOARD_KEY_88=!wlan # Fn+(F2|PrtScr|Home) Turn On/Off Wireless ++ KEYBOARD_KEY_88=unknown # Fn+F2 Turn On/Off Wireless - handled in hardware + KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD + KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate + KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") +@@ -288,65 +317,80 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pn* + KEYBOARD_KEY_d9=f21 # Touchpad toggle + + # +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*910:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*101[012]:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1110:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1210:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*910:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*101[012]:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1110:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1210:* + KEYBOARD_KEY_84=wlan + ++# Dell Inspiron 11 3168 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron11-3168:pvr* ++ KEYBOARD_KEY_c7=!home # Fn-LeftArrow ++ KEYBOARD_KEY_cf=!end # Fn-RightArrow ++ KEYBOARD_KEY_c9=!pageup # Fn-UpArrow ++ KEYBOARD_KEY_d1=!pagedown # Fn-DownArrow ++ + # Dell Inspiron 1520 and Latitude 2110 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1520:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*2110:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1520:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*2110:* + KEYBOARD_KEY_85=unknown # Brightness Down, also emitted by acpi-video, ignore + KEYBOARD_KEY_86=unknown # Brightness Up, also emitted by acpi-video, ignore + ++# Dell Inspiron 537* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron537*:* ++ KEYBOARD_KEY_88=!wlan # Fn-PrtScr rfkill ++ + # Latitude XT2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*XT2:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*XT2:* + KEYBOARD_KEY_9b=up # tablet rocker up + KEYBOARD_KEY_9e=enter # tablet rocker press + KEYBOARD_KEY_9f=back # tablet back + KEYBOARD_KEY_a3=down # tablet rocker down + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio*155[78]:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio*155[78]:* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up + + # Dell Touchpad +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:* + KEYBOARD_KEY_88=! # wireless switch + KEYBOARD_KEY_9e=!f21 + + # Dell Latitude E7* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E7*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E7*:* + KEYBOARD_KEY_88=unknown # Fn-PrtScr rfkill - handled in HW + + # Dell XPS +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:* + KEYBOARD_KEY_8c=!unknown + + # Dell XPS L702x +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDellInc.:pnDellSystemXPSL702X:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDellInc.:pnDellSystemXPSL702X:* + KEYBOARD_KEY_84=prog1 + KEYBOARD_KEY_85=prog2 + + # Dell XPS12 9Q33 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:* + KEYBOARD_KEY_88=wlan + KEYBOARD_KEY_65=direction # Screen Rotate + + # Dell Latitude microphone mute +-evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude* ++evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* + # Dell Precision microphone mute +-evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision* +- KEYBOARD_KEY_100150=f20 # Mic mute toggle, should be micmute ++evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:* ++ KEYBOARD_KEY_100150=f20 # Mic mute toggle, should be micmute ++ ++# Dell Latitude privacy microphone mute ++evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* ++ KEYBOARD_KEY_120001=f20 # Mic mute toggle, should be micmute + + ########################################################### + # Everex + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:* + KEYBOARD_KEY_5c=media + KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle + KEYBOARD_KEY_67=prog3 # Fan speed control button +@@ -359,7 +403,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:pvr* + # Fujitsu + ########################################## + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*M*:* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + +@@ -373,25 +417,25 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pnAMILO*Li*2732:* + KEYBOARD_KEY_a9=switchvideomode # Fn+F10 Cycle between available video outputs + + # Amilo Pa 2548 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pa*2548*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pa*2548*:* + KEYBOARD_KEY_e0=volumedown + KEYBOARD_KEY_e1=volumeup + KEYBOARD_KEY_e5=prog1 + + # Amilo Pro Edition V3505 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*Edition*V3505*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*Edition*V3505*:* + KEYBOARD_KEY_a5=help # Fn+F1 + KEYBOARD_KEY_a9=switchvideomode # Fn+F3 + KEYBOARD_KEY_d9=brightnessdown # Fn+F8 + KEYBOARD_KEY_e0=brightnessup # Fn+F9 + + # Amilo Pro v3205 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*V3205*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*V3205*:* + KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock + KEYBOARD_KEY_f7=switchvideomode # Fn+F3 + + # Amilo Si 1520 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo*Si*1520*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo*Si*1520*:* + KEYBOARD_KEY_e1=wlan + KEYBOARD_KEY_f3=wlan + KEYBOARD_KEY_ee=brightnessdown +@@ -400,14 +444,14 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*Amilo*Si*1520*:pvr* + KEYBOARD_KEY_f7=video + + # Esprimo Mobile V5 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V5*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V5*:* + KEYBOARD_KEY_a9=switchvideomode + KEYBOARD_KEY_d9=brightnessdown + KEYBOARD_KEY_df=sleep + KEYBOARD_KEY_ef=brightnessup + + # Esprimo Mobile V6 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V6*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V6*:* + KEYBOARD_KEY_ce=brightnessup + KEYBOARD_KEY_ef=brightnessdown + +@@ -418,6 +462,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*ESPRIMO*Mobile*V6*:pvr* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pnU2442:* + KEYBOARD_KEY_a0=! # mute + ++########################################################### ++# Gemini ++########################################################### ++ ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGeminiDevices:pnNC14V1006:* ++ KEYBOARD_KEY_9c=enter ++ + ########################################################### + # Genius + ########################################################### +@@ -443,8 +494,11 @@ evdev:input:b0003v0458p0708* + # Hewlett Packard + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*:pvr* ++evdev:name:Intel HID events:dmi:bvn*:bvr*:bd*:svnHP*:pn*:* ++ KEYBOARD_KEY_8=unknown # Use hp-wireless instead ++ ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*:* + KEYBOARD_KEY_81=fn_esc + KEYBOARD_KEY_89=battery # Fn+F8 + KEYBOARD_KEY_8a=screenlock # Fn+F6 +@@ -459,7 +513,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*:pvr* + KEYBOARD_KEY_ee=switchvideomode # Fn+F4 + + # Tablet +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:* + KEYBOARD_KEY_82=prog2 # Funny Key + KEYBOARD_KEY_83=prog1 # Q + KEYBOARD_KEY_84=tab +@@ -468,59 +522,84 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:p + KEYBOARD_KEY_87=pagedown + + # Pavilion +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:* + KEYBOARD_KEY_88=media # FIXME: quick play + KEYBOARD_KEY_b7=print + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:* + KEYBOARD_KEY_b7=print + KEYBOARD_KEY_c2=media # FIXME: quick play + KEYBOARD_KEY_c6=break + KEYBOARD_KEY_94=reserved + +-# Pavilion x360 13 (Prevents random airplane mode activation) +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:pvr* ++# Pavilion 13 x360 (Tablet mode and SYSRQ key) ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:* ++ KEYBOARD_KEY_d7=!f22 # touchpad off ++ KEYBOARD_KEY_d9=unknown ++ KEYBOARD_KEY_d2=sysrq # Fn+Print = SYSRQ ++ ++# Spectre x360 13 (Prevents random airplane mode activation) ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[sS][pP][eE][cC][tT][rR][eE]*x360*13*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*[sS][pP][eE][cC][tT][rR][eE]*x360Convertible*:* + KEYBOARD_KEY_d7=unknown + ++# Spectre x360 13 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPSpectrex360Convertible13*:* ++# ENVY x360 13 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPENVYx360Convertible13*:* ++ KEYBOARD_KEY_82=f20 # Microphone mute button, should be micmute ++ ++# HP Elite x2 1013 G3 ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:* ++ KEYBOARD_KEY_f8=unknown # rfkill is also reported by HP Wireless hotkeys ++ KEYBOARD_KEY_64=calendar ++ KEYBOARD_KEY_81=f20 # Microphone mute button ++ KEYBOARD_KEY_ee=switchvideomode # Switch display outputs ++ KEYBOARD_KEY_92=brightnessdown ++ KEYBOARD_KEY_97=brightnessup ++ ++evdev:name:Intel HID events:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:* ++ KEYBOARD_KEY_08=unknown # rfkill is also reported by HP Wireless hotkeys ++ + # Elitebook +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2230s*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2230s*:* + KEYBOARD_KEY_88=presentation + KEYBOARD_KEY_d9=help # I key (high keycode: "info") + + # Presario +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:* + KEYBOARD_KEY_d8=f21 + KEYBOARD_KEY_d9=f21 + + # 2510p 2530p +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*G60*Notebook*PC:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*G60*Notebook*PC:* + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + + # 2570p +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2570p*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2570p*:* + KEYBOARD_KEY_f8=wlan # Wireless HW switch button + + # TX2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:* + KEYBOARD_KEY_c2=media + KEYBOARD_KEY_d8=!f23 # Toggle touchpad button on tx2 (OFF) + KEYBOARD_KEY_d9=!f22 # Toggle touchpad button on tx2 (ON) + + # Presario 2100 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario*2100*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario*2100*:* + KEYBOARD_KEY_f0=help + KEYBOARD_KEY_f1=screenlock + KEYBOARD_KEY_f3=search + + # Elitebook 8440p +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8440p:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8440p:* + KEYBOARD_KEY_88=www + KEYBOARD_KEY_a0=mute + KEYBOARD_KEY_ae=volumedown +@@ -528,71 +607,133 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8440p:pvr* + KEYBOARD_KEY_ec=mail + + # Elitebook 8460p +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8460p:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8460p:* + KEYBOARD_KEY_f8=wlan # Wireless HW switch button + KEYBOARD_KEY_b3=prog1 # Fn+F11 - Ambient Light Sensor button + KEYBOARD_KEY_b1=prog2 # Fn+ESC - System information button + + # HDX9494nr +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:* + KEYBOARD_KEY_b2=www # Fn+F3 + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + +-# Chromebook 14 +-# Top row keys (between ESC and power button) +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnFalco:pvr* +- KEYBOARD_KEY_3b=back +- KEYBOARD_KEY_3c=forward +- KEYBOARD_KEY_3d=refresh +- KEYBOARD_KEY_3f=switchvideomode +- KEYBOARD_KEY_40=brightnessdown +- KEYBOARD_KEY_41=brightnessup +- KEYBOARD_KEY_42=mute +- KEYBOARD_KEY_43=volumedown +- KEYBOARD_KEY_44=volumeup +- KEYBOARD_KEY_db=search # Same position as caps lock key on most keyboards +- # KEYBOARD_KEY_3e=fullscreen, no defined key sym +- + # HP EliteBook 725 G2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:* ++# HP EliteBook ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBook*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteBook*:* ++# HP Elite Dragonfly ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteDragonfly*:* + # HP ProBook 440 G2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP440G2:pvr* +-# several HP ProBooks 4xx +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook4*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*4*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP440G2:* ++# HP ProBook ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*:* + # HP ZBook +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBook*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBook*:* + KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute + +-# HP ZBook Studio G4 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPZBookStudioG4:pvr* ++# HP ZBook Studio G5 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBookStudioG5*:* ++ KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12) ++ KEYBOARD_KEY_6d=displaytoggle # Display icon ++ KEYBOARD_KEY_66=connect # Pickup phone button → connect → XF86Go ++ KEYBOARD_KEY_65=cancel # Hangup phone button → cancel → Cancel ++ ++# HP ZBook 15 G2 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook15G2:* + KEYBOARD_KEY_f8=wlan # Wireless HW switch button + +-# HP Folio 1040g2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:pvr* ++# HP ProBook 11 G1 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPProBook11G1:* + KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute ++ KEYBOARD_KEY_d8=f21 # touchpad toggle ++ KEYBOARD_KEY_d9=f21 # touchpad toggle ++ ++# HP ZBook Studio G4 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPZBookStudioG4:* ++ KEYBOARD_KEY_f8=wlan # Wireless HW switch button ++ ++# HP EliteBook Folio 1040 G2 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:* + KEYBOARD_KEY_d8=!f23 # touchpad off + KEYBOARD_KEY_d9=!f22 # touchpad on + ++# HP EliteBook Folio G1 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteBookFolioG1:* ++ KEYBOARD_KEY_64=calendar ++ KEYBOARD_KEY_81=f20 ++ ++# HP ProBook 650 ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*ProBook*650*:* ++ KEYBOARD_KEY_f8=wlan # Wireless HW switch button ++ + # HP ProBook 6555b + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard:pnHPProBook6555b:* + KEYBOARD_KEY_b2=www # Earth + + # HP ProBook 440 G3 +-evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*440*G3* ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*440*G3*:* + # HP ProBook 640 G2 +-evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*640*G2* ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*640*G2*:* + KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev + KEYBOARD_KEY_f8=unknown # rf kill; also reported via special evdev + ++# HP ProBook 645 G4 ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*645*G4*:* ++ KEYBOARD_KEY_73=slash # Slash key ++ KEYBOARD_KEY_f8=wlan # Wireless HW switch button ++ ++# HP ProBook 455 G5 ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*455*G5*:* ++ KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev ++ KEYBOARD_KEY_f8=wlan # Wireless HW switch button ++ ++# HP mt44 Mobile Thin Client ++evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*mt44*Mobile*Thin*Client*:* ++ KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12) ++ KEYBOARD_KEY_6d=displaytoggle # Display icon ++ KEYBOARD_KEY_66=connect # Pickup phone button → connect → XF86Go ++ KEYBOARD_KEY_65=cancel # Hangup phone button → cancel → Cancel ++ KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute ++ KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev ++ KEYBOARD_KEY_f8=wlan # Wireless HW switch button ++ ++# HP Stream 7 ++# The ACPI tables contains a gpio-keys entry for a non connected GPIO ++# causing spurious events, map this to unknown to disable it ++# older kernels use "ev:23" newer kernels "ev:3" ++evdev:name:gpio-keys:phys:gpio-keys/input0:ev:3:dmi:*:svnHewlett-Packard:pnHPStream7Tablet:* ++evdev:name:gpio-keys:phys:gpio-keys/input0:ev:23:dmi:*:svnHewlett-Packard:pnHPStream7Tablet:* ++ KEYBOARD_KEY_0=unknown ++ ++########################################################## ++# Huawei ++########################################################## ++ ++# Huawei WMI hotkeys driver ++evdev:name:Huawei WMI hotkeys:dmi:bvn*:bvr*:bd*:svnHUAWEI:* ++ KEYBOARD_KEY_287=f20 # Microphone mute button, should be micmute ++ ++# Huawei MACH-WX9 and EUL-WX9 ++evdev:atkbd:dmi:bvn*:bvr*:svnHUAWEI*:pnMACH-WX9:* ++evdev:atkbd:dmi:bvn*:bvr*:svnHUAWEI*:pnEUL-WX9:* ++ KEYBOARD_KEY_f7=unknown ++ KEYBOARD_KEY_f8=fn ++ ++evdev:name:Huawei WMI hotkeys:dmi:bvn*:bvr*:bd*:svnHUAWEI*:pnMACH-WX9:* ++evdev:name:Huawei WMI hotkeys:dmi:bvn*:bvr*:bd*:svnHUAWEI*:pnEUL-WX9:* ++ KEYBOARD_KEY_281=unknown # Brightness Down, also emitted by acpi-video, ignore ++ KEYBOARD_KEY_282=unknown # Brightness Up, also emitted by acpi-video, ignore ++ + ########################################################### + # IBM + ########################################################### + + # thinkpad_acpi driver +-evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:pvr* ++evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnIBM*:pn*:* + KEYBOARD_KEY_01=battery # Fn+F2 + KEYBOARD_KEY_02=screenlock # Fn+F3 + KEYBOARD_KEY_03=sleep # Fn+F4 +@@ -625,7 +766,7 @@ evdev:input:b0003v04B3p301[89]* + ########################################################### + + # Symphony +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY*6.0/7.0:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY*6.0/7.0:* + KEYBOARD_KEY_f3=prog2 + KEYBOARD_KEY_f4=prog1 + +@@ -634,7 +775,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY*6.0/7.0:pvr* + ########################################################### + + # thinkpad_acpi driver +-evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* ++evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:* + KEYBOARD_KEY_01=screenlock + KEYBOARD_KEY_02=battery + KEYBOARD_KEY_03=sleep +@@ -652,6 +793,7 @@ evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* + KEYBOARD_KEY_16=mute + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_1a=f20 # Microphone mute button; should be micmute ++ KEYBOARD_KEY_45=bookmarks + + # ThinkPad Keyboard with TrackPoint + evdev:input:b0003v17EFp6009* +@@ -669,7 +811,7 @@ evdev:input:b0003v17EFp6009* + KEYBOARD_KEY_090010=f20 # Microphone mute button; should be micmute + + # Lenovo 3000 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:* + KEYBOARD_KEY_8b=switchvideomode # Fn+F7 video + KEYBOARD_KEY_96=wlan # Fn+F5 wireless + KEYBOARD_KEY_97=sleep # Fn+F4 suspend +@@ -681,8 +823,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn0769AP2:pvr3000N200:* + KEYBOARD_KEY_b4=prog1 + + # lenovo-ideapad +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:* + KEYBOARD_KEY_81=rfkill # does nothing in BIOS + KEYBOARD_KEY_83=display_off # BIOS toggles screen state + KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS +@@ -692,7 +834,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:pvr* + KEYBOARD_KEY_f3=f21 + + # Thinkpad X200_Tablet +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X2*Tablet* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X2*Tablet*:* + KEYBOARD_KEY_5d=menu + KEYBOARD_KEY_63=fn + KEYBOARD_KEY_66=screenlock +@@ -701,7 +843,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X2*Tablet* + KEYBOARD_KEY_6c=direction # rotate screen + + # ThinkPad X6 Tablet +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet*:* + KEYBOARD_KEY_6c=direction # rotate + KEYBOARD_KEY_68=leftmeta # toolbox + KEYBOARD_KEY_6b=esc # escape +@@ -712,39 +854,56 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet* + KEYBOARD_KEY_69=enter # enter on d-pad + + # ThinkPad X41 Tablet +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnIBM*:pn18666TU:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnIBM*:pn18666TU:* + KEYBOARD_KEY_6c=direction # rotate + KEYBOARD_KEY_68=leftmeta # toolbox + KEYBOARD_KEY_6b=esc # escape + KEYBOARD_KEY_69=enter # enter on d-pad + + # IdeaPad +-evdev:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* ++evdev:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:* + KEYBOARD_KEY_0d=rfkill # airplane mode switch (toggle all wireless devices) + KEYBOARD_KEY_08=f20 # micmute + KEYBOARD_KEY_42=f23 + KEYBOARD_KEY_43=f22 + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:* + KEYBOARD_KEY_95=media + KEYBOARD_KEY_a3=play + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:* + KEYBOARD_KEY_f1=f21 + KEYBOARD_KEY_ce=f20 # micmute + +-evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:* ++ KEYBOARD_KEY_a0=!mute ++ KEYBOARD_KEY_ae=!volumedown ++ KEYBOARD_KEY_b0=!volumeup ++ ++evdev:atkbd:dmi:*:svnLENOVO:*:pvrLenovoYoga300-11IBR:* ++ KEYBOARD_KEY_62=unknown # Touchpad on, also emitted by "Ideapad extra buttons", ignore ++ KEYBOARD_KEY_63=unknown # Touchpad off, also emitted by "Ideapad extra buttons", ignore ++ ++# Fix for volume keys on Lenovo Yoga S940 ++# For 10th gen it should be pn81Q8 instead of pn81Q7 but ++# I don't have a device to test ++# perhaps pn81Q* would work for both generations ++evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO:pn81Q7*:pvrLenovoYogaS940:* + KEYBOARD_KEY_a0=!mute + KEYBOARD_KEY_ae=!volumedown + KEYBOARD_KEY_b0=!volumeup + ++# Lenovo Y50-70 ++evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*20378*:* ++ KEYBOARD_KEY_f3=f21 # Fn+F6 (toggle touchpad) ++ + # V480 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:* + KEYBOARD_KEY_f1=f21 + +-# Lenovo Thinkcentre M800z AIO machine ++# Lenovo ThinkCentre M800z/M820z/M920z AIO machines + # key_scancode 00 is KEY_MICMUTE +-keyboard:name:Microphone Mute Button:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn* ++evdev:name:Microphone Mute Button:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:* + KEYBOARD_KEY_00=f20 + + # enhanced USB keyboard +@@ -758,11 +917,196 @@ evdev:input:b0003v04B3p301B* + KEYBOARD_KEY_90007=mail + KEYBOARD_KEY_90008=www + ++# Lenovo Ideapad D330-10IGM ++evdev:name:SIPODEV Lenovo HID Device:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:* ++ KEYBOARD_KEY_70073=f21 # Fn+Supr (Touchpad toggle) ++ + + ########################################################### + # Logitech + ########################################################### + ++# 27MHz wireless keyboards, these all have a PID of 00?? and all send c10xx ++# logitech custom consumer usage-page codes. The mappings below are the most ++# common, but some mapping may differ, especially the Fn F1-F12 mappings ++evdev:input:b0003v046Dp00* ++ KEYBOARD_KEY_c0183=media # HUT:config, kbd:Media/Music player button ++ KEYBOARD_KEY_c1001=chat # Messenger button ++ KEYBOARD_KEY_c1002=camera # Webcam button ++ KEYBOARD_KEY_c1003=audio # Music Browser button ++ KEYBOARD_KEY_c1004=video # Video Browser button ++ KEYBOARD_KEY_c1005=images # Image Browser button ++ KEYBOARD_KEY_c100a=documents # Document Browser button ++ KEYBOARD_KEY_c100b=rewind # Rewind button ++ KEYBOARD_KEY_c100c=fastforward # Fast Forward button ++ KEYBOARD_KEY_c100f=f14 # Track 1 button → f14 → XF86Launch5 ++ KEYBOARD_KEY_c1010=f15 # Track 2 button → f15 → XF86Launch6 ++ KEYBOARD_KEY_c1011=channeldown # Playlist back button ++ KEYBOARD_KEY_c1012=channelup # Playlist advance button ++ KEYBOARD_KEY_c1013=camera # Webcam button ++ KEYBOARD_KEY_c1014=coffee # Status button ++ KEYBOARD_KEY_c1015=record # Record symbol button ++ KEYBOARD_KEY_c1016=sound # Flame/CD burning → sound → XF86AudioPreset ++ KEYBOARD_KEY_c1017=ejectcd # Eject button ++ KEYBOARD_KEY_c1018=config # Remote-control ico ++ KEYBOARD_KEY_c1019=f14 # Preset 1 → f14 → XF86Launch5 ++ KEYBOARD_KEY_c101a=f15 # Preset 2 → f15 → XF86Launch6 ++ KEYBOARD_KEY_c101b=f16 # Preset 3 → f16 → XF86Launch7 ++ KEYBOARD_KEY_c101c=cyclewindows # 2 overlapping windows icon ++ KEYBOARD_KEY_c101f=zoomout # zoom - button / - side of zoomrocker ++ KEYBOARD_KEY_c1020=zoomin # zoom + button / + side off zoom rocker ++ KEYBOARD_KEY_c1021=zoomreset # 100% symbol on kbd left side ++ KEYBOARD_KEY_c1023=close # [x] symbol on kbd left side ++ KEYBOARD_KEY_c1027=menu # Hamburger menu icon ++ KEYBOARD_KEY_c1028=angle # Rotate button ++ KEYBOARD_KEY_c1029=shuffle # Shuffle button ++ KEYBOARD_KEY_c102a=back # Back button ++ KEYBOARD_KEY_c102b=cyclewindows # Empty window icon ++ KEYBOARD_KEY_c102c=fn # Fn key ++ KEYBOARD_KEY_c102d=www # www text + magnifierglass icon ++ KEYBOARD_KEY_c1031=connect # Pickup phone button → connect → XF86Go ++ KEYBOARD_KEY_c1032=cancel # Hangup phone button → cancel → Cancel ++ KEYBOARD_KEY_c1041=help # Help text or icon (Fn + F1) ++ KEYBOARD_KEY_c1042=wordprocessor # Word icon (Fn + F2) ++ KEYBOARD_KEY_c1043=spreadsheet # Excel icon (Fn + F3) ++ KEYBOARD_KEY_c1044=presentation # Presentation icon (Fn + F4) ++ KEYBOARD_KEY_c1045=undo # Undo Icon (Fn + F5) ++ KEYBOARD_KEY_c1046=redo # Redo Icon (Fn + F6) ++ KEYBOARD_KEY_c1047=print # Printer Icon (Fn + F7) ++ KEYBOARD_KEY_c1048=save # Floppy Icon (Fn + F8) ++ KEYBOARD_KEY_c1049=prog1 # Smartkey A (Fn + F9) → XF86Launch1 ++ KEYBOARD_KEY_c104a=prog2 # Smartkey B (Fn + F10) → XF86Launch2 ++ KEYBOARD_KEY_c104b=prog3 # Smartkey C (Fn + F11) → XF86Launch3 ++ KEYBOARD_KEY_c104c=prog4 # Smartkey D (Fn + F12) → XF86Launch4 ++ ++# Cordless Access Keyboard (27 MHz, modelnumber Y-RH35) ++evdev:input:b0003v046Dp0042* ++ KEYBOARD_KEY_c1041=new ++ KEYBOARD_KEY_c1042=reply ++ KEYBOARD_KEY_c1043=forward ++ KEYBOARD_KEY_c1044=send ++ KEYBOARD_KEY_c1045=previoussong ++ KEYBOARD_KEY_c1046=nextsong ++ KEYBOARD_KEY_c1047=playpause ++ KEYBOARD_KEY_c1048=stopcd ++ KEYBOARD_KEY_c1049=file ++ KEYBOARD_KEY_c104a=documents ++ KEYBOARD_KEY_c104b=images ++ KEYBOARD_KEY_c104c=audio ++ ++# "Cordless Rechargeable Desktop" keyboard (27 MHz, modelnumber Y-RK49) ++evdev:input:b0003v046Dp0045* ++ KEYBOARD_KEY_c1041=new ++ KEYBOARD_KEY_c1042=reply ++ KEYBOARD_KEY_c1043=forward ++ KEYBOARD_KEY_c1044=send ++ KEYBOARD_KEY_c1049=file ++ KEYBOARD_KEY_c104a=documents ++ KEYBOARD_KEY_c104b=images ++ KEYBOARD_KEY_c104c=audio ++ ++# S510 keyboard (27 MHz, modelnumber Y-RAK73) ++evdev:input:b0003v046Dp0056* ++ KEYBOARD_KEY_c1041=battery # Battery icon (Fn + F1) ++ ++# MX3000 keyboard (27 MHz, modelnumber Y-RAM74) ++# We ignore the scroll up / down keypress events since these buttons also ++# generate scroll-wheel events and we do not want to generate duplicate events ++# Note if the "Special Button Function" in the HID++ features register gets ++# cleared then the scroll-wheel events for these buttons go away and then ++# tilting the scrollwheel left/right starts sending c1022 / c1024 events ++evdev:input:b0003v046Dp0057* ++ KEYBOARD_KEY_c1041=battery # Battery icon (Fn + F1) ++ ++#KEYBOARD_KEY_c101d=scrolldown # Button below scrollwheel (see note above) ++#KEYBOARD_KEY_c101e=scrollup # Button above scrollwheel (see note above) ++#KEYBOARD_KEY_c1022=scrollleft # Left click on scroll-wheel (see note above) ++#KEYBOARD_KEY_c1024=scrollright # Right click on scroll-wheel (see note above) ++ ++# MX3200 keyboard (27 MHz, modelnumber Y-RAV80) ++evdev:input:b0003v046Dp005C* ++ KEYBOARD_KEY_c1001=phone # VOIP button ++ KEYBOARD_KEY_c1016=record # Record button ++ KEYBOARD_KEY_c1041=wordprocessor # Word icon (Fn + F1) ++ KEYBOARD_KEY_c1042=spreadsheet # Excel icon (Fn + F2) ++ KEYBOARD_KEY_c1043=calendar # Calendar icon (Fn + F3) ++ KEYBOARD_KEY_c1044=documents # My Documents icon (Fn + F4) ++ KEYBOARD_KEY_c1045=prog1 # Smartkey A (Fn + F5) → XF86Launch1 ++ KEYBOARD_KEY_c1046=prog2 # Smartkey B (Fn + F6) → XF86Launch2 ++ KEYBOARD_KEY_c1047=prog3 # Smartkey C (Fn + F7) → XF86Launch3 ++ KEYBOARD_KEY_c1048=prog4 # Smartkey D (Fn + F8) → XF86Launch4 ++ ++# EX100 keyboard (27 MHz, modelnumber Y-RBH94) ++evdev:input:b0003v046Dp0065* ++ KEYBOARD_KEY_c104b=battery # Battery icon (Fn + F11) ++ KEYBOARD_KEY_c104c=ejectcd # Eject icon (Fn + F12) ++ ++# S520 keyboard (27 MHz, modelnumber Y-RBA97) ++# Note this one uses non-standard codes for FN + F9 - Fn + F12? ++evdev:input:b0003v046Dp0066* ++ KEYBOARD_KEY_c100e=prog4 # Smartkey D (Fn + F12) → XF86Launch4 ++ KEYBOARD_KEY_c1019=prog1 # Smartkey A (Fn + F9) → XF86Launch1 ++ KEYBOARD_KEY_c101a=prog2 # Smartkey B (Fn + F10) → XF86Launch2 ++ KEYBOARD_KEY_c101b=prog3 # Smartkey C (Fn + F11) → XF86Launch3 ++ KEYBOARD_KEY_c1041=wordprocessor # Word icon (Fn + F1) ++ KEYBOARD_KEY_c1042=spreadsheet # Excel icon (Fn + F2) ++ KEYBOARD_KEY_c1043=presentation # Presentation icon (Fn + F3) ++ KEYBOARD_KEY_c1044=calendar # Calendar icon (Fn + F4) ++ KEYBOARD_KEY_c1045=homepage # Home icon (Fn + F5) ++ KEYBOARD_KEY_c1046=email # Letter icon (Fn + F6) ++ KEYBOARD_KEY_c1047=search # Magnifying glass icon (Fn + F7) ++ KEYBOARD_KEY_c1048=config # Window with gear icon (Fn + F8) ++ KEYBOARD_KEY_c106f=battery # Battery icon ++ ++# S510 remote control (27 MHz) ++evdev:input:b0003v046Dp00FE* ++ KEYBOARD_KEY_c1018=media # Media button ++ ++# MX5000 keyboard (HID proxy mode and bluetooth matches) ++evdev:input:b0003v046DpB305* ++evdev:input:b0005v046DpB305* ++ KEYBOARD_KEY_c0183=media # HUT says config, kbd says Media ++ KEYBOARD_KEY_c0230=zoomreset # HUT says fullscreen, kbd says 100% ++ KEYBOARD_KEY_c1004=send # Send and receive / sync button ++ KEYBOARD_KEY_c1006=coffee # Status (online/away) button ++ KEYBOARD_KEY_c1007=camera # Webcam button ++ KEYBOARD_KEY_c100c=kbd_lcd_menu1 # 1st button below the builtin LCD ++ KEYBOARD_KEY_c100d=kbd_lcd_menu4 # 4th button below the builtin LCD ++ KEYBOARD_KEY_c100e=kbd_lcd_menu2 # 2nd button below the builtin LCD ++ KEYBOARD_KEY_c100f=kbd_lcd_menu3 # 3th button below the builtin LCD ++ KEYBOARD_KEY_c1038=prog1 # Smartkey A → XF86Launch1 ++ KEYBOARD_KEY_c1039=prog2 # Smartkey B → XF86Launch2 ++ KEYBOARD_KEY_c103a=prog3 # Smartkey C → XF86Launch3 ++ KEYBOARD_KEY_c103b=prog4 # Smartkey D → XF86Launch4 ++ KEYBOARD_KEY_c1040=fn_esc # Fn mode on/off toggle ++ ++# Dinovo Edge (HID proxy mode and bluetooth matches) ++evdev:input:b0003v046DpB309* ++evdev:input:b0005v046DpB309* ++ KEYBOARD_KEY_c102c=fn # Fn key ++ KEYBOARD_KEY_c1038=prog1 # Fn + F9 Smartkey A → XF86Launch1 ++ KEYBOARD_KEY_c1039=prog2 # Fn + F10 Smartkey B → XF86Launch2 ++ KEYBOARD_KEY_c103a=prog3 # Fn + F11 Smartkey C → XF86Launch3 ++ KEYBOARD_KEY_c103b=prog4 # Fn + F12 Smartkey D → XF86Launch4 ++ KEYBOARD_KEY_c1050=phone # Fn + F1 Phone button ++ ++# MX5500 keyboard (HID proxy mode and bluetooth matches) ++evdev:input:b0003v046DpB30B* ++evdev:input:b0005v046DpB30B* ++ KEYBOARD_KEY_c0183=media # HUT says consumer control configuration, kbd says Media Center ++ KEYBOARD_KEY_c100e=images # Camera icon, "Photo Gallery" ++ KEYBOARD_KEY_c100f=config # Window with gear icon ++ KEYBOARD_KEY_c102c=fn # Fn key ++ KEYBOARD_KEY_c1038=prog1 # Smartkey A → XF86Launch1 ++ KEYBOARD_KEY_c1039=prog2 # Smartkey B → XF86Launch2 ++ KEYBOARD_KEY_c103a=prog3 # Smartkey C → XF86Launch3 ++ KEYBOARD_KEY_c103b=prog4 # Smartkey D → XF86Launch4 ++ ++# Logitech K811 ++evdev:input:b0005v046DpB317* ++ KEYBOARD_KEY_70047=brightnessdown ++ KEYBOARD_KEY_70048=brightnessup ++ + # iTouch + evdev:input:b0003v046DpC308* + KEYBOARD_KEY_90001=shop # Shopping +@@ -835,22 +1179,22 @@ evdev:input:b0003v046DpC52D* + + # Internet Navigator + evdev:input:b0003v046DpC309* +- KEYBOARD_KEY_90001=chat # Messenger/SMS +- KEYBOARD_KEY_90002=camera # webcam +- KEYBOARD_KEY_90003=prog1 # iTouch +- KEYBOARD_KEY_90004=shop # Shopping +- KEYBOARD_KEY_c0201=new # New (F1) +- KEYBOARD_KEY_c0289=reply # Reply mail (F2) +- KEYBOARD_KEY_c028b=forwardmail # Forward mail (F3) +- KEYBOARD_KEY_c028c=send # Send (F4) +- KEYBOARD_KEY_c021a=undo # Undo (F5) +- KEYBOARD_KEY_c0279=redo # Redo (F6) +- KEYBOARD_KEY_c0208=print # Print (F7) +- KEYBOARD_KEY_c0207=save # Save (F8) +- KEYBOARD_KEY_c0194=file # My Computer (F9) +- KEYBOARD_KEY_c01a7=documents # My Documents (F10) +- KEYBOARD_KEY_c01b6=images # My Pictures (F11) ?? +- KEYBOARD_KEY_c01b7=sound # My Music (F12) ?? ++ KEYBOARD_KEY_90001=chat # Messenger/SMS ++ KEYBOARD_KEY_90002=camera # webcam ++ KEYBOARD_KEY_90003=prog1 # iTouch ++ KEYBOARD_KEY_90004=shop # Shopping ++ KEYBOARD_KEY_c0201=new # New (F1) ++ KEYBOARD_KEY_c0289=reply # Reply mail (F2) ++ KEYBOARD_KEY_c028b=forwardmail # Forward mail (F3) ++ KEYBOARD_KEY_c028c=send # Send (F4) ++ KEYBOARD_KEY_c021a=undo # Undo (F5) ++ KEYBOARD_KEY_c0279=redo # Redo (F6) ++ KEYBOARD_KEY_c0208=print # Print (F7) ++ KEYBOARD_KEY_c0207=save # Save (F8) ++ KEYBOARD_KEY_c0194=file # My Computer (F9) ++ KEYBOARD_KEY_c01a7=documents # My Documents (F10) ++ KEYBOARD_KEY_c01b6=images # My Pictures (F11) ++ KEYBOARD_KEY_c01b7=audio # My Music (F12) + + + ########################################################### +@@ -858,7 +1202,7 @@ evdev:input:b0003v046DpC309* + ########################################################### + + # Pro 7000 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro*7000*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro*7000*:* + KEYBOARD_KEY_97=prog2 + KEYBOARD_KEY_9f=prog1 + KEYBOARD_KEY_a0=mute # Fn+F5 +@@ -874,8 +1218,9 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMAXDATA:pnPro*7000*:pvr* + ########################################################### + + # Akoya +-evdev:atkbd:dmi:bvn*:bvr*:svnMEDION*:pnS3409*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnAkoya*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:svnMEDION*:pnS3409*:* ++evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnAkoya*:* ++evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnP6669*:* + KEYBOARD_KEY_a0=!mute + KEYBOARD_KEY_ae=!volumedown + KEYBOARD_KEY_b0=!volumeup +@@ -883,17 +1228,23 @@ evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnAkoya*:pvr* + KEYBOARD_KEY_df=sleep + + # FID2060 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMEDION*:pn*FID2060*:* + KEYBOARD_KEY_6b=channeldown # Thottle Down + KEYBOARD_KEY_6d=channelup # Thottle Up + + # NB-A555 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMEDIONNB:pnA555*:* + KEYBOARD_KEY_63=www # N button + KEYBOARD_KEY_66=prog1 # link 1 button + KEYBOARD_KEY_67=email # envelope button + KEYBOARD_KEY_69=prog2 # link 2 button + ++# Erazer ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMedion*:pnErazer*:* ++ KEYBOARD_KEY_a0=!mute ++ KEYBOARD_KEY_ae=!volumedown ++ KEYBOARD_KEY_b0=!volumeup ++ + ########################################################### + # Microsoft + ########################################################### +@@ -903,16 +1254,23 @@ evdev:input:b0003v045Ep00DB* + KEYBOARD_KEY_c022d=up # zoomin + KEYBOARD_KEY_c022e=down # zoomout + ++# Microsoft (Razer produced) Reclusa keyboard ++evdev:input:b0003v1532p0200* ++ KEYBOARD_KEY_c01c9=shuffle ++ KEYBOARD_KEY_c01ca=up # zoomin ++ KEYBOARD_KEY_c01cb=down # zoomout ++ + ########################################################### +-# Micro Star ++# MSI (aka "Micro Star") + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:* + KEYBOARD_KEY_a0=mute # Fn+F9 + KEYBOARD_KEY_ae=volumedown # Fn+F7 + KEYBOARD_KEY_b0=volumeup # Fn+F8 + KEYBOARD_KEY_b2=www # e button ++ KEYBOARD_KEY_c2=ejectcd + KEYBOARD_KEY_df=sleep # Fn+F12 + KEYBOARD_KEY_e2=bluetooth # satellite dish2 + KEYBOARD_KEY_e4=f21 # Fn+F3 Touchpad disable +@@ -923,20 +1281,18 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn* + KEYBOARD_KEY_f8=brightnessup # Fn+F5 + KEYBOARD_KEY_f9=search + +-# +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE60*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE70*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE60*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnGE70*:* + KEYBOARD_KEY_c2=ejectcd + + # some MSI models generate ACPI/input events on the LNXVIDEO input devices, + # plus some extra synthesized ones on atkbd as an echo of actually changing the + # brightness; so ignore those atkbd ones, to avoid loops +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*VR420*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*PR200*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*VR420*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*PR200*:* + KEYBOARD_KEY_f7=reserved + KEYBOARD_KEY_f8=reserved + +@@ -944,20 +1300,46 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*PR200*:pvr* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:* + KEYBOARD_KEY_e4=reserved + ++# Keymaps MSI Prestige And MSI Modern FnKeys and Special keys ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Prestige*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Modern*:* ++ KEYBOARD_KEY_f1=f20 # Fn+F5 Micmute ++ KEYBOARD_KEY_76=f21 # Fn+F4 Toggle touchpad, sends meta+ctrl+toggle ++ KEYBOARD_KEY_91=prog1 # Fn+F7 Creation Center, sometime F7 ++ KEYBOARD_KEY_f2=prog2 # Fn+F12 Screen rotation ++ KEYBOARD_KEY_8d=prog3 # Fn+A Change True Color selections ++ KEYBOARD_KEY_8c=prog4 # Fn+Z Launch True Color ++ KEYBOARD_KEY_f5=fn_esc # Fn+esc Toggle the behaviour of Fn keys ++ KEYBOARD_KEY_97=unknown # Lid close ++ KEYBOARD_KEY_98=unknown # Lid open ++ ++evdev:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:* ++ KEYBOARD_KEY_0213=f22 ++ KEYBOARD_KEY_0214=f23 ++ + ########################################################### +-# MSI ++# Olimex + ########################################################### + +-evdev:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:pvr* +- KEYBOARD_KEY_0213=f22 +- KEYBOARD_KEY_0214=f23 ++# Teres-I ++evdev:input:b0003v15BAp003C* ++ KEYBOARD_KEY_70066=sleep # Fn+F1 ++ KEYBOARD_KEY_700f6=wlan # Fn+F2 ++ KEYBOARD_KEY_700c7=f21 # Fn+F3 touchpad toggle ++ KEYBOARD_KEY_7006f=brightnessdown # Fn+F7 ++ KEYBOARD_KEY_70070=brightnessup # Fn+F8 ++ KEYBOARD_KEY_7006e=switchvideomode # Fn+F9 + + ########################################################### + # OLPC + ########################################################### + +-# XO ++# XO-1 and XO-1.5 + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* ++# XO-1.75 and XO-1.4 (sp/ is the Security Processor) ++evdev:name:AT Translated Set 2 keyboard:phys:sp/serio*/input*:ev:120013:* ++ KEYBOARD_LED_CAPSLOCK=0 ++ KEYBOARD_LED_NUMLOCK=0 + KEYBOARD_KEY_59=fn + KEYBOARD_KEY_81=fn_esc + KEYBOARD_KEY_f9=camera +@@ -1002,15 +1384,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:* + KEYBOARD_KEY_dc=rightmeta # right grab + KEYBOARD_KEY_85=rightmeta # Right grab releases on a different scancode + KEYBOARD_KEY_d6=kbdillumtoggle # Fn+Space +- KEYBOARD_KEY_69=switchvideomode # Brightness key +- KEYBOARD_KEY_65=kp8 # up +- KEYBOARD_KEY_66=kp2 # down +- KEYBOARD_KEY_67=kp4 # left +- KEYBOARD_KEY_68=kp6 # right +- KEYBOARD_KEY_e5=kp9 # pgup +- KEYBOARD_KEY_e6=kp3 # pgdn +- KEYBOARD_KEY_e7=kp7 # home +- KEYBOARD_KEY_e8=kp1 # end ++ KEYBOARD_KEY_69=rotate_display ++ KEYBOARD_KEY_65=btn_dpad_up ++ KEYBOARD_KEY_66=btn_dpad_down ++ KEYBOARD_KEY_67=btn_dpad_left ++ KEYBOARD_KEY_68=btn_dpad_right ++ KEYBOARD_KEY_e5=btn_north ++ KEYBOARD_KEY_e6=btn_south ++ KEYBOARD_KEY_e7=btn_west ++ KEYBOARD_KEY_e8=btn_east + + ########################################################### + # Onkyo +@@ -1037,32 +1419,92 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnONKYO*CORPORATION:pnONKYOPC:* + ########################################################### + + # Model 2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnOQO*Inc.*:pnOQO*Model*2*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnOQO*Inc.*:pnOQO*Model*2*:* + KEYBOARD_KEY_8e=wlan + KEYBOARD_KEY_f0=switchvideomode + KEYBOARD_KEY_f1=mute + KEYBOARD_KEY_f2=volumedown + KEYBOARD_KEY_f3=volumeup + ++########################################################### ++# Ortek ++########################################################### ++ ++# Adesso AKB-805MAC ++# The key code identifiers used below exactly match the text ++# labels on the keys/buttons (or standard icons on the buttons ++# that have no text labels), except as noted. ++evdev:input:b0003v05A4p9735* ++ KEYBOARD_KEY_c0015=back ++ KEYBOARD_KEY_c0012=forward ++ KEYBOARD_KEY_c000c=stop ++ KEYBOARD_KEY_c0018=refresh ++ KEYBOARD_KEY_c00b9=search ++ KEYBOARD_KEY_c0006=bookmarks # Button labeled "Favorites" ++ KEYBOARD_KEY_c00a8=homepage # Button labeled "Web/Home" ++ KEYBOARD_KEY_c0010=mute ++ KEYBOARD_KEY_c0011=volumedown ++ KEYBOARD_KEY_c0014=volumeup ++ KEYBOARD_KEY_c000e=close ++ KEYBOARD_KEY_c00a7=print ++ KEYBOARD_KEY_c0013=documents # Button labeled "Stickies" ++ KEYBOARD_KEY_c000d=find # Button labeled "Sherlock2" ++ KEYBOARD_KEY_c000f=mail ++ KEYBOARD_KEY_c000a=calc ++ KEYBOARD_KEY_c000b=sleep ++ KEYBOARD_KEY_c0007=previoussong # Button with standard |<< icon ++ KEYBOARD_KEY_c0008=playpause # Button with standad >/|| icon ++ KEYBOARD_KEY_c0009=nextsong # Button with standard >>| icon ++ KEYBOARD_KEY_c00b2=stopcd # Button with standard square box icon ++ KEYBOARD_KEY_c0016=prog1 # Key labeled "pf1" ++ KEYBOARD_KEY_c00bb=prog2 # Key labeled "pf2" ++ KEYBOARD_KEY_c00b8=prog3 # Key labeled "pf3" ++ ++########################################################### ++# Pine64 ++########################################################### ++ ++# Pinebook Pro ++evdev:input:b0003v258Ap001E* ++ KEYBOARD_KEY_700a5=brightnessdown ++ KEYBOARD_KEY_700a6=brightnessup ++ KEYBOARD_KEY_70066=sleep ++ + ########################################################### + # Plantronics + ########################################################### + + # Plantronics .Audio 626 DSP + evdev:input:b0003v047FpC006* +- KEYBOARD_KEY_b002f=f20 # Microphone mute button; should be micmute ++ KEYBOARD_KEY_b002f=f20 # Microphone mute button; should be micmute + + ########################################################### + # Purism + ########################################################### + +-# Purism Librem 13 V2 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v2*:pvr* +- KEYBOARD_KEY_56=backslash +- +-# Purism Librem 13 V3 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v3*:pvr* +- KEYBOARD_KEY_56=backslash ++# If you're using an us layout keyboard in one of the below models of ++# Purism Librem 13 consider copying this file to /etc/systemd/hwdb.d/ ++# to enable the following rule acording to your model. ++# ++# There's a bug in the keyboards firmware and the additional rule ++# will make your keyboard behave as expected. ++# ++# More info: ++# - https://github.com/systemd/systemd/issues/15360 ++# - https://github.com/systemd/systemd/pull/11516 ++# - https://tracker.pureos.net/T888 ++# ++# # Purism Librem 13 V2 ++# evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v2*:* ++# KEYBOARD_KEY_56=backslash ++# ++# # Purism Librem 13 V3 ++# evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v3*:* ++# KEYBOARD_KEY_56=backslash ++# ++# # Purism Librem 13 V4 ++# evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPurism*:pn*Librem13v4*:* ++# KEYBOARD_KEY_56=backslash + + ########################################################### + # Quanta +@@ -1075,7 +1517,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*:rvnQuanta:rn30B7:rvr65.2B:* + # Samsung + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*:* + KEYBOARD_KEY_74=prog1 # User key + KEYBOARD_KEY_75=www + KEYBOARD_KEY_78=mail +@@ -1094,28 +1536,42 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn* + KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off + + # Series 3 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*200E[45]*:* + KEYBOARD_KEY_ce=! # Fn+F1 launch control setting + ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*356V[45]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*355V[45]*:pvr* ++ KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch control setting ++ KEYBOARD_KEY_89=!brightnessdown # Fn+F2 brightness down ++ KEYBOARD_KEY_88=!brightnessup # Fn+F3 brightness up ++ KEYBOARD_KEY_82=!switchvideomode # Fn+F4 display toggle ++ KEYBOARD_KEY_f7=!f22 # Fn+F5 touchpad on ++ KEYBOARD_KEY_f9=!f23 # Fn+F5 touchpad off ++ KEYBOARD_KEY_a0=!mute # Fn+F6 mute ++ KEYBOARD_KEY_ae=!volumedown # Fn+F7 volume down ++ KEYBOARD_KEY_b0=!volumeup # Fn+F8 volume up ++ KEYBOARD_KEY_b3=!prog2 # Fn+F11 toggle fan/cool mode ++ KEYBOARD_KEY_d5=!wlan # Fn+F12 toggle wifi ++ + # Series 5 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*530U*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*530U*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_a8=! # Fn Lock - Function lock on + KEYBOARD_KEY_a9=! # Fn Lock - Function lock off + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_a8=! # Fn Lock - Function lock on + KEYBOARD_KEY_a9=! # Fn Lock - Function lock off + + # Series 7 / 9 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*350V*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*670Z*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700G*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*350V*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*670Z*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700G*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_a0=!mute # Fn+F6 mute + KEYBOARD_KEY_ae=!volumedown # Fn+F7 +@@ -1124,14 +1580,14 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr* + KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up + KEYBOARD_KEY_b3=!prog3 # Fn+F11 fan/cooling mode changer + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34][AB]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X3A*:* + KEYBOARD_KEY_ce=! # Fn+F8 keyboard backlight up + KEYBOARD_KEY_8d=! # Fn+F7 keyboard backlight down + KEYBOARD_KEY_96=! # Fn+F1 performance mode (?) + KEYBOARD_KEY_97=! # Fn+F12 Wi-Fi toggle + KEYBOARD_KEY_d5=! # Fn+F6 battery life extender + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_8d=!prog3 # Fn+F6 performance mode + KEYBOARD_KEY_97=!kbdillumdown # Fn+F7 keyboard backlight down +@@ -1139,7 +1595,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr* + KEYBOARD_KEY_d5=!wlan # Fn+F12 Wi-Fi toggle + + # Series 7 Ultra +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*7[34]0U3E*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*7[34]0U3E*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_97=!kbdillumdown # Fn+F9 keyboard backlight down + KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up +@@ -1147,13 +1603,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*7[34]0U3E*:pvr + KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch + + # ATIV Book 6 / 8 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*[68][78]0Z*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*[68][78]0Z*:* + KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings + KEYBOARD_KEY_96=!kbdillumup # Fn+F10 keyboard backlight up + KEYBOARD_KEY_97=!kbdillumdown # Fn+F9 keyboard backlight down + + # SQ1US +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:* + KEYBOARD_KEY_d4=menu + KEYBOARD_KEY_d8=f1 + KEYBOARD_KEY_d9=f10 +@@ -1163,13 +1619,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr* + KEYBOARD_KEY_ee=f11 + + # SX20S +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:* + KEYBOARD_KEY_74=mute + KEYBOARD_KEY_75=mute + KEYBOARD_KEY_77=f22 # Touchpad on + KEYBOARD_KEY_79=f23 # Touchpad off + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:* + KEYBOARD_KEY_ad=leftmeta + + ########################################################### +@@ -1177,7 +1633,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:pvr* + ########################################################### + + # sony-laptop driver +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*:* + KEYBOARD_KEY_06=mute # Fn+F2 + KEYBOARD_KEY_07=volumedown # Fn+F3 + KEYBOARD_KEY_08=volumeup # Fn+F4 +@@ -1187,22 +1643,22 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn* + KEYBOARD_KEY_0e=zoom # Fn+F10 + KEYBOARD_KEY_10=suspend # Fn+F12 + +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-C1*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-K25*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-F[1-6]*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FX*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FRV*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-GR*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-TR*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-NV*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-Z*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*VGN-S360*:pvr* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-C1*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-K25*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-F[1-6]*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FX*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-FRV*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-GR*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-TR*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-NV*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*PCG-Z*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pn*VGN-S360*:* + KEYBOARD_KEY_06=battery + KEYBOARD_KEY_07=mute + +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-AR71*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW*:pvr* +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-AR71*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW*:* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:* + KEYBOARD_KEY_00=brightnessdown # Fn+F5 + KEYBOARD_KEY_10=brightnessup # Fn+F6 + KEYBOARD_KEY_11=switchvideomode # Fn+F7 +@@ -1212,19 +1668,27 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-Z21*:pvr* + KEYBOARD_KEY_17=prog1 + KEYBOARD_KEY_20=media + +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW250*:pvr* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW250*:* + KEYBOARD_KEY_10=suspend # Fn+F12 + +-evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:pvr* ++evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:* + KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) + KEYBOARD_KEY_0d=down # Fn+F9 zoomout + KEYBOARD_KEY_0e=up # Fn+F10 zoomin + ++########################################################### ++# System76 ++########################################################### ++ ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pn*:* ++ KEYBOARD_KEY_f7=f21 # Touchpad toggle ++ KEYBOARD_KEY_f8=f21 # Touchpad toggle ++ + ########################################################### + # T-bao + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:* + KEYBOARD_KEY_76=f21 # Touchpad toggle + + ########################################################### +@@ -1232,12 +1696,12 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:pvr* + ########################################################### + + # Satellite A100 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE*A100:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITE*A100:* + KEYBOARD_KEY_a4=stopcd + KEYBOARD_KEY_b2=www + + # Satellite A110 +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*A110:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*A110:* + KEYBOARD_KEY_92=stop + KEYBOARD_KEY_93=www + KEYBOARD_KEY_94=media +@@ -1250,7 +1714,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*A110:pvr* + KEYBOARD_KEY_f7=playpause + + # Satellite M30X +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:* + KEYBOARD_KEY_ef=brightnessdown + KEYBOARD_KEY_d9=brightnessup + KEYBOARD_KEY_ee=screenlock +@@ -1259,21 +1723,21 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:pvr* + KEYBOARD_KEY_9f=f23 # touchpad disable + + # Satellite P75-A +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:* + KEYBOARD_KEY_ef=brightnessdown + KEYBOARD_KEY_ee=brightnessup + KEYBOARD_KEY_a9=switchvideomode # switch display outputs + KEYBOARD_KEY_d4=wlan # RF Switch Off + + # Satellite U940 +-evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITEU940:pvr* ++evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITEU940:* + KEYBOARD_KEY_13c=brightnessdown + KEYBOARD_KEY_13d=brightnessup + KEYBOARD_KEY_13e=switchvideomode + KEYBOARD_KEY_13f=f21 # Touchpad toggle + + # Satellite P75-A7200 +-evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:pvr* ++evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:* + KEYBOARD_KEY_13c=brightnessdown + KEYBOARD_KEY_13d=brightnessup + KEYBOARD_KEY_13e=switchvideomode +@@ -1284,16 +1748,24 @@ evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A: + # VIA + ########################################################### + +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:* + KEYBOARD_KEY_81=prog1 + + ########################################################### + # VIOS + ########################################################### + +-evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:pvr* ++evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:* + KEYBOARD_KEY_70073=f21 # Touchpad toggle + ++########################################################### ++# WeiHeng ++########################################################### ++ ++# P325J ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINET:pnP325J:* ++ KEYBOARD_KEY_76=f21 # Touchpad toggle ++ + ########################################################### + # Zepto + ########################################################### +@@ -1388,21 +1860,21 @@ evdev:input:b0003v1038p0310* + ########################################################### + + # Common Volume Keys +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*SIEMENS:pnAMILO*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*SIEMENS:pnAMILO*:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFOXCONN:pnQBOOK:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMTC:pn*:pvrA0:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMio*Technology:pnN890:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPEGATRON*CORP.:pnSpring*Peak:* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*[uU][35]0[05]*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE*[uU][35]0[05]*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*Pro*[uU]300*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnEQUIUM [uU][35]0[05]*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*[uU][35]0[05]*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSATELLITE*[uU][35]0[05]*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnSatellite*Pro*[uU]300*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA:pnEQUIUM [uU][35]0[05]*:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnViooo*Corporation:pnPT17:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHANNspree:pnSN10E100:* + evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGIGABYTE:pni1520M:* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook*Lite*:pvr* +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnBenQ:pn*nScreen*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnBenQ:pnJoybook*Lite*:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:* + KEYBOARD_KEY_a0=! # mute + KEYBOARD_KEY_ae=! # volume down + KEYBOARD_KEY_b0=! # volume up +@@ -1423,8 +1895,8 @@ evdev:input:b0003v1050p0111* + evdev:input:b0003v1050p0116* + # OKE Electron Company USB barcode reader + evdev:input:b0003v05FEp1010* +- XKB_FIXED_LAYOUT="us" +- XKB_FIXED_VARIANT="" ++ XKB_FIXED_LAYOUT=us ++ XKB_FIXED_VARIANT= + + ######################### LACK OF MODIFIER LEDS ############################ + # This section lists keyboard which do not have their own LEDs for some +@@ -1439,23 +1911,38 @@ evdev:input:b0003v046Dp4002* + KEYBOARD_LED_NUMLOCK=0 + KEYBOARD_LED_CAPSLOCK=0 + ++# PFU Limited HHKB Professional JP ++evdev:input:b0003v04FEp000D* ++ KEYBOARD_LED_NUMLOCK=0 ++ KEYBOARD_LED_CAPSLOCK=0 ++ + # Lenovo ThinkPad T430s +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT430s ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT430s:* + KEYBOARD_LED_CAPSLOCK=0 + + # Lenovo ThinkPad T440s +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT440s ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT440s:* + KEYBOARD_LED_CAPSLOCK=0 + + # Lenovo ThinkPad T450s +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT450s ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT450s:* + KEYBOARD_LED_CAPSLOCK=0 + + # Lenovo ThinkPad T560s +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT560s ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadT560s:* + KEYBOARD_LED_CAPSLOCK=0 + KEYBOARD_LED_NUMLOCK=0 + + # Lenovo ThinkPad X1 Carbon 3rd Gen +-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd:* + KEYBOARD_LED_CAPSLOCK=0 ++ ++######################### FIXED MODEL DEVICES ############################# ++# This section lists devices which require special handling in their key ++# code to keysym mapping by setting the xkb model. ++# The model must be an xkb compatible model (defined with XKB_FIXED_MODEL). ++ ++# Chromebooks ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnFalco:* ++evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPeppy:* ++ XKB_FIXED_MODEL=chromebook +diff --git a/hwdb/60-seat.hwdb b/hwdb/60-seat.hwdb +new file mode 100644 +index 0000000000..fcb8f53cd1 +--- /dev/null ++++ b/hwdb/60-seat.hwdb +@@ -0,0 +1,36 @@ ++# This file is part of systemd. ++# ++# This file lists graphic devices that don't have a DRM driver and fall back to ++# a frame-buffer one instead. Since commit 6260d28b8a, frame-buffer devices are ++# no more considered as graphical capable. ++# ++# The matches have the 'fb' prefix to make sure that only the framebuffer ++# device, and not the (parent) PCI device, is tagged with 'master-of-seat'. ++# ++# Allowed properties are: ++# ID_TAG_MASTER_OF_SEAT=1 ++ ++######################################### ++# eXtreme Graphic Innovation (XGI) ++######################################### ++ ++# Z7/Z9 (XG20 core), a rather ancient graphic chip, doesn't have a DRM driver ++# and falls back to vesafb. ++fb:pci:v000018CAd00000020* ++ ID_TAG_MASTER_OF_SEAT=1 ++ ++######################################### ++# HyperV ++######################################### ++ ++# HyperV currently doesn't do DRM, hence we need to synthesize for HyperV's fb ++# device instead. ++fb:pci:v00001414d00005353* ++ ID_TAG_MASTER_OF_SEAT=1 ++ ++######################################### ++# Parallels ++######################################### ++ ++fb:pci:v00001ab8d00004005* ++ ID_TAG_MASTER_OF_SEAT=1 +diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb +index 36d13e68ca..9859ce5b12 100644 +--- a/hwdb/60-sensor.hwdb ++++ b/hwdb/60-sensor.hwdb +@@ -3,13 +3,24 @@ + # The lookup keys are composed in: + # 60-sensor.rules + # +-# Note: The format of the "sensor:" prefix match key is a +-# contract between the rules file and the hardware data, it might +-# change in later revisions to support more or better matches, it +-# is not necessarily expected to be a stable ABI. ++# Note: The format of the "sensor:" prefix match key is a contract between the ++# rules file and the hardware data, it might change in later revisions to ++# support more or better matches, it is not necessarily expected to be a stable ++# ABI. + # + # Match string formats: +-# sensor:modalias::dmi: ++# sensor:modalias::dmi: ++# ++# The device modalias can be seen in the `modalias` file of the sensor parent, ++# for example: ++# cat /sys/`udevadm info -q path -n /dev/iio:device0`/../modalias ++# ++# The full DMI string of the running machine can be read from ++# /sys/class/dmi/id/modalias ++# That requires a kernel built with CONFIG_DMIID set, which is common. ++# The full DMI string is not needed here and the meaning of individual parts ++# can be seen in the source of the DMIID kernel module ++# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/dmi-id.c + # + # To add local entries, create a new file + # /etc/udev/hwdb.d/61-sensor-local.hwdb +@@ -30,11 +41,15 @@ + # + # Allowed properties are: + # ACCEL_MOUNT_MATRIX= ++# PROXIMITY_NEAR_LEVEL= + # + # where is a mount-matrix in the format specified in the IIO + # subsystem[1]. The default, when unset, is equivalent to: + # ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, 1 +-# eg. the identity matrix. ++# eg. the identity matrix, ++# and is an integer value above which an object is considered ++# close by a proximity sensor: ++# PROXIMITY_NEAR_LEVEL=100 + # + # [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfc57732ad38f93ae6232a3b4e64fd077383a0f1 + # +@@ -46,17 +61,56 @@ + # automatically flip their output for an upside-down display when the device + # is held upright. + # ++# ACCEL_LOCATION= ++# ++# where is the location of the sensor. This value could be 'base' ++# or 'display'. The default, when unset, is equivalent to: ++# ACCEL_LOCATION=display ++# ++# A note about setting ACCEL_MOUNT_MATRIX for ACCEL_LOCATION=base sensors, ++# on 360 degree hinges style 2-in-1s with 2 sensors (one in the display and ++# 1 in the base). Userspace will use both sensors to calculate the angle between ++# the 2 halves and the angle is defined as being 0 when the device is folded ++# as a regular clamshell laptop with its lid closed. This means that the ++# base-accelerometer's mount-matrix must be such, that after applying ++# the mount-matrices to both sensors, the base-accelerometer's readings must ++# be identical to the display-accelerometer's readings (when the lid is ++# closed). ++# + # Sort by brand, model + + ######################################### + # Acer + ######################################### +-sensor:modalias:acpi:INVN6500*:dmi:*svn*Acer*:*pn*AspireSW5-012* ++sensor:modalias:acpi:KIOX0009*:dmi:*:svnAcer:pnAspireSW3-016:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, -1 ++ ++sensor:modalias:acpi:INVN6500*:dmi:*svn*Acer*:*pn*AspireSW5-011:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:INVN6500*:dmi:*svn*Acer*:*pn*AspireSW5-012:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++sensor:modalias:acpi:BOSC0200*:dmi:*svnAcer*:*TP-SW5-017-17BU:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, -1 ++ + sensor:modalias:acpi:BMA250E*:dmi:*:svnAcer:pnIconiaW1-810:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + ++sensor:modalias:acpi:SMO8500:*:dmi:*Acer*:pnOneS1002:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, -1 ++ ++sensor:modalias:acpi:KIOX0009*:dmi:*:svnAcer:pnOneS1003:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnAcer*:pnSwitchSW312-31:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:BOSC0200*:dmi:*svn*Acer*:*pn*Spin*SP111-32:* ++sensor:modalias:acpi:BOSC0200*:dmi:*svn*Acer*:*pn*Spin*SP111-33:* ++sensor:modalias:acpi:BOSC0200*:dmi:*svnAcer*:*pnSpinSP111-34:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ + ######################################### + # Archos + ######################################### +@@ -66,34 +120,50 @@ sensor:modalias:acpi:SMO8500*:dmi:*:svnARCHOS:pnARCHOS80Cesium:* + ######################################### + # AsusTek + ######################################### +-sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100CHI* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100CHI:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + +-sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TA* +- ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pnT300CHI:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, 1 + +-sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pnT200TA* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnM80TA:* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TA:* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pnT200TA:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +-sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LA* +- ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnTP201SA:* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pn*E205SA:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +-sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LD* ++sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LA:* ++sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LD:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + +-sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ* ++sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pn*Q551LN:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:KXJ2109*:dmi:*:svnASUSTeK*:pnME176C:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +-sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB* ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LAB:* ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB:* ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP550LA:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + +-sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LD* ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LD:* ++sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LAB:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++sensor:modalias:acpi:BOSC0200*:dmi:*svn*ASUSTeK*:*pn*TP412UA:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, 1 ++ + ######################################### + # Axxo + ######################################### +-sensor:modalias:acpi:SMO8500*:dmi:*:svnStandard:pnWCBT1011:* ++sensor:modalias:acpi:SMO8500*:dmi:*:svnStandard:pnWCBT1011::* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + + ######################################### +@@ -108,30 +178,74 @@ sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrCHUWI.D86JLBNR*:svnInsyde:pn + sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnD2D3_Vi8A1:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +-# Chuwi Hi8 Pro ++# Chuwi Vi10 (CWI505) ++sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrG1D_S165*:svnilife:pnS165:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Chuwi Hi8 (CWI509) ++sensor:modalias:acpi:BMA250E*:dmi:*svnilife*:pnS806:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Chuwi Hi8 Pro (CWI513) + sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnX1D3_C806N:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++# Chuwi Hi10 (CWI515) ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:*:svnDefaultstring:pnDefaultstring:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++# Chuwi Hi10 (CWI1515) ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrP02A_C106.60E:*:svnDefaultstring:pnDefaultstring:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ + # Chuwi Hi10 Pro + sensor:modalias:acpi:BOSC0200*:dmi:*:svn*CHUWIINNOVATIONANDTECHNOLOGY*:pnHi10protablet:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++# Chuwi Hi10 X ++sensor:modalias:acpi:MXC6655*:dmi:*:svnCHUWIInnovationAndTechnology*:pnHi10X:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ + # Chuwi Hi12 + sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnP02BD6_HI-122LP:* ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnDefaultstring:pnDefaultstring:* ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnE4D6_HI-122LP:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + + # Chuwi Hi13 +-sensor:modalias:acpi:KIOX000A*:dmi:svnChuwi*:pnHi13 ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnChuwi*:pnHi13:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + ++# Chuwi Hi13 (CWI534) with BMA250 sensor ++# Note this sets the norm matrix, since the matrix which the kernel reads ++# from the ACPI tables is actually wrong on these models ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnChuwi*:pnHi13:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, 1 ++ + # Chuwi HiBook + # Chuwi HiBook does not have its product name filled, so we + # match the entire dmi-alias, assuming that the use of a BOSC0200 + + # bios-version + bios-date combo is unique +-sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring: +-sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring: ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + ++# Chuwi HiBook Pro (CWI526) ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo*:pnP1D6_C109K:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Chuwi CoreBook ++# Chuwi CoreBook does not have its product name filled, so we ++# match the entire dmi-alias ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrY13D_KB133.103:bd06/01/2018:svnHampoo:pnDefaultstring:pvrV100:rvnHampoo:rnY13D_KB133:rvrV100:cvnDefaultstring:ct9:cvrDefaultstring:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++######################################### ++# Connect ++######################################### ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnConnect:pnTablet9:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ + ######################################### + # Cube + ######################################### +@@ -140,52 +254,172 @@ sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/201 + sensor:modalias:acpi:KIOX000A*:dmi:*:svncube:pni1-TF:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +-# Cube i7 Stylus +-sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni7Stylus:* +- ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++# Cube i7 ++sensor:modalias:acpi:SMO8500*:dmi:*:svncube:pni7:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +-# Cube i7 Book (i16) ++# Cube i7 Stylus, i7 Stylus I8L Model, i7 Book (i16) and Mix Plus (i18B) ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni7Stylus:* ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni8-L:* + sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni16:* ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni18B:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + +-# Cube i7 Stylus I8L Model +-sensor:modalias:acpi:KIOX000A*:dmi:*:svnCube:pni8-L:* ++# Cube iWork 10 Flagship ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnCube:pnI15-TC:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Cube iWork 11 Stylus ++sensor:modalias:acpi:KIOX000A*:dmi:*:svncube:pni8-T:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Cube KNote 5 ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnALLDOCUBE:pni1102:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + + ######################################### + # Cytrix (Mytrix) + ######################################### +-sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t* ++sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + ++######################################### ++# Dell ++######################################### ++sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:pnVostro5581:* ++ ACCEL_LOCATION=base ++ ++sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0A3E:* ++ ACCEL_LOCATION=base ++ ++sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0B0B:* ++ ACCEL_LOCATION=base ++ ++# Dell Venue 8 Pro 3845 ++sensor:modalias:acpi:INVN6500*:dmi:*svnDellInc.*:pnVenue8Pro3845:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++# Dell Venue 10 Pro 5055 ++sensor:modalias:acpi:INVN6500*:dmi:*svnDell*:pnVenue10Pro5055:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, 1 ++ ++######################################### ++# DEXP ++######################################### ++sensor:modalias:acpi:SMO8500*:dmi:*svn*DEXP*:*pn*DEXPOEM:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++######################################### ++# Digibras ++######################################### ++ ++# Digibras F10-30 ++sensor:modalias:acpi:SMO8500*:dmi:*:svnDigibras:pnF10-30:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++######################################### ++# DIGMA ++######################################### ++ ++# Digma CITI E203 ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnDigma:pnCITIE203ES2010EW:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ + ######################################### + # Endless + ######################################### +-sensor:modalias:acpi:ACCE0001*:dmi:*svnEndless*:*pnELT-NL3* ++sensor:modalias:acpi:ACCE0001*:dmi:*svnEndless*:*pnELT-NL3:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 0, 0, -1; -1, 0, 0 + ++######################################### ++# Estar ++######################################### ++sensor:modalias:acpi:SMO8500*:dmi:*:svnEstar:pneSTARBEAUTYHDIntelQuadcore:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # Eve Technology + ######################################### + sensor:modalias:acpi:KIOX000A*:dmi:*:svnEVE*:pnEveV:* + ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 + ++######################################### ++# Geo Computers ++######################################### ++ ++# Geoflex ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnGEO*:pnGeoFlex*:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++######################################### ++# Glavey ++######################################### ++ ++# Glavey TM800A550L ++sensor:modalias:acpi:KXCJ9000*:dmi:*:bvrZY-8-BI-PX4S70VTR400-X423B-005-D:*:rvnAMICorporation:rnAptioCRB:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++######################################### ++# Google Chromebooks ++######################################### ++sensor:modalias:platform:cros-ec-accel:dmi:*:svnGOOGLE:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ++# caroline board (Samsung Chromebook Pro) reports itself as svnGoogle ++sensor:modalias:platform:cros-ec-accel:dmi:*:svnGoogle:pnCaroline*:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ++# Dell Inspiron Chromebook 14 2-in-1 ++sensor:modalias:platform:cros-ec-accel:dmi:*svnGoogle:pnVayne*:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ++# nocturne board (Google Pixel Slate) ++sensor:modalias:platform:cros-ec-accel:dmi:*Google_Nocturne*:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # GP-electronic + ######################################### + sensor:modalias:acpi:KIOX000A*:dmi:bvnINSYDECorp.:bvrBYT70A.YNCHENG.WIN.007:*:svnInsyde:pnT701:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++######################################### ++# GPD ++######################################### ++ ++# GPD win (version 1, with the X5-Z8750 CPU) ++# Note we match all dmi fields including the BIOS date checking for all known ++# BIOS dates, since the strings are unfortunately very generic. ++# Out of a sample set of 15 similar boards only the GPDwin has board_vendor=AMI ++# and no other devices have both board_name *and* product_name set to ++# "Default string". So combined with the sensor modalias and BIOS date this ++# should be unique enough to identify the GPDwin ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd10/25/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd11/18/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/23/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/26/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd02/21/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd03/20/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/25/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++ ACCEL_LOCATION=base ++ + ######################################### + # HP + ######################################### +-sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8540w* +-sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8560w* +- ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 0, -1; 0, 1, 0 ++ ++# Most HP Laptop using the lis3lv02d device have it in the base, ++# mark these sensors as such. ++sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:* ++sensor:modalias:platform:lis3lv02d:dmi:*svn*HP*:* ++ ACCEL_LOCATION=base + + sensor:modalias:acpi:SMO8500*:dmi:*:svnHewlett-Packard:pnHPStream7Tablet:* + sensor:modalias:acpi:SMO8500*:dmi:*:svnHewlett-Packard:pnHPStream8Tablet:* +- ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# HP Pavillion X2 10-n000nd ++sensor:modalias:i2c:bmc150_accel:dmi:*:svnHewlett-Packard:pnHPPavilionx2Detachable:*:rn815D:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + + ######################################### + # I.T.Works +@@ -194,17 +428,33 @@ sensor:modalias:acpi:SMO8500*:dmi:*:svnHewlett-Packard:pnHPStream8Tablet:* + # The I.T.Works TW891 2-in-1's DMI has the product-name field set, but not + # the sys-vendor field. This makes the DMI data a bit generic, so we match + # the whole dmi modalias, except for the BIOS version/date +-sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:*:svnTobefilledbyO.E.M.:pnTW891:pvrTobefilledbyO.E.M.:rvnTobefilledbyO.E.M.:rnTW891:rvr1.0:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.: ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:*:svnTobefilledbyO.E.M.:pnTW891:pvrTobefilledbyO.E.M.:rvnTobefilledbyO.E.M.:rnTW891:rvr1.0:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + + # I.T.Works TW701 7" windows tablet, same hw as Trekstor ST70416-6 + sensor:modalias:acpi:BMA250*:dmi:*:bvritWORKS.G.WI71C.JGBMRB*:*:svnInsyde:pni71c:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++######################################### ++# Irbis ++######################################### ++ ++#TW90 ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnIRBIS:pnTW90:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 ++ ++# NB111 ++sensor:modalias:acpi:KIOX010A*:dmi:*svn*IRBIS*:*pn*NB111:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++#TW118 ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnIRBIS:pnTW118:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # iOTA 360 + ######################################### +-sensor:modalias:acpi:KIOX000A*:dmi:*svn*iOTA*:*pn*IOTA2210* ++sensor:modalias:acpi:KIOX000A*:dmi:*svn*iOTA*:*pn*IOTA2210:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + + ######################################### +@@ -212,26 +462,40 @@ sensor:modalias:acpi:KIOX000A*:dmi:*svn*iOTA*:*pn*IOTA2210* + ######################################### + + # EZpad mini 3 +-sensor:modalias:acpi:BOSC0200*:dmi:bvnINSYDECorp.:bvrjumperx.T87.KFBNEE* ++sensor:modalias:acpi:BOSC0200*:dmi:bvnINSYDECorp.:bvrjumperx.T87.KFBNEE:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + + # EZpad 6 Pro + sensor:modalias:acpi:BOSC0200*:dmi:*:svnJumper:pnEZpad:*:rvr.A006:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1 + ++# EZpad 7 ++sensor:modalias:acpi:KIOX0009*:dmi:*:bvrJumper12x.WJ2012.bsBKRCP*:svnJumper:pnEZpad:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++# EZpad Go ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:*:svnjumper:pnEZpad:*:ct31:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # Kazam + ######################################### + sensor:modalias:acpi:KIOX000A*:dmi:bvnINSYDECorp.:bvrVISION.I22K*:svnKAZAM:pnVISION:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++######################################### ++# KD / Kurio ++######################################### ++sensor:modalias:acpi:SMO8500*:dmi:*:svnKDInteractive:pnKurioSmart:*:rnKDM960BCP:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # Lamina + ######################################### +-sensor:modalias:acpi:SMO8500*:dmi:*svnLamina*:*pnT701BR.SE* ++sensor:modalias:acpi:SMO8500*:dmi:*svnLamina*:*pnT701BR.SE:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 + +-sensor:modalias:acpi:KIOX000A*:dmi:*svnLAMINA:pnT-1016BNORD* ++sensor:modalias:acpi:KIOX000A*:dmi:*svnLAMINA:pnT-1016BNORD:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + + ######################################### +@@ -240,27 +504,55 @@ sensor:modalias:acpi:KIOX000A*:dmi:*svnLAMINA:pnT-1016BNORD* + sensor:modalias:acpi:NCPE0388*:dmi:*:rnLenovoYOGA510-14IKB:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1 + +-sensor:modalias:acpi:BOSC0200:BOSC0200:dmi:*ThinkPadYoga11e3rdGen* +- ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 ++sensor:modalias:acpi:BOSC0200*:dmi:*ThinkPadYoga11e3rdGen:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, -1 ++ ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnLENOVO:*pvrThinkPadYoga11e4thGen:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, -1 + + # Miix3-1030 + sensor:modalias:acpi:BMA250E*:dmi:bvnLENOVO:*:pvrLenovoMIIX3-1030:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +-# IdeaPad Miix 310 note this only is for BIOS version (bvr) 1HCN4?WW, which has ++# Miix3-830 ++sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrLenovoMIIX3-830:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++# IdeaPad D330-10IGM (both 81H3 and 81MD product names) ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 ++ ++# IdeaPad Miix 300 ++sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrMIIX300-*:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++# IdeaPad Miix 310 note this only is for BIOS version (bvr) 1HCN4?WW and 1HCN2?WW, which has + # a portrait LCD panel, versions with bvr 1HCN3?WW have a landscape panel + sensor:modalias:acpi:KIOX000A*:dmi:bvnLENOVO:bvr1HCN4?WW:*:svnLENOVO:pn80SG:* ++sensor:modalias:acpi:KIOX000A*:dmi:bvnLENOVO:bvr1HCN2?WW:*:svnLENOVO:pn80SG:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + + # IdeaPad Miix 320, different batches use a different sensor + sensor:modalias:acpi:*BOSC0200*:dmi:*:svnLENOVO*:pn80XF:* +-sensor:modalias:acpi:SMO8840*:dmi:*:svnLENOVO:pn80XF:pvrLenovoMIIX320* ++sensor:modalias:acpi:SMO8840*:dmi:*:svnLENOVO:pn80XF:pvrLenovoMIIX320:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + +-# IdeaPad Miix 510 ++# IdeaPad Miix 510, multiple expressions match different internal names ++# pn80U1 matches IdeaPad Miix510-12ISK + sensor:modalias:acpi:*BOSC0200*:dmi:*:svnLENOVO*:pn80XE:* ++sensor:modalias:acpi:*BOSC0200*:dmi:*:svnLENOVO*:pn80U1:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++# Yoga 300-11IBR, display sensor ++sensor:modalias:acpi:DUAL250E*:dmi:*:svnLENOVO:*:pvrLenovoYoga300-11IBR:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ACCEL_LOCATION=display ++ ++# Yoga 300-11IBR, base sensor ++sensor:modalias:i2c:bmc150_accel:dmi:*:svnLENOVO:*:pvrLenovoYoga300-11IBR:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, -1 ++ ACCEL_LOCATION=base ++ + ######################################### + # LINX + ######################################### +@@ -269,25 +561,140 @@ sensor:modalias:acpi:*BOSC0200*:dmi:*:svnLENOVO*:pn80XE:* + sensor:modalias:acpi:BOSC0200*:dmi:*:svnLINX*:pnLINX1010B:* + ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, -1 + ++# Linx 12X64, 12V64 and Vision 8 ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnLINX*:pnLINX12*64:* ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnLINX:pnVISION004:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++######################################### ++# Mediacom ++######################################### ++# Mediacom Winpad 7.0 W700 ++sensor:modalias:acpi:BMA250*:dmi:*svnMEDIACOM*:pnWinPad7W10-WPW700:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++######################################### ++# Medion ++######################################### ++# Medion Akoya E2228T MD61900 ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnMEDION:pnE2228TMD61900:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ACCEL_LOCATION=base ++ ++# Medion Akoya E1239T MD60568 ++sensor:modalias:acpi:KIOX0009*:dmi:*:svnMEDION:pnE1239TMD60568:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Medion Akoya E2212T MD99720 ++sensor:modalias:acpi:SMO8500*:dmi:*:svnMEDION:pnAkoyaE2212TMD99720:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++# Medion Akoya E2215T MD60198 ++sensor:modalias:acpi:KIOX000A*:dmi:*svnMEDION:pnE2215TMD60198:* ++# Medion Akoya E3216 MD60900 ++# Medion Akoya E3221 MD61237 ++# Medion Akoya E2292 MD63390 ++# Medion Akoya E2293 MD61130 ++# Medion Akoya E2293 MD61144 ++# Medion Akoya E3222 MD62450 ++# and presumably all other Akoya Exxxx ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnMEDION:pnE*:* ++# Medion Akoya E3222 MD62450 ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnMEDION:pnMEDION*:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ACCEL_LOCATION=display ++ ++# Same as above, but for base sensor ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnMEDION:pnE*:* ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnMEDION:pnMEDION*:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, -1 ++ ACCEL_LOCATION=base ++ ++######################################### ++# MPMAN ++######################################### ++ ++# MPMAN Converter 9, same hw as the I.T.Works TW891 2-in-1 ++sensor:modalias:acpi:SMO8500*:dmi:*:svnMPMAN:pnConverter9:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# MPMAN MPWIN895C ++sensor:modalias:acpi:BMA250E*:dmi:*:svnMPMAN:pnMPWIN8900CL:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # MSI + ######################################### + sensor:modalias:acpi:SMO8500*:dmi:*:svnMicro-StarInternationalCo.,Ltd.:pnS100:* + ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, 1 + ++######################################### ++# MYRIA ++######################################### ++ ++# MY8307 ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnCompletElectroServ:pnMY8307:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++# MY8312 ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnCompletElectroServSA:pnMY8312:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, 1 ++ + ######################################### + # Nuvision (TMax) + ######################################### ++ ++# Nuvision/TMAX 8" Windows signature edition. TM800W560L + sensor:modalias:acpi:KIOX000A*:dmi:*:svnTMAX:pnTM800W560L:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + ++# Nuvision Solo 10 Draw. TM101W610L ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTMAX:pnTM101W610L:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++# Nuvision Encite Split 11. NES11-C432SSA ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnNuvision:pnNES11:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++######################################### ++# Odys ++######################################### ++sensor:modalias:acpi:BOSC0200*:dmi:bvnINSYDECorp.:bvrODYS.FUSIONWIN12:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ + ######################################### + # Onda + ######################################### ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnONDA:pnV80PLUS:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ + sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrONDA.D89*:svnInsyde:pnONDATablet:* ++sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrONDA.D86*:svnONDA:pnV820wDualOS:* + sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrONDA.W89*:svnInsyde:pnONDATablet:* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + ++# Onda v975w, generic DMI strings, match entire dmi modalias inc. bios-date ++sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd07/25/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++######################################### ++# One-netbook ++######################################### ++ ++# One-netbook OneMix 2s ++# OneMix 2s has no product name filled, matching entire dmi-alias ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd10/26/2018:br5.12:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# One-netbook OneMix 3 Pro ++sensor:modalias:acpi:BOSC0200*:dmi:*svnONE-NETBOOKTECHNOLOGYCO*:pnOne-Mix3Pro:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++# One-netbook OneMix 3s ++# OneMix 3s has no product name filled, matching entire dmi-alias ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd07/17/2019:br5.12:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ + ######################################### + # Peaq + ######################################### +@@ -317,19 +724,112 @@ sensor:modalias:acpi:BMA250E*:dmi:*:svnShenzhenPLOYER*:pnMOMO7W:* + # The Point of View TAB-P800W does not have its product name filled, so we + # match the entire dmi-alias, assuming that the use of a BMA250E + + # bios-version + bios-date combo is unique +-sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1013:bd08/22/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.: +-sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1014:bd10/24/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.: ++sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1013:bd08/22/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* ++sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1014:bd10/24/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++# Point of View TAB-P1005W-232 (v2.0) ++sensor:modalias:acpi:KIOX000A*:dmi:*:rvnPOV:rnI102A:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Point of View TAB-P1006W-232-3G (v1.0) ++sensor:modalias:i2c:bmc150_accel:dmi:bvnINSYDECorp.:*:svnInsyde:pnBayTrail:*:rvn105B:rn0E57:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++######################################### ++# Predia ++######################################### ++ ++# Predia Basic tablet, most DMI strings are generic, match on BIOS version ++sensor:modalias:acpi:BOSC0200*:dmi:bvnINSYDECorp.:bvrMx.WT107.KUBNGEA*svnInsyde:pnCherryTrail:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++######################################### ++# Prowise ++######################################### ++sensor:modalias:acpi:SMO8500*:dmi:*:svnProwise:pnPT301:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++######################################### ++# Reeder ++######################################### ++ ++# A8iW-Rev.A ++sensor:modalias:acpi:SMO8500*:dmi:*:rvnReeder:rnA8iW-Rev.A:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++######################################### ++# Schneider ++######################################### ++ ++# SCT101CTM ++sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrSCH12i.WJ210Z.KtBJRCA03:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ + ######################################### + # Teclast + ######################################### ++# Teclast F5 ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTECLAST:pnF5:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Teclast F6 Pro (2 sensors) ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTECLAST:pnF6Pro:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ACCEL_LOCATION=display ++ ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnTECLAST:pnF6Pro:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ACCEL_LOCATION=base ++ ++# Teclast Tbook 11 (E5A6) ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnTbooK11:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Teclast X4 2-in-1 (G4M6) ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX4:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Teclast X80 Plus (H5C5) ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnDefaultstring:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Teclast X80 Pro (E3E6) + sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX80Pro:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++# Teclast X89 (E7ED), "tPAD" is too generic also match on BIOS date ++sensor:modalias:acpi:SMO8500*:dmi:*bd12/19/2014:*:rvnTECLAST:rntPAD:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# Teclast X98 Plus I (A5C6), generic DMI strings, match entire dmi modalias inc. bios-date ++sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.011:bd11/03/2015:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnCherryTrailCR:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ++# Teclast X98 Plus II + sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX98PlusII:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + ++######################################### ++# Thundersoft ++######################################### ++ ++# Thundersoft TST168 tablet, generic DMI strings, match entire dmi modalias inc. bios-date ++sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd04/15/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++######################################### ++# Toshiba ++######################################### ++ ++# Toshiba Encore WT8-B tablet ++sensor:modalias:acpi:INVN6500*:dmi:*:svnTOSHIBA:pnTOSHIBAENCORE2WT8-B:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++# Toshiba Encore WT10A tablet ++sensor:modalias:acpi:INVN6500*:dmi:*:svnTOSHIBA:pnTOSHIBAWT10-A-103:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ + ######################################### + # Trekstor + ######################################### +@@ -337,6 +837,62 @@ sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnInsyde:pnST7041 + sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnTrekStor:pnSurfTabwintron7.0ST70416-6:* + ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 + ++# SurfTab Wintron 10.1 ST10432-3, generic DMI string, use partial BIOS version match ++sensor:modalias:acpi:SMO8500*:dmi:*:bvrWintron.R25M.02.0*:*:svnInsyde:pnBayTrail:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTrekStor:pnSurfTabtwin10.1:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR*:pnPrimetabS11B:* ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR:pnPrimetabT13B:* ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabtwin11.6:* ++sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabduoW110.1(VT4):* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++# alternative version of Trekstor's SurfTab Twin 11.6 ++sensor:modalias:acpi:BOSC0200*:dmi:*:bvrTP15-VT5.2.1.3:*:svnTrekStor*:pnSurfTabtwin11.6:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, -1 ++ ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnPrimebookC11B:* ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:* ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnYourbookC11B:* ++sensor:modalias:acpi:KIOX010A*:dmi:*:svnTREKSTOR:pnYOURBOOKC11B:* ++ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1 ++ ACCEL_LOCATION=display ++ ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPrimebookC11B:* ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:* ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnYourbookC11B:* ++sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnYOURBOOKC11B:* ++ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ++ ACCEL_LOCATION=base ++ ++######################################### ++# Umax ++######################################### ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnUMAX:pnVisionBook10WiPro:* ++ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ++ ++sensor:modalias:acpi:SMO8500*:dmi:*:svnUMAX:pnVisionBook10WiPlus:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ++ ++######################################### ++# Voyo ++######################################### ++# Voyo Winpad A15 ++# The Winpad A15 does not have its product name filled, so we ++# match the entire dmi-alias, assuming that the use of a SMO8500 + ++# bios-version + bios-date combo is unique ++sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd11/20/2014:br5.6:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, -1 ++ ++######################################### ++# Wortmann ++######################################### ++sensor:modalias:acpi:KIOX000A*:dmi:*:svnWortmann_AG:pnTERRA_PAD_1061:* ++ ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, -1 ++ + ######################################### + # Yours + ######################################### +diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb +index 5adf793752..b14ad6f1fa 100644 +--- a/hwdb/70-mouse.hwdb ++++ b/hwdb/70-mouse.hwdb +@@ -6,35 +6,37 @@ + # The lookup keys are composed in: + # 70-mouse.rules + # +-# Note: The format of the "mouse:" prefix match key is a +-# contract between the rules file and the hardware data, it might +-# change in later revisions to support more or better matches, it +-# is not necessarily expected to be a stable ABI. ++# Note: The format of the "mouse:" prefix match key is a contract between the ++# rules file and the hardware data, it might change in later revisions to ++# support more or better matches, it is not necessarily expected to be a stable ++# ABI. + # +-# Match string format: ++# Match key format: + # mouse::vp:name:: + # + # Supported subsystems: usb, bluetooth + # vid/pid as 4-digit hex lowercase vendor/product + # + # if vid/pid is unavailable, use +-# mouse:*:name:: ++# mouse:*:name::* + # if name is unavailable, use +-# mouse::vp:* ++# mouse::vp:* + # + # For example, the following 5 matches all match the same mouse: +-# mouse:usb:v17efp6019:name:Lenovo Optical USB Mouse: +-# mouse:usb:*:name:Lenovo Optical USB Mouse: +-# mouse:usb:v17efp6019:* +-# mouse:*:name:Lenovo Optical USB Mouse: ++# mouse:usb:v17efp6019:name:Lenovo Optical USB Mouse:* ++# mouse:usb:*:name:Lenovo Optical USB Mouse:* ++# mouse:usb:v17efp6019:* ++# mouse:*:name:Lenovo Optical USB Mouse:* ++# ++# All matches should end in ':*' to allow future expansions of the match key. + # + # To add local entries, create a new file + # /etc/udev/hwdb.d/71-mouse-local.hwdb + # and add your rules there. To load the new rules execute (as root): + # systemd-hwdb update + # udevadm trigger /dev/input/eventXX +-# where /dev/input/eventXX is the mouse in question. If in +-# doubt, simply use /dev/input/event* to reload all input rules. ++# where /dev/input/eventXX is the mouse in question. If in doubt, simply use ++# /dev/input/event* to reload all input rules. + # + # If your changes are generally applicable, preferably send them as a pull + # request to +@@ -44,14 +46,12 @@ + # udevadm info /dev/input/eventXX. + # + # Allowed properties are: +-# ID_INPUT_TRACKBALL +-# MOUSE_DPI +-# MOUSE_WHEEL_CLICK_ANGLE +-# MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL +-# MOUSE_WHEEL_CLICK_COUNT +-# MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL +-# MOUSE_WHEEL_TILT_HORIZONTAL +-# MOUSE_WHEEL_TILT_VERTICAL ++# ID_INPUT_TRACKBALL ++# MOUSE_DPI ++# MOUSE_WHEEL_CLICK_ANGLE ++# MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL ++# MOUSE_WHEEL_CLICK_COUNT ++# MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL + # + ######################################### + # ID_INPUT_TRACKBALL # +@@ -65,7 +65,7 @@ + ######################################### + # + # DPI settings are specified as +-# MOUSE_DPI=[@] ++# MOUSE_DPI=[@] + # + # Where is the resolution in dots per inch, and the + # sampling frequency in Hz (optional). If a device supports dynamic +@@ -96,7 +96,7 @@ + # The list may contain a single item which must be marked with an + # asterisk. + # +-# Local changes to the a non-default resolution of the mouse (e.g. through ++# Local changes to the non-default resolution of the mouse (e.g. through + # third-party software) must not be entered into this file, use a local + # hwdb instead. + # +@@ -136,26 +136,6 @@ + # MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL works the same way but also follows the + # rules of MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL. + +-######################################### +-# MOUSE_WHEEL_TILT_HORIZONTAL # +-# MOUSE_WHEEL_TILT_VERTICAL # +-######################################### +-# +-# Indicates that the respective axis is not a mouse wheel rotation but a +-# tilt along that axis. Wheel tilt is most commonly used for horizontal +-# scroll wheel emulation on mice with only a single vertical wheel. +-# +-# The vertical and horizontal Axes are independently marked as tilt axes, +-# for example it is permitted to have a MOUSE_WHEEL_CLICK_COUNT or +-# MOUSE_WHEEL_CLICK_ANGLE for the vertical axis and mark the horizontal axis +-# marked as as MOUSE_WHEEL_TILT_HORIZONTAL. +-# +-# It is a bug to have either CLICK_COUNT or CLICK_ANGLE set on the same axis +-# as WHEEL_TILT. Applications should give priority to WHEEL_TILT and ignore +-# other settings. +-# +-# This is a flag only, permitted values: 0 or 1 +- + # + # Sort by brand, type (usb, bluetooth), DPI, frequency. + # For mice with switchable resolution, sort by the starred entry. +@@ -163,9 +143,9 @@ + ########################################## + # Generic + ########################################## +-mouse:*:name:*Trackball*: +-mouse:*:name:*trackball*: +-mouse:*:name:*TrackBall*: ++mouse:*:name:*Trackball*:* ++mouse:*:name:*trackball*:* ++mouse:*:name:*TrackBall*:* + ID_INPUT_TRACKBALL=1 + + ########################################## +@@ -175,7 +155,7 @@ mouse:*:name:*TrackBall*: + # Apple MagicMouse + # Note: this device changes name once connected to a mac, the name ends up + # as $username`s mouse +-mouse:bluetooth:v05acp030d:name:*: ++mouse:bluetooth:v05acp030d:name:*:* + MOUSE_DPI=1300@1000 + + ########################################## +@@ -183,7 +163,7 @@ mouse:bluetooth:v05acp030d:name:*: + ########################################## + + # Chicony 2.4G Multimedia Wireless Kit MG-0919 +-mouse:usb:v04f2p0963:name:Chicony 2.4G Multimedia Wireless Kit: ++mouse:usb:v04f2p0963:name:Chicony 2.4G Multimedia Wireless Kit:* + MOUSE_DPI=1000@142 + + ########################################## +@@ -191,15 +171,15 @@ mouse:usb:v04f2p0963:name:Chicony 2.4G Multimedia Wireless Kit: + ########################################## + + # Dell MUAR DEL7 +-mouse:usb:v413cp3012:name:Dell Dell USB Optical Mouse: ++mouse:usb:v413cp3012:name:Dell Dell USB Optical Mouse:* + MOUSE_DPI=400@166 + + # Dell USB Laser Mouse +-mouse:usb:v046dpc063:name:DELL DELL USB Laser Mouse: ++mouse:usb:v046dpc063:name:DELL DELL USB Laser Mouse:* + MOUSE_DPI=1000@125 + + # Dell MS116t +-mouse:usb:v413cp301a:name:PixArt Dell MS116 USB Optical Mouse: ++mouse:usb:v413cp301a:name:PixArt Dell MS116 USB Optical Mouse:* + MOUSE_DPI=1000@125 + + ########################################## +@@ -207,14 +187,22 @@ mouse:usb:v413cp301a:name:PixArt Dell MS116 USB Optical Mouse: + ######################################### + + # Dynex Wired Optical Mouse (DX-WMSE2) +-mouse:usb:v0461p4d46:name:USB Optical Mouse: ++mouse:usb:v0461p4d46:name:USB Optical Mouse:* + MOUSE_DPI=1000@125 + ++########################################## ++# Elecom ++######################################### ++ ++# Elecom HUGE TrackBall (M-HT1DR) ++mouse:usb:v056ep010d:name:ELECOM TrackBall Mouse HUGE TrackBall:* ++ MOUSE_DPI=500@125 *1000@125 1500@125 ++ + ########################################## + # Fujitsu Siemens + ########################################## + +-mouse:usb:v0461p4d16:name:USB Optical Mouse: ++mouse:usb:v0461p4d16:name:USB Optical Mouse:* + MOUSE_DPI=500@125 + + ########################################## +@@ -222,7 +210,7 @@ mouse:usb:v0461p4d16:name:USB Optical Mouse: + ########################################## + + # SNES Mouse plugged into a Retrode 2 +-mouse:usb:v0403p97c1:name:Retrode SNES Mouse: ++mouse:usb:v0403p97c1:name:Retrode SNES Mouse:* + MOUSE_DPI=235@126 + + ########################################## +@@ -230,11 +218,11 @@ mouse:usb:v0403p97c1:name:Retrode SNES Mouse: + ########################################## + + # FM-901 Wireless Mouse +-mouse:usb:v1ea7p000b:name:2.4G RF Mouse: ++mouse:usb:v1ea7p000b:name:2.4G RF Mouse:* + MOUSE_DPI=*800@125 1600@125 + + # WK-727 +-mouse:usb:v04d9p0499:name:* ++mouse:usb:v04d9p0499:name:*:* + MOUSE_DPI=800@125 + + ########################################## +@@ -242,7 +230,7 @@ mouse:usb:v04d9p0499:name:* + ########################################## + + # HandShoe Mouse +-mouse:usb:v192fp0916:name:USB Optical Mouse: ++mouse:usb:v192fp0916:name:USB Optical Mouse:* + MOUSE_DPI=1000@128 + + ########################################## +@@ -250,7 +238,7 @@ mouse:usb:v192fp0916:name:USB Optical Mouse: + ########################################## + + # Hoverstop active ergonomic mouse +-mouse:usb:v088dp1234:name:HoverStop NL Hoverstop active ergonomic mouse: ++mouse:usb:v088dp1234:name:HoverStop NL Hoverstop active ergonomic mouse:* + MOUSE_DPI=400@129 + + ########################################## +@@ -258,18 +246,18 @@ mouse:usb:v088dp1234:name:HoverStop NL Hoverstop active ergonomic mouse: + ########################################## + + # HP USB 1000dpi Laser Mouse +-mouse:usb:v0458p0133:name:Mouse Laser Mouse: ++mouse:usb:v0458p0133:name:Mouse Laser Mouse:* + MOUSE_DPI=1000@125 + MOUSE_WHEEL_CLICK_ANGLE=15 + + # HP X1000 + # Dell MS111-T +-mouse:usb:v093ap2510:name:PixArt USB Optical Mouse: +-mouse:usb:v093ap2510:name:PIXART USB OPTICAL MOUSE: ++mouse:usb:v093ap2510:name:PixArt USB Optical Mouse:* ++mouse:usb:v093ap2510:name:PIXART USB OPTICAL MOUSE:* + MOUSE_DPI=1000@125 + + # HP X1200 Optical Mouse +-mouse:usb:v03f0p0641:name:PixArt HP X1200 USB Optical Mouse: ++mouse:usb:v03f0p0641:name:PixArt HP X1200 USB Optical Mouse:* + MOUSE_DPI=1100@125 + + ########################################## +@@ -280,32 +268,46 @@ mouse:usb:v03f0p0641:name:PixArt HP X1200 USB Optical Mouse: + mouse:usb:v04b3p3107:name:* + MOUSE_DPI=800@125 + ++########################################## ++# Kensington ++########################################## ++ ++# Kensington Expert Mouse trackball ++mouse:usb:v047dp1020:*Kensington Expert Mouse*:* ++ ID_INPUT_TRACKBALL=1 ++ MOUSE_DPI=400@125 ++ + ########################################## + # Lenovo + ########################################## + + # Lenovo Optical USB Mouse +-mouse:usb:v17efp6019:name:Lenovo Optical USB Mouse: ++mouse:usb:v17efp6019:name:Lenovo Optical USB Mouse:* + MOUSE_DPI=1000@125 + + # Lenovo M-U0025-O +-mouse:usb:v17efp6019:name:Logitech Lenovo USB Optical Mouse: ++mouse:usb:v17efp6019:name:Logitech Lenovo USB Optical Mouse:* + MOUSE_DPI=1000@166 + +-# ThinkPad USB Laser Mouse +-mouse:usb:v17efp6044:name:ThinkPad USB Laser Mouse: +- MOUSE_DPI=1200@125 ++# Lenovo USB mouse model MO28UOL ++mouse:usb:v04b3p310c:name:USB Optical Mouse:* ++ MOUSE_DPI=400@142 + + # Lenovo Precision USB Mouse +-mouse:usb:v17efp6050:name:Lenovo Precision USB Mouse: ++mouse:usb:v17efp6050:name:Lenovo Precision USB Mouse:* + MOUSE_DPI=1200@127 + + # Lenovo MOBGUL +-mouse:usb:v17efp601d:name:Primax Lenovo Laser Mouse: ++mouse:usb:v17efp601d:name:Primax Lenovo Laser Mouse:* ++ MOUSE_DPI=1600@125 ++ + # Lenovo MOBGULA +-mouse:usb:v17efp6045:name:Lenovo USB Laser Mouse: ++mouse:usb:v17efp6045:name:Lenovo USB Laser Mouse:* + MOUSE_DPI=1600@125 + ++# ThinkPad USB Laser Mouse ++mouse:usb:v17efp6044:name:ThinkPad USB Laser Mouse:* ++ MOUSE_DPI=1200@125 + + ########################################## + # Logitech +@@ -316,265 +318,380 @@ mouse:usb:v17efp6045:name:Lenovo USB Laser Mouse: + # model name. The usb vid/pid is the same for all those devices. + # Until 3.19 is available, this list just has the Wireless PID entry. + +-# Logitech Anywhere MX +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:1017: +-mouse:usb:v046dp1017:name:Logitech Anywhere MX: +- MOUSE_WHEEL_CLICK_ANGLE=20 +- +-# Logitech M-BJ58 Optical Mouse +-mouse:usb:v046dpc00e:name:Logitech USB-PS/2 Optical Mouse: +-# Logitech Mini Optical Mouse +-mouse:usb:v046dpc016:name:Logitech Optical USB Mouse: +-# Logitech MX310 Optical Mouse +-mouse:usb:v046dpc01b:name:Logitech USB-PS/2 Optical Mouse: +-# Logitech USB-PS/2 M-BT58 +-mouse:usb:v046dpc03e:name:Logitech USB-PS/2 Optical Mouse: +-# Logitech TrackMan Marble Wheel USB +-mouse:usb:v046dpc401:name:Logitech USB-PS/2 Trackball: +- MOUSE_DPI=400@125 +- +-# Logitech Cordless MouseMan Optical M-RM63 +-mouse:usb:v046dpc501:name:Logitech USB Receiver: +- MOUSE_DPI=800@63 +- +-# Lenovo USB mouse model MO28UOL +-mouse:usb:v04b3p310c:name:USB Optical Mouse: +- MOUSE_DPI=400@142 +- +-# Logitech M570 trackball +-mouse:usb:v046dp1028:name:Logitech M570: +- MOUSE_DPI=540@167 +- ID_INPUT_TRACKBALL=1 +- +-# Logitech USB-PS/2 M-BZ96C +-mouse:usb:v046dpc045:name:Logitech USB-PS/2 Optical Mouse: +- MOUSE_DPI=600@125 +- +-# Logitech Wireless Mouse M325 +-mouse:usb:v046dp400a:name:Logitech M325: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:400a: +- MOUSE_DPI=600@166 +- MOUSE_WHEEL_CLICK_ANGLE=20 +- +-# Logitech MX400 Performance Laser Mouse +-mouse:usb:v046dpc043:name:Logitech USB-PS/2 Optical Mouse: +-# Logitech MX1000 Laser Cordless Mouse +-mouse:usb:v046dpc50e:name:Logitech USB RECEIVER: +-# Logitech Cordless Click! Plus +-mouse:usb:v046dpc50e:name:Logitech USB Receiver: +-# Logitech, Inc. RX 300 Optical Mouse +-mouse:usb:v046dpc040:name:Logitech USB-PS/2 Optical Mouse: +- MOUSE_DPI=800@125 +- +-# Logitech MX 518 +-mouse:usb:v046dpc01e:name:Logitech USB-PS/2 Optical Mouse: +- MOUSE_DPI=400@125 *800@125 1600@125 +- +-# Logitech, Inc. RX 250 Optical Mouse +-mouse:usb:v046dpc050:name:Logitech USB-PS/2 Optical Mouse: +- MOUSE_DPI=1000@142 +- +-# Logitech Wireless Mouse M185 +-mouse:usb:v046dp4008:name:Logitech M185: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4008: +-# Logitech Wireless Mouse M510 +-mouse:usb:v046dp1025:name:Logitech M510: +-# Logitech M705 (marathon mouse) +-mouse:usb:v046dp101b:name:Logitech M705: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101b: +- MOUSE_DPI=1000@125 +- +-# Logitech MX Revolution +-mouse:usb:v046dpc51a:name:Logitech USB Receiver: +- MOUSE_DPI=800@200 ++## G Series ## + + # Logitech G5 Laser Mouse +-mouse:usb:v046dpc049:name:Logitech USB Gaming Mouse: ++mouse:usb:v046dpc049:name:Logitech USB Gaming Mouse:* ++ MOUSE_DPI=400@500 *800@500 2000@500 ++ + # Logitech G500s Laser Gaming Mouse +-mouse:usb:v046dpc24e:name:Logitech G500s Laser Gaming Mouse: ++mouse:usb:v046dpc24e:name:Logitech G500s Laser Gaming Mouse:* + MOUSE_DPI=400@500 *800@500 2000@500 + + # Logitech G9 +-mouse:usb:v046dpc048:name:Logitech G9 Laser Mouse: ++mouse:usb:v046dpc048:name:Logitech G9 Laser Mouse:* + MOUSE_DPI=400@1000 800@1000 *1600@1000 + + # Logitech G9x [Call of Duty MW3 Edition] +-mouse:usb:v046dpc249:name:Logitech G9x Laser Mouse: ++mouse:usb:v046dpc249:name:Logitech G9x Laser Mouse:* + MOUSE_DPI=400@1000 800@1000 *1600@1000 3200@1000 + ++# Logitech G100s Optical Gaming Mouse ++mouse:usb:v046dpc247:name:Logitech G100s Optical Gaming Mouse:* ++ MOUSE_DPI=*1000@500 1750@500 2500@500 ++ + # Logitech G400 (Wired) +-mouse:usb:v046dpc245:name:Logitech Gaming Mouse G400: ++mouse:usb:v046dpc245:name:Logitech Gaming Mouse G400:* + MOUSE_DPI=400@1000 *800@1000 1800@1000 3600@1000 + + # Logitech G400s (Wired) +-mouse:usb:v046dpc24c:name:Logitech G400s Optical Gaming Mouse: ++mouse:usb:v046dpc24c:name:Logitech G400s Optical Gaming Mouse:* + MOUSE_DPI=400@1000 *800@1000 2000@1000 4000@1000 + + # Logitech G402 Hyperion Fury +-mouse:usb:v046dpc07e:name:Logitech Gaming Mouse G402: ++mouse:usb:v046dpc07e:name:Logitech Gaming Mouse G402:* ++ MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000 ++ ++# Logitech G403 Prodigy (Wired) ++mouse:usb:v046dpc083:name:Logitech G403 Prodigy Gaming Mouse:* ++ MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000 ++ ++# Logitech G403 Hero ++mouse:usb:v046dpc08f:name:Logitech G403 HERO Gaming Mouse:* + MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000 + ++# Logitech G500 Mouse ++mouse:usb:v046dpc068:name:Logitech G500:* ++ MOUSE_DPI=400@500 *800@500 2000@500 ++ + # Logitech G502 Proteus Spectrum +-mouse:usb:v046dpc332:name:Logitech Gaming Mouse G502: ++mouse:usb:v046dpc332:name:Logitech Gaming Mouse G502:* ++# Logitech G502 HERO SE ++mouse:usb:v046dpc08b:name:Logitech G502 HERO SE:* ++# Logitech G502 Hero ++mouse:usb:v046dpc08b:name:Logitech G502 HERO Gaming Mouse:* + MOUSE_DPI=1200@1000 *2400@1000 3200@1000 6400@1000 + +-# Logitech B605 Wireless Mouse (also M505) +-mouse:usb:v046dp101d:name:Logitech B605: +-mouse:usb:v046dp101d:name:Logitech M505: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101d: +- MOUSE_DPI=900@166 ++# Logitech G700 Laser Mouse (Wired) ++mouse:usb:v046dpc06b:name:Logitech G700 Laser Mouse:* ++# Logitech G700 Laser Mouse (Wireless) ++mouse:usb:v046dp1023:name:Logitech G700:* ++mouse:usb:v046dpc531:name:Logitech USB Receiver:* ++ MOUSE_DPI=400@500 800@500 *1200@500 1600@500 3200@500 ++ ++# Logitech G703 (Wired) ++mouse:usb:v046dpc087:name:Logitech G703 Wired/Wireless Gaming Mouse:* ++# Logitech G703 (Wireless) ++mouse:usb:v046dpc539:name:Logitech USB Receiver Mouse:* ++ MOUSE_DPI=400@1000 800@1000 *1600@1000 3200@1000 + +-# Logitech Cordless Desktop Wave Mouse +-mouse:usb:v046dpc517:name:Logitech USB Receiver: +- MOUSE_DPI=950@125 ++# Logitech G Pro Wireless (Wired) ++mouse:usb:v046dpc088:name:Logitech G Pro Wireless Gaming Mouse:* ++# Logitech G Pro Wireless (Wireless) ++mouse:usb:v046dp4079:name:Logitech G Pro:* ++ MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000 6400@1000 + +-# Logitech RX1000 Laser Mouse +-mouse:usb:v046dpc046:name:Logitech USB Optical Mouse: +-# Logitech M100 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 +-mouse:usb:v046dp402d:name:Logitech M560: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:402d: ++## M Series ## ++ ++# Logitech Wireless Mouse M185 ++mouse:usb:v046dp4008:name:Logitech M185:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4008:* + MOUSE_DPI=1000@125 + ++# Logitech Wireless Mouse M510 ++mouse:usb:v046dp1025:name:Logitech M510:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech M705 (marathon mouse) ++mouse:usb:v046dp101b:name:Logitech M705:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101b:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech M705 (newer version?) ++mouse:usb:v046dp406d:name:Logitech M705:* ++ MOUSE_DPI=1000@167 ++ + # Logitech M305 Wireless Optical Mouse +-mouse:usb:v046dpc52f:name:Logitech USB Receiver: ++mouse:usb:v046dpc52f:name:Logitech USB Receiver:* + MOUSE_DPI=1000@170 + ++# Logitech Wireless Mouse M310 ++mouse:usb:v046dp1024:name:Logitech M310:* ++ MOUSE_DPI=800@125 ++ ++# Logitech Wireless Mouse M325 ++mouse:usb:v046dp400a:name:Logitech M325:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:400a:* ++ MOUSE_DPI=600@166 ++ MOUSE_WHEEL_CLICK_ANGLE=20 ++ ++# Logitech M570 trackball ++mouse:usb:v046dp1028:name:Logitech M570:* ++ MOUSE_DPI=540@167 ++ ID_INPUT_TRACKBALL=1 ++ ++## MX Series ## ++ + # Logitech Performance MX +-mouse:usb:v046dp101a:name:Logitech Performance MX: ++mouse:usb:v046dp101a:name:Logitech Performance MX:* + MOUSE_DPI=1000@166 + +-# Logitech MX Master ++# Logitech MX Revolution ++mouse:usb:v046dpc51a:name:Logitech USB Receiver:* ++ MOUSE_DPI=800@200 ++ ++# Logitech MX 518 ++mouse:usb:v046dpc01e:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=400@125 *800@125 1600@125 ++ ++# Logitech MX 518 Legendary (HERO sensor) ++mouse:usb:v046dpc08e:name:Logitech MX518 Gaming Mouse:* ++ MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000 6400@1000 ++ ++# Logitech MX1000 Laser Cordless Mouse ++mouse:bluetooth:v046dpb003:name:Logitech MX1000 mouse:* ++ MOUSE_DPI=800@80 ++ ++# Logitech Anywhere MX ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:1017:* ++mouse:usb:v046dp1017:name:Logitech Anywhere MX:* ++ MOUSE_WHEEL_CLICK_ANGLE=20 ++ ++# Logitech Anywhere MX 2S (via Logitech Unifying Receiver) ++mouse:usb:v046dp406a:name:Logitech MX Anywhere 2S:* ++ MOUSE_WHEEL_CLICK_ANGLE=20 ++ ++# Logitech Anywhere MX 2S (via Bluetooth) ++mouse:bluetooth:v046dpb01a:name:MX Anywhere 2S Mouse:* ++ MOUSE_WHEEL_CLICK_ANGLE=20 ++ ++# Logitech MX Master (via Logitech Unifying Receiver) + # Horiz wheel has 14 stops, angle is rounded up +-mouse:usb:v046dp4041:name:Logitech MX Master: ++mouse:usb:v046dp4060:name:Logitech MX Master:* ++mouse:usb:v046dp4041:name:Logitech MX Master:* + MOUSE_DPI=1000@166 + MOUSE_WHEEL_CLICK_ANGLE=15 + MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26 + MOUSE_WHEEL_CLICK_COUNT=24 + MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14 + +-# Logitech MX Master 2s ++# Logitech MX Master (via Bluetooth) + # Horiz wheel has 14 stops, angle is rounded up +-mouse:usb:v046dp4069:name:Logitech MX Master 2s: ++mouse:bluetooth:v046dpb012:name:MX Master Mouse:* ++ MOUSE_DPI=1000@2000 ++ MOUSE_WHEEL_CLICK_ANGLE=15 ++ MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26 ++ MOUSE_WHEEL_CLICK_COUNT=24 ++ MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14 ++ ++# Logitech MX Master 2S (via Logitech Unifying Receiver) ++# Horiz wheel has 14 stops, angle is rounded up ++mouse:usb:v046dp4069:name:Logitech MX Master 2s:* + MOUSE_DPI=1000@125 + MOUSE_WHEEL_CLICK_ANGLE=15 + MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26 + MOUSE_WHEEL_CLICK_COUNT=24 + MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14 + +-# Logitech MK260 Wireless Combo Receiver aka M-R0011 +-mouse:usb:v046dpc52e:name:Logitech USB Receiver: +- MOUSE_DPI=1000@200 ++# Logitech MX Master 2S (via Bluetooth) ++# Horiz wheel has 14 stops, angle is rounded up ++mouse:bluetooth:v046dpb019:name:MX Master 2S Mouse:* ++ MOUSE_DPI=1000@2000 ++ MOUSE_WHEEL_CLICK_ANGLE=15 ++ MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26 ++ MOUSE_WHEEL_CLICK_COUNT=24 ++ MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14 + +-# Logitech G100s Optical Gaming Mouse +-mouse:usb:v046dpc247:name:Logitech G100s Optical Gaming Mouse: +- MOUSE_DPI=*1000@500 1750@500 2500@500 ++# Logitech MX Ergo ++mouse:usb:v046dp406f:name:Logitech MX Ergo:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:406f:* ++mouse:bluetooth:v046dpb01d:name:MX Ergo Mouse:* ++ ID_INPUT_TRACKBALL=1 ++ MOUSE_DPI=380@125 + +-# Logitech G700 Laser Mouse (Wired) +-mouse:usb:v046dpc06b:name:Logitech G700 Laser Mouse: +-# Logitech G700 Laser Mouse (Wireless) +-mouse:usb:v046dpc531:name:Logitech USB Receiver: +- MOUSE_DPI=*1000@500 3800@500 500@1000 1500@1000 2000@1000 ++## Other ## + +-# Logitech Wireless Mouse M310 +-mouse:usb:v046dp1024:name:Logitech M310: +- MOUSE_DPI=1100@168 ++# Logitech M-BJ58 Optical Mouse ++mouse:usb:v046dpc00e:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=400@125 ++ ++# Logitech Mini Optical Mouse ++mouse:usb:v046dpc016:name:Logitech Optical USB Mouse:* ++ MOUSE_DPI=400@125 ++ ++# Logitech MX310 Optical Mouse ++mouse:usb:v046dpc01b:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=400@125 ++ ++# Logitech USB-PS/2 M-BT58 ++mouse:usb:v046dpc03e:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=400@125 ++ ++# Logitech TrackMan Marble Wheel USB ++mouse:usb:v046dpc401:name:Logitech USB-PS/2 Trackball:* ++ MOUSE_DPI=400@125 ++ ++# Logitech Cordless MouseMan Optical M-RM63 ++mouse:usb:v046dpc501:name:Logitech USB Receiver:* ++ MOUSE_DPI=800@63 ++ ++# Logitech USB-PS/2 M-BZ96C ++mouse:usb:v046dpc045:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=600@125 ++ ++# Logitech MX400 Performance Laser Mouse ++mouse:usb:v046dpc043:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=800@125 ++ ++# Logitech MX1000 Laser Cordless Mouse ++mouse:usb:v046dpc50e:name:Logitech USB RECEIVER:* ++ MOUSE_DPI=800@125 ++ ++# Logitech Cordless Click! Plus ++mouse:usb:v046dpc50e:name:Logitech USB Receiver:* ++ MOUSE_DPI=800@125 ++ ++# Logitech, Inc. RX 300 Optical Mouse ++mouse:usb:v046dpc040:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=800@125 ++ ++# Logitech, Inc. RX 250 Optical Mouse ++mouse:usb:v046dpc050:name:Logitech USB-PS/2 Optical Mouse:* ++ MOUSE_DPI=1000@142 ++ ++# Logitech B605 Wireless Mouse (also M505) ++mouse:usb:v046dp101d:name:Logitech B605:* ++mouse:usb:v046dp101d:name:Logitech M505:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101d:* ++ MOUSE_DPI=900@166 ++ ++# Logitech Cordless Desktop Wave Mouse ++mouse:usb:v046dpc517:name:Logitech USB Receiver:* ++ MOUSE_DPI=950@125 ++ ++# Logitech RX1000 Laser Mouse ++mouse:usb:v046dpc046:name:Logitech USB Optical Mouse:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech M100 Optical Mouse ++mouse:usb:v046dpc05a:name:Logitech USB Optical Mouse:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech USB Laser Mouse M-U0011-O rebranded as "terra Laser" ++mouse:usb:v046dpc065:name:Logitech USB Laser Mouse:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech USB Laser Mouse M-U0007 [M500] ++mouse:usb:v046dpc069:name:Logitech USB Laser Mouse:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech V500 Cordless Notebook Mouse ++mouse:usb:v046dpc510:name:Logitech USB Receiver:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech M560 Wireless Mouse ++mouse:usb:v046dp402d:name:Logitech M560:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:402d:* ++ MOUSE_DPI=1000@125 ++ ++# Logitech MK260 Wireless Combo Receiver aka M-R0011 ++mouse:usb:v046dpc52e:name:Logitech USB Receiver:* ++ MOUSE_DPI=1000@200 + + # Logitech USB Laser Mouse M-UAS144 [LS1 Laser Mouse] +-mouse:usb:v046dpc062:name:Logitech USB Laser Mouse: ++mouse:usb:v046dpc062:name:Logitech USB Laser Mouse:* + MOUSE_DPI=1200@125 + + # Logitech T620 (or, the soap) +-mouse:usb:v046dp4027:name:Logitech T620: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4027: ++mouse:usb:v046dp4027:name:Logitech T620:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4027:* + MOUSE_DPI=1200@250 + + # Logitech ZoneTouch Mouse T400 +-mouse:usb:v046dp4026:name:Logitech T400: +-mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4026: ++mouse:usb:v046dp4026:name:Logitech T400:* ++mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4026:* + MOUSE_DPI=1300@166 + +-# Logitech G500 Mouse +-mouse:usb:v046dpc068:name:Logitech G500: +- MOUSE_DPI=*1600@500 2600@500 3600@500 +- + # Logitech TrackMan Wheel (USB) +-mouse:usb:v046dpc404:name:Logitech Trackball: ++mouse:usb:v046dpc404:name:Logitech Trackball:* + MOUSE_DPI=300@125 + +-# Logitech MX1000 Laser Cordless Mouse +-mouse:bluetooth:v046dpb003:name:Logitech MX1000 mouse: +- MOUSE_DPI=800@80 ++# Logitech Trackman Marble ++mouse:usb:v046dpc408:name:Logitech USB Trackball:* ++ MOUSE_DPI=300@125 + + # Logitech Ultrathin Touch Mouse +-mouse:bluetooth:v046dpb00d:name:Ultrathin Touch Mouse: ++mouse:bluetooth:v046dpb00d:name:Ultrathin Touch Mouse:* + MOUSE_DPI=1000@1000 + + # ImPS/2 Logitech Wheel Mouse +-mouse:ps2:*:name:ImPS/2 Logitech Wheel Mouse: ++mouse:ps2:*:name:ImPS/2 Logitech Wheel Mouse:* + MOUSE_DPI=400@100 + + # ImExPS/2 Logitech Wheel Mouse +-mouse:ps2:*:name:ImExPS/2 Logitech Wheel Mouse: ++mouse:ps2:*:name:ImExPS/2 Logitech Wheel Mouse:* + MOUSE_DPI=400@250 + + ########################################## + # Microsoft + ########################################## + +-mouse:usb:v045ep0040:name:Microsoft Microsoft 3-Button Mouse with IntelliEye(TM): ++mouse:usb:v045ep0040:name:Microsoft Microsoft 3-Button Mouse with IntelliEye(TM):* + MOUSE_DPI=400@125 + + # Note: unsure that these work, it's likely that all devices on these + # receivers show up with the same vid/pid/name + + # Microsoft Wireless Mouse 5000 +-mouse:usb:v045ep0745:name:Microsoft Microsoft® 2.4GHz Transceiver v6.0: ++mouse:usb:v045ep0745:name:Microsoft Microsoft® 2.4GHz Transceiver v6.0:* + MOUSE_DPI=800@142 + + # Microsoft Comfort Mouse 4500 +-mouse:usb:v045ep076c:name:Microsoft Microsoft® Comfort Mouse 4500: ++mouse:usb:v045ep076c:name:Microsoft Microsoft® Comfort Mouse 4500:* + MOUSE_DPI=1000@125 + + # Microsoft Wireless Mobile Mouse 4000 +-mouse:usb:v045ep0745:name:Microsoft Microsoft® Nano Transceiver v2.0: ++mouse:usb:v045ep0745:name:Microsoft Microsoft® Nano Transceiver v2.0:* ++ MOUSE_DPI=1000@142 ++ + # Microsoft Sculpt Ergonomic Mouse +-mouse:usb:v045ep07a5:name:Microsoft Microsoft® 2.4GHz Transceiver v9.0: ++mouse:usb:v045ep07a5:name:Microsoft Microsoft® 2.4GHz Transceiver v9.0:* + MOUSE_DPI=1000@142 + + # Microsoft Arc Touch Mouse USB +-mouse:usb:v045ep07b1:name:Microsoft Microsoft® Nano Transceiver v1.0: ++mouse:usb:v045ep07b1:name:Microsoft Microsoft® Nano Transceiver v1.0:* + MOUSE_DPI=1400@142 + + # Microsoft Wireless Laser Mouse 8000 +-mouse:bluetooth:v045ep0702:name:Microsoft Wireless Laser Mouse 8000: ++mouse:bluetooth:v045ep0702:name:Microsoft Wireless Laser Mouse 8000:* + MOUSE_DPI=1000@1000 + + # Microsoft Sculpt Comfort Mouse +-mouse:bluetooth:v045ep07a2:name:Microsoft Sculpt Comfort Mouse: ++mouse:bluetooth:v045ep07a2:name:Microsoft Sculpt Comfort Mouse:* + MOUSE_DPI=1000@2000 + + # Microsoft Arc Touch Mouse SE: +-mouse:bluetooth:v045ep07f3:name:Arc Touch Mouse SE: ++mouse:bluetooth:v045ep07f3:name:Arc Touch Mouse SE:* + MOUSE_DPI=1000@2000 + + # Microsoft Surface Mouse +-mouse:bluetooth:v0000p0000:name:Surface Mouse: ++mouse:bluetooth:v0000p0000:name:Surface Mouse:* + MOUSE_DPI=2000@2000 + ++# Microsoft Classic IntelliMouse ++mouse:usb:v045ep0823:name:Microsoft Microsoft?? Classic IntelliMouse??:* ++ MOUSE_DPI=3200@1000 ++ ++# Microsoft Pro Intellimouse ++mouse:usb:v045ep082a:name:Microsoft Microsoft Pro Intellimouse Mouse:* ++ MOUSE_DPI=1600@1000 ++ + ########################################## + # Mionix + ########################################## + + #Mionix Avior 7000 +-mouse:usb:v22d4p1308:name:Laview Technology Mionix Avior 7000: ++mouse:usb:v22d4p1308:name:Laview Technology Mionix Avior 7000:* + MOUSE_DPI=400@1000 *1600@1000 7000@1000 + MOUSE_WHEEL_CLICK_ANGLE=15 + +@@ -583,7 +700,7 @@ mouse:usb:v22d4p1308:name:Laview Technology Mionix Avior 7000: + ########################################## + + # MODECOM MC-WM4 Wireless Optical Mouse +-mouse:usb:v0e8fp00a7:name:DaKai 2.4G RX: ++mouse:usb:v0e8fp00a7:name:DaKai 2.4G RX:* + MOUSE_DPI=*800@126 1600@126 + + ########################################## +@@ -591,7 +708,7 @@ mouse:usb:v0e8fp00a7:name:DaKai 2.4G RX: + ########################################## + + # Oklick 406S Bluetooth Laser Mouse +-mouse:bluetooth:v056ep0061:name:Laser BTmouse: ++mouse:bluetooth:v056ep0061:name:Laser BTmouse:* + MOUSE_DPI=*800@333 1600@333 + + ########################################## +@@ -599,7 +716,7 @@ mouse:bluetooth:v056ep0061:name:Laser BTmouse: + ########################################## + + # P-Active Wireless Mouse PA-27K2 +-mouse:usb:v0425p0101:name:G-Tech CHINA USB Wireless Mouse & KeyBoard V1.01 : ++mouse:usb:v0425p0101:name:G-Tech CHINA USB Wireless Mouse & KeyBoard V1.01 :* + MOUSE_DPI=800@125 + + ########################################## +@@ -607,11 +724,11 @@ mouse:usb:v0425p0101:name:G-Tech CHINA USB Wireless Mouse & KeyBoard V1.01 : + ########################################## + + # Razer Abyssus +-mouse:usb:v1532p0042:name:Razer Razer Abyssus: +- MOUSE_DPI=3500@1000 ++mouse:usb:v1532p0042:name:Razer Razer Abyssus:* ++ MOUSE_DPI=1600@1000 + + # Razer DeathAdder Black Edition +-mouse:usb:v1532p0029:name:Razer Razer DeathAdder: ++mouse:usb:v1532p0029:name:Razer Razer DeathAdder:* + MOUSE_DPI=3500@1000 + + ########################################## +@@ -619,7 +736,7 @@ mouse:usb:v1532p0029:name:Razer Razer DeathAdder: + ########################################## + + # Roccat Lua (ROC-11-310) +-mouse:usb:v1e7dp2c2e:name:ROCCAT ROCCAT Lua: ++mouse:usb:v1e7dp2c2e:name:ROCCAT ROCCAT Lua:* + MOUSE_DPI=250@125 500@125 1000@125 1250@125 1500@125 1750@125 2000@125 250@250 500@250 1000@250 1250@250 1500@250 1750@250 2000@250 250@500 500@500 1000@500 1250@500 1500@500 1750@500 2000@500 250@1000 500@1000 *1000@1000 1250@1000 1500@1000 1750@1000 2000@1000 + MOUSE_WHEEL_CLICK_ANGLE=15 + +@@ -628,7 +745,7 @@ mouse:usb:v1e7dp2c2e:name:ROCCAT ROCCAT Lua: + ########################################## + + # Sharkoon Shark Force Gaming Mouse +-mouse:usb:v093ap2521:name:USB OPTICAL MOUSE: ++mouse:usb:v093ap2521:name:USB OPTICAL MOUSE:* + MOUSE_DPI=*1000@125 1600@125 600@125 + + ########################################## +@@ -636,7 +753,7 @@ mouse:usb:v093ap2521:name:USB OPTICAL MOUSE: + ########################################## + + # SteelSeries Sensei Raw +-mouse:usb:v1038p1369:name:SteelSeries Sensei Raw Gaming Mouse: ++mouse:usb:v1038p1369:name:SteelSeries Sensei Raw Gaming Mouse:* + MOUSE_DPI=1000@1022 + + ########################################## +@@ -644,13 +761,29 @@ mouse:usb:v1038p1369:name:SteelSeries Sensei Raw Gaming Mouse: + ########################################## + + # Trust illuminated mouse gxt 152 +-mouse:usb:v145fp01ac:name:HID-compliant Mouse Trust Gaming Mouse: ++mouse:usb:v145fp01ac:name:HID-compliant Mouse Trust Gaming Mouse:* + MOUSE_DPI=*800@528 1200@537 1600@536 2400@521 + +- ########################################## +- # Zelotes +- ########################################## ++########################################## ++# Zelotes ++########################################## + + # Zelotes 5500 DPI 7 Button USB Wired Gaming Mouse + mouse:usb:v1d57pad17:* + MOUSE_DPI=1000@500 1600@500 2400@500 3200@500 5500@500 *1000@1000 1600@1000 2400@1000 3200@1000 5500@1000 ++ ++########################################## ++# Zowie ++########################################## ++ ++# Zowie FK2 ++mouse:usb:v3057p0001:* ++ MOUSE_DPI=400@125 *800@125 1600@125 3200@125 400@500 800@500 1600@500 3200@500 400@1000 800@1000 1600@1000 3200@1000 ++ MOUSE_WHEEL_CLICK_COUNT=16 ++ MOUSE_WHEEL_CLICK_ANGLE=23 ++ ++# Zowie ZA12 ++mouse:usb:v1af3p0001:name:Kingsis Peripherals ZOWIE Gaming mouse:* ++ MOUSE_DPI=400@125 *800@125 1600@125 3200@125 400@500 800@500 1600@500 3200@500 400@1000 800@1000 1600@1000 3200@1000 ++ MOUSE_WHEEL_CLICK_COUNT=16 ++ MOUSE_WHEEL_CLICK_ANGLE=23 +diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb +index 3f070e09de..b427f21ea5 100644 +--- a/hwdb/70-pointingstick.hwdb ++++ b/hwdb/70-pointingstick.hwdb +@@ -22,7 +22,7 @@ + # in /sys/class/input/eventX/device/id. + # + # - Input driver device name and DMI data match: +-# evdev:name::dmi:bvn*:bvr*:bd*:svn:pn* ++# evdev:name::dmi:bvn*:bvr*:bd*:svn:pn*:* + # is the name device specified by the driver, + # is the firmware-provided string from the kernel DMI modalias, + # see /sys/class/dmi/id/modalias +@@ -43,7 +43,7 @@ + # udevadm info /dev/input/eventXX. + # + # Allowed properties are: +-# POINTINGSTICK_CONST_ACCEL ++# POINTINGSTICK_CONST_ACCEL (deprecated) + # POINTINGSTICK_SENSITIVITY + # + # Entries should be sorted with growing _SENSITIVITY and _CONST_ACCEL. +@@ -52,10 +52,15 @@ + # POINTINGSTICK_CONST_ACCEL # + ######################################### + # ++# DO NOT USE THIS PROPERTY. This property is kept for backwards ++# compatibility. The only known consumer, libinput, stopped reading this ++# property in version 1.9.0. No new entries for this property should be ++# added. ++# + # Trackpoint const accel settings are specified as + # POINTINGSTICK_CONST_ACCEL= + # +-# Where is a floating point number, using a '.' seperator, specifying ++# Where is a floating point number, using a '.' separator, specifying + # by how much to multiply deltas generated by the pointingstick to get + # normalized deltas. + # +@@ -71,7 +76,6 @@ + # drivers/input/mouse/trackpoint.c in the Linux kernel sources. + # + +-# + # Sort by brand, model + + ######################################### +@@ -79,23 +83,23 @@ + ######################################### + + # Latitude D620 +-evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:pvr* ++evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:* + POINTINGSTICK_CONST_ACCEL=0.5 + + # Latitude E5570 +-evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE5570*:pvr* ++evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE5570*:* + POINTINGSTICK_CONST_ACCEL=0.1 + + # Latitude E6320 +-evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:pvr* ++evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:* + POINTINGSTICK_CONST_ACCEL=2.0 + + # Latitude E6400 +-evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6400*:pvr* ++evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6400*:* + POINTINGSTICK_CONST_ACCEL=1.5 + + # Latitude E7470 +-evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*:pvr* ++evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*:* + POINTINGSTICK_CONST_ACCEL=0.6 + + ######################################### +@@ -104,6 +108,8 @@ evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*:pvr* + + # Lenovo Thinkpad X220 + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX220:* ++# Lenovo Thinkpad X220 tablet ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX220Tablet:* + # Lenovo Thinkpad X230 + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX230:* + # Lenovo Thinkpad X230 tablet +@@ -120,6 +126,15 @@ evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??50 + # Lenovo Thinkpad *60 series + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??60:* + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??60?:* ++# Lenovo Thinkpad *70 series ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??70:* ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??70?:* ++# Lenovo Thinkpad *80 series ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??80:* ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??80?:* ++# Lenovo Thinkpad *90 series ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??90:* ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??90?:* + # Lenovo Thinkpad X1 Carbon 3rd gen + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd:* + # Lenovo Thinkpad X1 Carbon 4th gen +@@ -129,12 +144,13 @@ evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Ta + POINTINGSTICK_SENSITIVITY=200 + POINTINGSTICK_CONST_ACCEL=1.0 + +-# Lenovo Thinkpad X200/X201/X200s/X201s ++# Lenovo Thinkpad X200/X201/X200s/X201s/X200 Tablet/X201 Tablet + # Note these come with 2 revisions of keyboard, with the trackpoints having a + # different sensitivity in the different revisions. 1.25 is a bit slow for the + # least sensitive revision, but it is better to be a bit slow than too fast. + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?:* + evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20??:* ++evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?Tablet:* + POINTINGSTICK_SENSITIVITY=200 + POINTINGSTICK_CONST_ACCEL=1.25 + +diff --git a/hwdb/70-touchpad.hwdb b/hwdb/70-touchpad.hwdb +index 979635357d..8194d98358 100644 +--- a/hwdb/70-touchpad.hwdb ++++ b/hwdb/70-touchpad.hwdb +@@ -42,9 +42,28 @@ touchpad:usb:* + touchpad:bluetooth:* + ID_INPUT_TOUCHPAD_INTEGRATION=external + ++########################################################### ++# Apple ++########################################################### ++# Magic Trackpad (1 and 2) ++touchpad:usb:v05acp030e:* ++touchpad:usb:v05acp0265:* ++ ID_INPUT_TOUCHPAD_INTEGRATION=external ++ ++########################################################### ++# HP Elite x2 1013 G3 ++########################################################### ++touchpad:usb:v044ep1221:* ++ ID_INPUT_TOUCHPAD_INTEGRATION=external ++ ++########################################################### ++# Logitech ++########################################################### ++touchpad:usb:v046d* ++ ID_INPUT_TOUCHPAD_INTEGRATION=external ++ + ########################################################### + # Wacom + ########################################################### + touchpad:usb:v056a* + ID_INPUT_TOUCHPAD_INTEGRATION=external +- +diff --git a/hwdb/80-ieee1394-unit-function.hwdb b/hwdb/80-ieee1394-unit-function.hwdb +new file mode 100644 +index 0000000000..2f879da346 +--- /dev/null ++++ b/hwdb/80-ieee1394-unit-function.hwdb +@@ -0,0 +1,1359 @@ ++# This file is part of systemd. ++ ++# Description ++# ++# Each node on IEEE 1394 bus has configuration ROM with information for identification. Although the ++# typical content of configuration ROM is defined by 1394 Trading Association, many nodes have own ++# quirks. This database includes supplemental information to unit in the node. ++ ++# Convention ++# ++# One entry has two keys. One is customized key to match a node. Another is for kernel alias to ++# match an unit included in the node. ++# ++# The customized key has two formats according to whether the node has model attribute: ++# - ven0x000000mo0x000000units0x000000:0x000000 ++# - ven0x000000units0x000000:0x000000 ++# ++# Even when the node has multiple units, the entry should match to one of the units. In the case, ++# the customized key should have wild pattern for units field: ++# - ven0x000000mo0x000000units*0x000000:0x000000* ++# - ven0x000000units*0x000000:0x000000* ++# ++# The hexadecimal digits part of the customized key should be lower-case. Linux FireWire subsystem ++# uses lower-case value for attributes of sysfs node, and systemd-hwdb parses the custom key by ++# case-sensitive way. On the other hand, it parses kernel alias by case-insensitive way. ++# ++# The entry should have some of IEEE1394_UNIT_FUNCTION_XXX environment variables to express function ++# of the unit. The variables are used to decide group owner of special file for character device ++# corresponding to node including the unit. At present, below variables are supported: ++# - IEEE1394_UNIT_FUNCTION_MIDI ++# - For any unit to process MIDI messages. For example, the unit includes AV/C music subunit. ++# - IEEE1394_UNIT_FUNCTION_AUDIO ++# - For any unit to process audio signal. For example, the unit includes AV/C audio subunit. ++# - IEEE1394_UNIT_FUNCTION_VIDEO ++# - For any unit to process video signal. ++# ++# Additionally, ID_VENDOR_FROM_DATABASE and ID_MODEL_FROM_DATABASE environment variables are ++# preferable. ++ ++# ++# General entry for AV/C device compliant to AV/C command set generic specification: ++# * Configuration ROM for AV/C Devices 1.0 (Dec. 12, 2000, 1394 Trading Association, TA Document ++# 1999027) ++# ++ ++# Just for backward compatibility. Please invalidate IEEE1394_UNIT_FUNCTION_VIDEO by adding entries ++# if it is inconvenient. ++ieee1394:node:ven*mo*units*0x00a02d:0x010001* ++ieee1394:ven*mo*sp0000A02Dver00010001 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# General entries for AV/C device with vendor unique command set: ++# * IEC 61883-1:1998 ++# ++ ++# Please invalidate IEEE1394_UNIT_FUNCTION_VIDEO by adding entries if it is inconvenient. ++ieee1394:node:ven*mo*units*0x00a02d:0x014000* ++ieee1394:ven*mo*sp0000A02Dver00014000 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# Just for backward compatibility. Please invalidate IEEE1394_UNIT_FUNCTION_VIDEO by adding entries ++# if it is inconvenient. ++ieee1394:node:ven*mo*units*0x00a02d:0x014001* ++ieee1394:ven*mo*sp0000A02Dver00014001 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# General entry for: ++# * 1394-based Digital Camera Specification Version 1.04 (Aug. 9, 1996, 1394 Trading Association) ++# ++ ++ieee1394:node:ven*units0x00a02d:0x000100 ++ieee1394:ven*sp0000A02Dver00000100 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# General entry for: ++# * 1394-based Digital Camera Specification Version 1.20 (Jul. 23, 1998, 1394 Trading Association) ++# ++ ++ieee1394:node:ven*units0x00a02d:0x000101 ++ieee1394:ven*sp0000A02Dver00000101 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# General entry for: ++# * IIDC Digital Camera Control Specification Ver.1.30 (Jul. 25, 2000, 1394 Trading Association) ++# * IIDC Digital Camera Control Specification Ver.1.31 (Feb. 2, 2004, 1394 Trading Association, TA ++# Document 2003017) ++# * IIDC Digital Camera Control Specification Ver.1.32 (Jul. 24, 2008, 1394 Trading Association, ++# Document number 2007009) ++# ++ ++ieee1394:node:ven*units0x00a02d:0x000102 ++ieee1394:ven*sp0000A02Dver00000102 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# General entry for: ++# * IIDC2 Digital Camera Control Specification Ver.1.0.0 (Jan 26th, 2012, 1394 Trading Association, ++# TS2011001) ++# * IIDC2 Digital Camera Control Specification Ver.1.1.0 (May 19th, 2015, 1394 Trading Association, ++# TS2015001) ++# ++ ++ieee1394:node:ven*units0x00a02d:0x000110 ++ieee1394:ven*sp0000A02Dver00000110 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# BridgeCo. Enhancement BreakOut Box (BeBoB) for DM1000, DM1100, and DM1500 ASICs. ++# ++ ++ieee1394:node:ven0x0003dbmo0x01eeeeunits0x00a02d:0x010001 ++ieee1394:ven000003DBmo0001EEEEsp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Apogee Electronics ++ ID_MODEL_FROM_DATABASE=Ensemble FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# An extension card for Rosetta 200, Rosetta 800, AD16X, DA16X, DD16X, and BigBen. ++ieee1394:node:ven0x0003dbmo0x010048units0x00a02d:0x010001 ++ieee1394:ven000003DBmo00010048sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Apogee Electronics ++ ID_MODEL_FROM_DATABASE=X-FireWire Card ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001564mo0x000610units0x00a02d:0x010001 ++ieee1394:ven00001564mo00000610sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=F-Control Audio 610 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001564mo0x001616units0x00a02d:0x010001 ++ieee1394:ven00001564mo00001616sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=F-Control Audio 1616 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001564mo0x001204units0x00a02d:0x010001 ++ieee1394:ven00001564mo00001204sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=XENYX UFX1204 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001564mo0x001604units0x00a02d:0x010001 ++ieee1394:ven00001564mo00001604sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=XENYX UFX1604 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# An extension card for Behringer X32. ++ieee1394:node:ven0x001564mo0x000006units0x00a02d:0x010001 ++ieee1394:ven00001564mo00000006sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=X-UF ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00000amo0x030000units0x00a02d:0x010001 ++ieee1394:ven0000000Amo00030000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=CME ++ ID_MODEL_FROM_DATABASE=Matrix K FW ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00a07emo0x0000a9units0x00a02d:0x014001 ++ieee1394:ven0000A07Emo000000A9sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=Digidesign ++ ID_MODEL_FROM_DATABASE=Mbox 2 Pro ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x0040abmo0x010048units0x00a02d:0x010001 ++ieee1394:ven000040ABmo00010048sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Edirol ++ ID_MODEL_FROM_DATABASE=FA-101 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x0040abmo0x010049units0x00a02d:0x010001 ++ieee1394:ven000040ABmo00010049sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Edirol ++ ID_MODEL_FROM_DATABASE=FA-66 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# The value of model field differs depending on firmware. ++ieee1394:node:ven0x000f1bmo0x010064units0x00a02d:0x010001 ++ieee1394:ven00000F1Bmo00010064sp0000A02Dver00010001 ++ieee1394:node:ven0x000f1bmo0x000210units0x00a02d:0x010001 ++ieee1394:ven00000F1Bmo00000210sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Ego Systems ++ ID_MODEL_FROM_DATABASE=QuataFire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to Saffire and Saffire LE. ++ieee1394:node:ven0x00130emo0x000000units0x00a02d:0x010001 ++ieee1394:ven0000130Emo00000000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00130emo0x000006units0x00a02d:0x010001 ++ieee1394:ven0000130Emo00000006sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 10 i/o ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00130emo0x000003units0x00a02d:0x010001 ++ieee1394:ven0000130Emo00000003sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 26 i/o ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x01a9eemo0x000001units0x00a02d:0x010001 ++ieee1394:ven0001A9EEmo00000001sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=ICON ++ ID_MODEL_FROM_DATABASE=FireXon ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x010071units0x00a02d:0x014001 ++ieee1394:ven00000D6Cmo00010071sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=FW 1814 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Vendor is BridgeCo Co AG but M-Audio. ++ieee1394:node:ven0x0007f5mo0x010046units0x00a02d:0x014001 ++ieee1394:ven000007F5mo00010046sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=FW 410 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x010060units0x00a02d:0x014001 ++ieee1394:ven00000D6Cmo00010060sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=FW Audiophile ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x010062units0x00a02d:0x010001 ++ieee1394:ven00000D6Cmo00010062sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=FW Solo ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x010081units0x00a02d:0x010001 ++ieee1394:ven00000D6Cmo00010081sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=NRV10 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x00000aunits0x00a02d:0x014001 ++ieee1394:ven00000D6Cmo0000000Asp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=Ozonic ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x0100a1units0x00a02d:0x014001 ++ieee1394:ven00000D6Cmo000100A1sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=ProFire Lightbridge ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000d6cmo0x010091units0x00a02d:0x014001 ++ieee1394:ven00000D6Cmo00010091sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=ProjectMix I/O ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# An extension card for Mackie Onyx 1220, 1620, and 1640. ++ieee1394:node:ven0x000ff2mo0x010065units0x00a02d:0x010001 ++ieee1394:ven00000FF2mo00010065sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# An extension card for Mackie d.2. Mackie d.2 Pro is preinstalled model. ++ieee1394:node:ven0x000ff2mo0x010067units0x00a02d:0x010001 ++ieee1394:ven00000FF2mo00010067sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie DJ Mixer ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001496mo0x050000units0x00a02d:0x010001 ++ieee1394:ven00001496mo00050000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Phonic ++ ID_MODEL_FROM_DATABASE=Helixboard 12 FireWire MkII ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001496mo0x060000units0x00a02d:0x010001 ++ieee1394:ven00001496mo00060000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Phonic ++ ID_MODEL_FROM_DATABASE=Helixboard 18 FireWire MkII ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001496mo0x070000units0x00a02d:0x010001 ++ieee1394:ven00001496mo00070000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Phonic ++ ID_MODEL_FROM_DATABASE=Helixboard 24 FireWire MkII ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001496mo0x080000units0x00a02d:0x010001 ++ieee1394:ven00001496mo00080000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Phonic ++ ID_MODEL_FROM_DATABASE=Firefly 808 FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to FireFly 202, 302, 808 Universal. ++# Match to HelixBoard 12 FireWire, 18 FireWire, 24 FireWire. ++# Match to HelixBoard 12 Universal, 18 Universal, and 24 Universal. ++ieee1394:node:ven0x001496mo0x000000units0x00a02d:0x010001 ++ieee1394:ven00001496mo00000000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Phonic ++ ID_MODEL_FROM_DATABASE=FireFly/Helixboard ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000a92mo0x010000units0x00a02d:0x010001 ++ieee1394:ven00000A92mo00010000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FireBox ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000a92mo0x010001units0x00a02d:0x010001 ++ieee1394:ven00000A92mo00010001sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=Inspire 1394 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001198mo0x010048units0x00a02d:0x010001 ++ieee1394:ven00001198mo00010048sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Prism Media Products ++ ID_MODEL_FROM_DATABASE=Orpheus ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000a92mo0x010066units0x00a02d:0x010001 ++ieee1394:ven00000A92mo00010066sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=PreSonus FP10 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001260mo0x000001units0x00a02d:0x010001 ++ieee1394:ven00001260mo00000001sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Stanton Magnetics ++ ID_MODEL_FROM_DATABASE=ScratchAmp ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x010065mo0x010067units0x00a02d:0x010001 ++ieee1394:ven00010065mo00010067sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=IF-FW/DM ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to TerraTec Aureon 7.1 FireWire. ++# Match to eAR Master One, Eroica, Figaro, and Ciaccona. OEM by TerraTec perhaps. ++ieee1394:node:ven0x000aacmo0x000002units0x00a02d:0x010001 ++ieee1394:ven00000AACmo00000002sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=TerraTec ++ ID_MODEL_FROM_DATABASE=Aureon 7.1 FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000aacmo0x000003units0x00a02d:0x010001 ++ieee1394:ven00000AACmo00000003sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=TerraTec Electronic ++ ID_MODEL_FROM_DATABASE=PHASE 88 FW ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000aacmo0x000004units0x00a02d:0x010001 ++ieee1394:ven00000AACmo00000004sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=TerraTec Electronic ++ ID_MODEL_FROM_DATABASE=PHASE 24 FW ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000aacmo0x000007units0x00a02d:0x010001 ++ieee1394:ven00000AACmo00000007sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=TerraTec Electronic ++ ID_MODEL_FROM_DATABASE=PHASE X24 FW ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x002327mo0x020002units0x00a02d:0x010001 ++ieee1394:ven00002327mo00020002sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=ToneWeal ++ ID_MODEL_FROM_DATABASE=FW66 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00a0demo0x10000bunits0x00a02d:0x010001 ++ieee1394:ven0000A0DEmo0010000Bsp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Yamaha ++ ID_MODEL_FROM_DATABASE=GO44 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00a0demo0x10000cunits0x00a02d:0x010001 ++ieee1394:ven0000A0DEmo0010000Csp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Yamaha ++ ID_MODEL_FROM_DATABASE=GO46 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# ++# Fireworks board module. ++# ++# DSP model (Texus Instruments TMS320C67) and FPGA model (Xilinx Spartan XC35250E) exists. ++# Both models use Texus Instruments TSB43CB43 (IceLynx Micro, iCEM) as communication engine. ++# ++ ++# Match to DSP model of AudioFire8. ++ieee1394:node:ven0x001486mo0x000af8units0x00a02d:0x010000 ++ieee1394:ven00001486mo00000AF8sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Echo Digital Audio ++ ID_MODEL_FROM_DATABASE=AudioFire8 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Match to both DSP and FPGA models of AudioFire12. ++ieee1394:node:ven0x001486mo0x00af12units0x00a02d:0x010000 ++ieee1394:ven00001486mo0000AF12sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Echo Digital Audio ++ ID_MODEL_FROM_DATABASE=AudioFire12 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# DSP model. ++ieee1394:node:ven0x000ff2mo0x01200funits0x00a02d:0x010000 ++ieee1394:ven00000FF2mo0001200Fsp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Mackie ++ ID_MODEL_FROM_DATABASE=Onyx 1200F ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# DSP model. ++ieee1394:node:ven0x000ff2mo0x00400funits0x00a02d:0x010000 ++ieee1394:ven00000FF2mo0000400Fsp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Mackie ++ ID_MODEL_FROM_DATABASE=Onyx 400F ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# FPGA model. ++ieee1394:node:ven0x001486mo0x000af2units0x00a02d:0x010000 ++ieee1394:ven00001486mo00000AF2sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Echo Digital Audio ++ ID_MODEL_FROM_DATABASE=AudioFire2 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# FPGA model. ++ieee1394:node:ven0x001486mo0x000af4units0x00a02d:0x010000 ++ieee1394:ven00001486mo00000AF4sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Echo Digital Audio ++ ID_MODEL_FROM_DATABASE=AudioFire4 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Match to FPGA model of AudioFire8, and AudioFirePre8. ++ieee1394:node:ven0x001486mo0x000af9units0x00a02d:0x010000 ++ieee1394:ven00001486mo00000AF9sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Echo Digital Audio ++ ID_MODEL_FROM_DATABASE=AudioFire8/Pre8 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# FPGA model. ++ieee1394:node:ven0x00075bmo0x00afb2units0x00a02d:0x010000 ++ieee1394:ven0000075Bmo0000AFB2sp0000A02Dver00010000 ++ ID_VENDOR_FROM_DATABASE=Gibson ++ ID_MODEL_FROM_DATABASE=RIP ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Oxford Semiconductor FW970/971. ++# ++ ++ieee1394:node:ven0x0003dbmo0x01ddddunits0x00a02d:0x010001 ++ieee1394:ven000003DBmo0001DDDDsp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Apogee Electronics ++ ID_MODEL_FROM_DATABASE=Duet FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001564mo0x00fc22units0x00a02d:0x010001 ++ieee1394:ven00001564mo0000FC22sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Behringer ++ ID_MODEL_FROM_DATABASE=F-Control Audio 202 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001292mo0x00f970units0x00a02d:0x010001 ++ieee1394:ven00001292mo0000F970sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Griffin Technology ++ ID_MODEL_FROM_DATABASE=Griffin FireWave ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00d04bmo0x00f970units0x00a02d:0x010001 ++ieee1394:ven0000D04Bmo0000F970sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=LaCie ++ ID_MODEL_FROM_DATABASE=LaCie FireWire Speakers ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to former models of Onyx 820i, 1220i, and 1620i. ++ieee1394:node:ven0x000ff2mo0x081216units0x00a02d:0x010001 ++ieee1394:ven00000FF2mo00081216sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx-i series ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to former model of Onyx 1640i. ++ieee1394:node:ven0x000ff2mo0x001640units0x00a02d:0x010001 ++ieee1394:ven00000FF2mo00001640sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx 1640i ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000ff2mo0x00200funits0x00a02d:0x010001 ++ieee1394:ven00000FF2mo0000200Fsp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx Satellite ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x000ff2mo0x000460units0x00a02d:0x010001 ++ieee1394:ven00000FF2mo00000460sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Tapco LINK.firewire 4x6 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001260mo0x002000units0x00a02d:0x010001 ++ieee1394:ven00001260mo00002000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Stanton Magnetics ++ ID_MODEL_FROM_DATABASE=SCS.1d ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x001260mo0x001000units0x00a02d:0x010001 ++ieee1394:ven00001260mo00001000sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Stanton Magnetics ++ ID_MODEL_FROM_DATABASE=SCS.1m ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++ieee1394:node:ven0x00022emo0x800007units0x00a02d:0x010001 ++ieee1394:ven0000022Emo00800007sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=FireOne ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# ++# TC Applied Technologies. Digital Interface Communication Engine (DICE). ++# ++# DICE with DICE II, TCD2210, TCD2220, and TCD3070 ASICs. ++# ++ ++ieee1394:node:ven0x0004c4mo0x000000units0x0004c4:0x000001 ++ieee1394:ven000004C4mo00000000sp000004C4ver00000001 ++ ID_VENDOR_FROM_DATABASE=Allen and Heath ++ ID_MODEL_FROM_DATABASE=Zed R16 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Match to iO 14, iO 26 ++ieee1394:node:ven0x000595mo0x000001units0x000595:0x000001 ++ieee1394:ven00000595mo00000001sp00000595ver00000001 ++ ID_VENDOR_FROM_DATABASE=Alesis ++ ID_MODEL_FROM_DATABASE=iO FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000595mo0x000002units0x000595:0x000001 ++ieee1394:ven00000595mo00000002sp00000595ver00000001 ++ ID_VENDOR_FROM_DATABASE=Alesis ++ ID_MODEL_FROM_DATABASE=MasterControl ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Match to Multimix 8, 12, and 16. ++ieee1394:node:ven0x000595mo0x000000units0x000595:0x000001 ++ieee1394:ven00000595mo00000000sp00000595ver00000001 ++ ID_VENDOR_FROM_DATABASE=Alesis ++ ID_MODEL_FROM_DATABASE=MultiMix FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a07emo0x000004units0x00a07e:0x000001 ++ieee1394:ven0000A07Emo00000004sp0000A07Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Avid ++ ID_MODEL_FROM_DATABASE=Mbox 3 Pro ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c2dmo0x000001units0x001c2d:0x000001 ++ieee1394:ven00001C2Dmo00000001sp00001C2Dver00000001 ++ ID_VENDOR_FROM_DATABASE=FlexRadio Systems ++ ID_MODEL_FROM_DATABASE=FLEX-5000 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c2dmo0x000002units0x001c2d:0x000001 ++ieee1394:ven00001C2Dmo00000002sp00001C2Dver00000001 ++ ID_VENDOR_FROM_DATABASE=FlexRadio Systems ++ ID_MODEL_FROM_DATABASE=FLEX-3000 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130emo0x000006units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000006sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Liquid Saffire 56 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130emo0x000009units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000009sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 14 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130emo0x000007units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000007sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 24 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130emo0x000008units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000008sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 24 DSP ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130emo0x000012units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000012sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 26 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Revision with TCD2210. ++ieee1394:node:ven0x00130emo0x000005units0x00130e:0x000001 ++ieee1394:ven0000130Emo00000005sp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 40 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Revision with TCD3070. ++ieee1394:node:ven0x00130emo0x0000deunits0x00130e:0x000001 ++ieee1394:ven0000130Emo000000DEsp0000130Ever00000001 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Saffire Pro 40 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000fd7mo0x000001units0x000fd7:0x000001 ++ieee1394:ven00000FD7mo00000001sp00000FD7ver00000001 ++ ID_VENDOR_FROM_DATABASE=Harman Music Group ++ ID_MODEL_FROM_DATABASE=Lexicon I-ONIX FW810S ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000ff2mo0x000007units0x000ff2:0x000001 ++ieee1394:ven00000FF2mo00000007sp00000FF2ver00000001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx Blackbird ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Match to latter models of Onyx 820i, 1220i, 1620i, and 1640i. ++ieee1394:node:ven0x000ff2mo0x000006units0x000ff2:0x000001 ++ieee1394:ven00000FF2mo00000006sp00000FF2ver00000001 ++ ID_VENDOR_FROM_DATABASE=Loud Technologies ++ ID_MODEL_FROM_DATABASE=Mackie Onyx-i series ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000d6cmo0x000011units0x000d6c:0x0100d1 ++ieee1394:ven00000D6Cmo00000011sp00000D6Cver000100D1 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=ProFire 610 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000d6cmo0x000010units0x000d6c:0x0100c1 ++ieee1394:ven00000D6Cmo00000010sp00000D6Cver000100C1 ++ ID_VENDOR_FROM_DATABASE=M-Audio ++ ID_MODEL_FROM_DATABASE=ProFire 2626 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001ee8mo0x000002units0x001ee8:0x000001 ++ieee1394:ven00001EE8mo00000002sp00001EE8ver00000001 ++ ID_VENDOR_FROM_DATABASE=Mytek ++ ID_MODEL_FROM_DATABASE=Stereo192-DSD DAC ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x10c73fmo0x000001units0x10c73f:0x000001 ++ieee1394:ven0010C73Fmo00000001sp0010C73Fver00000001 ++ ID_VENDOR_FROM_DATABASE=Midas Klark Teknik ++ ID_MODEL_FROM_DATABASE=VeniceF series ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000008units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000008sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FireStudio ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000011units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000011sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FireStudio Mobile ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x00000bunits0x000a92:0x000001 ++ieee1394:ven00000A92mo0000000Bsp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FireStudio Project ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x00000cunits0x000a92:0x000001 ++ieee1394:ven00000A92mo0000000Csp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FireStudio Tube ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000010units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000010sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=StudioLive 16.4.2 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000012units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000012sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=StudioLive 24.4.2 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000013units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000013sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=StudioLive 16.0.2 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a92mo0x000014units0x000a92:0x000001 ++ieee1394:ven00000A92mo00000014sp00000A92ver00000001 ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=StudioLive 32.4.2AI ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Unregistered OUI. Match to Duende Classic and Duende Mini. They are differentiated by category ++# field of GUID (0x51/0x52) in TCAT specification. ++ieee1394:node:ven0x0050c2mo0x000070units0x0050c2:0x000001 ++ieee1394:ven000050C2mo00000070sp000050C2ver00000001 ++ ID_VENDOR_FROM_DATABASE=Solid State Logic ++ ID_MODEL_FROM_DATABASE=Duende FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000024units0x000166:0x000001 ++ieee1394:ven00000166mo00000024sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Desktop Konnekt 6 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000030units0x000166:0x000001 ++ieee1394:ven00000166mo00000030sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Digital Konnekt x32 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000027units0x000166:0x000001 ++ieee1394:ven00000166mo00000027sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Impact Twin ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000020units0x000166:0x000001 ++ieee1394:ven00000166mo00000020sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Konnekt 24D ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000021units0x000166:0x000001 ++ieee1394:ven00000166mo00000021sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Konnekt 8 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000023units0x000166:0x000001 ++ieee1394:ven00000166mo00000023sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Konnekt Live ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000022units0x000166:0x000001 ++ieee1394:ven00000166mo00000022sp00000166ver00000001 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=Studio Konnekt 48 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000001units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000001sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=ADC2 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000002units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000002sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=Vesta ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000003units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000003sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=Minerva ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000004units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000004sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=AFI1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000005units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000005sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=DAC1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000006units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000006sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=INT202 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x001c6amo0x000007units0x001c6a:0x000001 ++ieee1394:ven00001C6Amo00000007sp00001C6Aver00000001 ++ ID_VENDOR_FROM_DATABASE=Weiss Engineering ++ ID_MODEL_FROM_DATABASE=DAC202 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Digidesign Digi00x family. ++# ++ ++ieee1394:node:ven0x00a07eunits0x0000a3:0x000001 ++ieee1394:ven0000A07Emo00000001sp000000A3ver00000001 ++ ID_VENDOR_FROM_DATABASE=Digidesign ++ ID_MODEL_FROM_DATABASE=Digi 002 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a07eunits0x0000a4:0x000001 ++ieee1394:ven0000A07Emo00000002sp000000A4ver00000001 ++ ID_VENDOR_FROM_DATABASE=Digidesign ++ ID_MODEL_FROM_DATABASE=Digi 002Rack ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a07eunits0x0000aa:0x000001 ++ieee1394:ven0000A07Emo00000001sp000000AAver00000001 ++ ID_VENDOR_FROM_DATABASE=Digidesign ++ ID_MODEL_FROM_DATABASE=Digi 003 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a07eunits0x0000ab:0x000001 ++ieee1394:ven0000A07Emo00000002sp000000ABver00000001 ++ ID_VENDOR_FROM_DATABASE=Digidesign ++ ID_MODEL_FROM_DATABASE=Digi 003 Rack ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Tascam FireWire series. ++# ++ ++ieee1394:node:ven0x00022eunits0x00022e:0x800001 ++ieee1394:ven0000022Emo00000000sp0000022Ever00800001 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=FE-8 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ ++ieee1394:node:ven0x00022eunits0x00022e:0x800003 ++ieee1394:ven0000022Emo00000000sp0000022Ever00800003 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=FW-1082 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00022eunits0x00022e:0x800004 ++ieee1394:ven0000022Emo00000000sp0000022Ever00800004 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=FW-1804 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00022eunits0x00022e:0x800000 ++ieee1394:ven0000022Emo00000000sp0000022Ever00800000 ++ ID_VENDOR_FROM_DATABASE=Tascam ++ ID_MODEL_FROM_DATABASE=FW-1884 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Mark of the Unicorn FireWire series. ++# ++# The model field in unit directory should be ignored since it expresses firmware version. ++# ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000001 ++ieee1394:ven000001F2mo*sp000001F2ver00000001 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 828 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000002 ++ieee1394:ven000001F2mo*sp000001F2ver00000002 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 896 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000003 ++ieee1394:ven000001F2mo*sp000001F2ver00000003 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 828 mkII ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000005 ++ieee1394:ven000001F2mo*sp000001F2ver00000005 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 896 HD ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000009 ++ieee1394:ven000001F2mo*sp000001F2ver00000009 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=Traveler ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x00000d ++ieee1394:ven000001F2mo*sp000001F2ver0000000D ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=UltraLite ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x00000f ++ieee1394:ven000001F2mo*sp000001F2ver0000000F ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 8pre ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000015 ++ieee1394:ven000001F2mo*sp000001F2ver00000015 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 828 mk3 FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000017 ++ieee1394:ven000001F2mo*sp000001F2ver00000017 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 896 mk3 FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000019 ++ieee1394:ven000001F2mo*sp000001F2ver00000019 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=UltraLite mk3 FireWire ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x00001b ++ieee1394:ven000001F2mo*sp000001F2ver0000001B ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=Traveler mk3 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000030 ++ieee1394:ven000001F2mo*sp000001F2ver00000030 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=UltraLite mk3 Hybrid ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000033 ++ieee1394:ven000001F2mo*sp000001F2ver00000033 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=Audio Express ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000035 ++ieee1394:ven000001F2mo*sp000001F2ver00000035 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 828 mk3 Hybrid ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x0001f2units0x0001f2:0x000045 ++ieee1394:ven000001F2mo*sp000001F2ver00000045 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU 4pre ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# RME Fireface series. ++# ++ieee1394:node:ven0x000a35units0x000a35:0x000001 ++ieee1394:ven00000A35mo00101800sp00000A35ver00000001 ++ ID_VENDOR_FROM_DATABASE=RME ++ ID_MODEL_FROM_DATABASE=Fireface 800 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a35units0x000a35:0x000002 ++ieee1394:ven00000A35mo00101800sp00000A35ver00000002 ++ ID_VENDOR_FROM_DATABASE=RME ++ ID_MODEL_FROM_DATABASE=Fireface 400 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a35units0x000a35:0x000003 ++ieee1394:ven00000A35mo00101800sp00000A35ver00000003 ++ ID_VENDOR_FROM_DATABASE=RME ++ ID_MODEL_FROM_DATABASE=Fireface UFX ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a35units0x000a35:0x000004 ++ieee1394:ven00000A35mo00101800sp00000A35ver00000004 ++ ID_VENDOR_FROM_DATABASE=RME ++ ID_MODEL_FROM_DATABASE=Fireface UCX ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000a35units0x000a35:0x000005 ++ieee1394:ven00000A35mo00101800sp00000A35ver00000005 ++ ID_VENDOR_FROM_DATABASE=RME ++ ID_MODEL_FROM_DATABASE=Fireface 802 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Yamaha mLAN 2nd generation. ++# ++# The combination of Yamaha mLAN-NC1, Yamaha mLAN-PH2, and Fujifilm PHY MD8408B. ++# ++ ++ieee1394:node:ven0x000a92mo0x000000units0x00a0de:0xffffff ++ieee1394:ven00000A92mo00000000sp0000A0DEver00FFFFFF ++ ID_VENDOR_FROM_DATABASE=PreSonus ++ ID_MODEL_FROM_DATABASE=FIREStation ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a0demo0x100005units0x00a0de:0xffffff ++ieee1394:ven0000A0DEmo00100005sp0000A0DEver00FFFFFF ++ ID_VENDOR_FROM_DATABASE=Yamaha ++ ID_MODEL_FROM_DATABASE=01X ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a0demo0x100007units0x00a0de:0xffffff ++ieee1394:ven0000A0DEmo00100007sp0000A0DEver00FFFFFF ++ ID_VENDOR_FROM_DATABASE=Yamaha ++ ID_MODEL_FROM_DATABASE=i88X ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Yamaha mLAN 3rd generation. ++# ++# DICE II ASIC is used with specific firmware. ++# ++ ++ieee1394:node:ven0x00a0demo0x100013units0x00a02d:0x000300 ++ieee1394:ven0000A0DEmo00100013sp0000A02Dver00000300 ++ ID_VENDOR_FROM_DATABASE=Steinberg ++ ID_MODEL_FROM_DATABASE=MR816 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00a0demo0x100010units0x00a02d:0x000300 ++ieee1394:ven0000A0DEmo00100010sp0000A02Dver00000300 ++ ID_VENDOR_FROM_DATABASE=Yamaha ++ ID_MODEL_FROM_DATABASE=n8 ++ IEEE1394_UNIT_FUNCTION_MIDI=1 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# Focusrite Liquid Mix series. ++# ++# OEM by Sintefex Audio lda. ++# ++ ++ieee1394:node:ven0x00130eunits0x00130e:0x000700 ++ieee1394:ven0000130Emo00010204sp0000130Ever00000700 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Liquid Mix 16 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x00130eunits0x00130e:0x000200 ++ieee1394:ven0000130Emo00010200sp0000130Ever00000200 ++ ID_VENDOR_FROM_DATABASE=Focusrite ++ ID_MODEL_FROM_DATABASE=Liquid Mix 32 ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# ++# TC Electronic PowerCore series. ++# ++# Consists of NXP PowerQUICC II Processor with PCI interface (XPC8245, MPC8245), Texus Instruments ++# OHCI 1.1, 1394a link layer controller (TSB43AB23). Xilinx Spartan-II FPGA (XC2S50), and some ++# NXP 24-Bit Audio Digital Signal Processor (DSP56367). ++# ++ ++ieee1394:node:ven0x000166mo0x000001units0x00a02d:0x000000 ++ieee1394:ven00000166mo00000001sp0000A02Dver00000000 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=PowerCore FireWire ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++ieee1394:node:ven0x000166mo0x000002units0x00a02d:0x014000 ++ieee1394:ven00000166mo00000002sp0000A02Dver00014000 ++ ID_VENDOR_FROM_DATABASE=TC Electronic ++ ID_MODEL_FROM_DATABASE=PowerCore Compact ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=0 ++ ++# Match to Adrenaline, Mojo, and V10. ++ieee1394:node:ven0x00a07eunits0x00a02d:0x014001 ++ieee1394:ven0000A07Emo00000001sp0000A02Dver00014001 ++ ID_VENDOR_FROM_DATABASE=Avid Technology ++ ID_MODEL_FROM_DATABASE=Digital Nonlinear Accelerator ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# Point Grey cameras. ++# ++ ++# IIDC v1.04 compatible. ++ieee1394:node:ven0x00b09dmo*units0x00b09d:0x000100 ++ieee1394:ven0000B09Dmo*spec0000B09Dver00000100 ++ ID_VENDOR_FROM_DATABASE=Point Grey Research ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# IIDC v1.20 compatible. ++ieee1394:node:ven0x00b09dmo*units0x00b09d:0x000101 ++ieee1394:ven0000B09Dmo*spec0000B09Dver00000101 ++ ID_VENDOR_FROM_DATABASE=Point Grey Research ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# IIDC v1.30/v1.31/v1.32 compatible. ++ieee1394:node:ven0x00b09dmo*units0x00b09d:0x000102 ++ieee1394:ven0000B09Dmo*spec0000B09Dver00000102 ++ ID_VENDOR_FROM_DATABASE=Point Grey Research ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# Unique protocol. ++ieee1394:node:ven0x00b09dmo*units0x00b09d:0x000114 ++ieee1394:ven0000B09Dmo*spec0000B09Dver00000114 ++ ID_VENDOR_FROM_DATABASE=Point Grey Research ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# Digital Everywhere FloppyDTV and FireDtv series. ++# ++ ++ieee1394:node:ven0x001287mo0x000024units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000024sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FloppyDTV S/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++ieee1394:node:ven0x001287mo0x000025units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000025sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FloppyDTV T/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++ieee1394:node:ven0x001287mo0x000026units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000026sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FloppyDTV C/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++ieee1394:node:ven0x001287mo0x000034units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000034sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FireDTV S/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++ieee1394:node:ven0x001287mo0x000035units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000035sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FireDTV T/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++ieee1394:node:ven0x001287mo0x000036units0x00a02d:0x010001 ++ieee1394:ven00001287mo00000036sp0000A02Dver00010001 ++ ID_VENDOR_FROM_DATABASE=Digital Everywhere ++ ID_MODEL_FROM_DATABASE=FireDTV C/CI ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# ++# Node with multiple units for several functions. ++# ++# When deciding the type of unit, please cooperate with kernel developers working for driver. ++# ++ ++# Apple iSight: unit 0: IIDC v1.30 function. ++ieee1394:node:ven0x080007mo0x000008units*0x00a02d:0x000102* ++ieee1394:ven00080007mo00000008sp0000A02Dver00000102 ++ ID_VENDOR_FROM_DATABASE=Apple ++ ID_MODEL_FROM_DATABASE=iSight ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# Apple iSight: unit 1: audio function. ++ieee1394:node:ven0x080007mo0x000008units*0x000a27:0x000010* ++ieee1394:ven00080007mo00000008sp00000A27ver00000010 ++ ID_VENDOR_FROM_DATABASE=Apple ++ ID_MODEL_FROM_DATABASE=iSight ++ IEEE1394_UNIT_FUNCTION_AUDIO=1 ++ ++# Apple iSight: unit 2: factory function. ++ieee1394:node:ven0x080007mo0x000008units*0x000a27:0x000011* ++ieee1394:ven00080007mo00000008sp00000A27ver00000011 ++ ID_VENDOR_FROM_DATABASE=Apple ++ ID_MODEL_FROM_DATABASE=iSight ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# Apple iSight: unit 3: iris diaphragm function. ++ieee1394:node:ven0x080007mo0x000008units*0x000a27:0x000012* ++ieee1394:ven00080007mo00000008sp00000A27ver00000012 ++ ID_VENDOR_FROM_DATABASE=Apple ++ ID_MODEL_FROM_DATABASE=iSight ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# MOTU V4HD: unit 0: unknown function. ++ieee1394:node:ven0x0001f2units*0x0001f2:0x000021* ++ieee1394:ven000001F2mo*sp000001F2ver00000021 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU V4HD ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# MOTU V4HD: unit 1: unknown function. ++ieee1394:node:ven0x0001f2units*0x0001f2:0x000022* ++ieee1394:ven000001F2mo*sp000001F2ver00000022 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU V4HD ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# MOTU V4HD: unit 2: unknown function. ++ieee1394:node:ven0x0001f2units*0x0001f2:0x000023* ++ieee1394:ven000001F2mo*sp000001F2ver00000023 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU V4HD ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 ++ ++# MOTU V4HD: unit 3: unknown function. ++ieee1394:node:ven0x0001f2units*0x0001f2:0x000024* ++ieee1394:ven000001F2mo*sp000001F2ver00000024 ++ ID_VENDOR_FROM_DATABASE=MOTU ++ ID_MODEL_FROM_DATABASE=MOTU V4HD ++ IEEE1394_UNIT_FUNCTION_VIDEO=1 +diff --git a/hwdb/meson.build b/hwdb/meson.build +index 158292c712..58d6982c23 100644 +--- a/hwdb/meson.build ++++ b/hwdb/meson.build +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: LGPL-2.1+ + + hwdb_files = files(''' ++ 20-dmi-id.hwdb + 20-pci-vendor-model.hwdb + 20-pci-classes.hwdb + 20-usb-vendor-model.hwdb +@@ -12,13 +13,17 @@ hwdb_files = files(''' + 20-OUI.hwdb + 20-net-ifname.hwdb + 20-vmbus-class.hwdb ++ 60-autosuspend-fingerprint-reader.hwdb ++ 60-autosuspend.hwdb + 60-evdev.hwdb + 60-keyboard.hwdb ++ 60-seat.hwdb + 60-sensor.hwdb + 70-joystick.hwdb + 70-mouse.hwdb + 70-pointingstick.hwdb + 70-touchpad.hwdb ++ 80-ieee1394-unit-function.hwdb + '''.split()) + + if conf.get('ENABLE_HWDB') == 1 diff --git a/SOURCES/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch b/SOURCES/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch new file mode 100644 index 0000000..28f4c24 --- /dev/null +++ b/SOURCES/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch @@ -0,0 +1,26 @@ +From b029865ef6d8b23ecdbfda4e277a3f75cb59ee94 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 25 Oct 2021 15:27:27 +0200 +Subject: [PATCH] Disable libpitc to fix CentOS Stream CI + +We have disabled it in our spec starting with 8.5.0, so let's follow +suit here. + +Related: #2017033 +--- + .github/workflows/unit_tests.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index ad4584ec1d..def38bffe2 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -50,7 +50,7 @@ CONFIGURE_OPTS=( + -Dgnutls=true + -Dmicrohttpd=true + -Dlibidn2=true +- -Dlibiptc=true ++ -Dlibiptc=false + -Dlibcurl=true + -Defi=true + -Dtpm=true diff --git a/SOURCES/0640-rpm-Fix-typo-in-_environmentdir.patch b/SOURCES/0640-rpm-Fix-typo-in-_environmentdir.patch new file mode 100644 index 0000000..150dcd4 --- /dev/null +++ b/SOURCES/0640-rpm-Fix-typo-in-_environmentdir.patch @@ -0,0 +1,25 @@ +From 74cbe4b73a1dbb1113c822690561b8b41b2fb60a Mon Sep 17 00:00:00 2001 +From: Neal Gompa +Date: Mon, 25 Jun 2018 12:56:50 -0400 +Subject: [PATCH] rpm: Fix typo in %_environmentdir + +Signed-off-by: Neal Gompa +(cherry picked from commit 6ea4cb975f99cdfd447332ffa9631790a5975eea) +Resolves: #2018024 +--- + src/core/macros.systemd.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index f3b74f4273..a24d7bbe58 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -18,7 +18,7 @@ + %_sysctldir @sysctldir@ + %_sysusersdir @sysusersdir@ + %_tmpfilesdir @tmpfilesdir@ +-%_environmnentdir @environmentdir@ ++%_environmentdir @environmentdir@ + %_modulesloaddir @modulesloaddir@ + %_modprobedir @modprobedir@ + %_systemdgeneratordir @systemgeneratordir@ diff --git a/SOURCES/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch b/SOURCES/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch new file mode 100644 index 0000000..9c01b95 --- /dev/null +++ b/SOURCES/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch @@ -0,0 +1,30 @@ +From 7b2d5268cf43a4ed7847bdbed2328bccddd5a716 Mon Sep 17 00:00:00 2001 +From: Neal Gompa +Date: Tue, 26 Jun 2018 07:42:29 -0400 +Subject: [PATCH] rpm: Add misspelled %_environmentdir macro for temporary + compatibility + +This should be removed after systemd 240 is released. + +Signed-off-by: Neal Gompa +(cherry picked from commit a6bb5504583e3267d35fa385fe20f60fd998ca5d) +Related: #2018024 +--- + src/core/macros.systemd.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index a24d7bbe58..abbb42b22f 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -26,6 +26,10 @@ + %_systemd_system_env_generator_dir @systemenvgeneratordir@ + %_systemd_user_env_generator_dir @userenvgeneratordir@ + ++# Because we had one release with a typo... ++# This is temporary (Remove after systemd 240 is released) ++%_environmnentdir %_environmentdir ++ + %systemd_requires \ + Requires(post): systemd \ + Requires(preun): systemd \ diff --git a/SOURCES/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch b/SOURCES/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch new file mode 100644 index 0000000..beca147 --- /dev/null +++ b/SOURCES/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch @@ -0,0 +1,32 @@ +From 4d994a262ec1ad3e33e197cb09aa5aeabb5835dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 3 Jul 2018 15:40:53 +0200 +Subject: [PATCH] rpm: emit warning when macro with typo is used + +Follow-up for a6bb550458. Suggested by @ignatenkobrain. + +$ rpmbuild --eval %_environmentdir +/usr/lib/environment.d +$ rpmbuild --eval %_environmnentdir +warning: Use %_environmentdir instead +/usr/lib/environment.d + +(cherry picked from commit be9bf171bbf764997551f8a9b3c2aba5c6a875d3) +Related: #2018024 +--- + src/core/macros.systemd.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index abbb42b22f..fe7ca26a34 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -28,7 +28,7 @@ + + # Because we had one release with a typo... + # This is temporary (Remove after systemd 240 is released) +-%_environmnentdir %_environmentdir ++%_environmnentdir %{warn:Use %%_environmentdir instead}%_environmentdir + + %systemd_requires \ + Requires(post): systemd \ diff --git a/SOURCES/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch b/SOURCES/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch new file mode 100644 index 0000000..0021bdb --- /dev/null +++ b/SOURCES/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch @@ -0,0 +1,75 @@ +From f29b7bcd85d4e8d824d36fecc130a0d74af718f8 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 12 Oct 2021 16:47:48 +0200 +Subject: [PATCH] Remove unintended additions to systemd-analyze man page + +These changes were introduced in commit +a2e00522971897909db2a81b4daf10e5700f453e . + +Resolves: #2004765 +--- + man/systemd-analyze.xml | 51 +---------------------------------------- + 1 file changed, 1 insertion(+), 50 deletions(-) + +diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml +index 7c873cbdd1..e17ff0cf90 100644 +--- a/man/systemd-analyze.xml ++++ b/man/systemd-analyze.xml +@@ -354,56 +354,7 @@ $ eog targets.svg + they elapse next. This takes the same input as the OnCalendar= setting in + systemd.timer5, + following the syntax described in +- systemd.time7. By +- default, only the next time the calendar expression will elapse is shown; use +- to show the specified number of next times the expression +- elapses. +- +- +- Show leap days in the near future +- +- $ systemd-analyze calendar --iterations=5 '*-2-29 0:0:0' +- Original form: *-2-29 0:0:0 +-Normalized form: *-02-29 00:00:00 +- Next elapse: Sat 2020-02-29 00:00:00 UTC +- From now: 11 months 15 days left +- Iter. #2: Thu 2024-02-29 00:00:00 UTC +- From now: 4 years 11 months left +- Iter. #3: Tue 2028-02-29 00:00:00 UTC +- From now: 8 years 11 months left +- Iter. #4: Sun 2032-02-29 00:00:00 UTC +- From now: 12 years 11 months left +- Iter. #5: Fri 2036-02-29 00:00:00 UTC +- From now: 16 years 11 months left +- +- +- +- +- +- <command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command> +- +- This command parses a time span and outputs the normalized form and the equivalent value in +- microseconds. The time span should adhere to the same syntax documented in +- systemd.time7. +- Values without associated magnitudes are parsed as seconds. +- +- +- Show parsing of timespans +- +- $ systemd-analyze timespan 1s 300s '1year 0.000001s' +-Original: 1s +- μs: 1000000 +- Human: 1s +- +-Original: 300s +- μs: 300000000 +- Human: 5min +- +-Original: 1year 0.000001s +- μs: 31557600000001 +- Human: 1y 1us +- +- ++ systemd.time7. + + + diff --git a/SOURCES/0644-Disable-iptables-for-CI.patch b/SOURCES/0644-Disable-iptables-for-CI.patch new file mode 100644 index 0000000..a479a58 --- /dev/null +++ b/SOURCES/0644-Disable-iptables-for-CI.patch @@ -0,0 +1,21 @@ +From ffd20a699280a4732d0fe4cddafe12ee8010ddb6 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 13 Oct 2021 10:01:59 +0200 +Subject: [PATCH] Disable iptables for CI + +--- + .github/workflows/unit_tests.sh | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index def38bffe2..814870e7a0 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -92,7 +92,6 @@ SYSTEMD_BUILD_DEPS=( + gnutls-devel + gobject-introspection-devel + gperf +- iptables-devel + kmod-devel + libacl-devel + libblkid-devel diff --git a/SOURCES/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch b/SOURCES/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch new file mode 100644 index 0000000..4fead0e --- /dev/null +++ b/SOURCES/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch @@ -0,0 +1,103 @@ +From 8e322f5bc24547963978be071a8a2547abad875a Mon Sep 17 00:00:00 2001 +From: Henri Chain +Date: Tue, 5 Oct 2021 13:10:31 +0200 +Subject: [PATCH] core: fix SIGABRT on empty exec command argv + +This verifies that the argv part of any exec_command parameters that +are sent through dbus is not empty at deserialization time. + +There is an additional check in service.c service_verify() that again +checks if all exec_commands are correctly populated, after the service +has been loaded, whether through dbus or otherwise. + +Fixes #20933. + +(cherry picked from commit 29500cf8c47e6eb0518d171d62aa8213020c9152) + +Resolves: #2020239 +--- + src/core/dbus-execute.c | 4 ++++ + src/core/service.c | 12 +++++++++++ + test/TEST-23-TYPE-EXEC/testsuite.sh | 31 +++++++++++++++++++++++++++++ + 3 files changed, 47 insertions(+) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 8348663000..2e64f0baf4 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -969,6 +969,10 @@ int bus_set_transient_exec_command( + if (r < 0) + return r; + ++ if (strv_isempty(argv)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ "\"%s\" argv cannot be empty", name); ++ + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; +diff --git a/src/core/service.c b/src/core/service.c +index 5e3e75b5ae..12adf89dd4 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -536,6 +536,18 @@ static int service_verify(Service *s) { + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + ++ for (ServiceExecCommand c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { ++ ExecCommand *command; ++ ++ LIST_FOREACH(command, command, s->exec_command[c]) ++ if (strv_isempty(command->argv)) { ++ log_unit_error(UNIT(s), ++ "Service has an empty argv in %s=. Refusing.", ++ service_exec_command_to_string(c)); ++ return -ENOEXEC; ++ } ++ } ++ + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { + log_unit_error(UNIT(s), "Service lacks both ExecStart= and ExecStop= setting. Refusing."); + return -ENOEXEC; +diff --git a/test/TEST-23-TYPE-EXEC/testsuite.sh b/test/TEST-23-TYPE-EXEC/testsuite.sh +index 80734bbbdc..e0c34cfd04 100755 +--- a/test/TEST-23-TYPE-EXEC/testsuite.sh ++++ b/test/TEST-23-TYPE-EXEC/testsuite.sh +@@ -21,6 +21,37 @@ systemd-run --unit=four -p Type=exec /bin/sleep infinity + ! systemd-run --unit=five -p Type=exec -p User=idontexist /bin/sleep infinity + ! systemd-run --unit=six -p Type=exec /tmp/brokenbinary + ++# For issue #20933 ++ ++# Should work normally ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-ok.service replace 1 \ ++ ExecStart "a(sasb)" 1 \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ 0 ++ ++# DBus call should fail but not crash systemd ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-bad.service replace 1 \ ++ ExecStart "a(sasb)" 1 \ ++ /usr/bin/sleep 0 true \ ++ 0 && { echo 'unexpected success'; exit 1; } ++ ++# Same but with the empty argv in the middle ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-bad-middle.service replace 1 \ ++ ExecStart "a(sasb)" 3 \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ /usr/bin/sleep 0 true \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ 0 && { echo 'unexpected success'; exit 1; } ++ + systemd-analyze set-log-level info + + echo OK > /testok diff --git a/SOURCES/0646-core-service-also-check-path-in-exec-commands.patch b/SOURCES/0646-core-service-also-check-path-in-exec-commands.patch new file mode 100644 index 0000000..d887be6 --- /dev/null +++ b/SOURCES/0646-core-service-also-check-path-in-exec-commands.patch @@ -0,0 +1,39 @@ +From 71ebbd2da606c9cb4da694bbcc925078f253f496 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 6 Oct 2021 00:19:41 +0900 +Subject: [PATCH] core/service: also check path in exec commands + +(cherry picked from commit 8688a389cabdff61efe187bb85cc1776de03c460) + +Related: #2020239 +--- + src/core/service.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 12adf89dd4..ae31973774 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -539,13 +539,21 @@ static int service_verify(Service *s) { + for (ServiceExecCommand c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { + ExecCommand *command; + +- LIST_FOREACH(command, command, s->exec_command[c]) ++ LIST_FOREACH(command, command, s->exec_command[c]) { ++ if (!path_is_absolute(command->path) && !filename_is_valid(command->path)) { ++ log_unit_error(UNIT(s), ++ "Service %s= binary path \"%s\" is neither a valid executable name nor an absolute path. Refusing.", ++ command->path, ++ service_exec_command_to_string(c)); ++ return -ENOEXEC; ++ } + if (strv_isempty(command->argv)) { + log_unit_error(UNIT(s), + "Service has an empty argv in %s=. Refusing.", + service_exec_command_to_string(c)); + return -ENOEXEC; + } ++ } + } + + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { diff --git a/SOURCES/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch b/SOURCES/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch new file mode 100644 index 0000000..43206fe --- /dev/null +++ b/SOURCES/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch @@ -0,0 +1,124 @@ +From 397aaad6da5c4bfb160adca7a68f865086f2ed0a Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Thu, 30 Sep 2021 14:05:36 +0200 +Subject: [PATCH] mount-util: fix fd_is_mount_point() when both the parent and + directory are network fs + +The second call to name_to_handle_at_loop() didn't check for the specific +errors that can happen when the parent dir is mounted by nfs and instead of +falling back like it's done for the child dir, fd_is_mount_point() failed in +this case. + +(cherry picked from commit 964ccab8286a7e75d7e9107f574f5cb23752bd5d) + +Resolves: #2015057 +--- + src/basic/mount-util.c | 71 ++++++++++++++++++++++++------------------ + 1 file changed, 41 insertions(+), 30 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 45348bf878..0c709001be 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -139,6 +139,19 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id + return safe_atoi(p, mnt_id); + } + ++static bool is_name_to_handle_at_fatal_error(int err) { ++ /* name_to_handle_at() can return "acceptable" errors that are due to the context. For ++ * example the kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall ++ * was blocked (EACCES/EPERM; maybe through seccomp, because we are running inside of a ++ * container), or the mount point is not triggered yet (EOVERFLOW, think nfs4), or some ++ * general name_to_handle_at() flakiness (EINVAL). However other errors are not supposed to ++ * happen and therefore are considered fatal ones. */ ++ ++ assert(err < 0); ++ ++ return !IN_SET(err, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL); ++} ++ + int fd_is_mount_point(int fd, const char *filename, int flags) { + _cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL; + int mount_id = -1, mount_id_parent = -1; +@@ -173,42 +186,40 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { + * real mounts of their own. */ + + r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags); +- if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) +- /* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked +- * (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount +- * point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness +- * (EINVAL): fall back to simpler logic. */ +- goto fallback_fdinfo; +- else if (r == -EOPNOTSUPP) +- /* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs +- * supports it (in which case it is a mount point), otherwise fallback to the traditional stat() +- * logic */ ++ if (r < 0) { ++ if (is_name_to_handle_at_fatal_error(r)) ++ return r; ++ if (r != -EOPNOTSUPP) ++ goto fallback_fdinfo; ++ ++ /* This kernel or file system does not support name_to_handle_at(), hence let's see ++ * if the upper fs supports it (in which case it is a mount point), otherwise fall ++ * back to the traditional stat() logic */ + nosupp = true; +- else if (r < 0) +- return r; ++ } + + r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH); +- if (r == -EOPNOTSUPP) { ++ if (r < 0) { ++ if (is_name_to_handle_at_fatal_error(r)) ++ return r; ++ if (r != -EOPNOTSUPP) ++ goto fallback_fdinfo; + if (nosupp) +- /* Neither parent nor child do name_to_handle_at()? We have no choice but to fall back. */ ++ /* Both the parent and the directory can't do name_to_handle_at() */ + goto fallback_fdinfo; +- else +- /* The parent can't do name_to_handle_at() but the directory we are interested in can? If so, +- * it must be a mount point. */ +- return 1; +- } else if (r < 0) +- return r; + +- /* The parent can do name_to_handle_at() but the +- * directory we are interested in can't? If so, it +- * must be a mount point. */ ++ /* The parent can't do name_to_handle_at() but the directory we are ++ * interested in can? If so, it must be a mount point. */ ++ return 1; ++ } ++ ++ /* The parent can do name_to_handle_at() but the directory we are interested in can't? If ++ * so, it must be a mount point. */ + if (nosupp) + return 1; + +- /* If the file handle for the directory we are +- * interested in and its parent are identical, we +- * assume this is the root directory, which is a mount +- * point. */ ++ /* If the file handle for the directory we are interested in and its parent are identical, ++ * we assume this is the root directory, which is a mount point. */ + + if (h->handle_bytes == h_parent->handle_bytes && + h->handle_type == h_parent->handle_type && +@@ -300,10 +311,10 @@ int path_get_mnt_id(const char *path, int *ret) { + int r; + + r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0); +- if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */ +- return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); ++ if (r == 0 || is_name_to_handle_at_fatal_error(r)) ++ return r; + +- return r; ++ return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); + } + + int umount_recursive(const char *prefix, int flags) { diff --git a/SOURCES/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch b/SOURCES/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch new file mode 100644 index 0000000..8685575 --- /dev/null +++ b/SOURCES/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch @@ -0,0 +1,28 @@ +From 537055fc407d7cff32ddd3414a6900ccff579c46 Mon Sep 17 00:00:00 2001 +From: Cyprien Laplace +Date: Thu, 14 Nov 2019 09:42:14 -0500 +Subject: [PATCH] basic: add vmware hypervisor detection from device-tree + +Allow ConditionVirtualization=vmware to work on ESXi on arm VMs +using device-tree. + +(cherry picked from commit 4d4ac92c928fcbc60b85fcbf8370af3883ee63db) + +Resolves: #1959150 +--- + src/basic/virt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 0b88005ed6..8d862b6d67 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -122,6 +122,8 @@ static int detect_vm_device_tree(void) { + return VIRTUALIZATION_KVM; + else if (strstr(hvtype, "xen")) + return VIRTUALIZATION_XEN; ++ else if (strstr(hvtype, "vmware")) ++ return VIRTUALIZATION_VMWARE; + else + return VIRTUALIZATION_VM_OTHER; + #else diff --git a/SOURCES/0649-pam-do-not-require-a-non-expired-password-for-user-..patch b/SOURCES/0649-pam-do-not-require-a-non-expired-password-for-user-..patch new file mode 100644 index 0000000..fdd68b2 --- /dev/null +++ b/SOURCES/0649-pam-do-not-require-a-non-expired-password-for-user-..patch @@ -0,0 +1,45 @@ +From a677e477ef541d172ede2a5bd728a4ff1ffb312d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 1 Jun 2021 16:17:16 +0200 +Subject: [PATCH] pam: do not require a non-expired password for user@.service + +Without this parameter, we would allow user@ to start if the user +has no password (i.e. the password is "locked"). But when the user does have a password, +and it is marked as expired, we would refuse to start the service. +There are other authentication mechanisms and we should not tie this service to +the password state. + +The documented way to disable an *account* is to call 'chage -E0'. With a disabled +account, user@.service will still refuse to start: + +systemd[16598]: PAM failed: User account has expired +systemd[16598]: PAM failed: User account has expired +systemd[16598]: user@1005.service: Failed to set up PAM session: Operation not permitted +systemd[16598]: user@1005.service: Failed at step PAM spawning /usr/lib/systemd/systemd: Operation not permitted +systemd[1]: user@1005.service: Main process exited, code=exited, status=224/PAM +systemd[1]: user@1005.service: Failed with result 'exit-code'. +systemd[1]: Failed to start user@1005.service. +systemd[1]: Stopping user-runtime-dir@1005.service... + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1961746. + +(cherry picked from commit 71889176e4372b443018584c3520c1ff3efe2711) + +Resolves: #1961746 +--- + src/login/systemd-user.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/systemd-user.m4 b/src/login/systemd-user.m4 +index 4f85b4b7fe..20c8999331 100644 +--- a/src/login/systemd-user.m4 ++++ b/src/login/systemd-user.m4 +@@ -2,7 +2,7 @@ + # + # Used by systemd --user instances. + +-account required pam_unix.so ++account sufficient pam_unix.so no_pass_expiry + m4_ifdef(`HAVE_SELINUX', + session required pam_selinux.so close + session required pam_selinux.so nottys open diff --git a/SOURCES/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch b/SOURCES/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch new file mode 100644 index 0000000..7519191 --- /dev/null +++ b/SOURCES/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch @@ -0,0 +1,26 @@ +From c0e530dc95fa7842ec1a48fd5df98956a76ae26c Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 26 Feb 2021 10:25:31 +0000 +Subject: [PATCH] udev rules: add rule to create /dev/ptp_hyperv + +As for the KVM case, necessary for network cards with +PTP devices when running a guest on HyperV + +(cherry picked from commit 32e868f058da8b90add00b2958c516241c532b70) + +Resolves: #1991834 +--- + rules/50-udev-default.rules.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/rules/50-udev-default.rules.in b/rules/50-udev-default.rules.in +index 191f56f42e..36657ce1a4 100644 +--- a/rules/50-udev-default.rules.in ++++ b/rules/50-udev-default.rules.in +@@ -83,4 +83,6 @@ KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@", OPTIONS+="static_node=kvm" + + SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm" + ++SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK += "ptp_hyperv" ++ + LABEL="default_end" diff --git a/SOURCES/0651-process-util-explicitly-handle-processes-lacking-par.patch b/SOURCES/0651-process-util-explicitly-handle-processes-lacking-par.patch new file mode 100644 index 0000000..3dfb66a --- /dev/null +++ b/SOURCES/0651-process-util-explicitly-handle-processes-lacking-par.patch @@ -0,0 +1,223 @@ +From 9b30c003c8f80bf44f18168d07ea11c48e6d8864 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 7 Jul 2021 15:57:51 +0200 +Subject: [PATCH] process-util: explicitly handle processes lacking parents in + get_process_ppid() + +Let's make sure we signal out-of-band via an error message if a process +doesn't have a parent process whose PID we could return. Otherwise we'll +too likely hide errors, as we return an invalid PID 0, which in other +contexts has special meaning (i.e. usually "myself"). + +Replaces: #20153 + +This is based on work by @dtardon, but goes a different route, by +ensuring we propagate a proper error in this case. + +This modernizes the function in question a bit in other ways, i.e. +renames stuff and makes the return parameter optional. + +(cherry picked from commit 0c4d1e6d96a549054bfe0597d197f829838917f1) + +Resolves: #1977569 +--- + src/basic/process-util.c | 27 +++++++++++++------- + src/coredump/coredump.c | 23 +++++++++-------- + src/test/test-process-util.c | 48 +++++++++++++++++++++++++++++++++--- + 3 files changed, 74 insertions(+), 24 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index 0a4a747ba4..6016d83d41 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -603,20 +603,23 @@ int get_process_environ(pid_t pid, char **env) { + return 0; + } + +-int get_process_ppid(pid_t pid, pid_t *_ppid) { +- int r; ++int get_process_ppid(pid_t pid, pid_t *ret) { + _cleanup_free_ char *line = NULL; + long unsigned ppid; + const char *p; ++ int r; + + assert(pid >= 0); +- assert(_ppid); + + if (pid == 0 || pid == getpid_cached()) { +- *_ppid = getppid(); ++ if (ret) ++ *ret = getppid(); + return 0; + } + ++ if (pid == 1) /* PID 1 has no parent, shortcut this case */ ++ return -EADDRNOTAVAIL; ++ + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r == -ENOENT) +@@ -624,9 +627,8 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) { + if (r < 0) + return r; + +- /* Let's skip the pid and comm fields. The latter is enclosed +- * in () but does not escape any () in its value, so let's +- * skip over it manually */ ++ /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its ++ * value, so let's skip over it manually */ + + p = strrchr(line, ')'); + if (!p) +@@ -640,10 +642,17 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) { + &ppid) != 1) + return -EIO; + +- if ((long unsigned) (pid_t) ppid != ppid) ++ /* If ppid is zero the process has no parent. Which might be the case for PID 1 but also for ++ * processes originating in other namespaces that are inserted into a pidns. Return a recognizable ++ * error in this case. */ ++ if (ppid == 0) ++ return -EADDRNOTAVAIL; ++ ++ if ((pid_t) ppid < 0 || (long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + +- *_ppid = (pid_t) ppid; ++ if (ret) ++ *ret = (pid_t) ppid; + + return 0; + } +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 2a130e8838..fb3a6ecfe9 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -591,8 +591,7 @@ static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) { + return 0; + } + +-static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { +- pid_t cpid = pid, ppid = 0; ++static int get_mount_namespace_leader(pid_t pid, pid_t *ret) { + ino_t proc_mntns; + int r = 0; + +@@ -602,8 +601,12 @@ static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { + + for (;;) { + ino_t parent_mntns; ++ pid_t ppid; + +- r = get_process_ppid(cpid, &ppid); ++ r = get_process_ppid(pid, &ppid); ++ if (r == -EADDRNOTAVAIL) /* Reached the top (i.e. typically PID 1, but could also be a process ++ * whose parent is not in our pidns) */ ++ return -ENOENT; + if (r < 0) + return r; + +@@ -611,17 +614,13 @@ static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { + if (r < 0) + return r; + +- if (proc_mntns != parent_mntns) +- break; +- +- if (ppid == 1) +- return -ENOENT; ++ if (proc_mntns != parent_mntns) { ++ *ret = ppid; ++ return 0; ++ } + +- cpid = ppid; ++ pid = ppid; + } +- +- *container_pid = ppid; +- return 0; + } + + /* Returns 1 if the parent was found. +diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c +index 26e3247993..6b14ff592b 100644 +--- a/src/test/test-process-util.c ++++ b/src/test/test-process-util.c +@@ -19,6 +19,7 @@ + #include "macro.h" + #include "parse-util.h" + #include "process-util.h" ++#include "procfs-util.h" + #include "signal-util.h" + #include "stdio-util.h" + #include "string-util.h" +@@ -56,9 +57,12 @@ static void test_get_process_comm(pid_t pid) { + 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_ppid(pid, &e) >= 0); +- log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e); +- assert_se(pid == 1 ? e == 0 : e > 0); ++ r = get_process_ppid(pid, &e); ++ assert_se(pid == 1 ? r == -EADDRNOTAVAIL : r >= 0); ++ if (r >= 0) { ++ log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e); ++ assert_se(e > 0); ++ } + + assert_se(is_kernel_thread(pid) == 0 || pid != 1); + +@@ -585,6 +589,43 @@ static void test_ioprio_class_from_to_string(void) { + test_ioprio_class_from_to_string_one("-1", -1); + } + ++static void test_get_process_ppid(void) { ++ uint64_t limit; ++ int r; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL); ++ ++ /* the process with the PID above the global limit definitely doesn't exist. Verify that */ ++ assert_se(procfs_tasks_get_limit(&limit) >= 0); ++ assert_se(limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH); ++ ++ for (pid_t pid = 0;;) { ++ _cleanup_free_ char *c1 = NULL, *c2 = NULL; ++ pid_t ppid; ++ ++ r = get_process_ppid(pid, &ppid); ++ if (r == -EADDRNOTAVAIL) { ++ log_info("No further parent PID"); ++ break; ++ } ++ ++ assert_se(r >= 0); ++ ++ /* NOTE: The size is SIZE_MAX in the original commit, but it would require backporting a ++ * lot more stuff to support that (the current version of get_process_cmdline() just fails with ++ * ENOMEM). UINT16_MAX should be enough for practical purposes. ++ */ ++ assert_se(get_process_cmdline(pid, UINT16_MAX, true, &c1) >= 0); ++ assert_se(get_process_cmdline(ppid, UINT16_MAX, true, &c2) >= 0); ++ ++ log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pid, c1, ppid, c2); ++ ++ pid = ppid; ++ } ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); +@@ -614,6 +655,7 @@ int main(int argc, char *argv[]) { + test_safe_fork(); + test_pid_to_ptr(); + test_ioprio_class_from_to_string(); ++ test_get_process_ppid(); + + return 0; + } diff --git a/SOURCES/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch b/SOURCES/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch new file mode 100644 index 0000000..b341839 --- /dev/null +++ b/SOURCES/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch @@ -0,0 +1,30 @@ +From c078d4d4bc3a61d186a98e03afc699b11134e09f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Nov 2019 12:22:40 +0100 +Subject: [PATCH] errno-util: add ERRNO_IS_PRIVILEGE() helper + +(cherry picked from commit e884e000714c2db006384058a63788ffcce8c8b8) + +Related: #1977569 +--- + src/basic/util.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index c70467f98c..76b76d7e91 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -170,6 +170,13 @@ static inline int negative_errno(void) { + return -errno; + } + ++/* Two different errors for access problems */ ++static inline bool ERRNO_IS_PRIVILEGE(int r) { ++ return IN_SET(abs(r), ++ EACCES, ++ EPERM); ++} ++ + static inline unsigned u64log2(uint64_t n) { + #if __SIZEOF_LONG_LONG__ == 8 + return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0; diff --git a/SOURCES/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch b/SOURCES/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch new file mode 100644 index 0000000..d85bfc5 --- /dev/null +++ b/SOURCES/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch @@ -0,0 +1,318 @@ +From 62678ec1aa02b53cb116b6f7dd72a54bf61153b7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 2 Nov 2021 18:18:21 +0100 +Subject: [PATCH] procfs-util: fix confusion wrt. quantity limit and maximum + value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From packit/rawhide-arm64 logs: +Assertion 'limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH' failed at src/test/test-process-util.c:855, function test_get_process_ppid(). Aborting. +―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― + +The kernel has a few different limits. In particular kernel.threads-max can be +set to some lower value, and kernel.pid_max can be set to a higher value. This +is nice because it reduces PID reuse, even if the number of threads that is +allowed is limited. But the tests assumed that we cannot have a thread with +PID above MIN(kernel.threads-max, kernel.pid_max-1), which is not valid. + +So let's rework the whole thing: let's expose the helpers to read +kernel.threads-max and kernel.pid_max, and print what they return in tests. +procfs_tasks_get_limit() was something that is only used in tests, and wasn't +very well defined, so let's drop it. + +Fixes #21193. + +(cherry picked from commit c3dead53d50e334f2d072a2248256983d6dc9f8c) + +Related: #1977569 +--- + src/basic/procfs-util.c | 53 +++++++++--------------------------- + src/basic/procfs-util.h | 4 ++- + src/basic/util.c | 49 +++++++++++++++++++++++---------- + src/test/test-process-util.c | 10 +++++-- + src/test/test-procfs-util.c | 37 +++++++++++++++++++------ + 5 files changed, 88 insertions(+), 65 deletions(-) + +diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c +index 7aaf95bfce..fa5671dd72 100644 +--- a/src/basic/procfs-util.c ++++ b/src/basic/procfs-util.c +@@ -12,54 +12,34 @@ + #include "stdio-util.h" + #include "string-util.h" + +-int procfs_tasks_get_limit(uint64_t *ret) { ++int procfs_get_pid_max(uint64_t *ret) { + _cleanup_free_ char *value = NULL; +- uint64_t pid_max, threads_max; + int r; + + assert(ret); + +- /* So there are two sysctl files that control the system limit of processes: +- * +- * 1. kernel.threads-max: this is probably the sysctl that makes more sense, as it directly puts a limit on +- * concurrent tasks. +- * +- * 2. kernel.pid_max: this limits the numeric range PIDs can take, and thus indirectly also limits the number +- * of concurrent threads. AFAICS it's primarily a compatibility concept: some crappy old code used a signed +- * 16bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond INT16_MAX by +- * default. +- * +- * By default #2 is set to much lower values than #1, hence the limit people come into contact with first, as +- * it's the lowest boundary they need to bump when they want higher number of processes. +- * +- * Also note the weird definition of #2: PIDs assigned will be kept below this value, which means the number of +- * tasks that can be created is one lower, as PID 0 is not a valid process ID. */ +- + r = read_one_line_file("/proc/sys/kernel/pid_max", &value); + if (r < 0) + return r; + +- r = safe_atou64(value, &pid_max); +- if (r < 0) +- return r; ++ return safe_atou64(value, ret); ++} + +- value = mfree(value); +- r = read_one_line_file("/proc/sys/kernel/threads-max", &value); +- if (r < 0) +- return r; ++int procfs_get_threads_max(uint64_t *ret) { ++ _cleanup_free_ char *value = NULL; ++ int r; + +- r = safe_atou64(value, &threads_max); ++ assert(ret); ++ ++ r = read_one_line_file("/proc/sys/kernel/threads-max", &value); + if (r < 0) + return r; + +- /* Subtract one from pid_max, since PID 0 is not a valid PID */ +- *ret = MIN(pid_max-1, threads_max); +- return 0; ++ return safe_atou64(value, ret); + } + + int procfs_tasks_set_limit(uint64_t limit) { + char buffer[DECIMAL_STR_MAX(uint64_t)+1]; +- _cleanup_free_ char *value = NULL; + uint64_t pid_max; + int r; + +@@ -74,10 +54,7 @@ int procfs_tasks_set_limit(uint64_t limit) { + * set it to the maximum. */ + limit = CLAMP(limit, 20U, TASKS_MAX); + +- r = read_one_line_file("/proc/sys/kernel/pid_max", &value); +- if (r < 0) +- return r; +- r = safe_atou64(value, &pid_max); ++ r = procfs_get_pid_max(&pid_max); + if (r < 0) + return r; + +@@ -98,14 +75,10 @@ int procfs_tasks_set_limit(uint64_t limit) { + /* Hmm, we couldn't write this? If so, maybe it was already set properly? In that case let's not + * generate an error */ + +- value = mfree(value); +- if (read_one_line_file("/proc/sys/kernel/threads-max", &value) < 0) +- return r; /* return original error */ +- +- if (safe_atou64(value, &threads_max) < 0) ++ if (procfs_get_threads_max(&threads_max) < 0) + return r; /* return original error */ + +- if (MIN(pid_max-1, threads_max) != limit) ++ if (MIN(pid_max - 1, threads_max) != limit) + return r; /* return original error */ + + /* Yay! Value set already matches what we were trying to set, hence consider this a success. */ +diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h +index 5a44e9eff7..caaee8b0b6 100644 +--- a/src/basic/procfs-util.h ++++ b/src/basic/procfs-util.h +@@ -5,7 +5,9 @@ + + #include "time-util.h" + +-int procfs_tasks_get_limit(uint64_t *ret); ++int procfs_get_pid_max(uint64_t *ret); ++int procfs_get_threads_max(uint64_t *ret); ++ + int procfs_tasks_set_limit(uint64_t limit); + int procfs_tasks_get_current(uint64_t *ret); + +diff --git a/src/basic/util.c b/src/basic/util.c +index 609f8c2f33..548e3652cc 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -527,23 +527,46 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { + } + + uint64_t system_tasks_max(void) { +- +- uint64_t a = TASKS_MAX, b = TASKS_MAX; ++ uint64_t a = TASKS_MAX, b = TASKS_MAX, c = TASKS_MAX; + _cleanup_free_ char *root = NULL; + int r; + +- /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this +- * limit: ++ /* Determine the maximum number of tasks that may run on this system. We check three sources to ++ * determine this limit: ++ * ++ * a) kernel.threads-max sysctl: the maximum number of tasks (threads) the kernel allows. ++ * ++ * This puts a direct limit on the number of concurrent tasks. ++ * ++ * b) kernel.pid_max sysctl: the maximum PID value. ++ * ++ * This limits the numeric range PIDs can take, and thus indirectly also limits the number of ++ * concurrent threads. It's primarily a compatibility concept: some crappy old code used a signed ++ * 16bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond ++ * INT16_MAX by default. + * +- * a) the maximum tasks value the kernel allows on this architecture +- * b) the cgroups pids_max attribute for the system +- * c) the kernel's configured maximum PID value ++ * Also note the weird definition: PIDs assigned will be kept below this value, which means ++ * the number of tasks that can be created is one lower, as PID 0 is not a valid process ID. + * +- * And then pick the smallest of the three */ ++ * c) pids.max on the root cgroup: the kernel's configured maximum number of tasks. ++ * ++ * and then pick the smallest of the three. ++ * ++ * By default pid_max is set to much lower values than threads-max, hence the limit people come into ++ * contact with first, as it's the lowest boundary they need to bump when they want higher number of ++ * processes. ++ */ ++ ++ r = procfs_get_threads_max(&a); ++ if (r < 0) ++ log_debug_errno(r, "Failed to read kernel.threads-max, ignoring: %m"); + +- r = procfs_tasks_get_limit(&a); ++ r = procfs_get_pid_max(&b); + if (r < 0) +- log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m"); ++ log_debug_errno(r, "Failed to read kernel.pid_max, ignoring: %m"); ++ else if (b > 0) ++ /* Subtract one from pid_max, since PID 0 is not a valid PID */ ++ b--; + + r = cg_get_root_path(&root); + if (r < 0) +@@ -555,15 +578,13 @@ uint64_t system_tasks_max(void) { + if (r < 0) + log_debug_errno(r, "Failed to read pids.max attribute of cgroup root, ignoring: %m"); + else if (!streq(value, "max")) { +- r = safe_atou64(value, &b); ++ r = safe_atou64(value, &c); + if (r < 0) + log_debug_errno(r, "Failed to parse pids.max attribute of cgroup root, ignoring: %m"); + } + } + +- return MIN3(TASKS_MAX, +- a <= 0 ? TASKS_MAX : a, +- b <= 0 ? TASKS_MAX : b); ++ return MIN3(a, b, c); + } + + uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { +diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c +index 6b14ff592b..6295889b47 100644 +--- a/src/test/test-process-util.c ++++ b/src/test/test-process-util.c +@@ -598,8 +598,14 @@ static void test_get_process_ppid(void) { + assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL); + + /* the process with the PID above the global limit definitely doesn't exist. Verify that */ +- assert_se(procfs_tasks_get_limit(&limit) >= 0); +- assert_se(limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH); ++ assert_se(procfs_get_pid_max(&limit) >= 0); ++ log_debug("kernel.pid_max = %"PRIu64, limit); ++ ++ if (limit < INT_MAX) { ++ r = get_process_ppid(limit + 1, NULL); ++ log_debug_errno(r, "get_process_limit(%"PRIu64") → %d/%m", limit + 1, r); ++ assert(r == -ESRCH); ++ } + + for (pid_t pid = 0;;) { + _cleanup_free_ char *c1 = NULL, *c2 = NULL; +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index 1d0612985b..bb6943fed0 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -5,11 +5,13 @@ + #include "log.h" + #include "parse-util.h" + #include "procfs-util.h" ++#include "process-util.h" ++#include "util.h" + + int main(int argc, char *argv[]) { + char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_BYTES_MAX)]; + nsec_t nsec; +- uint64_t v; ++ uint64_t v, w; + int r; + + log_parse_environment(); +@@ -24,22 +26,41 @@ int main(int argc, char *argv[]) { + assert_se(procfs_tasks_get_current(&v) >= 0); + log_info("Current number of tasks: %" PRIu64, v); + +- assert_se(procfs_tasks_get_limit(&v) >= 0); ++ v = TASKS_MAX; ++ r = procfs_get_pid_max(&v); ++ assert(r >= 0 || r == -ENOENT || ERRNO_IS_PRIVILEGE(r)); ++ log_info("kernel.pid_max: %"PRIu64, v); ++ ++ w = TASKS_MAX; ++ r = procfs_get_threads_max(&w); ++ assert(r >= 0 || r == -ENOENT || ERRNO_IS_PRIVILEGE(r)); ++ log_info("kernel.threads-max: %"PRIu64, w); ++ ++ v = MIN(v - (v > 0), w); ++ ++ assert_se(r >= 0); + log_info("Limit of tasks: %" PRIu64, v); + assert_se(v > 0); +- assert_se(procfs_tasks_set_limit(v) >= 0); ++ r = procfs_tasks_set_limit(v); ++ if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r)) { ++ log_notice_errno(r, "Skipping test: can't set task limits"); ++ return EXIT_TEST_SKIP; ++ } ++ assert(r >= 0); + + if (v > 100) { +- uint64_t w; ++ log_info("Reducing limit by one to %"PRIu64"…", v-1); ++ + r = procfs_tasks_set_limit(v-1); +- assert_se(IN_SET(r, 0, -EPERM, -EACCES, -EROFS)); ++ log_info_errno(r, "procfs_tasks_set_limit: %m"); ++ assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r)); + +- assert_se(procfs_tasks_get_limit(&w) >= 0); +- assert_se((r == 0 && w == v - 1) || (r < 0 && w == v)); ++ assert_se(procfs_get_threads_max(&w) >= 0); ++ assert_se(r >= 0 ? w == v - 1 : w == v); + + assert_se(procfs_tasks_set_limit(v) >= 0); + +- assert_se(procfs_tasks_get_limit(&w) >= 0); ++ assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(v == w); + } + diff --git a/SOURCES/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch b/SOURCES/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch new file mode 100644 index 0000000..8b756d2 --- /dev/null +++ b/SOURCES/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch @@ -0,0 +1,31 @@ +From fe15b97e44beb69305d3970a3748624ae76f9f04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Nov 2021 09:39:16 +0100 +Subject: [PATCH] test-process-util: also add EROFS to the list of "good" + errors + +It is only added in the one place where we actually try to set the +setting to a new value. Before we were testing if we can set to it the +existing value, which was a noop. We could still get a permission error, +but this is the first place where we would propagate EROFS. + +(cherry picked from commit 6434a83d01d96e9f9a17ed9ce1f04a7d64859950) + +Related: #1977569 +--- + src/test/test-procfs-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index bb6943fed0..d656c4df4f 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { + + r = procfs_tasks_set_limit(v-1); + log_info_errno(r, "procfs_tasks_set_limit: %m"); +- assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r)); ++ assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS); + + assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(r >= 0 ? w == v - 1 : w == v); diff --git a/SOURCES/0655-journal-refresh-cached-credentials-of-stdout-streams.patch b/SOURCES/0655-journal-refresh-cached-credentials-of-stdout-streams.patch new file mode 100644 index 0000000..7b1481d --- /dev/null +++ b/SOURCES/0655-journal-refresh-cached-credentials-of-stdout-streams.patch @@ -0,0 +1,146 @@ +From a42cf9af339f48f633fa0b17a960e1e407b7450f Mon Sep 17 00:00:00 2001 +From: Lorenz Bauer +Date: Mon, 4 Nov 2019 16:35:46 +0000 +Subject: [PATCH] journal: refresh cached credentials of stdout streams + +journald assumes that getsockopt(SO_PEERCRED) correctly identifies the +process on the remote end of the socket. However, this is incorrect +according to man 7 socket: + + The returned credentials are those that were in effect at the + time of the call to connect(2) or socketpair(2). + +This becomes a problem when a new process inherits the stdout stream +from a parent. First, log messages from the child process will +be attributed to the parent. Second, the struct ucred used by journald +becomes invalid as soon as the parent exits. Further sendmsg calls then +fail with ENOENT. Logs for the child process then vanish from the journal. + +Fix this by using recvmsg on the stdout stream, and refreshing the cached +struct ucred if SCM_CREDENTIALS indicate a new process. + +Fixes #13708 + +(cherry picked from commit 09d0b46ab61bebafe5bdc1be95ee153dfb13d6bc) + +Resolves: #1931806 +--- + src/journal/journald-stream.c | 49 ++++++++++++++++++++++++++-- + test/TEST-04-JOURNAL/test-journal.sh | 13 ++++++++ + 2 files changed, 60 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 6f8a4011ff..302a82d3d7 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -484,11 +484,22 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + } + + static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { ++ uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + StdoutStream *s = userdata; ++ struct ucred *ucred = NULL; ++ struct cmsghdr *cmsg; ++ struct iovec iovec; + size_t limit; + ssize_t l; + int r; + ++ struct msghdr msghdr = { ++ .msg_iov = &iovec, ++ .msg_iovlen = 1, ++ .msg_control = buf, ++ .msg_controllen = sizeof(buf), ++ }; ++ + assert(s); + + if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { +@@ -508,20 +519,50 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + * always leave room for a terminating NUL we might need to add. */ + limit = MIN(s->allocated - 1, s->server->line_max); + +- l = read(s->fd, s->buffer + s->length, limit - s->length); ++ iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length); ++ ++ l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (l < 0) { +- if (errno == EAGAIN) ++ if (IN_SET(errno, EINTR, EAGAIN)) + return 0; + + log_warning_errno(errno, "Failed to read from stream: %m"); + goto terminate; + } ++ cmsg_close_all(&msghdr); + + if (l == 0) { + stdout_stream_scan(s, true); + goto terminate; + } + ++ CMSG_FOREACH(cmsg, &msghdr) ++ if (cmsg->cmsg_level == SOL_SOCKET && ++ cmsg->cmsg_type == SCM_CREDENTIALS && ++ cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { ++ ucred = (struct ucred *)CMSG_DATA(cmsg); ++ break; ++ } ++ ++ /* Invalidate the context if the pid of the sender changed. ++ * This happens when a forked process inherits stdout / stderr ++ * from a parent. In this case getpeercred returns the ucred ++ * of the parent, which can be invalid if the parent has exited ++ * in the meantime. ++ */ ++ if (ucred && ucred->pid != s->ucred.pid) { ++ /* force out any previously half-written lines from a ++ * different process, before we switch to the new ucred ++ * structure for everything we just added */ ++ r = stdout_stream_scan(s, true); ++ if (r < 0) ++ goto terminate; ++ ++ s->ucred = *ucred; ++ client_context_release(s->server, s->context); ++ s->context = NULL; ++ } ++ + s->length += l; + r = stdout_stream_scan(s, false); + if (r < 0) +@@ -559,6 +600,10 @@ int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { + if (r < 0) + return log_error_errno(r, "Failed to determine peer credentials: %m"); + ++ r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true); ++ if (r < 0) ++ return log_error_errno(r, "SO_PASSCRED failed: %m"); ++ + if (mac_selinux_use()) { + r = getpeersec(fd, &stream->label); + if (r < 0 && r != -EOPNOTSUPP) +diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh +index 260cae09ab..52a6ee84d1 100755 +--- a/test/TEST-04-JOURNAL/test-journal.sh ++++ b/test/TEST-04-JOURNAL/test-journal.sh +@@ -63,6 +63,19 @@ grep -q '^PRIORITY=6$' /output + ! grep -q '^FOO=' /output + ! grep -q '^SYSLOG_FACILITY=' /output + ++# https://github.com/systemd/systemd/issues/13708 ++ID=$(journalctl --new-id128 | sed -n 2p) ++systemd-cat -t "$ID" bash -c 'echo parent; (echo child) & wait' & ++PID=$! ++wait %% ++journalctl --sync ++# We can drop this grep when https://github.com/systemd/systemd/issues/13937 ++# has a fix. ++journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output ++[[ `grep -c . /output` -eq 2 ]] ++grep -q "^_PID=$PID" /output ++grep -vq "^_PID=$PID" /output ++ + # Don't lose streams on restart + systemctl start forever-print-hola + sleep 3 diff --git a/SOURCES/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch b/SOURCES/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch new file mode 100644 index 0000000..f51fced --- /dev/null +++ b/SOURCES/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch @@ -0,0 +1,35 @@ +From 39b10c9e7e4ad80adc0e8c43f7d1917edee515dd Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Sun, 2 Dec 2018 08:28:24 +0100 +Subject: [PATCH] util-lib: introduce HAS_FEATURE_ADDRESS_SANITIZER + +https://clang.llvm.org/docs/AddressSanitizer.html#conditional-compilation-with-has-feature-address-sanitizer +(cherry picked from commit 289acab951c5937fdf6d3a2666f411fd66dd20e5) + +Related: #2017033 +--- + src/basic/macro.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 0fe6a62aa8..62f2359633 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -55,6 +55,17 @@ + # endif + #endif + ++#if !defined(HAS_FEATURE_ADDRESS_SANITIZER) ++# if defined(__has_feature) ++# if __has_feature(address_sanitizer) ++# define HAS_FEATURE_ADDRESS_SANITIZER 1 ++# endif ++# endif ++# if !defined(HAS_FEATURE_ADDRESS_SANITIZER) ++# define HAS_FEATURE_ADDRESS_SANITIZER 0 ++# endif ++#endif ++ + /* Temporarily disable some warnings */ + #define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \ + _Pragma("GCC diagnostic push"); \ diff --git a/SOURCES/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch b/SOURCES/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch new file mode 100644 index 0000000..1b64c95 --- /dev/null +++ b/SOURCES/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch @@ -0,0 +1,34 @@ +From c0c7a5d73bd53375f90fbe70287512269bc8de16 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 12 Jan 2021 22:14:59 +0100 +Subject: [PATCH] ci: skip test-execute on GH Actions under ASan + +It seems to suffer from the same issue as on Travis CI, where the test +randomly fails due to timeouts in its subtests. + +See: https://github.com/systemd/systemd/issues/10696#issuecomment-758501797 +(cherry picked from commit f1a8fed286e3b9527b1837e9d5c6cb8d88bd2041) + +Related: #2017033 +--- + src/test/test-execute.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 294f8fe7dd..5303652b93 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -798,6 +798,13 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + ++#if HAS_FEATURE_ADDRESS_SANITIZER ++ if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions")) { ++ log_notice("Running on Travis CI/GH Actions under ASan, skipping, see https://github.com/systemd/systemd/issues/10696"); ++ return EXIT_TEST_SKIP; ++ } ++#endif ++ + (void) unsetenv("USER"); + (void) unsetenv("LOGNAME"); + (void) unsetenv("SHELL"); diff --git a/SOURCES/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch b/SOURCES/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch new file mode 100644 index 0000000..a7a10ed --- /dev/null +++ b/SOURCES/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch @@ -0,0 +1,27 @@ +From 8c15742d1194e0db9a2555553e4d77ebb441b3dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 22 Sep 2020 19:05:17 +0200 +Subject: [PATCH] test-seccomp: accept ENOSYS from sysctl(2) too + +It seems that kernel 5.9 started returning that. + +(cherry picked from commit 0af05e485a3a88f454c714901eb6109307dc893e) + +Related: #2017033 +--- + src/test/test-seccomp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 5eb1c78b8b..6ec04c4c55 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -239,7 +239,7 @@ static void test_protect_sysctl(void) { + if (pid == 0) { + #if defined __NR__sysctl && __NR__sysctl >= 0 + assert_se(syscall(__NR__sysctl, NULL) < 0); +- assert_se(errno == EFAULT); ++ assert_se(IN_SET(errno, EFAULT, ENOSYS)); + #endif + + assert_se(seccomp_protect_sysctl() >= 0); diff --git a/SOURCES/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch b/SOURCES/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch new file mode 100644 index 0000000..ac082a4 --- /dev/null +++ b/SOURCES/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch @@ -0,0 +1,51 @@ +From e61aa66a63bcfe9ce0d80f0db691ba40218b872a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 14 Aug 2020 21:50:55 +0200 +Subject: [PATCH] test: accept that char device 0/0 can now be created witout + privileges + +Fixes: #16721 +(cherry picked from commit 5b5ce6298e5a1c09beacd5c963e2350979cbf94a) + +Related: #2017033 +--- + src/test/test-fs-util.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c +index e3338ea440..aa32629f62 100644 +--- a/src/test/test-fs-util.c ++++ b/src/test/test-fs-util.c +@@ -518,8 +518,8 @@ static void test_touch_file(void) { + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + if (geteuid() == 0) { +- a = strjoina(p, "/cdev"); +- r = mknod(a, 0775 | S_IFCHR, makedev(0, 0)); ++ a = strjoina(p, "/bdev"); ++ r = mknod(a, 0775 | S_IFBLK, makedev(0, 0)); + if (r < 0 && errno == EPERM && detect_container() > 0) { + log_notice("Running in unprivileged container? Skipping remaining tests in %s", __func__); + return; +@@ -529,17 +529,17 @@ static void test_touch_file(void) { + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); +- assert_se(S_ISCHR(st.st_mode)); ++ assert_se(S_ISBLK(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + +- a = strjoina(p, "/bdev"); +- assert_se(mknod(a, 0775 | S_IFBLK, makedev(0, 0)) >= 0); ++ a = strjoina(p, "/cdev"); ++ assert_se(mknod(a, 0775 | S_IFCHR, makedev(0, 0)) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); +- assert_se(S_ISBLK(st.st_mode)); ++ assert_se(S_ISCHR(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + } diff --git a/SOURCES/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch b/SOURCES/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch new file mode 100644 index 0000000..9f61ab9 --- /dev/null +++ b/SOURCES/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch @@ -0,0 +1,54 @@ +From d5cefb7293d2999dcad81bd71933b319ca6c3590 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 12 Apr 2021 14:03:32 +0200 +Subject: [PATCH] meson: do not fail if rsync is not installed with meson + 0.57.2 + +https://github.com/mesonbuild/meson/issues/8641 + +Our CI started to fail. Even if the change is reverted in meson, +we need a quick workaround here. + +(cherry picked from commit 7c5fd25119a495009ea62f79e5daec34cc464628) + +Related: #2017033 +--- + man/meson.build | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/man/meson.build b/man/meson.build +index a953d34098..efc8836d0c 100644 +--- a/man/meson.build ++++ b/man/meson.build +@@ -178,17 +178,20 @@ html = custom_target( + depends : html_pages, + command : ['echo']) + +-run_target( +- 'doc-sync', +- depends : man_pages + html_pages, +- command : ['rsync', '-rlv', +- '--delete-excluded', +- '--include=man', +- '--include=*.html', +- '--exclude=*', +- '--omit-dir-times', +- meson.current_build_dir(), +- get_option('www-target')]) ++rsync = find_program('rsync', required : false) ++if rsync.found() ++ run_target( ++ 'doc-sync', ++ depends : man_pages + html_pages, ++ command : [rsync, '-rlv', ++ '--delete-excluded', ++ '--include=man', ++ '--include=*.html', ++ '--exclude=*', ++ '--omit-dir-times', ++ meson.current_build_dir(), ++ get_option('www-target')]) ++endif + + ############################################################ + diff --git a/SOURCES/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch b/SOURCES/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch new file mode 100644 index 0000000..c260547 --- /dev/null +++ b/SOURCES/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch @@ -0,0 +1,27 @@ +From 30afbfdc82eb61f3bf47d6b1fa67a61d0ffcc4f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Dec 2018 08:16:31 +0100 +Subject: [PATCH] pid1: fix free of uninitialized pointer in + unit_fail_if_noncanonical() + +https://bugzilla.redhat.com/show_bug.cgi?id=1653068 +(cherry picked from commit 58d9d89b4b41189bdcea86c2ad5cf708b7d54aca) + +Related: #1970945 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 93c13e58d9..152a860d08 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4785,7 +4785,7 @@ void unit_warn_if_dir_nonempty(Unit *u, const char* where) { + } + + int unit_fail_if_noncanonical(Unit *u, const char* where) { +- _cleanup_free_ char *canonical_where; ++ _cleanup_free_ char *canonical_where = NULL; + int r; + + assert(u); diff --git a/SOURCES/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch b/SOURCES/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch new file mode 100644 index 0000000..afba787 --- /dev/null +++ b/SOURCES/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch @@ -0,0 +1,32 @@ +From f025def77efc6bb1473b719e905fa70ed20b08d3 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 8 Sep 2021 15:42:11 +0200 +Subject: [PATCH] sd-event: take ref on event loop object before dispatching + event sources + +Idea is that all public APIs should take reference on objects that get +exposed to user-provided callbacks. We take the reference as a +protection from callbacks dropping it. We used to do this also here in +sd_event_loop(). However, in cleanup portion of f814c871e6 this was +accidentally dropped. + +(cherry picked from commit 9f6ef467818f902fe5369c8e37a39a3901bdcf4f) + +Related: #1970945 +--- + src/libsystemd/sd-event/sd-event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index f78da00c3a..47cf93b3f4 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3838,7 +3838,7 @@ _public_ int sd_event_loop(sd_event *e) { + assert_return(!event_pid_changed(e), -ECHILD); + assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + +- _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = NULL; ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); + + while (e->state != SD_EVENT_FINISHED) { + r = sd_event_run(e, (uint64_t) -1); diff --git a/SOURCES/0663-core-consider-service-with-no-start-command-immediat.patch b/SOURCES/0663-core-consider-service-with-no-start-command-immediat.patch new file mode 100644 index 0000000..c8eda89 --- /dev/null +++ b/SOURCES/0663-core-consider-service-with-no-start-command-immediat.patch @@ -0,0 +1,33 @@ +From c667291303bb876707d86ac3ab9ca62355bae1b3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 22:45:34 +0200 +Subject: [PATCH] core: consider service with no start command immediately + started + +The service would always be in state == SERVICE_INACTIVE, but it needs to go +through state == SERVICE_START so that SuccessAction/FailureAction are executed. + +(cherry picked from commit ef5ae8e71329e43c277e6d4f983f0c0793047b94) + +Related: #1860899 +--- + src/core/service.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/service.c b/src/core/service.c +index ae31973774..4da1c5accb 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2055,6 +2055,12 @@ static void service_enter_start(Service *s) { + goto fail; + } + ++ /* We force a fake state transition here. Otherwise, the unit would go directly from ++ * SERVICE_DEAD to SERVICE_DEAD without SERVICE_ACTIVATING or SERVICE_ACTIVE ++ * inbetween. This way we can later trigger actions that depend on the state ++ * transition, including SuccessAction=. */ ++ service_set_state(s, SERVICE_START); ++ + service_enter_start_post(s); + return; + } diff --git a/SOURCES/0664-man-move-description-of-Action-modes-to-FailureActio.patch b/SOURCES/0664-man-move-description-of-Action-modes-to-FailureActio.patch new file mode 100644 index 0000000..c034442 --- /dev/null +++ b/SOURCES/0664-man-move-description-of-Action-modes-to-FailureActio.patch @@ -0,0 +1,84 @@ +From 12ce6830c63b4a27bb6d5b7729d70a86079b108f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:56:35 +0200 +Subject: [PATCH] man: move description of *Action= modes to + FailureAction=/SuccessAction= + +FailureAction=/SuccessAction= were added later then StartLimitAction=, so it +was easiest to refer to the existing description. But those two settings are +somewhat simpler (they just execute the action unconditionally) while +StartLimitAction= has additional timing and burst parameters, and they are +about to take on a more prominent role, so let's move the description of +allowed values. + +(cherry picked from commit 454dd6ce7adb744584ecae9aa0bd1acf3a00e9ed) + +Related: #1860899 +--- + man/systemd.unit.xml | 44 +++++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 7605c43375..802db453a4 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -873,6 +873,24 @@ + + + ++ ++ FailureAction= ++ SuccessAction= ++ ++ Configure the action to take when the unit stops and enters a failed state or inactive ++ state. Takes one of , , , ++ , , or ++ . If is set, no action will be triggered. ++ causes a reboot following the normal shutdown procedure (i.e. equivalent to ++ systemctl reboot). causes a forced reboot which will ++ terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to ++ systemctl reboot -f) and causes immediate execution of the ++ reboot2 system call, which ++ might result in data loss. Similarly, , , ++ have the effect of powering down the system with similar semantics. Both ++ options default to . ++ ++ + + JobTimeoutSec= + JobRunningTimeoutSec= +@@ -929,29 +947,13 @@ + + StartLimitAction= + +- Configure the action to take if the rate limit configured with +- StartLimitIntervalSec= and StartLimitBurst= is hit. Takes one of +- , , , +- , , or +- . If is set, hitting the rate limit will trigger no +- action besides that the start will not be permitted. causes a reboot following the +- normal shutdown procedure (i.e. equivalent to systemctl reboot). +- causes a forced reboot which will terminate all processes forcibly but should +- cause no dirty file systems on reboot (i.e. equivalent to systemctl reboot -f) and +- causes immediate execution of the +- reboot2 system call, which +- might result in data loss. Similarly, , , +- have the effect of powering down the system with similar +- semantics. Defaults to . ++ Configure an additional action to take if the rate limit configured with ++ StartLimitIntervalSec= and StartLimitBurst= is hit. Takes the same ++ values as the setting FailureAction=/SuccessAction= settings and executes ++ the same actions. If is set, hitting the rate limit will trigger no action besides that ++ the start will not be permitted. Defaults to . + + +- +- FailureAction= +- SuccessAction= +- Configure the action to take when the unit stops and enters a failed state or inactive +- state. Takes the same values as the setting StartLimitAction= setting and executes the same +- actions. Both options default to . +- + + + RebootArgument= diff --git a/SOURCES/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch b/SOURCES/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch new file mode 100644 index 0000000..1c9f492 --- /dev/null +++ b/SOURCES/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch @@ -0,0 +1,361 @@ +From 19d91eef7f15b654cd96ad5350385e535fab9e2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 13:28:39 +0200 +Subject: [PATCH] core: define "exit" and "exit-force" actions for user units + and only accept that + +We would accept e.g. FailureAction=reboot-force in user units and then do an +exit in the user manager. Let's be stricter, and define "exit"/"exit-force" as +the only supported actions in user units. + +v2: +- rename 'exit' to 'exit-force' and add new 'exit' +- add test for the parsing function + +(cherry picked from commit 54fcb6192c618726d11404b24b1a1e9ec3169ee1) + +Related: #1860899 +--- + TODO | 4 +++ + man/systemd.unit.xml | 26 +++++++++------- + src/core/dbus-unit.c | 37 ++++++++++++++++++++++- + src/core/emergency-action.c | 47 ++++++++++++++++++++++------- + src/core/emergency-action.h | 5 ++++ + src/core/load-fragment.c | 42 +++++++++++++++++++++++++- + src/test/meson.build | 5 ++++ + src/test/test-emergency-action.c | 51 ++++++++++++++++++++++++++++++++ + 8 files changed, 195 insertions(+), 22 deletions(-) + create mode 100644 src/test/test-emergency-action.c + +diff --git a/TODO b/TODO +index 3100e067d6..0705b6b08e 100644 +--- a/TODO ++++ b/TODO +@@ -4,6 +4,10 @@ Bugfixes: + + * copy.c: set the right chattrs before copying files and others after + ++* Many manager configuration settings that are only applicable to user ++ manager or system manager can be always set. It would be better to reject ++ them when parsing config. ++ + External: + + * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 802db453a4..5772a6684e 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -877,18 +877,24 @@ + FailureAction= + SuccessAction= + +- Configure the action to take when the unit stops and enters a failed state or inactive +- state. Takes one of , , , +- , , or +- . If is set, no action will be triggered. +- causes a reboot following the normal shutdown procedure (i.e. equivalent to +- systemctl reboot). causes a forced reboot which will +- terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to +- systemctl reboot -f) and causes immediate execution of the ++ Configure the action to take when the unit stops and enters a failed state or inactive state. ++ Takes one of , , , ++ , , , ++ , , and . In system mode, ++ all options except and are allowed. In user mode, only ++ , , and are allowed. Both options default ++ to . ++ ++ If is set, no action will be triggered. causes a reboot ++ following the normal shutdown procedure (i.e. equivalent to systemctl reboot). ++ causes a forced reboot which will terminate all processes forcibly but should ++ cause no dirty file systems on reboot (i.e. equivalent to systemctl reboot -f) and ++ causes immediate execution of the + reboot2 system call, which + might result in data loss. Similarly, , , +- have the effect of powering down the system with similar semantics. Both +- options default to . ++ have the effect of powering down the system with similar ++ semantics. causes the user manager to exit following the normal shutdown procedure, and ++ causes it terminate without shutting down services. + + + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 549a166abc..e7ea9db3ac 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -1564,8 +1564,43 @@ static int bus_unit_set_live_property( + return 0; + } + ++static int bus_set_transient_emergency_action( ++ Unit *u, ++ const char *name, ++ EmergencyAction *p, ++ sd_bus_message *message, ++ UnitWriteFlags flags, ++ sd_bus_error *error) { ++ ++ const char *s; ++ EmergencyAction v; ++ int r; ++ bool system; ++ ++ assert(p); ++ ++ r = sd_bus_message_read(message, "s", &s); ++ if (r < 0) ++ return r; ++ ++ system = MANAGER_IS_SYSTEM(u->manager); ++ r = parse_emergency_action(s, system, &v); ++ if (v < 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ v == -EOPNOTSUPP ? "EmergencyAction setting invalid for manager type: %s" ++ : "Invalid %s setting: %s", ++ name, s); ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ *p = v; ++ unit_write_settingf(u, flags, name, ++ "%s=%s", name, s); ++ } ++ ++ return 1; ++} ++ + static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string); +-static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string); + static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string); + + static int bus_set_transient_conditions( +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 766a3b4d2b..00f5996317 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -39,15 +39,6 @@ int emergency_action( + return -ECANCELED; + } + +- if (!MANAGER_IS_SYSTEM(m)) { +- /* Downgrade all options to simply exiting if we run +- * in user mode */ +- +- log_warning("Exiting: %s", reason); +- m->exit_code = MANAGER_EXIT; +- return -ECANCELED; +- } +- + switch (action) { + + case EMERGENCY_ACTION_REBOOT: +@@ -80,11 +71,26 @@ int emergency_action( + (void) reboot(RB_AUTOBOOT); + break; + ++ case EMERGENCY_ACTION_EXIT: ++ assert(MANAGER_IS_USER(m)); ++ ++ log_and_status(m, "Exiting", reason); ++ ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); ++ break; ++ + case EMERGENCY_ACTION_POWEROFF: + log_and_status(m, "Powering off", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + ++ case EMERGENCY_ACTION_EXIT_FORCE: ++ assert(MANAGER_IS_USER(m)); ++ ++ log_and_status(m, "Exiting immediately", reason); ++ m->exit_code = MANAGER_EXIT; ++ break; ++ + case EMERGENCY_ACTION_POWEROFF_FORCE: + log_and_status(m, "Forcibly powering off", reason); + m->exit_code = MANAGER_POWEROFF; +@@ -113,6 +119,27 @@ static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = { + [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate", + [EMERGENCY_ACTION_POWEROFF] = "poweroff", + [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force", +- [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate" ++ [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate", ++ [EMERGENCY_ACTION_EXIT] = "exit", ++ [EMERGENCY_ACTION_EXIT_FORCE] = "exit-force", + }; + DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction); ++ ++int parse_emergency_action( ++ const char *value, ++ bool system, ++ EmergencyAction *ret) { ++ ++ EmergencyAction x; ++ ++ x = emergency_action_from_string(value); ++ if (x < 0) ++ return -EINVAL; ++ ++ if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) || ++ (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)) ++ return -EOPNOTSUPP; ++ ++ *ret = x; ++ return 0; ++} +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index 61791f176f..646ccc4e6b 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -13,6 +13,9 @@ typedef enum EmergencyAction { + EMERGENCY_ACTION_POWEROFF, + EMERGENCY_ACTION_POWEROFF_FORCE, + EMERGENCY_ACTION_POWEROFF_IMMEDIATE, ++ EMERGENCY_ACTION_EXIT, ++ _EMERGENCY_ACTION_FIRST_USER_ACTION = EMERGENCY_ACTION_EXIT, ++ EMERGENCY_ACTION_EXIT_FORCE, + _EMERGENCY_ACTION_MAX, + _EMERGENCY_ACTION_INVALID = -1 + } EmergencyAction; +@@ -24,3 +27,5 @@ int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg, + + const char* emergency_action_to_string(EmergencyAction i) _const_; + EmergencyAction emergency_action_from_string(const char *s) _pure_; ++ ++int parse_emergency_action(const char *value, bool system, EmergencyAction *ret); +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index e0d7b8f7f8..c102ffb9f0 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -77,7 +77,6 @@ DEFINE_CONFIG_PARSE(config_parse_socket_protocol, supported_socket_protocol_from + DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string, "Failed to parse secure bits"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); +-DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); +@@ -4253,6 +4252,47 @@ int config_parse_job_running_timeout_sec( + return 0; + } + ++int config_parse_emergency_action( ++ 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) { ++ ++ Manager *m = NULL; ++ EmergencyAction *x = data; ++ int r; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ assert(data); ++ ++ if (unit) ++ m = ((Unit*) userdata)->manager; ++ else ++ m = data; ++ ++ r = parse_emergency_action(rvalue, MANAGER_IS_SYSTEM(m), x); ++ if (r < 0) { ++ if (r == -EOPNOTSUPP) ++ log_syntax(unit, LOG_ERR, filename, line, r, ++ "%s= specified as %s mode action, ignoring: %s", ++ lvalue, MANAGER_IS_SYSTEM(m) ? "user" : "system", rvalue); ++ else ++ log_syntax(unit, LOG_ERR, filename, line, r, ++ "Failed to parse %s=, ignoring: %s", lvalue, rvalue); ++ return 0; ++ } ++ ++ return 0; ++} ++ + #define FOLLOW_MAX 8 + + static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { +diff --git a/src/test/meson.build b/src/test/meson.build +index 7b310d4ec7..40cf56d73d 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -65,6 +65,11 @@ tests += [ + libshared], + []], + ++ [['src/test/test-emergency-action.c'], ++ [libcore, ++ libshared], ++ []], ++ + [['src/test/test-job-type.c'], + [libcore, + libshared], +diff --git a/src/test/test-emergency-action.c b/src/test/test-emergency-action.c +new file mode 100644 +index 0000000000..493b23227e +--- /dev/null ++++ b/src/test/test-emergency-action.c +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "emergency-action.h" ++#include "tests.h" ++ ++static void test_parse_emergency_action(void) { ++ EmergencyAction x; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(parse_emergency_action("none", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("reboot", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("reboot-force", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("reboot-immediate", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff-force", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff-immediate", false, &x) == -EOPNOTSUPP); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("exit", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_EXIT); ++ assert_se(parse_emergency_action("exit-force", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_EXIT_FORCE); ++ assert_se(parse_emergency_action("exit-forcee", false, &x) == -EINVAL); ++ ++ assert_se(parse_emergency_action("none", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("reboot", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT); ++ assert_se(parse_emergency_action("reboot-force", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT_FORCE); ++ assert_se(parse_emergency_action("reboot-immediate", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT_IMMEDIATE); ++ assert_se(parse_emergency_action("poweroff", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF); ++ assert_se(parse_emergency_action("poweroff-force", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE); ++ assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0); ++ assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE); ++} ++ ++int main(int argc, char **argv) { ++ test_setup_logging(LOG_INFO); ++ ++ test_parse_emergency_action(); ++ ++ return EXIT_SUCCESS; ++} diff --git a/SOURCES/0666-core-accept-system-mode-emergency-action-specifiers-.patch b/SOURCES/0666-core-accept-system-mode-emergency-action-specifiers-.patch new file mode 100644 index 0000000..b6753ab --- /dev/null +++ b/SOURCES/0666-core-accept-system-mode-emergency-action-specifiers-.patch @@ -0,0 +1,40 @@ +From 9dbb6564826a0def39a77ad292aecde75537d164 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 14:49:36 +0200 +Subject: [PATCH] core: accept system mode emergency action specifiers with a + warning + +Before we would only accept those "system" values, so there wasn't other +chocie. Let's provide backwards compatiblity in case somebody made use of +this functionality in user mode. + +v2: use 'exit-force' not 'exit' +v3: use error value in log_syntax +(cherry picked from commit 469f76f170db39c72578e869ec7c087bb43f9350) + +Related: #1860899 +--- + src/core/load-fragment.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index c102ffb9f0..c0b1fd4f91 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -4280,6 +4280,16 @@ int config_parse_emergency_action( + + r = parse_emergency_action(rvalue, MANAGER_IS_SYSTEM(m), x); + if (r < 0) { ++ if (r == -EOPNOTSUPP && MANAGER_IS_USER(m)) { ++ /* Compat mode: remove for systemd 241. */ ++ ++ log_syntax(unit, LOG_INFO, filename, line, r, ++ "%s= in user mode specified as \"%s\", using \"exit-force\" instead.", ++ lvalue, rvalue); ++ *x = EMERGENCY_ACTION_EXIT_FORCE; ++ return 0; ++ } ++ + if (r == -EOPNOTSUPP) + log_syntax(unit, LOG_ERR, filename, line, r, + "%s= specified as %s mode action, ignoring: %s", diff --git a/SOURCES/0667-core-allow-services-with-no-commands-but-SuccessActi.patch b/SOURCES/0667-core-allow-services-with-no-commands-but-SuccessActi.patch new file mode 100644 index 0000000..8c081eb --- /dev/null +++ b/SOURCES/0667-core-allow-services-with-no-commands-but-SuccessActi.patch @@ -0,0 +1,43 @@ +From f97c6d921fb6b3d7ba88e064b03d3dd767df9ba1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:07:42 +0200 +Subject: [PATCH] core: allow services with no commands but SuccessAction set + +(cherry picked from commit 3f00d379fa6221a4570c8cd955afd9b661787db9) + +Related: #1860899 +--- + src/core/service.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 4da1c5accb..7969bbf071 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -556,8 +556,13 @@ static int service_verify(Service *s) { + } + } + +- if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { +- log_unit_error(UNIT(s), "Service lacks both ExecStart= and ExecStop= setting. Refusing."); ++ if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] ++ && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { ++ /* FailureAction= only makes sense if one of the start or stop commands is specified. ++ * SuccessAction= will be executed unconditionally if no commands are specified. Hence, ++ * either a command or SuccessAction= are required. */ ++ ++ log_unit_error(UNIT(s), "Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing."); + return -ENOEXEC; + } + +@@ -566,8 +571,8 @@ static int service_verify(Service *s) { + return -ENOEXEC; + } + +- if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START]) { +- log_unit_error(UNIT(s), "Service has no ExecStart= setting, which is only allowed for RemainAfterExit=yes services. Refusing."); ++ if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START] && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { ++ log_unit_error(UNIT(s), "Service has no ExecStart= and no SuccessAction= settings and does not have RemainAfterExit=yes set. Refusing."); + return -ENOEXEC; + } + diff --git a/SOURCES/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch b/SOURCES/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch new file mode 100644 index 0000000..a32dcd7 --- /dev/null +++ b/SOURCES/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch @@ -0,0 +1,120 @@ +From b8358d4edf1896a821c9370c9ba31c2bb07c277a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:24:44 +0200 +Subject: [PATCH] core: limit service-watchdogs=no to actual "watchdog" + commands + +The setting is now only looked at when considering an action for a job timeout +or unit start limit. It is ignored for ctrl-alt-del, SuccessAction, SuccessFailure. + +v2: turn the parameter into a flag field +v3: rename Options to Flags +(cherry picked from commit 1710d4beff6329cf6ae0767953cad09593517b2a) + +Related: #1860899 +--- + src/core/emergency-action.c | 3 ++- + src/core/emergency-action.h | 8 +++++++- + src/core/job.c | 3 ++- + src/core/manager.c | 2 +- + src/core/unit.c | 9 ++++++--- + 5 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 00f5996317..e9e757dfa3 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -24,6 +24,7 @@ static void log_and_status(Manager *m, const char *message, const char *reason) + int emergency_action( + Manager *m, + EmergencyAction action, ++ EmergencyActionFlags options, + const char *reboot_arg, + const char *reason) { + +@@ -34,7 +35,7 @@ int emergency_action( + if (action == EMERGENCY_ACTION_NONE) + return -ECANCELED; + +- if (!m->service_watchdogs) { ++ if (FLAGS_SET(options, EMERGENCY_ACTION_IS_WATCHDOG) && !m->service_watchdogs) { + log_warning("Watchdog disabled! Not acting on: %s", reason); + return -ECANCELED; + } +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index 646ccc4e6b..efbfaf6c6a 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -20,10 +20,16 @@ typedef enum EmergencyAction { + _EMERGENCY_ACTION_INVALID = -1 + } EmergencyAction; + ++typedef enum EmergencyActionFlags { ++ EMERGENCY_ACTION_IS_WATCHDOG = 1 << 0, ++} EmergencyActionFlags; ++ + #include "macro.h" + #include "manager.h" + +-int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg, const char *reason); ++int emergency_action(Manager *m, ++ EmergencyAction action, EmergencyActionFlags options, ++ const char *reboot_arg, const char *reason); + + const char* emergency_action_to_string(EmergencyAction i) _const_; + EmergencyAction emergency_action_from_string(const char *s) _pure_; +diff --git a/src/core/job.c b/src/core/job.c +index 870ec0a387..d647aac42d 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1076,7 +1076,8 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user + u = j->unit; + job_finish_and_invalidate(j, JOB_TIMEOUT, true, false); + +- emergency_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg, "job timed out"); ++ emergency_action(u->manager, u->job_timeout_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ u->job_timeout_reboot_arg, "job timed out"); + + return 0; + } +diff --git a/src/core/manager.c b/src/core/manager.c +index 3c44ad3dbc..ac1b198b21 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2528,7 +2528,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) { + if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE) + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); + else +- emergency_action(m, m->cad_burst_action, NULL, ++ emergency_action(m, m->cad_burst_action, 0, NULL, + "Ctrl-Alt-Del was pressed more than 7 times within 2s"); + } + +diff --git a/src/core/unit.c b/src/core/unit.c +index 152a860d08..dc5c89c195 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1669,7 +1669,8 @@ int unit_start_limit_test(Unit *u) { + log_unit_warning(u, "Start request repeated too quickly."); + u->start_limit_hit = true; + +- return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed"); ++ return emergency_action(u->manager, u->start_limit_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ u->reboot_arg, "unit failed"); + } + + bool unit_shall_confirm_spawn(Unit *u) { +@@ -2469,9 +2470,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + unit_check_binds_to(u); + + if (os != UNIT_FAILED && ns == UNIT_FAILED) +- (void) emergency_action(u->manager, u->failure_action, u->reboot_arg, "unit failed"); ++ (void) emergency_action(u->manager, u->failure_action, 0, ++ u->reboot_arg, "unit failed"); + else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && ns == UNIT_INACTIVE) +- (void) emergency_action(u->manager, u->success_action, u->reboot_arg, "unit succeeded"); ++ (void) emergency_action(u->manager, u->success_action, 0, ++ u->reboot_arg, "unit succeeded"); + } + + unit_add_to_dbus_queue(u); diff --git a/SOURCES/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch b/SOURCES/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch new file mode 100644 index 0000000..564997e --- /dev/null +++ b/SOURCES/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch @@ -0,0 +1,56 @@ +From b0394ad25fd601b9ef29d26b87f12b0a0c17cda0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:09:11 +0200 +Subject: [PATCH] units: use SuccessAction=exit-force in systemd-exit.service + +Fixes #10414. + +v2: +- rename .service.in to .service +- rename 'exit' to 'exit-force' + +(cherry picked from commit 631c9b7bf2dab5065d753a7b1cfaff5b100b3c90) + +Resolves: #1860899 +--- + units/user/meson.build | 2 +- + units/user/{systemd-exit.service.in => systemd-exit.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/user/{systemd-exit.service.in => systemd-exit.service} (87%) + +diff --git a/units/user/meson.build b/units/user/meson.build +index b1c2e95597..36341a42f5 100644 +--- a/units/user/meson.build ++++ b/units/user/meson.build +@@ -14,6 +14,7 @@ units = [ + 'sockets.target', + 'sound.target', + 'timers.target', ++ 'systemd-exit.service', + 'systemd-tmpfiles-clean.timer', + ] + +@@ -23,7 +24,6 @@ foreach file : units + endforeach + + in_units = [ +- 'systemd-exit.service', + 'systemd-tmpfiles-clean.service', + 'systemd-tmpfiles-setup.service', + ] +diff --git a/units/user/systemd-exit.service.in b/units/user/systemd-exit.service +similarity index 87% +rename from units/user/systemd-exit.service.in +rename to units/user/systemd-exit.service +index d69273f6b3..1d3b61e3ab 100644 +--- a/units/user/systemd-exit.service.in ++++ b/units/user/systemd-exit.service +@@ -13,7 +13,4 @@ Documentation=man:systemd.special(7) + DefaultDependencies=no + Requires=shutdown.target + After=shutdown.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --user --force exit ++SuccessAction=exit-force diff --git a/SOURCES/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch b/SOURCES/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch new file mode 100644 index 0000000..2b5e428 --- /dev/null +++ b/SOURCES/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch @@ -0,0 +1,51 @@ +From f531c34dd8ead33b9972bcd06017ac80ccedb757 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:30:53 +0200 +Subject: [PATCH] units: use SuccessAction=reboot-force in + systemd-reboot.service + +(cherry picked from commit d85515edcf9700dc068201ab9f7103f04f3b25b2) + +Related: #1860899 +--- + units/meson.build | 2 +- + units/{systemd-reboot.service.in => systemd-reboot.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/{systemd-reboot.service.in => systemd-reboot.service} (89%) + +diff --git a/units/meson.build b/units/meson.build +index a1cd2524dc..b482431a10 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -97,6 +97,7 @@ units = [ + 'sockets.target.wants/'], + ['systemd-networkd.socket', 'ENABLE_NETWORKD', + join_paths(pkgsysconfdir, 'system/sockets.target.wants/')], ++ ['systemd-reboot.service', ''], + ['systemd-rfkill.socket', 'ENABLE_RFKILL'], + ['systemd-tmpfiles-clean.timer', '', + 'timers.target.wants/'], +@@ -182,7 +183,6 @@ in_units = [ + ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'], + ['systemd-random-seed.service', 'ENABLE_RANDOMSEED', + 'sysinit.target.wants/'], +- ['systemd-reboot.service', ''], + ['systemd-remount-fs.service', '', + 'local-fs.target.wants/'], + ['systemd-resolved.service', 'ENABLE_RESOLVE', +diff --git a/units/systemd-reboot.service.in b/units/systemd-reboot.service +similarity index 89% +rename from units/systemd-reboot.service.in +rename to units/systemd-reboot.service +index 4763ccfdca..505f60aabf 100644 +--- a/units/systemd-reboot.service.in ++++ b/units/systemd-reboot.service +@@ -13,7 +13,4 @@ Documentation=man:systemd-halt.service(8) + DefaultDependencies=no + Requires=shutdown.target umount.target final.target + After=shutdown.target umount.target final.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force reboot ++SuccessAction=reboot-force diff --git a/SOURCES/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch b/SOURCES/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch new file mode 100644 index 0000000..93be5d6 --- /dev/null +++ b/SOURCES/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch @@ -0,0 +1,56 @@ +From 7e84234d9953f7ffacf7fff82679c9c9c3b78b7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:34:57 +0200 +Subject: [PATCH] units: use SuccessAction=poweroff-force in + systemd-poweroff.service + +Explicit systemctl calls remain in systemd-halt.service and the system +systemd-exit.service. To convert systemd-halt, we'd need to add +SuccessAction=halt-force. Halting doesn't make much sense, so let's just +leave that is. systemd-exit.service will be converted in the next commit. + +(cherry picked from commit afa6206583dfbc93e29981cb5d713841e4ca2865) + +Related: #1860899 +--- + units/meson.build | 2 +- + ...{systemd-poweroff.service.in => systemd-poweroff.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/{systemd-poweroff.service.in => systemd-poweroff.service} (89%) + +diff --git a/units/meson.build b/units/meson.build +index b482431a10..6fa804148b 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -97,6 +97,7 @@ units = [ + 'sockets.target.wants/'], + ['systemd-networkd.socket', 'ENABLE_NETWORKD', + join_paths(pkgsysconfdir, 'system/sockets.target.wants/')], ++ ['systemd-poweroff.service', ''], + ['systemd-reboot.service', ''], + ['systemd-rfkill.socket', 'ENABLE_RFKILL'], + ['systemd-tmpfiles-clean.timer', '', +@@ -179,7 +180,6 @@ in_units = [ + ['systemd-nspawn@.service', ''], + ['systemd-portabled.service', 'ENABLE_PORTABLED', + 'dbus-org.freedesktop.portable1.service'], +- ['systemd-poweroff.service', ''], + ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'], + ['systemd-random-seed.service', 'ENABLE_RANDOMSEED', + 'sysinit.target.wants/'], +diff --git a/units/systemd-poweroff.service.in b/units/systemd-poweroff.service +similarity index 89% +rename from units/systemd-poweroff.service.in +rename to units/systemd-poweroff.service +index e9fd655508..8d1d54389b 100644 +--- a/units/systemd-poweroff.service.in ++++ b/units/systemd-poweroff.service +@@ -13,7 +13,4 @@ Documentation=man:systemd-halt.service(8) + DefaultDependencies=no + Requires=shutdown.target umount.target final.target + After=shutdown.target umount.target final.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force poweroff ++SuccessAction=poweroff-force diff --git a/SOURCES/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch b/SOURCES/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch new file mode 100644 index 0000000..f578802 --- /dev/null +++ b/SOURCES/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch @@ -0,0 +1,164 @@ +From c0aa64901aa4d5d7c917fccf0993819fb1a1262f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 16:34:45 +0200 +Subject: [PATCH] units: allow and use SuccessAction=exit-force in system + systemd-exit.service + +C.f. 287419c119ef961db487a281162ab037eba70c61: 'systemctl exit 42' can be +used to set an exit value and pulls in exit.target, which pulls in systemd-exit.service, +which calls org.fdo.Manager.Exit, which calls method_exit(), which sets the objective +to MANAGER_EXIT. Allow the same to happen through SuccessAction=exit. + +v2: update for 'exit' and 'exit-force' +(cherry picked from commit a400bd8c2a6285576edf8e2147e1d17aab129501) + +Related: #1860899 +--- + man/systemd.unit.xml | 7 +++-- + src/core/emergency-action.c | 27 +++++++++++-------- + src/test/test-emergency-action.c | 6 ++--- + units/meson.build | 2 +- + ...d-exit.service.in => systemd-exit.service} | 5 +--- + 5 files changed, 24 insertions(+), 23 deletions(-) + rename units/{systemd-exit.service.in => systemd-exit.service} (88%) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 5772a6684e..e80c760dd6 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -881,9 +881,8 @@ + Takes one of , , , + , , , + , , and . In system mode, +- all options except and are allowed. In user mode, only +- , , and are allowed. Both options default +- to . ++ all options are allowed. In user mode, only , , and ++ are allowed. Both options default to . + + If is set, no action will be triggered. causes a reboot + following the normal shutdown procedure (i.e. equivalent to systemctl reboot). +@@ -893,7 +892,7 @@ + reboot2 system call, which + might result in data loss. Similarly, , , + have the effect of powering down the system with similar +- semantics. causes the user manager to exit following the normal shutdown procedure, and ++ semantics. causes the manager to exit following the normal shutdown procedure, and + causes it terminate without shutting down services. + + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index e9e757dfa3..44b92ae6f8 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -13,6 +13,7 @@ + #include "special.h" + #include "string-table.h" + #include "terminal-util.h" ++#include "virt.h" + + static void log_and_status(Manager *m, const char *message, const char *reason) { + log_warning("%s: %s", message, reason); +@@ -73,12 +74,14 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_EXIT: +- assert(MANAGER_IS_USER(m)); +- +- log_and_status(m, "Exiting", reason); ++ if (MANAGER_IS_USER(m) || detect_container() > 0) { ++ log_and_status(m, "Exiting", reason); ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); ++ break; ++ } + +- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); +- break; ++ log_notice("Doing \"poweroff\" action instead of an \"exit\" emergency action."); ++ _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF: + log_and_status(m, "Powering off", reason); +@@ -86,11 +89,14 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_EXIT_FORCE: +- assert(MANAGER_IS_USER(m)); ++ if (MANAGER_IS_USER(m) || detect_container() > 0) { ++ log_and_status(m, "Exiting immediately", reason); ++ m->exit_code = MANAGER_EXIT; ++ break; ++ } + +- log_and_status(m, "Exiting immediately", reason); +- m->exit_code = MANAGER_EXIT; +- break; ++ log_notice("Doing \"poweroff-force\" action instead of an \"exit-force\" emergency action."); ++ _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF_FORCE: + log_and_status(m, "Forcibly powering off", reason); +@@ -137,8 +143,7 @@ int parse_emergency_action( + if (x < 0) + return -EINVAL; + +- if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) || +- (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)) ++ if (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION) + return -EOPNOTSUPP; + + *ret = x; +diff --git a/src/test/test-emergency-action.c b/src/test/test-emergency-action.c +index 493b23227e..8ce28ed9f5 100644 +--- a/src/test/test-emergency-action.c ++++ b/src/test/test-emergency-action.c +@@ -36,10 +36,10 @@ static void test_parse_emergency_action(void) { + assert_se(parse_emergency_action("poweroff-force", true, &x) == 0); + assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE); + assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0); +- assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP); +- assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit", true, &x) == 0); ++ assert_se(parse_emergency_action("exit-force", true, &x) == 0); + assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL); +- assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE); ++ assert_se(x == EMERGENCY_ACTION_EXIT_FORCE); + } + + int main(int argc, char **argv) { +diff --git a/units/meson.build b/units/meson.build +index 6fa804148b..a74fa95195 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -86,6 +86,7 @@ units = [ + 'multi-user.target.wants/'], + ['systemd-coredump.socket', 'ENABLE_COREDUMP', + 'sockets.target.wants/'], ++ ['systemd-exit.service', ''], + ['systemd-initctl.socket', '', + 'sockets.target.wants/'], + ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], +@@ -135,7 +136,6 @@ in_units = [ + ['systemd-binfmt.service', 'ENABLE_BINFMT', + 'sysinit.target.wants/'], + ['systemd-coredump@.service', 'ENABLE_COREDUMP'], +- ['systemd-exit.service', ''], + ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT', + 'sysinit.target.wants/'], + ['systemd-fsck-root.service', ''], +diff --git a/units/systemd-exit.service.in b/units/systemd-exit.service +similarity index 88% +rename from units/systemd-exit.service.in +rename to units/systemd-exit.service +index 2fb6ebd767..6029b13a05 100644 +--- a/units/systemd-exit.service.in ++++ b/units/systemd-exit.service +@@ -13,7 +13,4 @@ Documentation=man:systemd.special(7) + DefaultDependencies=no + Requires=shutdown.target + After=shutdown.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force exit ++SuccessAction=exit diff --git a/SOURCES/0673-core-do-not-warn-about-mundane-emergency-actions.patch b/SOURCES/0673-core-do-not-warn-about-mundane-emergency-actions.patch new file mode 100644 index 0000000..c00324c --- /dev/null +++ b/SOURCES/0673-core-do-not-warn-about-mundane-emergency-actions.patch @@ -0,0 +1,174 @@ +From c8e9877d14c8742cc3732d305af2422f8a16f47d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 17 Oct 2018 17:27:20 +0200 +Subject: [PATCH] core: do not "warn" about mundane emergency actions + +For example in a container we'd log: +Oct 17 17:01:10 rawhide systemd[1]: Started Power-Off. +Oct 17 17:01:10 rawhide systemd[1]: Forcibly powering off: unit succeeded +Oct 17 17:01:10 rawhide systemd[1]: Reached target Power-Off. +Oct 17 17:01:10 rawhide systemd[1]: Shutting down. +and on the console we'd write (in red) +[ !! ] Forcibly powering off: unit succeeded + +This is not useful in any way, and the fact that we're calling an "emergency action" +is an internal implementation detail. Let's log about c-a-d and the watchdog actions +only. + +(cherry picked from commit c7adcb1af9946d0672c16bb4bb7eedf39b3d1fcb) + +Related: #1860899 +--- + src/core/emergency-action.c | 29 ++++++++++++++++------------- + src/core/emergency-action.h | 1 + + src/core/job.c | 3 ++- + src/core/manager.c | 2 +- + src/core/unit.c | 3 ++- + 5 files changed, 22 insertions(+), 16 deletions(-) + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 44b92ae6f8..fea1cb83db 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -15,11 +15,12 @@ + #include "terminal-util.h" + #include "virt.h" + +-static void log_and_status(Manager *m, const char *message, const char *reason) { +- log_warning("%s: %s", message, reason); +- manager_status_printf(m, STATUS_TYPE_EMERGENCY, +- ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL, +- "%s: %s", message, reason); ++static void log_and_status(Manager *m, bool warn, const char *message, const char *reason) { ++ log_full(warn ? LOG_WARNING : LOG_DEBUG, "%s: %s", message, reason); ++ if (warn) ++ manager_status_printf(m, STATUS_TYPE_EMERGENCY, ++ ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL, ++ "%s: %s", message, reason); + } + + int emergency_action( +@@ -41,17 +42,19 @@ int emergency_action( + return -ECANCELED; + } + ++ bool warn = FLAGS_SET(options, EMERGENCY_ACTION_WARN); ++ + switch (action) { + + case EMERGENCY_ACTION_REBOOT: +- log_and_status(m, "Rebooting", reason); ++ log_and_status(m, warn, "Rebooting", reason); + + (void) update_reboot_parameter_and_warn(reboot_arg); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_REBOOT_FORCE: +- log_and_status(m, "Forcibly rebooting", reason); ++ log_and_status(m, warn, "Forcibly rebooting", reason); + + (void) update_reboot_parameter_and_warn(reboot_arg); + m->exit_code = MANAGER_REBOOT; +@@ -59,7 +62,7 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_REBOOT_IMMEDIATE: +- log_and_status(m, "Rebooting immediately", reason); ++ log_and_status(m, warn, "Rebooting immediately", reason); + + sync(); + +@@ -75,7 +78,7 @@ int emergency_action( + + case EMERGENCY_ACTION_EXIT: + if (MANAGER_IS_USER(m) || detect_container() > 0) { +- log_and_status(m, "Exiting", reason); ++ log_and_status(m, warn, "Exiting", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + } +@@ -84,13 +87,13 @@ int emergency_action( + _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF: +- log_and_status(m, "Powering off", reason); ++ log_and_status(m, warn, "Powering off", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_EXIT_FORCE: + if (MANAGER_IS_USER(m) || detect_container() > 0) { +- log_and_status(m, "Exiting immediately", reason); ++ log_and_status(m, warn, "Exiting immediately", reason); + m->exit_code = MANAGER_EXIT; + break; + } +@@ -99,12 +102,12 @@ int emergency_action( + _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF_FORCE: +- log_and_status(m, "Forcibly powering off", reason); ++ log_and_status(m, warn, "Forcibly powering off", reason); + m->exit_code = MANAGER_POWEROFF; + break; + + case EMERGENCY_ACTION_POWEROFF_IMMEDIATE: +- log_and_status(m, "Powering off immediately", reason); ++ log_and_status(m, warn, "Powering off immediately", reason); + + sync(); + +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index efbfaf6c6a..2aa1497118 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -22,6 +22,7 @@ typedef enum EmergencyAction { + + typedef enum EmergencyActionFlags { + EMERGENCY_ACTION_IS_WATCHDOG = 1 << 0, ++ EMERGENCY_ACTION_WARN = 1 << 1, + } EmergencyActionFlags; + + #include "macro.h" +diff --git a/src/core/job.c b/src/core/job.c +index d647aac42d..43ab55ed18 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1076,7 +1076,8 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user + u = j->unit; + job_finish_and_invalidate(j, JOB_TIMEOUT, true, false); + +- emergency_action(u->manager, u->job_timeout_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ emergency_action(u->manager, u->job_timeout_action, ++ EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN, + u->job_timeout_reboot_arg, "job timed out"); + + return 0; +diff --git a/src/core/manager.c b/src/core/manager.c +index ac1b198b21..ee976f70b3 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2528,7 +2528,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) { + if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE) + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); + else +- emergency_action(m, m->cad_burst_action, 0, NULL, ++ emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, + "Ctrl-Alt-Del was pressed more than 7 times within 2s"); + } + +diff --git a/src/core/unit.c b/src/core/unit.c +index dc5c89c195..23afa24c77 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1669,7 +1669,8 @@ int unit_start_limit_test(Unit *u) { + log_unit_warning(u, "Start request repeated too quickly."); + u->start_limit_hit = true; + +- return emergency_action(u->manager, u->start_limit_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ return emergency_action(u->manager, u->start_limit_action, ++ EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN, + u->reboot_arg, "unit failed"); + } + diff --git a/SOURCES/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch b/SOURCES/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch new file mode 100644 index 0000000..09c3064 --- /dev/null +++ b/SOURCES/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch @@ -0,0 +1,43 @@ +From 2aaa40e698f66fd10d0a7a71ca39637e24809e97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 17 Oct 2018 17:48:35 +0200 +Subject: [PATCH] core: return true from cg_is_empty* on ENOENT + +(cherry picked from commit 1bcf3fc6c57d92927b96cad8c739099b4ceae236) + +Related: #1860899 +--- + src/basic/cgroup-util.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 992b12811a..14abe6e014 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -1177,7 +1177,7 @@ int cg_is_empty(const char *controller, const char *path) { + + r = cg_enumerate_processes(controller, path, &f); + if (r == -ENOENT) +- return 1; ++ return true; + if (r < 0) + return r; + +@@ -1207,6 +1207,8 @@ int cg_is_empty_recursive(const char *controller, const char *path) { + * via the "populated" attribute of "cgroup.events". */ + + r = cg_read_event(controller, path, "populated", &t); ++ if (r == -ENOENT) ++ return true; + if (r < 0) + return r; + +@@ -1221,7 +1223,7 @@ int cg_is_empty_recursive(const char *controller, const char *path) { + + r = cg_enumerate_subgroups(controller, path, &d); + if (r == -ENOENT) +- return 1; ++ return true; + if (r < 0) + return r; + diff --git a/SOURCES/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch b/SOURCES/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch new file mode 100644 index 0000000..53b5016 --- /dev/null +++ b/SOURCES/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch @@ -0,0 +1,29 @@ +From 01da36fadd365329cfd9e2c97eb419c63404b25f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 3 Dec 2018 17:30:19 +0100 +Subject: [PATCH] macro: define HAS_FEATURE_ADDRESS_SANITIZER also on gcc + +Let's make differences between compilers more minimal. + +(cherry picked from commit be5f77b26e22a806179c7b03e03d424682ed325c) + +Related: #2017033 +--- + src/basic/macro.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 62f2359633..e87026882f 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -56,7 +56,9 @@ + #endif + + #if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +-# if defined(__has_feature) ++# ifdef __SANITIZE_ADDRESS__ ++# define HAS_FEATURE_ADDRESS_SANITIZER 1 ++# elif defined(__has_feature) + # if __has_feature(address_sanitizer) + # define HAS_FEATURE_ADDRESS_SANITIZER 1 + # endif diff --git a/SOURCES/0676-tests-add-helper-function-to-autodetect-CI-environme.patch b/SOURCES/0676-tests-add-helper-function-to-autodetect-CI-environme.patch new file mode 100644 index 0000000..3d0cab9 --- /dev/null +++ b/SOURCES/0676-tests-add-helper-function-to-autodetect-CI-environme.patch @@ -0,0 +1,104 @@ +From 6fbbf368f5a6d181b21f448255d5a4182dc2ab3a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:00:21 +0100 +Subject: [PATCH] tests: add helper function to autodetect CI environments + +Sadly there is no standarized way to check if we're running in some +CI environment. So let's try to gather the heuristics in one helper +function. + +Loosely cherry-picked from 4eb0c875f8825199a829ddc597874915fbee0a84. + +Related: #2017033 +--- + src/basic/string-util.h | 6 ++++++ + src/shared/tests.c | 42 +++++++++++++++++++++++++++++++++++++++++ + src/shared/tests.h | 3 +++ + 3 files changed, 51 insertions(+) + +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index 96a9260f93..742b566932 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -32,6 +32,12 @@ static inline bool streq_ptr(const char *a, const char *b) { + return strcmp_ptr(a, b) == 0; + } + ++static inline char* strstr_ptr(const char *haystack, const char *needle) { ++ if (!haystack || !needle) ++ return NULL; ++ return strstr(haystack, needle); ++} ++ + static inline const char* strempty(const char *s) { + return s ?: ""; + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 100b62b9b0..1da80d653f 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -7,7 +7,9 @@ + #include + + #include "tests.h" ++#include "env-util.h" + #include "path-util.h" ++#include "strv.h" + + char* setup_fake_runtime_dir(void) { + char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p; +@@ -75,3 +77,43 @@ void test_setup_logging(int level) { + log_parse_environment(); + log_open(); + } ++ ++const char *ci_environment(void) { ++ /* We return a string because we might want to provide multiple bits of information later on: not ++ * just the general CI environment type, but also whether we're sanitizing or not, etc. The caller is ++ * expected to use strstr on the returned value. */ ++ static const char *ans = (void*) UINTPTR_MAX; ++ const char *p; ++ int r; ++ ++ if (ans != (void*) UINTPTR_MAX) ++ return ans; ++ ++ /* We allow specifying the environment with $CITYPE. Nobody uses this so far, but we are ready. */ ++ p = getenv("CITYPE"); ++ if (!isempty(p)) ++ return (ans = p); ++ ++ if (getenv_bool("TRAVIS") > 0) ++ return (ans = "travis"); ++ if (getenv_bool("SEMAPHORE") > 0) ++ return (ans = "semaphore"); ++ if (getenv_bool("GITHUB_ACTIONS") > 0) ++ return (ans = "github-actions"); ++ if (getenv("AUTOPKGTEST_ARTIFACTS") || getenv("AUTOPKGTEST_TMP")) ++ return (ans = "autopkgtest"); ++ ++ FOREACH_STRING(p, "CI", "CONTINOUS_INTEGRATION") { ++ /* Those vars are booleans according to Semaphore and Travis docs: ++ * https://docs.travis-ci.com/user/environment-variables/#default-environment-variables ++ * https://docs.semaphoreci.com/ci-cd-environment/environment-variables/#ci ++ */ ++ r = getenv_bool(p); ++ if (r > 0) ++ return (ans = "unknown"); /* Some other unknown thing */ ++ if (r == 0) ++ return (ans = NULL); ++ } ++ ++ return (ans = NULL); ++} +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 3d696d02fd..4f8f349097 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -5,3 +5,6 @@ char* setup_fake_runtime_dir(void); + bool test_is_running_from_builddir(char **exedir); + const char* get_testdata_dir(void); + void test_setup_logging(int level); ++ ++/* Provide a convenient way to check if we're running in CI. */ ++const char *ci_environment(void); diff --git a/SOURCES/0677-strv-rework-FOREACH_STRING-macro.patch b/SOURCES/0677-strv-rework-FOREACH_STRING-macro.patch new file mode 100644 index 0000000..6ebdf7d --- /dev/null +++ b/SOURCES/0677-strv-rework-FOREACH_STRING-macro.patch @@ -0,0 +1,48 @@ +From 3539a72c260063713e4ecba17966ba9a768d8af9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 16 Jan 2019 00:13:38 +0100 +Subject: [PATCH] strv: rework FOREACH_STRING() macro + +So it's apparently problematic that we use STRV_MAKE() (i.e. a compound +initializer) outside of the {} block we use it in (and that includes +outside of the ({}) block, too). Hence, let's rework the macro to not +need that. + +This also makes the macro shorter, which is definitely a good and more +readable. Moreover, it will now complain if the iterator is a "char*" +instead of a "const char*", which is good too. + +Fixes: #11394 +(cherry picked from commit 66a64081f82dfad90f2f9394a477820a2e3e6510) + +Related: #2017033 +--- + src/basic/strv.h | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index c1e4c973b6..a09d76706d 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -148,17 +148,10 @@ void strv_print(char **l); + _found; \ + }) + +-#define FOREACH_STRING(x, ...) \ +- for (char **_l = ({ \ +- char **_ll = STRV_MAKE(__VA_ARGS__); \ +- x = _ll ? _ll[0] : NULL; \ +- _ll; \ +- }); \ +- _l && *_l; \ +- x = ({ \ +- _l ++; \ +- _l[0]; \ +- })) ++#define FOREACH_STRING(x, y, ...) \ ++ for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \ ++ x; \ ++ x = *(++_l)) + + char **strv_reverse(char **l); + char **strv_shell_escape(char **l, const char *bad); diff --git a/SOURCES/0678-test-systemctl-use-const-char-instead-of-char.patch b/SOURCES/0678-test-systemctl-use-const-char-instead-of-char.patch new file mode 100644 index 0000000..866d5bb --- /dev/null +++ b/SOURCES/0678-test-systemctl-use-const-char-instead-of-char.patch @@ -0,0 +1,45 @@ +From fdfff847313222eed3306ac605db46d8cbd23212 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:47:24 +0100 +Subject: [PATCH] test,systemctl: use "const char*" instead of "char*" + +as iterator for FOREACH_STRING() + +The macro iterates through literal strings (i.e. constant strings), +hence it's more correct to have the iterator const too. + +Based on b2238e380e5f2fbcc129643b3fbd66f2828fd57c. + +Related: #2017033 +--- + src/systemctl/systemctl.c | 3 ++- + src/test/test-execute.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 3dd7c1522f..b967550b97 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -7011,7 +7011,8 @@ static int run_editor(char **paths) { + if (r == 0) { + const char **args; + char *editor, **editor_args = NULL; +- char **tmp_path, **original_path, *p; ++ char **tmp_path, **original_path; ++ const char *p; + size_t n_editor_args = 0, i = 1; + size_t argc; + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 5303652b93..7581d5ed68 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -146,7 +146,7 @@ invalid: + } + + static bool is_inaccessible_available(void) { +- char *p; ++ const char *p; + + FOREACH_STRING(p, + "/run/systemd/inaccessible/reg", diff --git a/SOURCES/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch b/SOURCES/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch new file mode 100644 index 0000000..ef37515 --- /dev/null +++ b/SOURCES/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch @@ -0,0 +1,27 @@ +From a8fd8d157c832ddad34a9a3e372579c58261f7fb Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:59:41 +0100 +Subject: [PATCH] ci: pass the $GITHUB_ACTIONS variable to the CentOS container + +so we can properly skip tests which are problematic when running in GH +Actions. + +Related: #2017033 +rhel-only +--- + .github/workflows/unit_tests.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index 814870e7a0..c1311310fb 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -131,7 +131,7 @@ for phase in "${PHASES[@]}"; do + # Pull a Docker image and start a new container + docker pull quay.io/centos/centos:$CENTOS_RELEASE + info "Starting container $CONT_NAME" +- $DOCKER_RUN -v $REPO_ROOT:/build:rw \ ++ $DOCKER_RUN -v $REPO_ROOT:/build:rw -e GITHUB_ACTIONS="$GITHUB_ACTIONS" \ + -w /build --privileged=true --name $CONT_NAME \ + -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init + diff --git a/SOURCES/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch b/SOURCES/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch new file mode 100644 index 0000000..d8f878e --- /dev/null +++ b/SOURCES/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch @@ -0,0 +1,171 @@ +From cecb3cc06f6025835324c1837c03def1d9be8eb1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 1 Dec 2021 21:31:43 +0100 +Subject: [PATCH] lgtm: detect uninitialized variables using the __cleanup__ + attribute + +This is a slightly modified version of the original +`cpp/uninitialized-local` CodeQL query which focuses only on variables +using the cleanup macros. Since this has proven to cause issues in the +past, let's panic on every uninitialized variable using any of the +cleanup macros (as long as they're written using the __cleanup__ +attribute). + +Some test results from a test I used when writing the query: + +``` + #define _cleanup_foo_ __attribute__((__cleanup__(foo))) + #define _cleanup_(x) __attribute__((__cleanup__(x))) + + static inline void freep(void *p) { + *(void**)p = mfree(*(void**) p); + } + + #define _cleanup_free_ _cleanup_(freep) + + static inline void foo(char **p) { + if (*p) + *p = free(*p); + } + + int main(void) { + __attribute__((__cleanup__(foo))) char *a; + char *b; + _cleanup_foo_ char *c; + char **d; + _cleanup_free_ char *e; + int r; + + r = fun(&e); + if (r < 0) + return 1; + + puts(a); + puts(b); + puts(c); + puts(*d); + puts(e); + + return 0; + } +``` + +``` ++| test.c:23:14:23:14 | e | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:20:26:20:26 | e | e | ++| test.c:27:10:27:10 | a | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:16:45:16:45 | a | a | ++| test.c:29:10:29:10 | c | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:18:25:18:25 | c | c | +``` + +(cherry picked from commit 863bff75488d33f519deea6390988f3d9d72e6de) + +Related: #2017033 +--- + .../UninitializedVariableWithCleanup.ql | 99 +++++++++++++++++++ + 1 file changed, 99 insertions(+) + create mode 100644 .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +new file mode 100644 +index 0000000000..6bf0ae01eb +--- /dev/null ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -0,0 +1,99 @@ ++/** ++ * vi: sw=2 ts=2 et syntax=ql: ++ * ++ * Based on cpp/uninitialized-local. ++ * ++ * @name Potentially uninitialized local variable using the cleanup attribute ++ * @description Running the cleanup handler on a possibly uninitialized variable ++ * is generally a bad idea. ++ * @id cpp/uninitialized-local-with-cleanup ++ * @kind problem ++ * @problem.severity error ++ * @precision high ++ * @tags security ++ */ ++ ++import cpp ++import semmle.code.cpp.controlflow.StackVariableReachability ++ ++/** ++ * Auxiliary predicate: Types that don't require initialization ++ * before they are used, since they're stack-allocated. ++ */ ++predicate allocatedType(Type t) { ++ /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */ ++ t instanceof ArrayType ++ or ++ /* Structs: "struct foo bar; bar.baz = 42" is ok. */ ++ t instanceof Class ++ or ++ /* Typedefs to other allocated types are fine. */ ++ allocatedType(t.(TypedefType).getUnderlyingType()) ++ or ++ /* Type specifiers don't affect whether or not a type is allocated. */ ++ allocatedType(t.getUnspecifiedType()) ++} ++ ++/** ++ * A declaration of a local variable using __attribute__((__cleanup__(x))) ++ * that leaves the variable uninitialized. ++ */ ++DeclStmt declWithNoInit(LocalVariable v) { ++ result.getADeclaration() = v and ++ not exists(v.getInitializer()) and ++ /* The variable has __attribute__((__cleanup__(...))) set */ ++ v.getAnAttribute().hasName("cleanup") and ++ /* The type of the variable is not stack-allocated. */ ++ exists(Type t | t = v.getType() | not allocatedType(t)) ++} ++ ++class UninitialisedLocalReachability extends StackVariableReachability { ++ UninitialisedLocalReachability() { this = "UninitialisedLocal" } ++ ++ override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) } ++ ++ /* Note: _don't_ use the `useOfVarActual()` predicate here (and a couple of lines ++ * below), as it assumes that the callee always modifies the variable if ++ * it's passed to the function. ++ * ++ * i.e.: ++ * _cleanup_free char *x; ++ * fun(&x); ++ * puts(x); ++ * ++ * `useOfVarActual()` won't treat this an an uninitialized read even if the callee ++ * doesn't modify the argument, however, `useOfVar()` will ++ */ ++ override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVar(v, node) } ++ ++ override predicate isBarrier(ControlFlowNode node, StackVariable v) { ++ // only report the _first_ possibly uninitialized use ++ useOfVar(v, node) or ++ definitionBarrier(v, node) ++ } ++} ++ ++pragma[noinline] ++predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) } ++ ++/** ++ * Auxiliary predicate: List common exceptions or false positives ++ * for this check to exclude them. ++ */ ++VariableAccess commonException() { ++ // If the uninitialized use we've found is in a macro expansion, it's ++ // typically something like va_start(), and we don't want to complain. ++ result.getParent().isInMacroExpansion() ++ or ++ result.getParent() instanceof BuiltInOperation ++ or ++ // Finally, exclude functions that contain assembly blocks. It's ++ // anyone's guess what happens in those. ++ containsInlineAssembly(result.getEnclosingFunction()) ++} ++ ++from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va ++where ++ r.reaches(_, v, va) and ++ not va = commonException() ++select va, "The variable $@ may not be initialized here, but has a cleanup handler.", v, v.getName() diff --git a/SOURCES/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch b/SOURCES/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch new file mode 100644 index 0000000..acccb51 --- /dev/null +++ b/SOURCES/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch @@ -0,0 +1,84 @@ +From c4a34b71d4f51f071f7a722059e36388b41d30e4 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 11 Mar 2019 21:05:13 +0100 +Subject: [PATCH] lgtm: replace the query used for looking for fgets with a + more general query + +to make it easier to comlain about `strtok` :-) + +Inspired by https://github.com/systemd/systemd/pull/11963, which, in turn, +was prompted by https://github.com/systemd/systemd/pull/11555. + +(cherry picked from commit 7ba5ded9dbd7737bc368521f5ea7c90e5b06ab3e) + +Related: #2017033 +--- + .../PotentiallyDangerousFunction.ql | 30 +++++++++++++++++++ + .lgtm/cpp-queries/fgets.ql | 21 ------------- + 2 files changed, 30 insertions(+), 21 deletions(-) + create mode 100644 .lgtm/cpp-queries/PotentiallyDangerousFunction.ql + delete mode 100644 .lgtm/cpp-queries/fgets.ql + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +new file mode 100644 +index 0000000000..ba80f4ad8c +--- /dev/null ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -0,0 +1,30 @@ ++/** ++ * @name Use of potentially dangerous function ++ * @description Certain standard library functions are dangerous to call. ++ * @kind problem ++ * @problem.severity error ++ * @precision high ++ * @id cpp/potentially-dangerous-function ++ * @tags reliability ++ * security ++ * ++ * Borrowed from ++ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql ++ */ ++import cpp ++ ++predicate potentiallyDangerousFunction(Function f, string message) { ++ ( ++ f.getQualifiedName() = "fgets" and ++ message = "Call to fgets is potentially dangerous. Use read_line() instead." ++ ) or ( ++ f.getQualifiedName() = "strtok" and ++ message = "Call to strtok is potentially dangerous. Use extract_first_word() instead." ++ ) ++} ++ ++from FunctionCall call, Function target, string message ++where ++ call.getTarget() = target and ++ potentiallyDangerousFunction(target, message) ++select call, message +diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql +deleted file mode 100644 +index a4181e4f3d..0000000000 +--- a/.lgtm/cpp-queries/fgets.ql ++++ /dev/null +@@ -1,21 +0,0 @@ +-/** +- * @name Use of fgets() +- * @description fgets() is dangerous to call. Use read_line() instead. +- * @kind problem +- * @problem.severity error +- * @precision high +- * @id cpp/fgets +- * @tags reliability +- * security +- */ +-import cpp +- +-predicate dangerousFunction(Function function) { +- exists (string name | name = function.getQualifiedName() | +- name = "fgets") +-} +- +-from FunctionCall call, Function target +-where call.getTarget() = target +- and dangerousFunction(target) +-select call, target.getQualifiedName() + " is potentially dangerous" diff --git a/SOURCES/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch b/SOURCES/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch new file mode 100644 index 0000000..03e3939 --- /dev/null +++ b/SOURCES/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch @@ -0,0 +1,48 @@ +From 8b60932555141e1fe61a343863eae7655c2449a9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 2 Apr 2019 12:43:47 +0200 +Subject: [PATCH] lgtm: beef up list of dangerous/questionnable API calls not + to make + +(cherry picked from commit 9b4805421eb2a7319f6507a26febfb9d2cdc3a93) + +Related: #2017033 +--- + .../PotentiallyDangerousFunction.ql | 22 +++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index ba80f4ad8c..cd0284b37a 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -16,10 +16,28 @@ import cpp + predicate potentiallyDangerousFunction(Function f, string message) { + ( + f.getQualifiedName() = "fgets" and +- message = "Call to fgets is potentially dangerous. Use read_line() instead." ++ message = "Call to fgets() is potentially dangerous. Use read_line() instead." + ) or ( + f.getQualifiedName() = "strtok" and +- message = "Call to strtok is potentially dangerous. Use extract_first_word() instead." ++ message = "Call to strtok() is potentially dangerous. Use extract_first_word() instead." ++ ) or ( ++ f.getQualifiedName() = "strsep" and ++ message = "Call to strsep() is potentially dangerous. Use extract_first_word() instead." ++ ) or ( ++ f.getQualifiedName() = "dup" and ++ message = "Call to dup() is potentially dangerous. Use fcntl(fd, FD_DUPFD_CLOEXEC, 3) instead." ++ ) or ( ++ f.getQualifiedName() = "htonl" and ++ message = "Call to htonl() is confusing. Use htobe32() instead." ++ ) or ( ++ f.getQualifiedName() = "htons" and ++ message = "Call to htons() is confusing. Use htobe16() instead." ++ ) or ( ++ f.getQualifiedName() = "ntohl" and ++ message = "Call to ntohl() is confusing. Use be32toh() instead." ++ ) or ( ++ f.getQualifiedName() = "ntohs" and ++ message = "Call to ntohs() is confusing. Use be16toh() instead." + ) + } + diff --git a/SOURCES/0683-lgtm-warn-about-strerror-use.patch b/SOURCES/0683-lgtm-warn-about-strerror-use.patch new file mode 100644 index 0000000..2661bfe --- /dev/null +++ b/SOURCES/0683-lgtm-warn-about-strerror-use.patch @@ -0,0 +1,26 @@ +From af6eac25456d4ca7e8233e00aec7531e640f17af Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Apr 2019 15:31:34 +0200 +Subject: [PATCH] lgtm: warn about strerror() use + +(cherry picked from commit 9ff46eded2b99d244455467eb55c0ff3f51c5362) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index cd0284b37a..96712cf1c6 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -38,6 +38,9 @@ predicate potentiallyDangerousFunction(Function f, string message) { + ) or ( + f.getQualifiedName() = "ntohs" and + message = "Call to ntohs() is confusing. Use be16toh() instead." ++ ) or ( ++ f.getQualifiedName() = "strerror" and ++ message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead." + ) + } + diff --git a/SOURCES/0684-lgtm-complain-about-accept-people-should-use-accept4.patch b/SOURCES/0684-lgtm-complain-about-accept-people-should-use-accept4.patch new file mode 100644 index 0000000..7c3b69c --- /dev/null +++ b/SOURCES/0684-lgtm-complain-about-accept-people-should-use-accept4.patch @@ -0,0 +1,27 @@ +From bfa090ce83f2b0734c526a4426a20f6f0f943aa0 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Apr 2019 19:36:40 +0200 +Subject: [PATCH] lgtm: complain about accept() [people should use accept4() + instead, due to O_CLOEXEC] + +(cherry picked from commit e2d0fa6feb3797246c8bfda3db45a2f5b62e1b5b) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index 96712cf1c6..865330430d 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -41,6 +41,9 @@ predicate potentiallyDangerousFunction(Function f, string message) { + ) or ( + f.getQualifiedName() = "strerror" and + message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead." ++ ) or ( ++ f.getQualifiedName() = "accept" and ++ message = "Call to accept() is not O_CLOEXEC-safe. Use accept4() instead." + ) + } + diff --git a/SOURCES/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch b/SOURCES/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch new file mode 100644 index 0000000..0eb213f --- /dev/null +++ b/SOURCES/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch @@ -0,0 +1,40 @@ +From 6eeaef95566e6d85e714280c412e5df347838e34 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 2 Dec 2021 16:55:17 +0100 +Subject: [PATCH] lgtm: don't treat the custom note as a list of tags + +Just a cosmetic change. + +(cherry picked from commit c7d70210fa45c3210b8b1eda51bc0f6d68bd8392) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index 865330430d..39e8dddd13 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -1,15 +1,17 @@ + /** ++ * vi: sw=2 ts=2 et syntax=ql: ++ * ++ * Borrowed from ++ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql ++ * + * @name Use of potentially dangerous function + * @description Certain standard library functions are dangerous to call. ++ * @id cpp/potentially-dangerous-function + * @kind problem + * @problem.severity error + * @precision high +- * @id cpp/potentially-dangerous-function + * @tags reliability + * security +- * +- * Borrowed from +- * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql + */ + import cpp + diff --git a/SOURCES/0686-lgtm-ignore-certain-cleanup-functions.patch b/SOURCES/0686-lgtm-ignore-certain-cleanup-functions.patch new file mode 100644 index 0000000..0793564 --- /dev/null +++ b/SOURCES/0686-lgtm-ignore-certain-cleanup-functions.patch @@ -0,0 +1,42 @@ +From 42123e9614ea73c7f64c684c90e4dbb049ef67ef Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sun, 5 Dec 2021 10:25:28 +0100 +Subject: [PATCH] lgtm: ignore certain cleanup functions + +as they don't do any illegal stuff even when used with an uninitialized +variable. + +(cherry picked from commit af1868213657b38b8d4008608976eb81546cfb8e) + +Related: #2017033 +--- + .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +index 6bf0ae01eb..8c24b6d8f1 100644 +--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -34,6 +34,13 @@ predicate allocatedType(Type t) { + allocatedType(t.getUnspecifiedType()) + } + ++/** Auxiliary predicate: List cleanup functions we want to explicitly ignore ++ * since they don't do anything illegal even when the variable is uninitialized ++ */ ++predicate cleanupFunctionDenyList(string fun) { ++ fun = "erase_char" ++} ++ + /** + * A declaration of a local variable using __attribute__((__cleanup__(x))) + * that leaves the variable uninitialized. +@@ -43,6 +50,8 @@ DeclStmt declWithNoInit(LocalVariable v) { + not exists(v.getInitializer()) and + /* The variable has __attribute__((__cleanup__(...))) set */ + v.getAnAttribute().hasName("cleanup") and ++ /* Check if the cleanup function is not on a deny list */ ++ not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and + /* The type of the variable is not stack-allocated. */ + exists(Type t | t = v.getType() | not allocatedType(t)) + } diff --git a/SOURCES/0687-lgtm-detect-more-possible-problematic-scenarios.patch b/SOURCES/0687-lgtm-detect-more-possible-problematic-scenarios.patch new file mode 100644 index 0000000..24edd31 --- /dev/null +++ b/SOURCES/0687-lgtm-detect-more-possible-problematic-scenarios.patch @@ -0,0 +1,96 @@ +From f9b19c9d4caaf870b30cce8a3d6be79eda099c4e Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sun, 5 Dec 2021 16:11:35 +0100 +Subject: [PATCH] lgtm: detect more possible problematic scenarios + +1) don't ignore stack-allocated variables, since they may hide + heap-allocated stuff (compound types) +2) check if there's a return between the variable declaration and its + initialization; if so, treat the variable as uninitialized +3) introduction of 2) increased the query runtime exponentially, so + introduce some optimizations to bring it back to some reasonable + values + +(cherry picked from commit c8fec8bf9b086f9fc7638db0f1a613a00d7c63a3) + +Related: #2017033 +--- + .../UninitializedVariableWithCleanup.ql | 48 ++++++++++--------- + 1 file changed, 25 insertions(+), 23 deletions(-) + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +index 8c24b6d8f1..6b3b62f8bc 100644 +--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -16,24 +16,6 @@ + import cpp + import semmle.code.cpp.controlflow.StackVariableReachability + +-/** +- * Auxiliary predicate: Types that don't require initialization +- * before they are used, since they're stack-allocated. +- */ +-predicate allocatedType(Type t) { +- /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */ +- t instanceof ArrayType +- or +- /* Structs: "struct foo bar; bar.baz = 42" is ok. */ +- t instanceof Class +- or +- /* Typedefs to other allocated types are fine. */ +- allocatedType(t.(TypedefType).getUnderlyingType()) +- or +- /* Type specifiers don't affect whether or not a type is allocated. */ +- allocatedType(t.getUnspecifiedType()) +-} +- + /** Auxiliary predicate: List cleanup functions we want to explicitly ignore + * since they don't do anything illegal even when the variable is uninitialized + */ +@@ -47,13 +29,11 @@ predicate cleanupFunctionDenyList(string fun) { + */ + DeclStmt declWithNoInit(LocalVariable v) { + result.getADeclaration() = v and +- not exists(v.getInitializer()) and ++ not v.hasInitializer() and + /* The variable has __attribute__((__cleanup__(...))) set */ + v.getAnAttribute().hasName("cleanup") and + /* Check if the cleanup function is not on a deny list */ +- not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and +- /* The type of the variable is not stack-allocated. */ +- exists(Type t | t = v.getType() | not allocatedType(t)) ++ not cleanupFunctionDenyList(v.getAnAttribute().getAnArgument().getValueText()) + } + + class UninitialisedLocalReachability extends StackVariableReachability { +@@ -78,7 +58,29 @@ class UninitialisedLocalReachability extends StackVariableReachability { + override predicate isBarrier(ControlFlowNode node, StackVariable v) { + // only report the _first_ possibly uninitialized use + useOfVar(v, node) or +- definitionBarrier(v, node) ++ ( ++ /* If there's an return statement somewhere between the variable declaration ++ * and a possible definition, don't accept is as a valid initialization. ++ * ++ * E.g.: ++ * _cleanup_free_ char *x; ++ * ... ++ * if (...) ++ * return; ++ * ... ++ * x = malloc(...); ++ * ++ * is not a valid initialization, since we might return from the function ++ * _before_ the actual iniitialization (emphasis on _might_, since we ++ * don't know if the return statement might ever evaluate to true). ++ */ ++ definitionBarrier(v, node) and ++ not exists(ReturnStmt rs | ++ /* The attribute check is "just" a complexity optimization */ ++ v.getFunction() = rs.getEnclosingFunction() and v.getAnAttribute().hasName("cleanup") | ++ rs.getLocation().isBefore(node.getLocation()) ++ ) ++ ) + } + } + diff --git a/SOURCES/0688-lgtm-enable-more-and-potentially-useful-queries.patch b/SOURCES/0688-lgtm-enable-more-and-potentially-useful-queries.patch new file mode 100644 index 0000000..784850e --- /dev/null +++ b/SOURCES/0688-lgtm-enable-more-and-potentially-useful-queries.patch @@ -0,0 +1,48 @@ +From 842c676a36abab0d92f1e68de2c8881fd00fdf4b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 30 Nov 2021 23:40:28 +0100 +Subject: [PATCH] lgtm: enable more (and potentially useful) queries + +Not all available queries on LGTM are enabled by default, but some of +the excluded ones might come in handy, hence let's enable them +explicitly. + +(cherry picked from commit 38f36b9f3443b4d2085799c772e901a402b84af3) + +Related: #2017033 +--- + .lgtm.yml | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/.lgtm.yml b/.lgtm.yml +index 5948d8c2bc..fe93957b67 100644 +--- a/.lgtm.yml ++++ b/.lgtm.yml +@@ -1,3 +1,27 @@ ++--- ++# vi: ts=2 sw=2 et: ++ ++# Explicitly enable certain checks which are hidden by default ++queries: ++ - include: cpp/bad-strncpy-size ++ - include: cpp/declaration-hides-variable ++ - include: cpp/inconsistent-null-check ++ - include: cpp/mistyped-function-arguments ++ - include: cpp/nested-loops-with-same-variable ++ - include: cpp/sizeof-side-effect ++ - include: cpp/suspicious-pointer-scaling ++ - include: cpp/suspicious-pointer-scaling-void ++ - include: cpp/suspicious-sizeof ++ - include: cpp/unsafe-strcat ++ - include: cpp/unsafe-strncat ++ - include: cpp/unsigned-difference-expression-compared-zero ++ - include: cpp/unused-local-variable ++ - include: ++ tags: ++ - "security" ++ - "correctness" ++ severity: "error" ++ + extraction: + cpp: + prepare: diff --git a/SOURCES/0689-meson-avoid-bogus-meson-warning.patch b/SOURCES/0689-meson-avoid-bogus-meson-warning.patch new file mode 100644 index 0000000..3453c1f --- /dev/null +++ b/SOURCES/0689-meson-avoid-bogus-meson-warning.patch @@ -0,0 +1,36 @@ +From 4433c31a80c4477b0a0c503c74e8faebc44f4453 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 7 Nov 2019 11:32:26 +0100 +Subject: [PATCH] meson: avoid bogus meson warning + +With meson-0.52.0-1.module_f31+6771+f5d842eb.noarch I get: +src/test/meson.build:19: WARNING: Overriding previous value of environment variable 'PATH' with a new one + +When we're using *prepend*, the whole point is to modify an existing variable, +so meson shouldn't warn. But let's set avoid the warning and shorten things by +setting the final value immediately. + +(cherry picked from commit cbe804947482998cc767bfb0c169e6263a6ef097) +--- + src/test/meson.build | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/test/meson.build b/src/test/meson.build +index 40cf56d73d..6eaa62e53f 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -10,12 +10,11 @@ test_hashmap_ordered_c = custom_target( + + test_include_dir = include_directories('.') + +-path = run_command('sh', ['-c', 'echo "$PATH"']).stdout() ++path = run_command('sh', ['-c', 'echo "$PATH"']).stdout().strip() + test_env = environment() + test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map) + test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map) +-test_env.set('PATH', path) +-test_env.prepend('PATH', meson.build_root()) ++test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path)) + + ############################################################ + diff --git a/SOURCES/0690-test-make-TEST-47-less-racy.patch b/SOURCES/0690-test-make-TEST-47-less-racy.patch new file mode 100644 index 0000000..4aa0371 --- /dev/null +++ b/SOURCES/0690-test-make-TEST-47-less-racy.patch @@ -0,0 +1,33 @@ +From de7125dcfe6d6c8af05262ab786f9fe7cbf15113 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 15 Dec 2021 12:15:19 +0100 +Subject: [PATCH] test: make TEST-47 less racy + +Based on: + - 2e7090e94d0c8b31d418555ab2f6a9b75318f6a4 + - e00e2e0b50bbd120290572c8d1242703fb98b34e + - 197298ff9fc930de450330095cc5b67d165d0801 + +Related: #2017033 +--- + test/TEST-47-ISSUE-14566/testsuite.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh +index d917cf52ff..b12b50e96c 100755 +--- a/test/TEST-47-ISSUE-14566/testsuite.sh ++++ b/test/TEST-47-ISSUE-14566/testsuite.sh +@@ -6,11 +6,13 @@ systemd-analyze log-level debug + systemd-analyze log-target console + + systemctl start issue_14566_test ++sleep 4 + systemctl status issue_14566_test + + leaked_pid=$(cat /leakedtestpid) + + systemctl stop issue_14566_test ++sleep 4 + + # Leaked PID will still be around if we're buggy. + # I personally prefer to see 42. diff --git a/SOURCES/0691-core-rename-unit_-start_limit-condition-assert-_test.patch b/SOURCES/0691-core-rename-unit_-start_limit-condition-assert-_test.patch new file mode 100644 index 0000000..2a25449 --- /dev/null +++ b/SOURCES/0691-core-rename-unit_-start_limit-condition-assert-_test.patch @@ -0,0 +1,179 @@ +From 894d307d0d149adb46e630550566e5a3f6ff8d2e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 18 Mar 2019 12:21:27 +0100 +Subject: [PATCH] core: rename unit_{start_limit|condition|assert}_test() to + unit_test_xyz() + +Just some renaming, no change in behaviour. + +Background: I'd like to add more functions unit_test_xyz() that test +various things, hence let's streamline the naming a bit. + +(cherry picked from commit 97a3f4ee052e1b8a0ff03accfa478e352891a84f) + +Related: #2036608 +--- + src/core/automount.c | 2 +- + src/core/mount.c | 2 +- + src/core/path.c | 2 +- + src/core/service.c | 2 +- + src/core/socket.c | 2 +- + src/core/swap.c | 2 +- + src/core/timer.c | 2 +- + src/core/unit.c | 11 +++++------ + src/core/unit.h | 2 +- + 9 files changed, 13 insertions(+), 14 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 76e70f4dac..2bc160cb07 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -808,7 +808,7 @@ static int automount_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/mount.c b/src/core/mount.c +index 7e80a0c974..aa586d88cb 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1065,7 +1065,7 @@ static int mount_start(Unit *u) { + + assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED)); + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/path.c b/src/core/path.c +index ed40bc6c19..4bccc0396b 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -565,7 +565,7 @@ static int path_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/service.c b/src/core/service.c +index 7969bbf071..1a1de43d0d 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2388,7 +2388,7 @@ static int service_start(Unit *u) { + assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)); + + /* Make sure we don't enter a busy loop of some kind. */ +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); + return r; +diff --git a/src/core/socket.c b/src/core/socket.c +index 50c32ed8f4..09491c6677 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2469,7 +2469,7 @@ static int socket_start(Unit *u) { + + assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)); + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/swap.c b/src/core/swap.c +index a8f127f660..823699699e 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -851,7 +851,7 @@ static int swap_start(Unit *u) { + if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING) + return -EAGAIN; + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/timer.c b/src/core/timer.c +index 1718ffc5a5..be16321296 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -599,7 +599,7 @@ static int timer_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/unit.c b/src/core/unit.c +index 23afa24c77..9013186d8a 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1633,7 +1633,7 @@ static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to + return triggered != 0; + } + +-static bool unit_condition_test(Unit *u) { ++static bool unit_test_condition(Unit *u) { + assert(u); + + dual_timestamp_get(&u->condition_timestamp); +@@ -1642,7 +1642,7 @@ static bool unit_condition_test(Unit *u) { + return u->condition_result; + } + +-static bool unit_assert_test(Unit *u) { ++static bool unit_test_assert(Unit *u) { + assert(u); + + dual_timestamp_get(&u->assert_timestamp); +@@ -1657,8 +1657,7 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg + REENABLE_WARNING; + } + +- +-int unit_start_limit_test(Unit *u) { ++int unit_test_start_limit(Unit *u) { + assert(u); + + if (ratelimit_below(&u->start_limit)) { +@@ -1750,14 +1749,14 @@ int unit_start(Unit *u) { + * speed up activation in case there is some hold-off time, + * but we don't want to recheck the condition in that case. */ + if (state != UNIT_ACTIVATING && +- !unit_condition_test(u)) { ++ !unit_test_condition(u)) { + log_unit_debug(u, "Starting requested but condition failed. Not starting unit."); + return -EALREADY; + } + + /* If the asserts failed, fail the entire job */ + if (state != UNIT_ACTIVATING && +- !unit_assert_test(u)) { ++ !unit_test_assert(u)) { + log_unit_notice(u, "Starting requested but asserts failed."); + return -EPROTO; + } +diff --git a/src/core/unit.h b/src/core/unit.h +index ec45b5fb48..a8bc350b66 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -786,7 +786,7 @@ static inline bool unit_supported(Unit *u) { + void unit_warn_if_dir_nonempty(Unit *u, const char* where); + int unit_fail_if_noncanonical(Unit *u, const char* where); + +-int unit_start_limit_test(Unit *u); ++int unit_test_start_limit(Unit *u); + + void unit_unref_uid(Unit *u, bool destroy_now); + int unit_ref_uid(Unit *u, uid_t uid, bool clean_ipc); diff --git a/SOURCES/0692-core-Check-unit-start-rate-limiting-earlier.patch b/SOURCES/0692-core-Check-unit-start-rate-limiting-earlier.patch new file mode 100644 index 0000000..cbe1aac --- /dev/null +++ b/SOURCES/0692-core-Check-unit-start-rate-limiting-earlier.patch @@ -0,0 +1,400 @@ +From 471eda89a25a3ceac91a2d05e39a54aae78038ed Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 24 Aug 2021 16:46:47 +0100 +Subject: [PATCH] core: Check unit start rate limiting earlier + +Fixes #17433. Currently, if any of the validations we do before we +check start rate limiting fail, we can still enter a busy loop as +no rate limiting gets applied. A common occurence of this scenario +is path units triggering a service that fails a condition check. + +To fix the issue, we simply move up start rate limiting checks to +be the first thing we do when starting a unit. To achieve this, +we add a new method to the unit vtable and implement it for the +relevant unit types so that we can do the start rate limit checks +earlier on. + +(cherry picked from commit 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95) + +Related: #2036608 + +[msekleta: I've deleted part of the original commit that adds test for +issue #17433. This was necessary because upstream commit assumes newer +organization of the test code which we don't have in RHEL-8 tree. As +a consequence we must add explicit test for this in the internal +test-suite.] +--- + src/core/automount.c | 23 +++++++++++++++++------ + src/core/mount.c | 23 +++++++++++++++++------ + src/core/path.c | 23 +++++++++++++++++------ + src/core/service.c | 25 ++++++++++++++++++------- + src/core/socket.c | 23 +++++++++++++++++------ + src/core/swap.c | 23 +++++++++++++++++------ + src/core/timer.c | 22 ++++++++++++++++------ + src/core/unit.c | 14 ++++++++++---- + src/core/unit.h | 4 ++++ + 9 files changed, 133 insertions(+), 47 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 2bc160cb07..5e16adabb5 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -808,12 +808,6 @@ static int automount_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1077,6 +1071,21 @@ static bool automount_supported(void) { + return supported; + } + ++static int automount_test_start_limit(Unit *u) { ++ Automount *a = AUTOMOUNT(u); ++ int r; ++ ++ assert(a); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { + [AUTOMOUNT_SUCCESS] = "success", + [AUTOMOUNT_FAILURE_RESOURCES] = "resources", +@@ -1135,4 +1144,6 @@ const UnitVTable automount_vtable = { + [JOB_FAILED] = "Failed to unset automount %s.", + }, + }, ++ ++ .test_start_limit = automount_test_start_limit, + }; +diff --git a/src/core/mount.c b/src/core/mount.c +index aa586d88cb..22848847e5 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1065,12 +1065,6 @@ static int mount_start(Unit *u) { + + assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED)); + +- r = unit_test_start_limit(u); +- if (r < 0) { +- mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1957,6 +1951,21 @@ static int mount_control_pid(Unit *u) { + return m->control_pid; + } + ++static int mount_test_start_limit(Unit *u) { ++ Mount *m = MOUNT(u); ++ int r; ++ ++ assert(m); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { + [MOUNT_EXEC_MOUNT] = "ExecMount", + [MOUNT_EXEC_UNMOUNT] = "ExecUnmount", +@@ -2048,4 +2057,6 @@ const UnitVTable mount_vtable = { + [JOB_TIMEOUT] = "Timed out unmounting %s.", + }, + }, ++ ++ .test_start_limit = mount_test_start_limit, + }; +diff --git a/src/core/path.c b/src/core/path.c +index 4bccc0396b..1e69a1f05f 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -565,12 +565,6 @@ static int path_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -730,6 +724,21 @@ static void path_reset_failed(Unit *u) { + p->result = PATH_SUCCESS; + } + ++static int path_test_start_limit(Unit *u) { ++ Path *p = PATH(u); ++ int r; ++ ++ assert(p); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const path_type_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = "PathExists", + [PATH_EXISTS_GLOB] = "PathExistsGlob", +@@ -782,4 +791,6 @@ const UnitVTable path_vtable = { + + .bus_vtable = bus_path_vtable, + .bus_set_property = bus_path_set_property, ++ ++ .test_start_limit = path_test_start_limit, + }; +diff --git a/src/core/service.c b/src/core/service.c +index 1a1de43d0d..c5f408d817 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2387,13 +2387,6 @@ static int service_start(Unit *u) { + + assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)); + +- /* Make sure we don't enter a busy loop of some kind. */ +- r = unit_test_start_limit(u); +- if (r < 0) { +- service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -4081,6 +4074,22 @@ static bool service_needs_console(Unit *u) { + SERVICE_FINAL_SIGKILL); + } + ++static int service_test_start_limit(Unit *u) { ++ Service *s = SERVICE(u); ++ int r; ++ ++ assert(s); ++ ++ /* Make sure we don't enter a busy loop of some kind. */ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { + [SERVICE_RESTART_NO] = "no", + [SERVICE_RESTART_ON_SUCCESS] = "on-success", +@@ -4222,4 +4231,6 @@ const UnitVTable service_vtable = { + [JOB_FAILED] = "Stopped (with error) %s.", + }, + }, ++ ++ .test_start_limit = service_test_start_limit, + }; +diff --git a/src/core/socket.c b/src/core/socket.c +index 09491c6677..36d2e4f823 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2469,12 +2469,6 @@ static int socket_start(Unit *u) { + + assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)); + +- r = unit_test_start_limit(u); +- if (r < 0) { +- socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -3267,6 +3261,21 @@ static int socket_control_pid(Unit *u) { + return s->control_pid; + } + ++static int socket_test_start_limit(Unit *u) { ++ Socket *s = SOCKET(u); ++ int r; ++ ++ assert(s); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + [SOCKET_EXEC_START_PRE] = "ExecStartPre", + [SOCKET_EXEC_START_CHOWN] = "ExecStartChown", +@@ -3359,4 +3368,6 @@ const UnitVTable socket_vtable = { + [JOB_TIMEOUT] = "Timed out stopping %s.", + }, + }, ++ ++ .test_start_limit = socket_test_start_limit, + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 823699699e..90fcd69300 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -851,12 +851,6 @@ static int swap_start(Unit *u) { + if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING) + return -EAGAIN; + +- r = unit_test_start_limit(u); +- if (r < 0) { +- swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1458,6 +1452,21 @@ static int swap_control_pid(Unit *u) { + return s->control_pid; + } + ++static int swap_test_start_limit(Unit *u) { ++ Swap *s = SWAP(u); ++ int r; ++ ++ assert(s); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { + [SWAP_EXEC_ACTIVATE] = "ExecActivate", + [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate", +@@ -1547,4 +1556,6 @@ const UnitVTable swap_vtable = { + [JOB_TIMEOUT] = "Timed out deactivating swap %s.", + }, + }, ++ ++ .test_start_limit = swap_test_start_limit, + }; +diff --git a/src/core/timer.c b/src/core/timer.c +index be16321296..fb9ae17990 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -599,12 +599,6 @@ static int timer_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -829,6 +823,21 @@ static void timer_timezone_change(Unit *u) { + timer_enter_waiting(t, false); + } + ++static int timer_test_start_limit(Unit *u) { ++ Timer *t = TIMER(u); ++ int r; ++ ++ assert(t); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const timer_base_table[_TIMER_BASE_MAX] = { + [TIMER_ACTIVE] = "OnActiveSec", + [TIMER_BOOT] = "OnBootSec", +@@ -884,4 +893,5 @@ const UnitVTable timer_vtable = { + .bus_set_property = bus_timer_set_property, + + .can_transient = true, ++ .test_start_limit = timer_test_start_limit, + }; +diff --git a/src/core/unit.c b/src/core/unit.c +index 9013186d8a..f0df7452fa 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1728,10 +1728,16 @@ int unit_start(Unit *u) { + + assert(u); + +- /* If this is already started, then this will succeed. Note +- * that this will even succeed if this unit is not startable +- * by the user. This is relied on to detect when we need to +- * wait for units and when waiting is finished. */ ++ /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->test_start_limit) { ++ int r = UNIT_VTABLE(u)->test_start_limit(u); ++ if (r < 0) ++ return r; ++ } ++ ++ /* If this is already started, then this will succeed. Note that this will even succeed if this unit ++ * is not startable by the user. This is relied on to detect when we need to wait for units and when ++ * waiting is finished. */ + state = unit_active_state(u); + if (UNIT_IS_ACTIVE_OR_RELOADING(state)) + return -EALREADY; +diff --git a/src/core/unit.h b/src/core/unit.h +index a8bc350b66..9e6f1bcf81 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -567,6 +567,10 @@ typedef struct UnitVTable { + /* The bus vtable */ + const sd_bus_vtable *bus_vtable; + ++ /* If this function is set, it's invoked first as part of starting a unit to allow start rate ++ * limiting checks to occur before we do anything else. */ ++ int (*test_start_limit)(Unit *u); ++ + /* The strings to print in status messages */ + UnitStatusMessageFormats status_message_formats; + diff --git a/SOURCES/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch b/SOURCES/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch new file mode 100644 index 0000000..42d59d7 --- /dev/null +++ b/SOURCES/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch @@ -0,0 +1,226 @@ +From 51210a849ea7f163a1760de989756206c01dd758 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 19:44:06 +0200 +Subject: [PATCH] sd-event: introduce callback invoked when event source + ratelimit expires + +(cherry picked from commit fd69f2247520b0be3190ded96d646a415edc97b7) + +Related: #2036608 +--- + src/libsystemd/libsystemd.sym | 5 +++ + src/libsystemd/sd-event/sd-event.c | 61 +++++++++++++++++++++++----- + src/libsystemd/sd-event/test-event.c | 12 ++++++ + src/systemd/sd-event.h | 1 + + 4 files changed, 68 insertions(+), 11 deletions(-) + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 149d2e7b82..f4a1426248 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -579,3 +579,8 @@ global: + sd_event_source_get_ratelimit; + sd_event_source_is_ratelimited; + } LIBSYSTEMD_239; ++ ++LIBSYSTEMD_250 { ++global: ++ sd_event_source_set_ratelimit_expire_callback; ++} LIBSYSTEMD_248; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 47cf93b3f4..0adfdd9e1a 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -125,6 +125,7 @@ struct sd_event_source { + uint64_t prepare_iteration; + + sd_event_destroy_t destroy_callback; ++ sd_event_handler_t ratelimit_expire_callback; + + LIST_FIELDS(sd_event_source, sources); + +@@ -2734,7 +2735,7 @@ fail: + return r; + } + +-static int event_source_leave_ratelimit(sd_event_source *s) { ++static int event_source_leave_ratelimit(sd_event_source *s, bool run_callback) { + int r; + + assert(s); +@@ -2766,6 +2767,23 @@ static int event_source_leave_ratelimit(sd_event_source *s) { + ratelimit_reset(&s->rate_limit); + + log_debug("Event source %p (%s) left rate limit state.", s, strna(s->description)); ++ ++ if (run_callback && s->ratelimit_expire_callback) { ++ s->dispatching = true; ++ r = s->ratelimit_expire_callback(s, s->userdata); ++ s->dispatching = false; ++ ++ if (r < 0) { ++ log_debug_errno(r, "Ratelimit expiry callback of event source %s (type %s) returned error, disabling: %m", ++ strna(s->description), ++ event_source_type_to_string(s->type)); ++ ++ sd_event_source_set_enabled(s, SD_EVENT_OFF); ++ } ++ ++ return 1; ++ } ++ + return 0; + + fail: +@@ -2966,6 +2984,7 @@ static int process_timer( + struct clock_data *d) { + + sd_event_source *s; ++ bool callback_invoked = false; + int r; + + assert(e); +@@ -2981,9 +3000,11 @@ static int process_timer( + * again. */ + assert(s->ratelimited); + +- r = event_source_leave_ratelimit(s); ++ r = event_source_leave_ratelimit(s, /* run_callback */ true); + if (r < 0) + return r; ++ else if (r == 1) ++ callback_invoked = true; + + continue; + } +@@ -2998,7 +3019,7 @@ static int process_timer( + event_source_time_prioq_reshuffle(s); + } + +- return 0; ++ return callback_invoked; + } + + static int process_child(sd_event *e) { +@@ -3698,15 +3719,15 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.realtime, &e->realtime); ++ r = process_inotify(e); + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.boottime, &e->boottime); ++ r = process_timer(e, e->timestamp.realtime, &e->realtime); + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.monotonic, &e->monotonic); ++ r = process_timer(e, e->timestamp.boottime, &e->boottime); + if (r < 0) + goto finish; + +@@ -3718,16 +3739,27 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { + if (r < 0) + goto finish; + ++ r = process_timer(e, e->timestamp.monotonic, &e->monotonic); ++ if (r < 0) ++ goto finish; ++ else if (r == 1) { ++ /* Ratelimit expiry callback was called. Let's postpone processing pending sources and ++ * put loop in the initial state in order to evaluate (in the next iteration) also sources ++ * there were potentially re-enabled by the callback. ++ * ++ * Wondering why we treat only this invocation of process_timer() differently? Once event ++ * source is ratelimited we essentially transform it into CLOCK_MONOTONIC timer hence ++ * ratelimit expiry callback is never called for any other timer type. */ ++ r = 0; ++ goto finish; ++ } ++ + if (e->need_process_child) { + r = process_child(e); + if (r < 0) + goto finish; + } + +- r = process_inotify(e); +- if (r < 0) +- goto finish; +- + if (event_next_pending(e)) { + e->state = SD_EVENT_PENDING; + +@@ -4054,7 +4086,7 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval + + /* When ratelimiting is configured we'll always reset the rate limit state first and start fresh, + * non-ratelimited. */ +- r = event_source_leave_ratelimit(s); ++ r = event_source_leave_ratelimit(s, /* run_callback */ false); + if (r < 0) + return r; + +@@ -4062,6 +4094,13 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval + return 0; + } + ++_public_ int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback) { ++ assert_return(s, -EINVAL); ++ ++ s->ratelimit_expire_callback = callback; ++ return 0; ++} ++ + _public_ int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval, unsigned *ret_burst) { + assert_return(s, -EINVAL); + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index e3ee4cd5c3..9135b22839 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -506,6 +506,11 @@ static int ratelimit_time_handler(sd_event_source *s, uint64_t usec, void *userd + return 0; + } + ++static int expired = -1; ++static int ratelimit_expired(sd_event_source *s, void *userdata) { ++ return ++expired; ++} ++ + static void test_ratelimit(void) { + _cleanup_close_pair_ int p[2] = {-1, -1}; + _cleanup_(sd_event_unrefp) sd_event *e = NULL; +@@ -568,12 +573,19 @@ static void test_ratelimit(void) { + + assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) >= 0); + ++ /* Set callback that will be invoked when we leave rate limited state. */ ++ assert_se(sd_event_source_set_ratelimit_expire_callback(s, ratelimit_expired) >= 0); ++ + do { + assert_se(sd_event_run(e, UINT64_MAX) >= 0); + } while (!sd_event_source_is_ratelimited(s)); + + log_info("ratelimit_time_handler: called 10 more times, event source got ratelimited"); + assert_se(count == 20); ++ ++ /* Dispatch the event loop once more and check that ratelimit expiration callback got called */ ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ assert_se(expired == 0); + } + + int main(int argc, char *argv[]) { +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index a17a9b3488..c2e9c9614d 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -147,6 +147,7 @@ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t + int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval_usec, unsigned burst); + int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval_usec, unsigned *ret_burst); + int sd_event_source_is_ratelimited(sd_event_source *s); ++int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback); + + /* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */ + _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref); diff --git a/SOURCES/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch b/SOURCES/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch new file mode 100644 index 0000000..4353eae --- /dev/null +++ b/SOURCES/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch @@ -0,0 +1,263 @@ +From 3674514b7220a136dcfd464c205d41609f0c99a7 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 17:51:52 +0200 +Subject: [PATCH] core: rename/generalize UNIT(u)->test_start_limit() hook + +Up until now the main reason why we didn't proceed with starting the +unit was exceed start limit burst. However, for unit types like mounts +the other reason could be effective ratelimit on /proc/self/mountinfo +event source. That means our mount unit state may not reflect current +kernel state. Hence, we need to attempt to re-run the start job again +after ratelimit on event source expires. + +As we will be introducing another reason than start limit let's rename +the virtual function that implements the check. + +(cherry picked from commit 705578c3b9d794097233aa66010cf67b2a444716) + +Related: #2036608 +--- + src/core/automount.c | 6 +++--- + src/core/mount.c | 6 +++--- + src/core/path.c | 6 +++--- + src/core/service.c | 6 +++--- + src/core/socket.c | 6 +++--- + src/core/swap.c | 6 +++--- + src/core/timer.c | 6 +++--- + src/core/unit.c | 6 +++--- + src/core/unit.h | 2 +- + 9 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 5e16adabb5..f212620c8f 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -1071,7 +1071,7 @@ static bool automount_supported(void) { + return supported; + } + +-static int automount_test_start_limit(Unit *u) { ++static int automount_can_start(Unit *u) { + Automount *a = AUTOMOUNT(u); + int r; + +@@ -1083,7 +1083,7 @@ static int automount_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +@@ -1145,5 +1145,5 @@ const UnitVTable automount_vtable = { + }, + }, + +- .test_start_limit = automount_test_start_limit, ++ .can_start = automount_can_start, + }; +diff --git a/src/core/mount.c b/src/core/mount.c +index 22848847e5..032a2ca156 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1951,7 +1951,7 @@ static int mount_control_pid(Unit *u) { + return m->control_pid; + } + +-static int mount_test_start_limit(Unit *u) { ++static int mount_can_start(Unit *u) { + Mount *m = MOUNT(u); + int r; + +@@ -1963,7 +1963,7 @@ static int mount_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { +@@ -2058,5 +2058,5 @@ const UnitVTable mount_vtable = { + }, + }, + +- .test_start_limit = mount_test_start_limit, ++ .can_start = mount_can_start, + }; +diff --git a/src/core/path.c b/src/core/path.c +index 1e69a1f05f..58f490589d 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -724,7 +724,7 @@ static void path_reset_failed(Unit *u) { + p->result = PATH_SUCCESS; + } + +-static int path_test_start_limit(Unit *u) { ++static int path_can_start(Unit *u) { + Path *p = PATH(u); + int r; + +@@ -736,7 +736,7 @@ static int path_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const path_type_table[_PATH_TYPE_MAX] = { +@@ -792,5 +792,5 @@ const UnitVTable path_vtable = { + .bus_vtable = bus_path_vtable, + .bus_set_property = bus_path_set_property, + +- .test_start_limit = path_test_start_limit, ++ .can_start = path_can_start, + }; +diff --git a/src/core/service.c b/src/core/service.c +index c5f408d817..e8ae1a5772 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -4074,7 +4074,7 @@ static bool service_needs_console(Unit *u) { + SERVICE_FINAL_SIGKILL); + } + +-static int service_test_start_limit(Unit *u) { ++static int service_can_start(Unit *u) { + Service *s = SERVICE(u); + int r; + +@@ -4087,7 +4087,7 @@ static int service_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { +@@ -4232,5 +4232,5 @@ const UnitVTable service_vtable = { + }, + }, + +- .test_start_limit = service_test_start_limit, ++ .can_start = service_can_start, + }; +diff --git a/src/core/socket.c b/src/core/socket.c +index 36d2e4f823..3589300e68 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -3261,7 +3261,7 @@ static int socket_control_pid(Unit *u) { + return s->control_pid; + } + +-static int socket_test_start_limit(Unit *u) { ++static int socket_can_start(Unit *u) { + Socket *s = SOCKET(u); + int r; + +@@ -3273,7 +3273,7 @@ static int socket_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { +@@ -3369,5 +3369,5 @@ const UnitVTable socket_vtable = { + }, + }, + +- .test_start_limit = socket_test_start_limit, ++ .can_start = socket_can_start, + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 90fcd69300..498c5a6d69 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -1452,7 +1452,7 @@ static int swap_control_pid(Unit *u) { + return s->control_pid; + } + +-static int swap_test_start_limit(Unit *u) { ++static int swap_can_start(Unit *u) { + Swap *s = SWAP(u); + int r; + +@@ -1464,7 +1464,7 @@ static int swap_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { +@@ -1557,5 +1557,5 @@ const UnitVTable swap_vtable = { + }, + }, + +- .test_start_limit = swap_test_start_limit, ++ .can_start = swap_can_start, + }; +diff --git a/src/core/timer.c b/src/core/timer.c +index fb9ae17990..684180bf99 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -823,7 +823,7 @@ static void timer_timezone_change(Unit *u) { + timer_enter_waiting(t, false); + } + +-static int timer_test_start_limit(Unit *u) { ++static int timer_can_start(Unit *u) { + Timer *t = TIMER(u); + int r; + +@@ -835,7 +835,7 @@ static int timer_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const timer_base_table[_TIMER_BASE_MAX] = { +@@ -893,5 +893,5 @@ const UnitVTable timer_vtable = { + .bus_set_property = bus_timer_set_property, + + .can_transient = true, +- .test_start_limit = timer_test_start_limit, ++ .can_start = timer_can_start, + }; +diff --git a/src/core/unit.c b/src/core/unit.c +index f0df7452fa..4de218feac 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1728,9 +1728,9 @@ int unit_start(Unit *u) { + + assert(u); + +- /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ +- if (UNIT_VTABLE(u)->test_start_limit) { +- int r = UNIT_VTABLE(u)->test_start_limit(u); ++ /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->can_start) { ++ int r = UNIT_VTABLE(u)->can_start(u); + if (r < 0) + return r; + } +diff --git a/src/core/unit.h b/src/core/unit.h +index 9e6f1bcf81..0cd259411f 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -569,7 +569,7 @@ typedef struct UnitVTable { + + /* If this function is set, it's invoked first as part of starting a unit to allow start rate + * limiting checks to occur before we do anything else. */ +- int (*test_start_limit)(Unit *u); ++ int (*can_start)(Unit *u); + + /* The strings to print in status messages */ + UnitStatusMessageFormats status_message_formats; diff --git a/SOURCES/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch b/SOURCES/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch new file mode 100644 index 0000000..cb7a006 --- /dev/null +++ b/SOURCES/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch @@ -0,0 +1,27 @@ +From cb519c7d769851ee5e24c797fc04eaa13383c674 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 19:41:34 +0200 +Subject: [PATCH] mount: make mount units start jobs not runnable if + /p/s/mountinfo ratelimit is in effect + +(cherry picked from commit a7c93dfe91e88a5a561341c523a45c7f8d71a588) + +Related: #2036608 +--- + src/core/mount.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 032a2ca156..ab09e6fbb0 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1957,6 +1957,9 @@ static int mount_can_start(Unit *u) { + + assert(m); + ++ if (sd_event_source_is_ratelimited(u->manager->mount_event_source)) ++ return -EAGAIN; ++ + r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); diff --git a/SOURCES/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch b/SOURCES/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch new file mode 100644 index 0000000..c4909f6 --- /dev/null +++ b/SOURCES/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch @@ -0,0 +1,54 @@ +From b0c226e9fd3e6bfa5388832cc2745d9ec935f3ec Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 20:31:49 +0200 +Subject: [PATCH] mount: retrigger run queue after ratelimit expired to run + delayed mount start jobs + +Fixes #20329 + +(cherry picked from commit edc027b4f1cfaa49e8ecdde763eb8c623402d464) + +Related: #2036608 +--- + src/core/mount.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index ab09e6fbb0..bdba9e6884 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1710,6 +1710,21 @@ static bool mount_is_mounted(Mount *m) { + return UNIT(m)->perpetual || m->is_mounted; + } + ++static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { ++ Manager *m = userdata; ++ int r; ++ ++ assert(m); ++ ++ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's ++ * make sure we dispatch them in the next iteration. */ ++ r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT); ++ if (r < 0) ++ log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m"); ++ ++ return 0; ++} ++ + static void mount_enumerate(Manager *m) { + int r; + +@@ -1763,6 +1778,12 @@ static void mount_enumerate(Manager *m) { + goto fail; + } + ++ r = sd_event_source_set_ratelimit_expire_callback(m->mount_event_source, mount_on_ratelimit_expire); ++ if (r < 0) { ++ log_error_errno(r, "Failed to enable rate limit for mount events: %m"); ++ goto fail; ++ } ++ + (void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch"); + } + diff --git a/SOURCES/0697-pid1-add-a-manager_trigger_run_queue-helper.patch b/SOURCES/0697-pid1-add-a-manager_trigger_run_queue-helper.patch new file mode 100644 index 0000000..96b3351 --- /dev/null +++ b/SOURCES/0697-pid1-add-a-manager_trigger_run_queue-helper.patch @@ -0,0 +1,98 @@ +From 5a218b6820be7ffaf21cd42cd4c96b47d18442ee Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 12 Nov 2021 09:43:07 +0100 +Subject: [PATCH] pid1: add a manager_trigger_run_queue() helper + +We have two different places where we re-trigger the run queue now. +let's unify it under a common function, that is part of the Manager +code. + +Follow-up for #20953 + +(cherry picked from commit b0c4b2824693fe6a27ea9439ec7a6328a0e23704) + +Related: #2036608 +--- + src/core/job.c | 5 ++--- + src/core/manager.c | 12 ++++++++++++ + src/core/manager.h | 2 ++ + src/core/mount.c | 9 +++------ + 4 files changed, 19 insertions(+), 9 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 43ab55ed18..55f36b928f 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1139,11 +1139,10 @@ void job_add_to_run_queue(Job *j) { + if (j->in_run_queue) + return; + +- if (!j->manager->run_queue) +- sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT); +- + LIST_PREPEND(run_queue, j->manager->run_queue, j); + j->in_run_queue = true; ++ ++ manager_trigger_run_queue(j->manager); + } + + void job_add_to_dbus_queue(Job *j) { +diff --git a/src/core/manager.c b/src/core/manager.c +index ee976f70b3..845c26f498 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2120,6 +2120,18 @@ static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) { + return 1; + } + ++void manager_trigger_run_queue(Manager *m) { ++ int r; ++ ++ assert(m); ++ ++ r = sd_event_source_set_enabled( ++ m->run_queue_event_source, ++ m->run_queue ? SD_EVENT_ONESHOT: SD_EVENT_OFF); ++ if (r < 0) ++ log_warning_errno(r, "Failed to enable job run queue event source, ignoring: %m"); ++} ++ + static unsigned manager_dispatch_dbus_queue(Manager *m) { + unsigned n = 0, budget; + Unit *u; +diff --git a/src/core/manager.h b/src/core/manager.h +index c4b8e80093..7b572c8dfd 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -416,6 +416,8 @@ unsigned manager_dispatch_load_queue(Manager *m); + int manager_environment_add(Manager *m, char **minus, char **plus); + int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); + ++void manager_trigger_run_queue(Manager *m); ++ + int manager_loop(Manager *m); + + int manager_open_serialization(Manager *m, FILE **_f); +diff --git a/src/core/mount.c b/src/core/mount.c +index bdba9e6884..c17154cde1 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1712,15 +1712,12 @@ static bool mount_is_mounted(Mount *m) { + + static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { + Manager *m = userdata; +- int r; + + assert(m); + +- /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's +- * make sure we dispatch them in the next iteration. */ +- r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT); +- if (r < 0) +- log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m"); ++ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so ++ * let's make sure we dispatch them in the next iteration. */ ++ manager_trigger_run_queue(m); + + return 0; + } diff --git a/SOURCES/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch b/SOURCES/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch new file mode 100644 index 0000000..bc7fe06 --- /dev/null +++ b/SOURCES/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch @@ -0,0 +1,46 @@ +From dd662fc39a28655b89619a828a15e5e457bf6f4c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 25 Nov 2021 18:28:25 +0100 +Subject: [PATCH] unit: add jobs that were skipped because of ratelimit back to + run_queue + +Assumption in edc027b was that job we first skipped because of active +ratelimit is still in run_queue. Hence we trigger the queue and dispatch +it in the next iteration. Actually we remove jobs from run_queue in +job_run_and_invalidate() before we call unit_start(). Hence if we want +to attempt to run the job again in the future we need to add it back +to run_queue. + +Fixes #21458 + +(cherry picked from commit c29e6a9530316823b0455cd83eb6d0bb8dd664f4) + +Related: #2036608 +--- + src/core/mount.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index c17154cde1..691b23ca74 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1712,9 +1712,19 @@ static bool mount_is_mounted(Mount *m) { + + static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { + Manager *m = userdata; ++ Job *j; ++ Iterator i; + + assert(m); + ++ /* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */ ++ HASHMAP_FOREACH(j, m->jobs, i) { ++ if (j->unit->type != UNIT_MOUNT) ++ continue; ++ ++ job_add_to_run_queue(j); ++ } ++ + /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so + * let's make sure we dispatch them in the next iteration. */ + manager_trigger_run_queue(m); diff --git a/SOURCES/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch b/SOURCES/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch new file mode 100644 index 0000000..5f9f27b --- /dev/null +++ b/SOURCES/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch @@ -0,0 +1,37 @@ +From 54faef034bb2062ed8afa72e2c1be40ef7cc41c5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:25:09 +0200 +Subject: [PATCH] Revert "Revert "sysctl: Enable ping(8) inside rootless Podman + containers"" + +This reverts commit be74f51605b4c7cb74fec3a50cd13b67598a8ac1. + +Let's add this again. With the new sysctl "-" thing we can make this +work. + +Resolves: #2037807 + +(cherry picked from commit 0338934f4bcda6a96a5342449ae96b003de3378d) +--- + sysctl.d/50-default.conf | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index e0afc9c702..21ae1df13d 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -33,6 +33,14 @@ net.ipv4.conf.all.accept_source_route = 0 + # Promote secondary addresses when the primary address is removed + net.ipv4.conf.all.promote_secondaries = 1 + ++# ping(8) without CAP_NET_ADMIN and CAP_NET_RAW ++# The upper limit is set to 2^31-1. Values greater than that get rejected by ++# the kernel because of this definition in linux/include/net/ping.h: ++# #define GID_T_MAX (((gid_t)~0U) >> 1) ++# That's not so bad because values between 2^31 and 2^32-1 are reserved on ++# systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary ++net.ipv4.ping_group_range = 0 2147483647 ++ + # Fair Queue CoDel packet scheduler to fight bufferbloat + net.core.default_qdisc = fq_codel + diff --git a/SOURCES/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch b/SOURCES/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch new file mode 100644 index 0000000..4e2e566 --- /dev/null +++ b/SOURCES/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch @@ -0,0 +1,27 @@ +From 41a32aeaf5d33f253f48bfbe8d00de9d160985f7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:26:07 +0200 +Subject: [PATCH] sysctl: prefix ping port range setting with a dash + +Fixes: #13177 + +Resolves: #2037807 + +(cherry picked from commit 000500c9d6347e0e2cdb92ec48fa10c0bb3ceca8) +--- + sysctl.d/50-default.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index 21ae1df13d..5156d55ca9 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -39,7 +39,7 @@ net.ipv4.conf.all.promote_secondaries = 1 + # #define GID_T_MAX (((gid_t)~0U) >> 1) + # That's not so bad because values between 2^31 and 2^32-1 are reserved on + # systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary +-net.ipv4.ping_group_range = 0 2147483647 ++-net.ipv4.ping_group_range = 0 2147483647 + + # Fair Queue CoDel packet scheduler to fight bufferbloat + net.core.default_qdisc = fq_codel diff --git a/SOURCES/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch b/SOURCES/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch new file mode 100644 index 0000000..adc7bd1 --- /dev/null +++ b/SOURCES/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch @@ -0,0 +1,56 @@ +From c236734f95550747c4979fe318e3a890adaa0a94 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 28 Nov 2018 12:41:44 +0100 +Subject: [PATCH] mount: don't propagate errors from mount_setup_unit() further + up + +If we can't process a specific line in /proc/self/mountinfo we should +log about it (which we do), but this should not affect other lines, nor +further processing of mount units. Let's keep these failures local. + +Fixes: #10874 + +Cherry picked from commit ba0d56f55f2073164799be714b5bd1aad94d059a. +Trivial conflict in src/core/mount.c, function mount_load_proc_self_mountinfo, +due to local commit ca634baa10e. Also, due to the same commit, int k +is no longer used and is thus removed. + +Resolves: #2036853 + +Signed-off-by: Kir Kolyshkin +--- + src/core/mount.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 691b23ca74..4e0a4f238a 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1615,12 +1615,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + if (r < 0) + return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + +- r = 0; + for (;;) { + struct libmnt_fs *fs; + const char *device, *path, *options, *fstype; + _cleanup_free_ char *d = NULL, *p = NULL; +- int k; + + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) +@@ -1644,12 +1642,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + + device_found_node(m, d, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT); + +- k = mount_setup_unit(m, d, p, options, fstype, set_flags); +- if (r == 0 && k < 0) +- r = k; ++ (void) mount_setup_unit(m, d, p, options, fstype, set_flags); + } + +- return r; ++ return 0; + } + + static void mount_shutdown(Manager *m) { diff --git a/SOURCES/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch b/SOURCES/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch new file mode 100644 index 0000000..822fafc --- /dev/null +++ b/SOURCES/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch @@ -0,0 +1,50 @@ +From d45e0cc7a64648dc3ad082b512ff488537d3ebef Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:35:19 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.5 + +RHEL-only + +Related: #2039797 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index 10e71dcb15..be969bc8d0 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -301,6 +301,12 @@ + avoid possible naming conflict. + + ++ ++ rhel-8.5 ++ ++ Same as naming scheme rhel-8.4. ++ ++ + Note that latest may be used to denote the latest scheme known (to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 7c153f0aef..81139e666b 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -134,6 +134,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_2 = NAMING_V239, + NAMING_RHEL_8_3 = NAMING_V239, + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, ++ NAMING_RHEL_8_5 = NAMING_RHEL_8_4, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -151,6 +152,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.2", NAMING_RHEL_8_2 }, + { "rhel-8.3", NAMING_RHEL_8_3 }, + { "rhel-8.4", NAMING_RHEL_8_4 }, ++ { "rhel-8.5", NAMING_RHEL_8_5 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0703-udev-net_id-remove-extraneous-bracket.patch b/SOURCES/0703-udev-net_id-remove-extraneous-bracket.patch new file mode 100644 index 0000000..6c3efb8 --- /dev/null +++ b/SOURCES/0703-udev-net_id-remove-extraneous-bracket.patch @@ -0,0 +1,25 @@ +From a967622c58e1ae76bb7e22e83389295c77d560df Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:35:54 +0100 +Subject: [PATCH] udev/net_id: remove extraneous bracket + +RHEL-only + +Related: #2039797 +--- + man/systemd.net-naming-scheme.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index be969bc8d0..a65da5c6c1 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -307,7 +307,7 @@ + Same as naming scheme rhel-8.4. + + +- Note that latest may be used to denote the latest scheme known (to this ++ Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +
diff --git a/SOURCES/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch b/SOURCES/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch new file mode 100644 index 0000000..a5f712f --- /dev/null +++ b/SOURCES/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch @@ -0,0 +1,50 @@ +From 7ee6542c64103205d6520c1165894b3b6a40f2c9 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:38:38 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.6 + +RHEL-only + +Related: #2039797 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index a65da5c6c1..fe1aa4b654 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -307,6 +307,12 @@ + Same as naming scheme rhel-8.4. + + ++ ++ rhel-8.6 ++ ++ Same as naming scheme rhel-8.4. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 81139e666b..eafcbb64c5 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -135,6 +135,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_3 = NAMING_V239, + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + NAMING_RHEL_8_5 = NAMING_RHEL_8_4, ++ NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -153,6 +154,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.3", NAMING_RHEL_8_3 }, + { "rhel-8.4", NAMING_RHEL_8_4 }, + { "rhel-8.5", NAMING_RHEL_8_5 }, ++ { "rhel-8.6", NAMING_RHEL_8_6 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0705-define-newly-needed-constants.patch b/SOURCES/0705-define-newly-needed-constants.patch new file mode 100644 index 0000000..9281b84 --- /dev/null +++ b/SOURCES/0705-define-newly-needed-constants.patch @@ -0,0 +1,60 @@ +From 08c1e6e304108e8bc8beca126f50888be7575bd0 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 26 Nov 2020 16:29:10 +0100 +Subject: [PATCH] define newly needed constants + +Related: #2005008 +--- + src/basic/missing.h | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/src/basic/missing.h b/src/basic/missing.h +index 14ad3d4914..b9376617fc 100644 +--- a/src/basic/missing.h ++++ b/src/basic/missing.h +@@ -747,10 +747,13 @@ struct input_mask { + #define IFLA_NUM_RX_QUEUES 32 + #define IFLA_CARRIER 33 + #define IFLA_PHYS_PORT_ID 34 +-#define __IFLA_MAX 35 ++#endif ++ ++#define IFLA_PROP_LIST 52 ++#define IFLA_ALT_IFNAME 53 ++#define __IFLA_MAX 53 + + #define IFLA_MAX (__IFLA_MAX - 1) +-#endif + + #if !HAVE_IFLA_BOND_AD_INFO + #define IFLA_BOND_UNSPEC 0 +@@ -1045,6 +1048,18 @@ struct input_mask { + #define RTA_EXPIRES 23 + #endif + ++#ifndef RTM_NEWLINKPROP ++#define RTM_NEWLINKPROP 108 ++#endif ++ ++#ifndef RTM_DELLINKPROP ++#define RTM_DELLINKPROP 109 ++#endif ++ ++#ifndef RTM_GETLINKPROP ++#define RTM_GETLINKPROP 110 ++#endif ++ + #ifndef IPV6_UNICAST_IF + #define IPV6_UNICAST_IF 76 + #endif +@@ -1057,6 +1072,10 @@ struct input_mask { + #define IPV4_MIN_MTU 68 + #endif + ++#ifndef ALTIFNAMSIZ ++#define ALTIFNAMSIZ 128 ++#endif ++ + #ifndef IFF_MULTI_QUEUE + #define IFF_MULTI_QUEUE 0x100 + #endif diff --git a/SOURCES/0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch b/SOURCES/0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch new file mode 100644 index 0000000..6b0e46b --- /dev/null +++ b/SOURCES/0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch @@ -0,0 +1,95 @@ +From 32e39fd249737c77248c32d064021426a2ec7a52 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 20:57:51 +0900 +Subject: [PATCH] sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME + attributes + +(cherry picked from commit ffeb16f5d832b1c65b8c8a1dd9bdd028bd76fc72) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-message.c | 2 +- + src/libsystemd/sd-netlink/netlink-types.c | 13 +++++++++++++ + src/libsystemd/sd-netlink/netlink-util.h | 4 +++- + src/libsystemd/sd-netlink/rtnl-message.c | 2 ++ + 4 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c +index 23907c8224..db9101c163 100644 +--- a/src/libsystemd/sd-netlink/netlink-message.c ++++ b/src/libsystemd/sd-netlink/netlink-message.c +@@ -89,7 +89,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) { + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + +- assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL); ++ assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETLINKPROP, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL); + + SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump); + +diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c +index c93fe9cb4c..47d9c7f1c4 100644 +--- a/src/libsystemd/sd-netlink/netlink-types.c ++++ b/src/libsystemd/sd-netlink/netlink-types.c +@@ -451,6 +451,15 @@ static const NLTypeSystem rtnl_af_spec_type_system = { + .types = rtnl_af_spec_types, + }; + ++static const NLType rtnl_prop_list_types[] = { ++ [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, ++}; ++ ++static const NLTypeSystem rtnl_prop_list_type_system = { ++ .count = ELEMENTSOF(rtnl_prop_list_types), ++ .types = rtnl_prop_list_types, ++}; ++ + static const NLType rtnl_link_types[] = { + [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, +@@ -501,6 +510,7 @@ static const NLType rtnl_link_types[] = { + /* + [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, + */ ++ [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, + }; + + static const NLTypeSystem rtnl_link_type_system = { +@@ -643,6 +653,9 @@ static const NLType rtnl_types[] = { + [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, ++ [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, ++ [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, ++ [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, +diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h +index 7c35a2cfa7..882a616310 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.h ++++ b/src/libsystemd/sd-netlink/netlink-util.h +@@ -19,7 +19,9 @@ static inline bool rtnl_message_type_is_route(uint16_t type) { + } + + static inline bool rtnl_message_type_is_link(uint16_t type) { +- return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK); ++ return IN_SET(type, ++ RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK, ++ RTM_NEWLINKPROP, RTM_DELLINKPROP, RTM_GETLINKPROP); + } + + static inline bool rtnl_message_type_is_addr(uint16_t type) { +diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c +index 4416e1720c..369c402986 100644 +--- a/src/libsystemd/sd-netlink/rtnl-message.c ++++ b/src/libsystemd/sd-netlink/rtnl-message.c +@@ -449,6 +449,8 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret, + + if (nlmsg_type == RTM_NEWLINK) + (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; ++ else if (nlmsg_type == RTM_NEWLINK) ++ (*ret)->hdr->nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND; + + ifi = NLMSG_DATA((*ret)->hdr); + diff --git a/SOURCES/0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch b/SOURCES/0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch new file mode 100644 index 0000000..ecf264c --- /dev/null +++ b/SOURCES/0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch @@ -0,0 +1,106 @@ +From cd3b4c5345a3500f190941454fff03fc143c6f2e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 21:32:25 +0900 +Subject: [PATCH] sd-netlink: introduce sd_netlink_message_read_strv() + +The combination of sd_netlink_message_enter_container() and +sd_netlink_message_read_string() only reads the last element if the attribute is +duplicated, such a situation easily happens for IFLA_ALT_IFNAME. +The function introduced here reads all matched attributes. + +(cherry picked from commit 8f3c1859669230c2c8458675f41de13e369b47e7) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-message.c | 58 +++++++++++++++++++++ + src/systemd/sd-netlink.h | 1 + + 2 files changed, 59 insertions(+) + +diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c +index db9101c163..5723e1d21c 100644 +--- a/src/libsystemd/sd-netlink/netlink-message.c ++++ b/src/libsystemd/sd-netlink/netlink-message.c +@@ -14,6 +14,7 @@ + #include "netlink-util.h" + #include "refcnt.h" + #include "socket-util.h" ++#include "strv.h" + #include "util.h" + + #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL) +@@ -754,6 +755,63 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, + return 0; + } + ++int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret) { ++ _cleanup_strv_free_ char **s = NULL; ++ const NLTypeSystem *type_system; ++ const NLType *nl_type; ++ struct rtattr *rta; ++ void *container; ++ unsigned short rt_len; ++ int r; ++ ++ assert_return(m, -EINVAL); ++ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); ++ ++ r = type_system_get_type(m->containers[m->n_containers].type_system, ++ &nl_type, ++ container_type); ++ if (r < 0) ++ return r; ++ ++ if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) ++ return -EINVAL; ++ ++ r = type_system_get_type_system(m->containers[m->n_containers].type_system, ++ &type_system, ++ container_type); ++ if (r < 0) ++ return r; ++ ++ r = type_system_get_type(type_system, &nl_type, type_id); ++ if (r < 0) ++ return r; ++ ++ if (type_get_type(nl_type) != NETLINK_TYPE_STRING) ++ return -EINVAL; ++ ++ r = netlink_message_read_internal(m, container_type, &container, NULL); ++ if (r < 0) ++ return r; ++ ++ rt_len = (unsigned short) r; ++ rta = container; ++ ++ for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) { ++ unsigned short type; ++ ++ type = RTA_TYPE(rta); ++ if (type != type_id) ++ continue; ++ ++ r = strv_extend(&s, RTA_DATA(rta)); ++ if (r < 0) ++ return r; ++ } ++ ++ *ret = TAKE_PTR(s); ++ return 0; ++} ++ + static int netlink_container_parse(sd_netlink_message *m, + struct netlink_container *container, + int count, +diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h +index 51f0fa16b4..1f5c093f11 100644 +--- a/src/systemd/sd-netlink.h ++++ b/src/systemd/sd-netlink.h +@@ -82,6 +82,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor + int sd_netlink_message_close_container(sd_netlink_message *m); + + int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data); ++int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret); + int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data); + int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data); + int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data); diff --git a/SOURCES/0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch b/SOURCES/0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch new file mode 100644 index 0000000..2f66c13 --- /dev/null +++ b/SOURCES/0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch @@ -0,0 +1,65 @@ +From bbfebb42c9023e36fb66f0e3b0bad132ab2fba55 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 21:47:21 +0900 +Subject: [PATCH] sd-netlink: introduce sd_netlink_message_append_strv() + +(cherry picked from commit 6d725977c4f98a8f5effc33f44aa646cc2b6a0b7) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-message.c | 29 +++++++++++++++++++++ + src/systemd/sd-netlink.h | 1 + + 2 files changed, 30 insertions(+) + +diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c +index 5723e1d21c..55d6510b63 100644 +--- a/src/libsystemd/sd-netlink/netlink-message.c ++++ b/src/libsystemd/sd-netlink/netlink-message.c +@@ -259,6 +259,35 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, + return 0; + } + ++int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data) { ++ size_t length, size; ++ char * const *p; ++ int r; ++ ++ assert_return(m, -EINVAL); ++ assert_return(!m->sealed, -EPERM); ++ assert_return(data, -EINVAL); ++ ++ r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH(p, data) { ++ if (size) { ++ length = strnlen(*p, size+1); ++ if (length > size) ++ return -EINVAL; ++ } else ++ length = strlen(*p); ++ ++ r = add_rtattr(m, type, *p, length + 1); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ + int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type) { + size_t size; + int r; +diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h +index 1f5c093f11..5a05cd4485 100644 +--- a/src/systemd/sd-netlink.h ++++ b/src/systemd/sd-netlink.h +@@ -67,6 +67,7 @@ int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority); + int sd_netlink_detach_event(sd_netlink *nl); + + int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data); ++int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data); + int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type); + int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data); + int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data); diff --git a/SOURCES/0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch b/SOURCES/0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch new file mode 100644 index 0000000..082a4e3 --- /dev/null +++ b/SOURCES/0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch @@ -0,0 +1,71 @@ +From 58d0d77ddda4c02943d1f03e4c142aec9c4930f5 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 21:48:12 +0900 +Subject: [PATCH] test: add a test for sd_netlink_message_{append,read}_strv() + +(cherry picked from commit d08d92d5ee508a80e35d6b95b962bd09527fb5f2) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/test-netlink.c | 33 ++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c +index 03773fb936..8ee6551385 100644 +--- a/src/libsystemd/sd-netlink/test-netlink.c ++++ b/src/libsystemd/sd-netlink/test-netlink.c +@@ -10,7 +10,9 @@ + #include "missing.h" + #include "netlink-util.h" + #include "socket-util.h" ++#include "stdio-util.h" + #include "string-util.h" ++#include "strv.h" + #include "util.h" + + static void test_message_link_bridge(sd_netlink *rtnl) { +@@ -357,6 +359,36 @@ static void test_message(sd_netlink *rtnl) { + assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); + } + ++static void test_strv(sd_netlink *rtnl) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; ++ _cleanup_strv_free_ char **names_in = NULL, **names_out; ++ const char *p; ++ ++ assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0); ++ ++ for (unsigned i = 0; i < 10; i++) { ++ char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)]; ++ ++ xsprintf(name, "hoge%" PRIu32, i + 1000); ++ assert_se(strv_extend(&names_in, name) >= 0); ++ } ++ ++ assert_se(sd_netlink_message_open_container(m, IFLA_PROP_LIST) >= 0); ++ assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0); ++ assert_se(sd_netlink_message_close_container(m) >= 0); ++ ++ rtnl_message_seal(m); ++ assert_se(sd_netlink_message_rewind(m) >= 0); ++ ++ assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0); ++ assert_se(strv_equal(names_in, names_out)); ++ ++ assert_se(sd_netlink_message_enter_container(m, IFLA_PROP_LIST) >= 0); ++ assert_se(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p) >= 0); ++ assert_se(streq(p, "hoge1009")); ++ assert_se(sd_netlink_message_exit_container(m) >= 0); ++} ++ + int main(void) { + sd_netlink *rtnl; + sd_netlink_message *m; +@@ -377,6 +409,7 @@ int main(void) { + test_message(rtnl); + + test_container(rtnl); ++ test_strv(rtnl); + + if_loopback = (int) if_nametoindex("lo"); + assert_se(if_loopback > 0); diff --git a/SOURCES/0710-util-introduce-ifname_valid_full.patch b/SOURCES/0710-util-introduce-ifname_valid_full.patch new file mode 100644 index 0000000..c04c995 --- /dev/null +++ b/SOURCES/0710-util-introduce-ifname_valid_full.patch @@ -0,0 +1,79 @@ +From 1b12b8e9c0f6f230e12ca13bd70f27ef0a2fcfdd Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 23:01:54 +0900 +Subject: [PATCH] util: introduce ifname_valid_full() + +(cherry picked from commit 4252696aec9ec038ff312a164e25f039da25126f) + +Related: #2005008 +--- + src/basic/socket-util.c | 12 +++++++++--- + src/basic/socket-util.h | 5 ++++- + src/test/test-socket-util.c | 1 + + 3 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index 053bcba670..7f8066123b 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + #include "alloc-util.h" + #include "fd-util.h" +@@ -868,7 +869,7 @@ static const char* const ip_tos_table[] = { + + DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); + +-bool ifname_valid(const char *p) { ++bool ifname_valid_full(const char *p, bool alternative) { + bool numeric = true; + + /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources +@@ -878,8 +879,13 @@ bool ifname_valid(const char *p) { + if (isempty(p)) + return false; + +- if (strlen(p) >= IFNAMSIZ) +- return false; ++ if (alternative) { ++ if (strlen(p) >= ALTIFNAMSIZ) ++ return false; ++ } else { ++ if (strlen(p) >= IFNAMSIZ) ++ return false; ++ } + + if (dot_or_dot_dot(p)) + return false; +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index c7c9ad34d6..30baba6c03 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -123,7 +123,10 @@ int fd_inc_rcvbuf(int fd, size_t n); + int ip_tos_to_string_alloc(int i, char **s); + int ip_tos_from_string(const char *s); + +-bool ifname_valid(const char *p); ++bool ifname_valid_full(const char *p, bool alternative); ++static inline bool ifname_valid(const char *p) { ++ return ifname_valid_full(p, false); ++} + bool address_label_valid(const char *p); + + int getpeercred(int fd, struct ucred *ucred); +diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c +index 19c5395b92..c545622c09 100644 +--- a/src/test/test-socket-util.c ++++ b/src/test/test-socket-util.c +@@ -39,6 +39,7 @@ static void test_ifname_valid(void) { + + assert(ifname_valid("xxxxxxxxxxxxxxx")); + assert(!ifname_valid("xxxxxxxxxxxxxxxx")); ++ assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true)); + } + + static void test_socket_address_parse(void) { diff --git a/SOURCES/0711-rename-function.patch b/SOURCES/0711-rename-function.patch new file mode 100644 index 0000000..f256c15 --- /dev/null +++ b/SOURCES/0711-rename-function.patch @@ -0,0 +1,69 @@ +From 3275093305c1305d163f26cb4e4d614a87f8ff43 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 27 Nov 2020 10:25:12 +0100 +Subject: [PATCH] rename function + +This happened upstream in commit +54a8423788ec3cc6240959ab9f5cdac40baf047a, but I don't want to backport +the whole commit... + +Related: #2005008 +--- + src/libsystemd-network/network-internal.c | 2 +- + src/libsystemd-network/network-internal.h | 2 +- + src/network/networkd-network-gperf.gperf | 2 +- + src/udev/net/link-config-gperf.gperf | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c +index 0849b44ee2..629e858def 100644 +--- a/src/libsystemd-network/network-internal.c ++++ b/src/libsystemd-network/network-internal.c +@@ -183,7 +183,7 @@ int config_parse_net_condition(const char *unit, + return 0; + } + +-int config_parse_ifnames( ++int config_parse_match_ifnames( + const char *unit, + const char *filename, + unsigned line, +diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h +index 883f34b95c..9074758bbb 100644 +--- a/src/libsystemd-network/network-internal.h ++++ b/src/libsystemd-network/network-internal.h +@@ -34,7 +34,7 @@ bool net_match_config(Set *match_mac, + CONFIG_PARSER_PROTOTYPE(config_parse_net_condition); + CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr); + CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs); +-CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); ++CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames); + CONFIG_PARSER_PROTOTYPE(config_parse_ifalias); + CONFIG_PARSER_PROTOTYPE(config_parse_iaid); + CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority); +diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf +index 6ad5257f79..c4a2eccdc2 100644 +--- a/src/network/networkd-network-gperf.gperf ++++ b/src/network/networkd-network-gperf.gperf +@@ -24,7 +24,7 @@ Match.MACAddress, config_parse_hwaddrs, + Match.Path, config_parse_strv, 0, offsetof(Network, match_path) + Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) + Match.Type, config_parse_strv, 0, offsetof(Network, match_type) +-Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) ++Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name) + Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) + Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) + Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline) +diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf +index 5640fa0513..b37836d852 100644 +--- a/src/udev/net/link-config-gperf.gperf ++++ b/src/udev/net/link-config-gperf.gperf +@@ -20,7 +20,7 @@ struct ConfigPerfItem; + %includes + %% + Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac) +-Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name) ++Match.OriginalName, config_parse_match_ifnames, 0, offsetof(link_config, match_name) + Match.Path, config_parse_strv, 0, offsetof(link_config, match_path) + Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver) + Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) diff --git a/SOURCES/0712-udev-support-AlternativeName-setting-in-.link-file.patch b/SOURCES/0712-udev-support-AlternativeName-setting-in-.link-file.patch new file mode 100644 index 0000000..d4fe837 --- /dev/null +++ b/SOURCES/0712-udev-support-AlternativeName-setting-in-.link-file.patch @@ -0,0 +1,238 @@ +From a29790ac578540ccb4264367603aba9bc41d1bf7 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 23:21:18 +0900 +Subject: [PATCH] udev: support AlternativeName= setting in .link file + +(cherry picked from commit a5053a158b43c5ddee90f4915b9fc603e0191d6d) + +Related: #2005008 +--- + man/systemd.link.xml | 8 ++++ + src/libsystemd/sd-netlink/netlink-util.c | 40 ++++++++++++++++ + src/libsystemd/sd-netlink/netlink-util.h | 1 + + src/shared/conf-parser.c | 60 ++++++++++++++++++++++++ + src/shared/conf-parser.h | 1 + + src/udev/net/link-config-gperf.gperf | 1 + + src/udev/net/link-config.c | 5 ++ + src/udev/net/link-config.h | 1 + + 8 files changed, 117 insertions(+) + +diff --git a/man/systemd.link.xml b/man/systemd.link.xml +index 32657308d0..0b0d83349d 100644 +--- a/man/systemd.link.xml ++++ b/man/systemd.link.xml +@@ -343,6 +343,14 @@ + + + ++ ++ AlternativeName= ++ ++ The alternative interface name to use. This option can be specified multiple times. ++ If the empty string is assigned to this option, the list is reset, and all prior assignments ++ have no effect. ++ ++ + + MTUBytes= + +diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c +index 3928dfbabf..c1c306f121 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.c ++++ b/src/libsystemd/sd-netlink/netlink-util.c +@@ -4,6 +4,7 @@ + + #include "netlink-internal.h" + #include "netlink-util.h" ++#include "strv.h" + + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; +@@ -80,6 +81,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, + return 0; + } + ++int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; ++ int r; ++ ++ assert(rtnl); ++ assert(ifindex > 0); ++ ++ if (strv_isempty(alternative_names)) ++ return 0; ++ ++ if (!*rtnl) { ++ r = sd_netlink_open(rtnl); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_message_open_container(message, IFLA_PROP_LIST); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_message_close_container(message); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_call(*rtnl, message, 0, NULL); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) { + struct nlmsgerr *err; + int r; +diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h +index 882a616310..92de19c092 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.h ++++ b/src/libsystemd/sd-netlink/netlink-util.h +@@ -38,6 +38,7 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) { + + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name); + int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu); ++int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names); + + int rtnl_log_parse_error(int r); + int rtnl_log_create_error(int r); +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index 246b7431e4..1f40f00c72 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -970,6 +970,66 @@ int config_parse_ifname( + return 0; + } + ++int config_parse_ifnames( ++ const char *unit, ++ const char *filename, ++ unsigned line, ++ const char *section, ++ unsigned section_line, ++ const char *lvalue, ++ int ltype, ++ const char *rvalue, ++ void *data, ++ void *userdata) { ++ ++ _cleanup_strv_free_ char **names = NULL; ++ char ***s = data; ++ const char *p; ++ int r; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ assert(data); ++ ++ if (isempty(rvalue)) { ++ *s = strv_free(*s); ++ return 0; ++ } ++ ++ p = rvalue; ++ for (;;) { ++ _cleanup_free_ char *word = NULL; ++ ++ r = extract_first_word(&p, &word, NULL, 0); ++ if (r < 0) { ++ log_syntax(unit, LOG_ERR, filename, line, r, ++ "Failed to extract interface name, ignoring assignment: %s", ++ rvalue); ++ return 0; ++ } ++ if (r == 0) ++ break; ++ ++ if (!ifname_valid_full(word, ltype)) { ++ log_syntax(unit, LOG_ERR, filename, line, 0, ++ "Interface name is not valid or too long, ignoring assignment: %s", ++ word); ++ continue; ++ } ++ ++ r = strv_consume(&names, TAKE_PTR(word)); ++ if (r < 0) ++ return log_oom(); ++ } ++ ++ r = strv_extend_strv(s, names, true); ++ if (r < 0) ++ return log_oom(); ++ ++ return 0; ++} ++ + int config_parse_ip_port( + const char *unit, + const char *filename, +diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h +index a0a5c89c27..375b2e5a74 100644 +--- a/src/shared/conf-parser.h ++++ b/src/shared/conf-parser.h +@@ -137,6 +137,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_signal); + CONFIG_PARSER_PROTOTYPE(config_parse_personality); + CONFIG_PARSER_PROTOTYPE(config_parse_permille); + CONFIG_PARSER_PROTOTYPE(config_parse_ifname); ++CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); + CONFIG_PARSER_PROTOTYPE(config_parse_ip_port); + CONFIG_PARSER_PROTOTYPE(config_parse_join_controllers); + CONFIG_PARSER_PROTOTYPE(config_parse_mtu); +diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf +index b37836d852..913c754145 100644 +--- a/src/udev/net/link-config-gperf.gperf ++++ b/src/udev/net/link-config-gperf.gperf +@@ -34,6 +34,7 @@ Link.MACAddressPolicy, config_parse_mac_policy, 0, + Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac) + Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy) + Link.Name, config_parse_ifname, 0, offsetof(link_config, name) ++Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names) + Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias) + Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu) + Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed) +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 5113586457..d07a1a1874 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -67,6 +67,7 @@ static void link_config_free(link_config *link) { + free(link->mac); + free(link->name_policy); + free(link->name); ++ strv_free(link->alternative_names); + free(link->alias); + + free(link); +@@ -468,6 +469,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + if (r < 0) + return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name); + ++ r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names); ++ if (r < 0) ++ return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name); ++ + *name = new_name; + + return 0; +diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h +index 4798bb101c..93d5fdce59 100644 +--- a/src/udev/net/link-config.h ++++ b/src/udev/net/link-config.h +@@ -50,6 +50,7 @@ struct link_config { + MACPolicy mac_policy; + NamePolicy *name_policy; + char *name; ++ char **alternative_names; + char *alias; + uint32_t mtu; + size_t speed; diff --git a/SOURCES/0713-network-make-Name-in-Match-support-alternative-names.patch b/SOURCES/0713-network-make-Name-in-Match-support-alternative-names.patch new file mode 100644 index 0000000..2783da9 --- /dev/null +++ b/SOURCES/0713-network-make-Name-in-Match-support-alternative-names.patch @@ -0,0 +1,143 @@ +From 0c178bf442aebcd2b42f10a0e4d2382a15505bb6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 15 Dec 2019 22:46:19 +0900 +Subject: [PATCH] network: make Name= in [Match] support alternative names of + interfaces + +(cherry picked from commit 572b21d96cabd5860b0670e98440b6cb99a4b749 +src/network bits have been left out.) + +Related: #2005008 +--- + man/systemd.network.xml | 7 +++---- + src/libsystemd-network/network-internal.c | 20 ++++++++++++++++++-- + src/libsystemd-network/network-internal.h | 3 ++- + src/network/netdev/netdev.c | 2 +- + src/network/networkd-network.c | 2 +- + src/udev/net/link-config.c | 3 ++- + 6 files changed, 27 insertions(+), 10 deletions(-) + +diff --git a/man/systemd.network.xml b/man/systemd.network.xml +index fc8e0aea68..8300540096 100644 +--- a/man/systemd.network.xml ++++ b/man/systemd.network.xml +@@ -133,10 +133,9 @@ + + Name= + +- A whitespace-separated list of shell-style globs +- matching the device name, as exposed by the udev property +- INTERFACE. If the list is prefixed +- with a "!", the test is inverted. ++ A whitespace-separated list of shell-style globs matching the device name, as exposed ++ by the udev property INTERFACE, or device's alternative names. If the ++ list is prefixed with a "!", the test is inverted. + + + +diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c +index 629e858def..a935709cd0 100644 +--- a/src/libsystemd-network/network-internal.c ++++ b/src/libsystemd-network/network-internal.c +@@ -92,6 +92,18 @@ static bool net_condition_test_strv(char * const *raw_patterns, + return string && strv_fnmatch(raw_patterns, string, 0); + } + ++static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) { ++ if (net_condition_test_strv(patterns, ifname)) ++ return true; ++ ++ char * const *p; ++ STRV_FOREACH(p, alternative_names) ++ if (net_condition_test_strv(patterns, *p)) ++ return true; ++ ++ return false; ++} ++ + bool net_match_config(Set *match_mac, + char * const *match_paths, + char * const *match_drivers, +@@ -107,7 +119,8 @@ bool net_match_config(Set *match_mac, + const char *dev_parent_driver, + const char *dev_driver, + const char *dev_type, +- const char *dev_name) { ++ const char *dev_name, ++ char * const *alternative_names) { + + if (match_host && condition_test(match_host) <= 0) + return false; +@@ -124,6 +137,9 @@ bool net_match_config(Set *match_mac, + if (match_arch && condition_test(match_arch) <= 0) + return false; + ++ if (!net_condition_test_ifname(match_names, dev_name, alternative_names)) ++ return false; ++ + if (match_mac && dev_mac && !set_contains(match_mac, dev_mac)) + return false; + +@@ -214,7 +230,7 @@ int config_parse_match_ifnames( + if (r == 0) + break; + +- if (!ifname_valid(word)) { ++ if (!ifname_valid_full(word, ltype)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue); + return 0; + } +diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h +index 9074758bbb..e1d098f3fe 100644 +--- a/src/libsystemd-network/network-internal.h ++++ b/src/libsystemd-network/network-internal.h +@@ -29,7 +29,8 @@ bool net_match_config(Set *match_mac, + const char *dev_parent_driver, + const char *dev_driver, + const char *dev_type, +- const char *dev_name); ++ const char *dev_name, ++ char * const *alternative_names); + + CONFIG_PARSER_PROTOTYPE(config_parse_net_condition); + CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr); +diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c +index 82ce88402f..e97cc07028 100644 +--- a/src/network/netdev/netdev.c ++++ b/src/network/netdev/netdev.c +@@ -640,7 +640,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { + netdev_raw->match_host, netdev_raw->match_virt, + netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version, + netdev_raw->match_arch, +- NULL, NULL, NULL, NULL, NULL, NULL) <= 0) ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL) <= 0) + return 0; + + if (netdev_raw->kind == _NETDEV_KIND_INVALID) { +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c +index 429aac5e6c..7637d135a4 100644 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -479,7 +479,7 @@ int network_get(Manager *manager, struct udev_device *device, + network->match_virt, network->match_kernel_cmdline, + network->match_kernel_version, network->match_arch, + address, path, parent_driver, driver, +- devtype, ifname)) { ++ devtype, ifname, NULL)) { + if (network->match_name && device) { + const char *attr; + uint8_t name_assign_type = NET_NAME_UNKNOWN; +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index d07a1a1874..e5052f8f29 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -238,7 +238,8 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device, + udev_device_get_driver(udev_device_get_parent(device)), + udev_device_get_property_value(device, "ID_NET_DRIVER"), + udev_device_get_devtype(device), +- udev_device_get_sysname(device))) { ++ udev_device_get_sysname(device), ++ NULL)) { + if (link->match_name) { + unsigned char name_assign_type = NET_NAME_UNKNOWN; + diff --git a/SOURCES/0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch b/SOURCES/0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch new file mode 100644 index 0000000..191049a --- /dev/null +++ b/SOURCES/0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch @@ -0,0 +1,170 @@ +From 9f59dca3868b1e934a2aac2d811c55ab33cca0eb Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Dec 2019 11:01:35 +0900 +Subject: [PATCH] udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ + +(cherry picked from commit 78f8849f84ca0939796edb840e878a9d2e124a4d) + +Related: #2005008 +--- + src/udev/net/link-config.c | 5 ++++- + src/udev/udev-builtin-net_id.c | 33 +++++++++++++++++---------------- + src/udev/udev-event.c | 4 ++-- + 3 files changed, 23 insertions(+), 19 deletions(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index e5052f8f29..4de8ee7d7e 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -19,6 +19,7 @@ + #include "path-util.h" + #include "proc-cmdline.h" + #include "random-util.h" ++#include "socket-util.h" + #include "stat-util.h" + #include "string-table.h" + #include "string-util.h" +@@ -405,7 +406,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + NamePolicy *policy; + + for (policy = config->name_policy; +- !new_name && *policy != _NAMEPOLICY_INVALID; policy++) { ++ *policy != _NAMEPOLICY_INVALID; policy++) { + switch (*policy) { + case NAMEPOLICY_KERNEL: + respect_predictable = true; +@@ -428,6 +429,8 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + default: + break; + } ++ if (ifname_valid(new_name)) ++ break; + } + } + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index eafcbb64c5..386d74ca5e 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -90,6 +90,7 @@ + #include + #include + #include ++#include + #include + + #include "dirent-util.h" +@@ -176,21 +177,21 @@ struct netnames { + bool mac_valid; + + struct udev_device *pcidev; +- char pci_slot[IFNAMSIZ]; +- char pci_path[IFNAMSIZ]; +- char pci_onboard[IFNAMSIZ]; ++ char pci_slot[ALTIFNAMSIZ]; ++ char pci_path[ALTIFNAMSIZ]; ++ char pci_onboard[ALTIFNAMSIZ]; + const char *pci_onboard_label; + +- char usb_ports[IFNAMSIZ]; +- char bcma_core[IFNAMSIZ]; +- char ccw_busid[IFNAMSIZ]; +- char vio_slot[IFNAMSIZ]; +- char platform_path[IFNAMSIZ]; ++ char usb_ports[ALTIFNAMSIZ]; ++ char bcma_core[ALTIFNAMSIZ]; ++ char ccw_busid[ALTIFNAMSIZ]; ++ char vio_slot[ALTIFNAMSIZ]; ++ char platform_path[ALTIFNAMSIZ]; + }; + + struct virtfn_info { + struct udev_device *physfn_pcidev; +- char suffix[IFNAMSIZ]; ++ char suffix[ALTIFNAMSIZ]; + }; + + static const NamingScheme* naming_scheme_from_name(const char *name) { +@@ -887,7 +888,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + + err = names_mac(dev, &names); + if (err >= 0 && names.mac_valid) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix, + names.mac[0], names.mac[1], names.mac[2], +@@ -900,7 +901,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + /* get path names for Linux on System z network devices */ + err = names_ccw(dev, &names); + if (err >= 0 && names.type == NET_CCW) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.ccw_busid)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); +@@ -910,7 +911,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + /* get ibmveth/ibmvnic slot-based names. */ + err = names_vio(dev, &names); + if (err >= 0 && names.type == NET_VIO) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.vio_slot)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); +@@ -920,7 +921,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + /* get ACPI path names for ARM64 platform devices */ + err = names_platform(dev, &names, test); + if (err >= 0 && names.type == NET_PLATFORM) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.platform_path)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); +@@ -934,7 +935,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + + /* plain PCI device */ + if (names.type == NET_PCI) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (names.pci_onboard[0] && + snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_onboard)) +@@ -957,7 +958,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + /* USB device */ + err = names_usb(dev, &names); + if (err >= 0 && names.type == NET_USB) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (names.pci_path[0] && + snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.usb_ports)) +@@ -972,7 +973,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + /* Broadcom bus */ + err = names_bcma(dev, &names); + if (err >= 0 && names.type == NET_BCMA) { +- char str[IFNAMSIZ]; ++ char str[ALTIFNAMSIZ]; + + if (names.pci_path[0] && + snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.bcma_core)) +diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c +index fd8406d959..19b100d4f8 100644 +--- a/src/udev/udev-event.c ++++ b/src/udev/udev-event.c +@@ -816,13 +816,13 @@ out: + + static int rename_netif(struct udev_event *event) { + struct udev_device *dev = event->dev; +- char name[IFNAMSIZ]; ++ char name[ALTIFNAMSIZ]; + const char *oldname; + int r; + + oldname = udev_device_get_sysname(dev); + +- strscpy(name, IFNAMSIZ, event->name); ++ strscpy(name, ALTIFNAMSIZ, event->name); + + r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name); + if (r < 0) diff --git a/SOURCES/0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch b/SOURCES/0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch new file mode 100644 index 0000000..29abb68 --- /dev/null +++ b/SOURCES/0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch @@ -0,0 +1,43 @@ +From f0b11f5042489c85d5016eceff06647bb49d486a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Dec 2019 15:32:22 +0900 +Subject: [PATCH] udev: do not fail if kernel does not support alternative + names + +(cherry picked from commit bb181dd4a664ca8e82a8f7194261fd6531e861d8) + +Related: #2005008 +--- + man/systemd.link.xml | 3 ++- + src/udev/net/link-config.c | 4 +++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/man/systemd.link.xml b/man/systemd.link.xml +index 0b0d83349d..c8ebb751ee 100644 +--- a/man/systemd.link.xml ++++ b/man/systemd.link.xml +@@ -348,7 +348,8 @@ + + The alternative interface name to use. This option can be specified multiple times. + If the empty string is assigned to this option, the list is reset, and all prior assignments +- have no effect. ++ have no effect. If the kernel does not support the alternative names, then this setting will ++ be ignored. + + + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 4de8ee7d7e..8e88c8e5c4 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -474,7 +474,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name); + + r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names); +- if (r < 0) ++ if (r == -EOPNOTSUPP) ++ log_debug_errno(r, "Could not set AlternativeName= on %s, ignoring: %m", old_name); ++ else if (r < 0) + return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name); + + *name = new_name; diff --git a/SOURCES/0716-udev-introduce-AlternativeNamesPolicy-setting.patch b/SOURCES/0716-udev-introduce-AlternativeNamesPolicy-setting.patch new file mode 100644 index 0000000..4b9087f --- /dev/null +++ b/SOURCES/0716-udev-introduce-AlternativeNamesPolicy-setting.patch @@ -0,0 +1,169 @@ +From 2faf160d0b8122e0dca603a441db68dc38c1bab6 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 16 Dec 2019 23:44:42 +0900 +Subject: [PATCH] udev: introduce AlternativeNamesPolicy= setting + +(cherry picked from commit ef1d2c07f9567dfea8a4e012d8779a4ded2d9ae6) + +Related: #2005008 +--- + man/systemd.link.xml | 11 +++++ + src/udev/net/link-config-gperf.gperf | 1 + + src/udev/net/link-config.c | 62 ++++++++++++++++++++++++++-- + src/udev/net/link-config.h | 5 +++ + 4 files changed, 76 insertions(+), 3 deletions(-) + +diff --git a/man/systemd.link.xml b/man/systemd.link.xml +index c8ebb751ee..13dcce0879 100644 +--- a/man/systemd.link.xml ++++ b/man/systemd.link.xml +@@ -343,6 +343,17 @@ + + + ++ ++ AlternativeNamesPolicy= ++ ++ A space-separated list of policies by which the interface's alternative names ++ should be set. Each of the policies may fail, and all successful policies are used. The ++ available policies are database, onboard, ++ slot, path, and mac. If the ++ kernel does not support the alternative names, then this setting will be ignored. ++ ++ ++ + + AlternativeName= + +diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf +index 913c754145..df8404e7b8 100644 +--- a/src/udev/net/link-config-gperf.gperf ++++ b/src/udev/net/link-config-gperf.gperf +@@ -35,6 +35,7 @@ Link.MACAddress, config_parse_hwaddr, 0, + Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy) + Link.Name, config_parse_ifname, 0, offsetof(link_config, name) + Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names) ++Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(link_config, alternative_names_policy) + Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias) + Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu) + Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed) +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 8e88c8e5c4..6ceb4c698e 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -69,6 +69,7 @@ static void link_config_free(link_config *link) { + free(link->name_policy); + free(link->name); + strv_free(link->alternative_names); ++ free(link->alternative_names_policy); + free(link->alias); + + free(link); +@@ -349,6 +350,7 @@ static int get_mac(struct udev_device *device, bool want_random, + + int link_config_apply(link_config_ctx *ctx, link_config *config, + struct udev_device *device, const char **name) { ++ _cleanup_strv_free_ char **altnames = NULL; + bool respect_predictable = false; + struct ether_addr generated_mac; + struct ether_addr *mac = NULL; +@@ -473,11 +475,52 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + if (r < 0) + return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name); + +- r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names); ++ if (config->alternative_names) { ++ altnames = strv_copy(config->alternative_names); ++ if (!altnames) ++ return log_oom(); ++ } ++ ++ if (config->alternative_names_policy) ++ for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) { ++ const char *n; ++ ++ switch (*p) { ++ case NAMEPOLICY_DATABASE: ++ n = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE"); ++ break; ++ case NAMEPOLICY_ONBOARD: ++ n = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD"); ++ break; ++ case NAMEPOLICY_SLOT: ++ n = udev_device_get_property_value(device, "ID_NET_NAME_SLOT"); ++ break; ++ case NAMEPOLICY_PATH: ++ n = udev_device_get_property_value(device, "ID_NET_NAME_PATH"); ++ break; ++ case NAMEPOLICY_MAC: ++ n = udev_device_get_property_value(device, "ID_NET_NAME_MAC"); ++ break; ++ default: ++ assert_not_reached("invalid policy"); ++ } ++ if (!isempty(n)) { ++ r = strv_extend(&altnames, n); ++ if (r < 0) ++ return log_oom(); ++ } ++ } ++ ++ if (new_name) ++ strv_remove(altnames, new_name); ++ strv_remove(altnames, old_name); ++ strv_uniq(altnames); ++ ++ r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); + if (r == -EOPNOTSUPP) +- log_debug_errno(r, "Could not set AlternativeName= on %s, ignoring: %m", old_name); ++ log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name); + else if (r < 0) +- return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name); ++ return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name); + + *name = new_name; + +@@ -524,3 +567,16 @@ DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy); + DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy, + _NAMEPOLICY_INVALID, + "Failed to parse interface name policy"); ++ ++static const char* const alternative_names_policy_table[_NAMEPOLICY_MAX] = { ++ [NAMEPOLICY_DATABASE] = "database", ++ [NAMEPOLICY_ONBOARD] = "onboard", ++ [NAMEPOLICY_SLOT] = "slot", ++ [NAMEPOLICY_PATH] = "path", ++ [NAMEPOLICY_MAC] = "mac", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy, NamePolicy); ++DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy, alternative_names_policy, NamePolicy, ++ _NAMEPOLICY_INVALID, ++ "Failed to parse alternative names policy"); +diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h +index 93d5fdce59..634bd2ec54 100644 +--- a/src/udev/net/link-config.h ++++ b/src/udev/net/link-config.h +@@ -49,6 +49,7 @@ struct link_config { + struct ether_addr *mac; + MACPolicy mac_policy; + NamePolicy *name_policy; ++ NamePolicy *alternative_names_policy; + char *name; + char **alternative_names; + char *alias; +@@ -78,6 +79,9 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret + const char *name_policy_to_string(NamePolicy p) _const_; + NamePolicy name_policy_from_string(const char *p) _pure_; + ++const char *alternative_names_policy_to_string(NamePolicy p) _const_; ++NamePolicy alternative_names_policy_from_string(const char *p) _pure_; ++ + const char *mac_policy_to_string(MACPolicy p) _const_; + MACPolicy mac_policy_from_string(const char *p) _pure_; + +@@ -86,3 +90,4 @@ const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN + + int config_parse_mac_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + int config_parse_name_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); ++int config_parse_alternative_names_policy(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/SOURCES/0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch b/SOURCES/0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch new file mode 100644 index 0000000..9f4a216 --- /dev/null +++ b/SOURCES/0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch @@ -0,0 +1,22 @@ +From 9a224b9480d218b782ac7bbacb3732672d0dad3f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Dec 2019 00:30:38 +0900 +Subject: [PATCH] network: set AlternativeNamesPolicy= in 99-default.link + +(cherry picked from commit 49f5cbe92484a6661bccc0ae6c547bc5767c83bf) + +Related: #2005008 +--- + network/99-default.link | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/network/99-default.link b/network/99-default.link +index 561bf329e4..58c0b74a7c 100644 +--- a/network/99-default.link ++++ b/network/99-default.link +@@ -9,4 +9,5 @@ + + [Link] + NamePolicy=kernel database onboard slot path ++AlternativeNamesPolicy=database onboard slot path + MACAddressPolicy=persistent diff --git a/SOURCES/0718-random-util-call-initialize_srand-after-fork.patch b/SOURCES/0718-random-util-call-initialize_srand-after-fork.patch new file mode 100644 index 0000000..f82e976 --- /dev/null +++ b/SOURCES/0718-random-util-call-initialize_srand-after-fork.patch @@ -0,0 +1,59 @@ +From 58cdc09af08e065c85b2f8834ee9848c010f5afe Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 16 Dec 2019 19:47:48 +0900 +Subject: [PATCH] random-util: call initialize_srand() after fork() + +(cherry picked from commit a0f11d1d11a546f791855ec9c47c2ff830e6a5aa) + +Related: #2005008 +--- + src/basic/random-util.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/basic/random-util.c b/src/basic/random-util.c +index 91481559db..801f6ad131 100644 +--- a/src/basic/random-util.c ++++ b/src/basic/random-util.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,8 @@ + #include "random-util.h" + #include "time-util.h" + ++static bool srand_called = false; ++ + int acquire_random_bytes(void *p, size_t n, bool high_quality_required) { + static int have_syscall = -1; + +@@ -81,8 +84,12 @@ int acquire_random_bytes(void *p, size_t n, bool high_quality_required) { + return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true); + } + ++static void clear_srand_initialization(void) { ++ srand_called = false; ++} ++ + void initialize_srand(void) { +- static bool srand_called = false; ++ static bool pthread_atfork_registered = false; + unsigned x; + #if HAVE_SYS_AUXV_H + void *auxv; +@@ -109,6 +116,11 @@ void initialize_srand(void) { + + srand(x); + srand_called = true; ++ ++ if (!pthread_atfork_registered) { ++ (void) pthread_atfork(NULL, NULL, clear_srand_initialization); ++ pthread_atfork_registered = true; ++ } + } + + /* INT_MAX gives us only 31 bits, so use 24 out of that. */ diff --git a/SOURCES/0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch b/SOURCES/0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch new file mode 100644 index 0000000..4c80d63 --- /dev/null +++ b/SOURCES/0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch @@ -0,0 +1,78 @@ +From bb7c49cc95e9de877fafc5c2be06932bc21aa762 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Dec 2019 18:28:36 +0900 +Subject: [PATCH] sd-netlink: introduce rtnl_resolve_link_alternative_names() + +(cherry picked from commit b04c5e51da7a61d41d564e73a1e92bd8b29b0223) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-types.c | 1 + + src/libsystemd/sd-netlink/netlink-util.c | 29 +++++++++++++++++++++++ + src/libsystemd/sd-netlink/netlink-util.h | 1 + + 3 files changed, 31 insertions(+) + +diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c +index 47d9c7f1c4..e118a0aa30 100644 +--- a/src/libsystemd/sd-netlink/netlink-types.c ++++ b/src/libsystemd/sd-netlink/netlink-types.c +@@ -511,6 +511,7 @@ static const NLType rtnl_link_types[] = { + [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, + */ + [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, ++ [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, + }; + + static const NLTypeSystem rtnl_link_type_system = { +diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c +index c1c306f121..62fc71a3d8 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.c ++++ b/src/libsystemd/sd-netlink/netlink-util.c +@@ -120,6 +120,35 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const + return 0; + } + ++int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; ++ int r; ++ ++ assert(rtnl); ++ assert(name); ++ assert(ret); ++ ++ if (!*rtnl) { ++ r = sd_netlink_open(rtnl); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_message_append_string(message, IFLA_ALT_IFNAME, name); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_call(*rtnl, message, 0, &reply); ++ if (r < 0) ++ return r; ++ ++ return sd_rtnl_message_link_get_ifindex(reply, ret); ++} ++ + int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) { + struct nlmsgerr *err; + int r; +diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h +index 92de19c092..ea98439fad 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.h ++++ b/src/libsystemd/sd-netlink/netlink-util.h +@@ -39,6 +39,7 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) { + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name); + int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu); + int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names); ++int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret); + + int rtnl_log_parse_error(int r); + int rtnl_log_create_error(int r); diff --git a/SOURCES/0720-udev-sort-alternative-names.patch b/SOURCES/0720-udev-sort-alternative-names.patch new file mode 100644 index 0000000..e3f0f94 --- /dev/null +++ b/SOURCES/0720-udev-sort-alternative-names.patch @@ -0,0 +1,27 @@ +From f5d149095f95704fe7660069a493c0329ddbb5aa Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 17 Dec 2019 20:41:21 +0900 +Subject: [PATCH] udev: sort alternative names + +Kernel preserves the order of alternative names. So, for user +visibility, let's sort the alternative names. + +(cherry picked from commit 4d016e965b13883cccc963a34a1299a0c4f900ca) + +Related: #2005008 +--- + src/udev/net/link-config.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 6ceb4c698e..8bd374d352 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -515,6 +515,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + strv_remove(altnames, new_name); + strv_remove(altnames, old_name); + strv_uniq(altnames); ++ strv_sort(altnames); + + r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); + if (r == -EOPNOTSUPP) diff --git a/SOURCES/0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch b/SOURCES/0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch new file mode 100644 index 0000000..0cc78fc --- /dev/null +++ b/SOURCES/0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch @@ -0,0 +1,102 @@ +From c6b2c2fb577d20879b5b4c610c4c29bac259beab Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 17 Jul 2020 21:29:13 +0900 +Subject: [PATCH] netlink: introduce rtnl_get/delete_link_alternative_names() + +(cherry picked from commit 14982526145de84201c7e3b4fc6be6aa5e9a08f7) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-util.c | 45 ++++++++++++++++++++++-- + src/libsystemd/sd-netlink/netlink-util.h | 2 ++ + 2 files changed, 45 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c +index 62fc71a3d8..7f09261981 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.c ++++ b/src/libsystemd/sd-netlink/netlink-util.c +@@ -81,12 +81,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, + return 0; + } + +-int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) { ++int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) { ++ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; ++ _cleanup_strv_free_ char **names = NULL; ++ int r; ++ ++ assert(rtnl); ++ assert(ifindex > 0); ++ assert(ret); ++ ++ if (!*rtnl) { ++ r = sd_netlink_open(rtnl); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_call(*rtnl, message, 0, &reply); ++ if (r < 0) ++ return r; ++ ++ r = sd_netlink_message_read_strv(reply, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names); ++ if (r < 0 && r != -ENODATA) ++ return r; ++ ++ *ret = TAKE_PTR(names); ++ ++ return 0; ++} ++ ++static int rtnl_update_link_alternative_names(sd_netlink **rtnl, uint16_t nlmsg_type, int ifindex, char * const *alternative_names) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; + int r; + + assert(rtnl); + assert(ifindex > 0); ++ assert(IN_SET(nlmsg_type, RTM_NEWLINKPROP, RTM_DELLINKPROP)); + + if (strv_isempty(alternative_names)) + return 0; +@@ -97,7 +130,7 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const + return r; + } + +- r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex); ++ r = sd_rtnl_message_new_link(*rtnl, &message, nlmsg_type, ifindex); + if (r < 0) + return r; + +@@ -120,6 +153,14 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const + return 0; + } + ++int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) { ++ return rtnl_update_link_alternative_names(rtnl, RTM_NEWLINKPROP, ifindex, alternative_names); ++} ++ ++int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) { ++ return rtnl_update_link_alternative_names(rtnl, RTM_DELLINKPROP, ifindex, alternative_names); ++} ++ + int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; + int r; +diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h +index ea98439fad..4fc31aa274 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.h ++++ b/src/libsystemd/sd-netlink/netlink-util.h +@@ -38,7 +38,9 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) { + + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name); + int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu); ++int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret); + int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names); ++int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names); + int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret); + + int rtnl_log_parse_error(int r); diff --git a/SOURCES/0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch b/SOURCES/0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch new file mode 100644 index 0000000..2774ac2 --- /dev/null +++ b/SOURCES/0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch @@ -0,0 +1,81 @@ +From 73ff88cdb6bd1991d75323c6c364bcc9bce7efda Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 17 Jul 2020 21:31:24 +0900 +Subject: [PATCH] netlink: do not fail when new interface name is already used + as an alternative name + +When renaming a network interface, the new name may be used as an +alternative name. In that case, let's swap the current name and the +alternative name. That is, first drop the new name from the list of +alternative names, then rename the interface, finally set the old name +as an alternative name. + +(cherry picked from commit 434a34838034347f45fb9a47df55b1a36e5addfd) + +Related: #2005008 +--- + src/libsystemd/sd-netlink/netlink-util.c | 30 +++++++++++++++++++++--- + 1 file changed, 27 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c +index 7f09261981..4e42ef9e26 100644 +--- a/src/libsystemd/sd-netlink/netlink-util.c ++++ b/src/libsystemd/sd-netlink/netlink-util.c +@@ -1,23 +1,40 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include ++ + #include "sd-netlink.h" + + #include "netlink-internal.h" + #include "netlink-util.h" ++#include "socket-util.h" ++#include "string-util.h" + #include "strv.h" + + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; ++ _cleanup_strv_free_ char **alternative_names = NULL; ++ char old_name[IF_NAMESIZE + 1] = {}; + int r; + + assert(rtnl); + assert(ifindex > 0); + assert(name); + +- if (!*rtnl) { +- r = sd_netlink_open(rtnl); ++ if (!ifname_valid(name)) ++ return -EINVAL; ++ ++ r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names); ++ if (r < 0) ++ log_debug_errno(r, "Failed to get alternative names on network interface %i, ignoring: %m", ++ ifindex); ++ ++ if (strv_contains(alternative_names, name)) { ++ r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name)); + if (r < 0) +- return r; ++ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m", ++ name, ifindex); ++ ++ if_indextoname(ifindex, old_name); + } + + r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex); +@@ -32,6 +49,13 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { + if (r < 0) + return r; + ++ if (!isempty(old_name)) { ++ r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name)); ++ if (r < 0) ++ log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m", ++ old_name, ifindex); ++ } ++ + return 0; + } + diff --git a/SOURCES/0723-udev-do-not-try-to-reassign-alternative-names.patch b/SOURCES/0723-udev-do-not-try-to-reassign-alternative-names.patch new file mode 100644 index 0000000..f707a3d --- /dev/null +++ b/SOURCES/0723-udev-do-not-try-to-reassign-alternative-names.patch @@ -0,0 +1,46 @@ +From aec8473f69877c353b9e788b2a7329e290ae14f9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 17 Jul 2020 21:36:05 +0900 +Subject: [PATCH] udev: do not try to reassign alternative names + +Setting alternative names may fail if some of them are already assigned. + +(cherry picked from commit 97fdae33dfe8e7e0a4e5230564f6cdebc4450eec) + +Related: #2005008 +--- + src/udev/net/link-config.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 8bd374d352..5220f247f0 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -350,7 +350,7 @@ static int get_mac(struct udev_device *device, bool want_random, + + int link_config_apply(link_config_ctx *ctx, link_config *config, + struct udev_device *device, const char **name) { +- _cleanup_strv_free_ char **altnames = NULL; ++ _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL; + bool respect_predictable = false; + struct ether_addr generated_mac; + struct ether_addr *mac = NULL; +@@ -514,9 +514,17 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + if (new_name) + strv_remove(altnames, new_name); + strv_remove(altnames, old_name); ++ ++ r = rtnl_get_link_alternative_names(&ctx->rtnl, ifindex, ¤t_altnames); ++ if (r < 0) ++ log_debug_errno(r, "Failed to get alternative names on %s, ignoring: %m", old_name); ++ ++ char **p; ++ STRV_FOREACH(p, current_altnames) ++ strv_remove(altnames, *p); ++ + strv_uniq(altnames); + strv_sort(altnames); +- + r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); + if (r == -EOPNOTSUPP) + log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name); diff --git a/SOURCES/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch b/SOURCES/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch new file mode 100644 index 0000000..46d537c --- /dev/null +++ b/SOURCES/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch @@ -0,0 +1,27 @@ +From 270e3f46d1fe474eb3b4cd6789520b36a740ef32 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 8 Dec 2021 09:49:24 +0100 +Subject: [PATCH] Do not fail if the same alt. name is set again + +This is a workaround for a kernel bug. + +RHEL-only + +Related: #2005008 +--- + src/udev/net/link-config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 5220f247f0..9046c5bd2a 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -526,7 +526,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + strv_uniq(altnames); + strv_sort(altnames); + r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); +- if (r == -EOPNOTSUPP) ++ if (IN_SET(r, -EOPNOTSUPP, -EEXIST)) + log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name); + else if (r < 0) + return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name); diff --git a/SOURCES/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch b/SOURCES/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch new file mode 100644 index 0000000..6a68caf --- /dev/null +++ b/SOURCES/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch @@ -0,0 +1,87 @@ +From 21e4d155ac04bf3b999834cd42e4773ae01bf3b3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 15 Nov 2019 14:00:54 +0100 +Subject: [PATCH] mount: do not update exec deps on mountinfo changes + +Fixes: #13978 +(cherry picked from commit bf7eedbf8f8c83d9e775c80275f98f506ec963c6) + +Related: #2008825 +--- + src/core/mount.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 4e0a4f238a..73c0531158 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -535,6 +535,32 @@ static int mount_verify(Mount *m) { + return 0; + } + ++static int mount_add_non_exec_dependencies(Mount *m) { ++ int r; ++ assert(m); ++ ++ /* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies ++ * resulting from the ExecContext and such. */ ++ ++ r = mount_add_device_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_mount_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_quota_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_default_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + static int mount_add_extras(Mount *m) { + Unit *u = UNIT(m); + int r; +@@ -558,18 +584,6 @@ static int mount_add_extras(Mount *m) { + return r; + } + +- r = mount_add_device_dependencies(m); +- if (r < 0) +- return r; +- +- r = mount_add_mount_dependencies(m); +- if (r < 0) +- return r; +- +- r = mount_add_quota_dependencies(m); +- if (r < 0) +- return r; +- + r = unit_patch_contexts(u); + if (r < 0) + return r; +@@ -582,7 +596,7 @@ static int mount_add_extras(Mount *m) { + if (r < 0) + return r; + +- r = mount_add_default_dependencies(m); ++ r = mount_add_non_exec_dependencies(m); + if (r < 0) + return r; + +@@ -1526,7 +1540,7 @@ static int mount_setup_existing_unit( + } + + if (load_extras) +- return mount_add_extras(MOUNT(u)); ++ return mount_add_non_exec_dependencies(MOUNT(u)); + + return 0; + } diff --git a/SOURCES/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch b/SOURCES/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch new file mode 100644 index 0000000..538c899 --- /dev/null +++ b/SOURCES/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch @@ -0,0 +1,46 @@ +From 1fb992c50f7fc6a5c399e302ba79097d36a0cedf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 29 Aug 2021 21:20:43 +0900 +Subject: [PATCH] core/mount: add implicit unit dependencies even if when mount + unit is generated from /proc/self/mountinfo + +Hopefully fixes #20566. + +(cherry picked from commit aebff2e7ce209fc2d75b894a3ae8b80f6f36ec11) + +Resolves: #2008825 +--- + src/core/mount.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 73c0531158..9547cb9b29 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1437,6 +1437,7 @@ static int mount_setup_new_unit( + MountSetupFlags *flags) { + + MountParameters *p; ++ int r; + + assert(u); + assert(flags); +@@ -1458,7 +1459,6 @@ static int mount_setup_new_unit( + + if (!mount_is_extrinsic(MOUNT(u))) { + const char *target; +- int r; + + target = mount_is_network(p) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; + r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT); +@@ -1470,6 +1470,10 @@ static int mount_setup_new_unit( + return r; + } + ++ r = mount_add_non_exec_dependencies(MOUNT(u)); ++ if (r < 0) ++ return r; ++ + unit_add_to_load_queue(u); + flags->is_mounted = true; + flags->just_mounted = true; diff --git a/SOURCES/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch b/SOURCES/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch new file mode 100644 index 0000000..bea7482 --- /dev/null +++ b/SOURCES/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch @@ -0,0 +1,27 @@ +From 7b9b641a7721f013fb12ab4e2a03423b5ede08c6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 22:23:14 +0200 +Subject: [PATCH] core: fix unfortunate typo in unit_is_unneeded() + +Follow-up for a3c1168ac293f16d9343d248795bb4c246aaff4a. + +(cherry picked from commit 93d4cb09d56e670b0c203dd6ec6939e391a0df59) + +Resolves: #2040147 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4de218feac..e2c61ce866 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1956,7 +1956,7 @@ bool unit_is_unneeded(Unit *u) { + * restart, then don't clean this one up. */ + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[deps[j]], i) { +- if (u->job) ++ if (other->job) + return false; + + if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) diff --git a/SOURCES/0728-core-make-destructive-transaction-error-a-bit-more-u.patch b/SOURCES/0728-core-make-destructive-transaction-error-a-bit-more-u.patch new file mode 100644 index 0000000..6694a5d --- /dev/null +++ b/SOURCES/0728-core-make-destructive-transaction-error-a-bit-more-u.patch @@ -0,0 +1,27 @@ +From 8cb38e1557b81740f49dff43a297aef7bd676424 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 22:22:52 +0200 +Subject: [PATCH] core: make destructive transaction error a bit more useful + +(cherry picked from commit cf99f8eacf1c864b19a6a02edea78c43f3185cb7) + +Related: #2040147 +--- + src/core/transaction.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/core/transaction.c b/src/core/transaction.c +index cdaaff4f55..ee5b39fef4 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -526,7 +526,9 @@ static int transaction_is_destructive(Transaction *tr, JobMode mode, sd_bus_erro + if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) && + job_type_is_conflicting(j->unit->job->type, j->type)) + return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, +- "Transaction is destructive."); ++ "Transaction for %s/%s is destructive (%s has '%s' job queued, but '%s' is included in transaction).", ++ tr->anchor_job->unit->id, job_type_to_string(tr->anchor_job->type), ++ j->unit->id, job_type_to_string(j->unit->job->type), job_type_to_string(j->type)); + } + + return 0; diff --git a/SOURCES/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch b/SOURCES/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch new file mode 100644 index 0000000..0e22dbb --- /dev/null +++ b/SOURCES/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch @@ -0,0 +1,89 @@ +From 81b967279f6e23474b1e7a0ea9b4ecf9405f87bb Mon Sep 17 00:00:00 2001 +From: Masahiro Matsuya +Date: Wed, 31 Mar 2021 11:44:24 +0900 +Subject: [PATCH] tmpfiles: use a entry in hashmap as ItemArray in + read_config_file() + +[zjs: squash commits and use size_t as appropriate. + +Bug seems to have been introduced in 811a15877825da9e53f9a2a8603da34589af6bbb. +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1944468.] + +(cherry picked from commit bec890e3cd6dac249cb12ce9430fdb78b6cf546b) + +Resolves: #1944468 +--- + src/tmpfiles/tmpfiles.c | 47 +++++++++++++++++++++++------------------ + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 927de35f32..1aeeed0d2e 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2646,7 +2646,7 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + char line[LINE_MAX]; + Iterator iterator; + unsigned v = 0; +- Item *i; ++ ItemArray *ia; + int r = 0; + + assert(fn); +@@ -2692,32 +2692,37 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + } + + /* we have to determine age parameter for each entry of type X */ +- ORDERED_HASHMAP_FOREACH(i, globs, iterator) { +- Iterator iter; +- Item *j, *candidate_item = NULL; ++ ORDERED_HASHMAP_FOREACH(ia, globs, iterator) ++ for (size_t ni = 0; ni < ia->count; ni++) { ++ Iterator iter; ++ ItemArray *ja; ++ Item *i = ia->items + ni, *candidate_item = NULL; + +- if (i->type != IGNORE_DIRECTORY_PATH) +- continue; +- +- ORDERED_HASHMAP_FOREACH(j, items, iter) { +- if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ if (i->type != IGNORE_DIRECTORY_PATH) + continue; + +- if (path_equal(j->path, i->path)) { +- candidate_item = j; +- break; +- } ++ ORDERED_HASHMAP_FOREACH(ja, items, iter) ++ for (size_t nj = 0; nj < ja->count; nj++) { ++ Item *j = ja->items + nj; + +- if ((!candidate_item && path_startswith(i->path, j->path)) || +- (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) +- candidate_item = j; +- } ++ if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ continue; + +- if (candidate_item && candidate_item->age_set) { +- i->age = candidate_item->age; +- i->age_set = true; ++ if (path_equal(j->path, i->path)) { ++ candidate_item = j; ++ break; ++ } ++ ++ if ((!candidate_item && path_startswith(i->path, j->path)) || ++ (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) ++ candidate_item = j; ++ } ++ ++ if (candidate_item && candidate_item->age_set) { ++ i->age = candidate_item->age; ++ i->age_set = true; ++ } + } +- } + + if (ferror(f)) { + log_error_errno(errno, "Failed to read from file %s: %m", fn); diff --git a/SOURCES/0730-tmpfiles-rework-condition-check.patch b/SOURCES/0730-tmpfiles-rework-condition-check.patch new file mode 100644 index 0000000..03611e4 --- /dev/null +++ b/SOURCES/0730-tmpfiles-rework-condition-check.patch @@ -0,0 +1,45 @@ +From 520ff5394187a0d6cb0cb40251f6e8e997ccdd0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Apr 2021 17:54:49 +0200 +Subject: [PATCH] tmpfiles: rework condition check + +(!a && b) || (a && c) is replaced by (a ? c : b). + +path_startswith() != NULL is need to avoid type warning. + +(cherry picked from commit 875e7b25d84a111755dab79241c9e64e44836910) + +Related: #1944468 +--- + src/tmpfiles/tmpfiles.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 1aeeed0d2e..50fada99dd 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2705,7 +2705,11 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + for (size_t nj = 0; nj < ja->count; nj++) { + Item *j = ja->items + nj; + +- if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ if (!IN_SET(j->type, CREATE_DIRECTORY, ++ TRUNCATE_DIRECTORY, ++ CREATE_SUBVOLUME, ++ CREATE_SUBVOLUME_INHERIT_QUOTA, ++ CREATE_SUBVOLUME_NEW_QUOTA)) + continue; + + if (path_equal(j->path, i->path)) { +@@ -2713,8 +2717,9 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + break; + } + +- if ((!candidate_item && path_startswith(i->path, j->path)) || +- (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) ++ if (candidate_item ++ ? (path_startswith(j->path, candidate_item->path) && fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0) ++ : path_startswith(i->path, j->path) != NULL) + candidate_item = j; + } + diff --git a/SOURCES/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch b/SOURCES/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch new file mode 100644 index 0000000..8234fed --- /dev/null +++ b/SOURCES/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch @@ -0,0 +1,160 @@ +From 4871d0807e4add56258633d3c3452b0ee5cc8f99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Apr 2021 22:35:19 +0200 +Subject: [PATCH] TEST-22-TMPFILES: add reproducer for bug with X + +(cherry picked from commit 1672be86021b5ae8e80d095409a4fffcba7cbb75) + +Related: #1944468 +--- + test/TEST-22-TMPFILES/test-11.sh | 141 +++++++++++++++++++++++++++++++ + 1 file changed, 141 insertions(+) + create mode 100755 test/TEST-22-TMPFILES/test-11.sh + +diff --git a/test/TEST-22-TMPFILES/test-11.sh b/test/TEST-22-TMPFILES/test-11.sh +new file mode 100755 +index 0000000000..21ef210cd1 +--- /dev/null ++++ b/test/TEST-22-TMPFILES/test-11.sh +@@ -0,0 +1,141 @@ ++#! /bin/bash ++ ++set -e ++set -x ++ ++rm -fr /tmp/x ++mkdir /tmp/x ++ ++# ++# 'x' ++# ++mkdir -p /tmp/x/{1,2} ++touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2} ++ ++systemd-tmpfiles --clean - < +Date: Wed, 22 Apr 2020 21:52:22 +0200 +Subject: [PATCH] core: make sure we don't get confused when setting TERM for a + tty fd + +Fixes: #15344 +(cherry picked from commit e8cf09b2a2ad0d48e5493050d54251d5f512d9b6) + +Resolves: #2045307 +--- + src/core/execute.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index d528d08830..a104294966 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1709,12 +1709,13 @@ static int build_environment( + + tty_path = exec_context_tty_path(c); + +- /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try to inherit +- * the $TERM set for PID 1. This is useful for containers so that the $TERM the container manager +- * passes to PID 1 ends up all the way in the console login shown. */ ++ /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try ++ * to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the ++ * container manager passes to PID 1 ends up all the way in the console login shown. */ + +- if (path_equal(tty_path, "/dev/console") && getppid() == 1) ++ if (path_equal_ptr(tty_path, "/dev/console") && getppid() == 1) + term = getenv("TERM"); ++ + if (!term) + term = default_term_for_tty(tty_path); + diff --git a/SOURCES/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch b/SOURCES/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch new file mode 100644 index 0000000..15bee3e --- /dev/null +++ b/SOURCES/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch @@ -0,0 +1,37 @@ +From cfa7b3d0a1900b725e5489dfec2c39abb8569c29 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 28 Nov 2018 14:10:04 +0900 +Subject: [PATCH] hash-funcs: introduce macro to create typesafe hash_ops + +(cherry picked from commit d1005d1c0050d3dc3a24c054bac4c4916073cbba) + +Resolves: #2037807 +--- + src/basic/hash-funcs.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 5e5989f021..2ff687e5f9 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -13,6 +13,20 @@ struct hash_ops { + compare_func_t compare; + }; + ++#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, scope) \ ++ _unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \ ++ _unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \ ++ scope const struct hash_ops name = { \ ++ .hash = (hash_func_t) hash_func, \ ++ .compare = (compare_func_t) compare_func, \ ++ } ++ ++#define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \ ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \ ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, static) ++ + void string_hash_func(const void *p, struct siphash *state); + int string_compare_func(const void *a, const void *b) _pure_; + extern const struct hash_ops string_hash_ops; diff --git a/SOURCES/0734-hash-func-add-destructors-for-key-and-value.patch b/SOURCES/0734-hash-func-add-destructors-for-key-and-value.patch new file mode 100644 index 0000000..c2d90a4 --- /dev/null +++ b/SOURCES/0734-hash-func-add-destructors-for-key-and-value.patch @@ -0,0 +1,369 @@ +From 3bee193141bdf3106732a2c925ffaf5ce48f0ecb Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 27 Nov 2018 22:25:40 +0900 +Subject: [PATCH] hash-func: add destructors for key and value + +If they are set, then they are called in hashmap_clear() or +hashmap_free(). + +(cherry picked from commit 59a5cda7b904cd7ef9853bda15b498bbc0577524) + +Resolves: #2037807 +--- + src/basic/hash-funcs.h | 54 ++++++++++++++++++++++++++--- + src/basic/hashmap.c | 76 +++++++++++------------------------------ + src/basic/hashmap.h | 50 ++++++++++++++++++--------- + src/basic/ordered-set.h | 6 ++-- + src/basic/set.h | 10 +++--- + 5 files changed, 109 insertions(+), 87 deletions(-) + +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 2ff687e5f9..2d3125d0f9 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + #pragma once + +- ++#include "alloc-util.h" + #include "macro.h" + #include "siphash24.h" + +@@ -11,21 +11,67 @@ typedef int (*compare_func_t)(const void *a, const void *b); + struct hash_ops { + hash_func_t hash; + compare_func_t compare; ++ free_func_t free_key; ++ free_func_t free_value; + }; + +-#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, scope) \ ++#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, free_key_func, free_value_func, scope) \ + _unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \ + _unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \ + scope const struct hash_ops name = { \ + .hash = (hash_func_t) hash_func, \ + .compare = (compare_func_t) compare_func, \ ++ .free_key = free_key_func, \ ++ .free_value = free_value_func, \ ++ } ++ ++#define _DEFINE_FREE_FUNC(uq, type, wrapper_name, func) \ ++ /* Type-safe free function */ \ ++ static void UNIQ_T(wrapper_name, uq)(void *a) { \ ++ type *_a = a; \ ++ func(_a); \ + } + ++#define _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(uq, name, type, hash_func, compare_func, free_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type, static_free_wrapper, free_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ UNIQ_T(static_free_wrapper, uq), NULL, scope) ++ ++#define _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(uq, name, type, hash_func, compare_func, type_value, free_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type_value, static_free_wrapper, free_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ NULL, UNIQ_T(static_free_wrapper, uq), scope) ++ ++#define _DEFINE_HASH_OPS_FULL(uq, name, type, hash_func, compare_func, free_key_func, type_value, free_value_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type, static_free_key_wrapper, free_key_func); \ ++ _DEFINE_FREE_FUNC(uq, type_value, static_free_value_wrapper, free_value_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ UNIQ_T(static_free_key_wrapper, uq), \ ++ UNIQ_T(static_free_value_wrapper, uq), scope) ++ + #define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \ +- _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func,) ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL,) + + #define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \ +- _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, static) ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL, static) ++ ++#define DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ ++ _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ ++ _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func, static) ++ ++#define DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ ++ _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ ++ _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func, static) ++ ++#define DEFINE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ ++ _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ ++ _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static) + + void string_hash_func(const void *p, struct siphash *state); + int string_compare_func(const void *a, const void *b) _pure_; +diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c +index 69a7d70b04..7c508086f0 100644 +--- a/src/basic/hashmap.c ++++ b/src/basic/hashmap.c +@@ -863,47 +863,38 @@ static void hashmap_free_no_clear(HashmapBase *h) { + free(h); + } + +-HashmapBase *internal_hashmap_free(HashmapBase *h) { +- +- /* Free the hashmap, but nothing in it */ +- ++HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { + if (h) { +- internal_hashmap_clear(h); ++ internal_hashmap_clear(h, default_free_key, default_free_value); + hashmap_free_no_clear(h); + } + + return NULL; + } + +-HashmapBase *internal_hashmap_free_free(HashmapBase *h) { ++void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { ++ free_func_t free_key, free_value; ++ if (!h) ++ return; + +- /* Free the hashmap and all data objects in it, but not the +- * keys */ ++ free_key = h->hash_ops->free_key ?: default_free_key; ++ free_value = h->hash_ops->free_value ?: default_free_value; + +- if (h) { +- internal_hashmap_clear_free(h); +- hashmap_free_no_clear(h); +- } +- +- return NULL; +-} ++ if (free_key || free_value) { ++ unsigned idx; + +-Hashmap *hashmap_free_free_free(Hashmap *h) { ++ for (idx = skip_free_buckets(h, 0); idx != IDX_NIL; ++ idx = skip_free_buckets(h, idx + 1)) { ++ struct hashmap_base_entry *e = bucket_at(h, idx); + +- /* Free the hashmap and all data and key objects in it */ ++ if (free_key) ++ free_key((void *) e->key); + +- if (h) { +- hashmap_clear_free_free(h); +- hashmap_free_no_clear(HASHMAP_BASE(h)); ++ if (free_value) ++ free_value(entry_value(h, e)); ++ } + } + +- return NULL; +-} +- +-void internal_hashmap_clear(HashmapBase *h) { +- if (!h) +- return; +- + if (h->has_indirect) { + free(h->indirect.storage); + h->has_indirect = false; +@@ -920,35 +911,6 @@ void internal_hashmap_clear(HashmapBase *h) { + base_set_dirty(h); + } + +-void internal_hashmap_clear_free(HashmapBase *h) { +- unsigned idx; +- +- if (!h) +- return; +- +- for (idx = skip_free_buckets(h, 0); idx != IDX_NIL; +- idx = skip_free_buckets(h, idx + 1)) +- free(entry_value(h, bucket_at(h, idx))); +- +- internal_hashmap_clear(h); +-} +- +-void hashmap_clear_free_free(Hashmap *h) { +- unsigned idx; +- +- if (!h) +- return; +- +- for (idx = skip_free_buckets(HASHMAP_BASE(h), 0); idx != IDX_NIL; +- idx = skip_free_buckets(HASHMAP_BASE(h), idx + 1)) { +- struct plain_hashmap_entry *e = plain_bucket_at(h, idx); +- free((void*)e->b.key); +- free(e->value); +- } +- +- internal_hashmap_clear(HASHMAP_BASE(h)); +-} +- + static int resize_buckets(HashmapBase *h, unsigned entries_add); + + /* +@@ -1771,7 +1733,7 @@ HashmapBase *internal_hashmap_copy(HashmapBase *h) { + } + + if (r < 0) { +- internal_hashmap_free(copy); ++ internal_hashmap_free(copy, false, false); + return NULL; + } + +diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h +index 5c70c102d7..9e4772b497 100644 +--- a/src/basic/hashmap.h ++++ b/src/basic/hashmap.h +@@ -23,6 +23,8 @@ + + #define HASH_KEY_SIZE 16 + ++typedef void* (*hashmap_destroy_t)(void *p); ++ + /* The base type for all hashmap and set types. Many functions in the + * implementation take (HashmapBase*) parameters and are run-time polymorphic, + * though the API is not meant to be polymorphic (do not call functions +@@ -88,25 +90,33 @@ OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HA + #define hashmap_new(ops) internal_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) + #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) + +-HashmapBase *internal_hashmap_free(HashmapBase *h); ++HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); + static inline Hashmap *hashmap_free(Hashmap *h) { +- return (void*)internal_hashmap_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL); + } + static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) { +- return (void*)internal_hashmap_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL); + } + +-HashmapBase *internal_hashmap_free_free(HashmapBase *h); + static inline Hashmap *hashmap_free_free(Hashmap *h) { +- return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free); + } + static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) { +- return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free); + } + +-Hashmap *hashmap_free_free_free(Hashmap *h); ++static inline Hashmap *hashmap_free_free_key(Hashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL); ++} ++static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL); ++} ++ ++static inline Hashmap *hashmap_free_free_free(Hashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free); ++} + static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) { +- return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free); + } + + IteratedCache *iterated_cache_free(IteratedCache *cache); +@@ -259,25 +269,33 @@ static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void + return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); + } + +-void internal_hashmap_clear(HashmapBase *h); ++void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); + static inline void hashmap_clear(Hashmap *h) { +- internal_hashmap_clear(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL); + } + static inline void ordered_hashmap_clear(OrderedHashmap *h) { +- internal_hashmap_clear(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL); + } + +-void internal_hashmap_clear_free(HashmapBase *h); + static inline void hashmap_clear_free(Hashmap *h) { +- internal_hashmap_clear_free(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, free); + } + static inline void ordered_hashmap_clear_free(OrderedHashmap *h) { +- internal_hashmap_clear_free(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, free); + } + +-void hashmap_clear_free_free(Hashmap *h); ++static inline void hashmap_clear_free_key(Hashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, NULL); ++} ++static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, NULL); ++} ++ ++static inline void hashmap_clear_free_free(Hashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, free); ++} + static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { +- hashmap_clear_free_free(PLAIN_HASHMAP(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), free, free); + } + + /* +diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h +index e7c054d8e4..7cbb71819b 100644 +--- a/src/basic/ordered-set.h ++++ b/src/basic/ordered-set.h +@@ -21,13 +21,11 @@ static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash + } + + static inline OrderedSet* ordered_set_free(OrderedSet *s) { +- ordered_hashmap_free((OrderedHashmap*) s); +- return NULL; ++ return (OrderedSet*) ordered_hashmap_free((OrderedHashmap*) s); + } + + static inline OrderedSet* ordered_set_free_free(OrderedSet *s) { +- ordered_hashmap_free_free((OrderedHashmap*) s); +- return NULL; ++ return (OrderedSet*) ordered_hashmap_free_free((OrderedHashmap*) s); + } + + static inline int ordered_set_put(OrderedSet *s, void *p) { +diff --git a/src/basic/set.h b/src/basic/set.h +index 664713810d..8e12670a6e 100644 +--- a/src/basic/set.h ++++ b/src/basic/set.h +@@ -9,13 +9,11 @@ Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); + #define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) + + static inline Set *set_free(Set *s) { +- internal_hashmap_free(HASHMAP_BASE(s)); +- return NULL; ++ return (Set*) internal_hashmap_free(HASHMAP_BASE(s), NULL, NULL); + } + + static inline Set *set_free_free(Set *s) { +- internal_hashmap_free_free(HASHMAP_BASE(s)); +- return NULL; ++ return (Set*) internal_hashmap_free(HASHMAP_BASE(s), free, NULL); + } + + /* no set_free_free_free */ +@@ -76,11 +74,11 @@ static inline unsigned set_buckets(Set *s) { + bool set_iterate(Set *s, Iterator *i, void **value); + + static inline void set_clear(Set *s) { +- internal_hashmap_clear(HASHMAP_BASE(s)); ++ internal_hashmap_clear(HASHMAP_BASE(s), NULL, NULL); + } + + static inline void set_clear_free(Set *s) { +- internal_hashmap_clear_free(HASHMAP_BASE(s)); ++ internal_hashmap_clear(HASHMAP_BASE(s), free, NULL); + } + + /* no set_clear_free_free */ diff --git a/SOURCES/0735-util-define-free_func_t.patch b/SOURCES/0735-util-define-free_func_t.patch new file mode 100644 index 0000000..c32c645 --- /dev/null +++ b/SOURCES/0735-util-define-free_func_t.patch @@ -0,0 +1,25 @@ +From 8d596fa931a32e517323379dde6a73ee2a72506c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 27 Nov 2018 16:33:28 +0900 +Subject: [PATCH] util: define free_func_t + +(cherry picked from commit e30f9c972b789152d67ff34fd3bda294d20d1f51) + +Resolves: #2037807 +--- + src/basic/alloc-util.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h +index ebe42889ea..f8294da68f 100644 +--- a/src/basic/alloc-util.h ++++ b/src/basic/alloc-util.h +@@ -8,6 +8,8 @@ + + #include "macro.h" + ++typedef void (*free_func_t)(void *p); ++ + #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + + #define new0(t, n) ((t*) calloc((n), sizeof(t))) diff --git a/SOURCES/0736-hash-funcs-make-basic-hash_ops-typesafe.patch b/SOURCES/0736-hash-funcs-make-basic-hash_ops-typesafe.patch new file mode 100644 index 0000000..76d5aee --- /dev/null +++ b/SOURCES/0736-hash-funcs-make-basic-hash_ops-typesafe.patch @@ -0,0 +1,145 @@ +From 9d8948b3f8d37c4667a50f57ab2e357b1aeb4019 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 2 Dec 2018 07:46:33 +0100 +Subject: [PATCH] hash-funcs: make basic hash_ops typesafe + +(cherry picked from commit 25073e5012cdb4de13d815197815c33194ff7dc9) + +Resolves: #2037807 +--- + src/basic/hash-funcs.c | 49 +++++++++++------------------------------- + src/basic/hash-funcs.h | 16 +++++++------- + 2 files changed, 21 insertions(+), 44 deletions(-) + +diff --git a/src/basic/hash-funcs.c b/src/basic/hash-funcs.c +index db48437be7..0617536ea5 100644 +--- a/src/basic/hash-funcs.c ++++ b/src/basic/hash-funcs.c +@@ -5,21 +5,13 @@ + #include "hash-funcs.h" + #include "path-util.h" + +-void string_hash_func(const void *p, struct siphash *state) { ++void string_hash_func(const char *p, struct siphash *state) { + siphash24_compress(p, strlen(p) + 1, state); + } + +-int string_compare_func(const void *a, const void *b) { +- return strcmp(a, b); +-} +- +-const struct hash_ops string_hash_ops = { +- .hash = string_hash_func, +- .compare = string_compare_func +-}; ++DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func); + +-void path_hash_func(const void *p, struct siphash *state) { +- const char *q = p; ++void path_hash_func(const char *q, struct siphash *state) { + size_t n; + + assert(q); +@@ -57,14 +49,11 @@ void path_hash_func(const void *p, struct siphash *state) { + } + } + +-int path_compare_func(const void *a, const void *b) { ++int path_compare_func(const char *a, const char *b) { + return path_compare(a, b); + } + +-const struct hash_ops path_hash_ops = { +- .hash = path_hash_func, +- .compare = path_compare_func +-}; ++DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func); + + void trivial_hash_func(const void *p, struct siphash *state) { + siphash24_compress(&p, sizeof(p), state); +@@ -79,36 +68,24 @@ const struct hash_ops trivial_hash_ops = { + .compare = trivial_compare_func + }; + +-void uint64_hash_func(const void *p, struct siphash *state) { ++void uint64_hash_func(const uint64_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(uint64_t), state); + } + +-int uint64_compare_func(const void *_a, const void *_b) { +- uint64_t a, b; +- a = *(const uint64_t*) _a; +- b = *(const uint64_t*) _b; +- return a < b ? -1 : (a > b ? 1 : 0); ++int uint64_compare_func(const uint64_t *a, const uint64_t *b) { ++ return CMP(*a, *b); + } + +-const struct hash_ops uint64_hash_ops = { +- .hash = uint64_hash_func, +- .compare = uint64_compare_func +-}; ++DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func); + + #if SIZEOF_DEV_T != 8 +-void devt_hash_func(const void *p, struct siphash *state) { ++void devt_hash_func(const dev_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(dev_t), state); + } + +-int devt_compare_func(const void *_a, const void *_b) { +- dev_t a, b; +- a = *(const dev_t*) _a; +- b = *(const dev_t*) _b; +- return a < b ? -1 : (a > b ? 1 : 0); ++int devt_compare_func(const dev_t *a, const dev_t *b) { ++ return CMP(*a, *b); + } + +-const struct hash_ops devt_hash_ops = { +- .hash = devt_hash_func, +- .compare = devt_compare_func +-}; ++DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func); + #endif +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 2d3125d0f9..3d2ae4b55e 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -73,12 +73,12 @@ struct hash_ops { + #define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ + _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static) + +-void string_hash_func(const void *p, struct siphash *state); +-int string_compare_func(const void *a, const void *b) _pure_; ++void string_hash_func(const char *p, struct siphash *state); ++#define string_compare_func strcmp + extern const struct hash_ops string_hash_ops; + +-void path_hash_func(const void *p, struct siphash *state); +-int path_compare_func(const void *a, const void *b) _pure_; ++void path_hash_func(const char *p, struct siphash *state); ++int path_compare_func(const char *a, const char *b) _pure_; + extern const struct hash_ops path_hash_ops; + + /* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings +@@ -89,15 +89,15 @@ extern const struct hash_ops trivial_hash_ops; + + /* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit + * values indirectly, since they don't fit in a pointer. */ +-void uint64_hash_func(const void *p, struct siphash *state); +-int uint64_compare_func(const void *a, const void *b) _pure_; ++void uint64_hash_func(const uint64_t *p, struct siphash *state); ++int uint64_compare_func(const uint64_t *a, const uint64_t *b) _pure_; + extern const struct hash_ops uint64_hash_ops; + + /* On some archs dev_t is 32bit, and on others 64bit. And sometimes it's 64bit on 32bit archs, and sometimes 32bit on + * 64bit archs. Yuck! */ + #if SIZEOF_DEV_T != 8 +-void devt_hash_func(const void *p, struct siphash *state) _pure_; +-int devt_compare_func(const void *a, const void *b) _pure_; ++void devt_hash_func(const dev_t *p, struct siphash *state) _pure_; ++int devt_compare_func(const dev_t *a, const dev_t *b) _pure_; + extern const struct hash_ops devt_hash_ops; + #else + #define devt_hash_func uint64_hash_func diff --git a/SOURCES/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch b/SOURCES/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch new file mode 100644 index 0000000..b7ecb42 --- /dev/null +++ b/SOURCES/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch @@ -0,0 +1,105 @@ +From dcb475e97a48cddacab3ab5178fb351c702cdfb8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 25 Nov 2018 21:54:44 +0900 +Subject: [PATCH] test: add tests for destructors of hashmap or set + +(cherry picked from commit 98233ee5e031cf39f5be73651a1f05c52927116b) + +Resolves: #2037807 +--- + src/test/test-hashmap-plain.c | 38 +++++++++++++++++++++++++++++++++++ + src/test/test-set.c | 19 ++++++++++++++++++ + 2 files changed, 57 insertions(+) + +diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c +index b695d4ee35..a34de067fc 100644 +--- a/src/test/test-hashmap-plain.c ++++ b/src/test/test-hashmap-plain.c +@@ -867,6 +867,43 @@ static void test_hashmap_clear_free_free(void) { + + hashmap_clear_free_free(m); + assert_se(hashmap_isempty(m)); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1); ++ ++ hashmap_clear_free_free(m); ++ assert_se(hashmap_isempty(m)); ++} ++ ++DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(test_hash_ops_key, char, string_hash_func, string_compare_func, free); ++DEFINE_PRIVATE_HASH_OPS_FULL(test_hash_ops_full, char, string_hash_func, string_compare_func, free, char, free); ++ ++static void test_hashmap_clear_free_with_destructor(void) { ++ _cleanup_hashmap_free_ Hashmap *m = NULL; ++ ++ log_info("%s", __func__); ++ ++ m = hashmap_new(&test_hash_ops_key); ++ assert_se(m); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1); ++ ++ hashmap_clear_free(m); ++ assert_se(hashmap_isempty(m)); ++ m = hashmap_free(m); ++ ++ m = hashmap_new(&test_hash_ops_full); ++ assert_se(m); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1); ++ ++ hashmap_clear_free(m); ++ assert_se(hashmap_isempty(m)); + } + + static void test_hashmap_reserve(void) { +@@ -924,5 +961,6 @@ void test_hashmap_funcs(void) { + test_hashmap_steal_first_key(); + test_hashmap_steal_first(); + test_hashmap_clear_free_free(); ++ test_hashmap_clear_free_with_destructor(); + test_hashmap_reserve(); + } +diff --git a/src/test/test-set.c b/src/test/test-set.c +index 6307403e4c..340edeb65f 100644 +--- a/src/test/test-set.c ++++ b/src/test/test-set.c +@@ -45,6 +45,24 @@ static void test_set_free_with_destructor(void) { + assert_se(items[3].seen == 0); + } + ++DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_func, trivial_compare_func, Item, item_seen); ++ ++static void test_set_free_with_hash_ops(void) { ++ Set *m; ++ struct Item items[4] = {}; ++ unsigned i; ++ ++ assert_se(m = set_new(&item_hash_ops)); ++ for (i = 0; i < ELEMENTSOF(items) - 1; i++) ++ assert_se(set_put(m, items + i) == 1); ++ ++ m = set_free(m); ++ assert_se(items[0].seen == 1); ++ assert_se(items[1].seen == 1); ++ assert_se(items[2].seen == 1); ++ assert_se(items[3].seen == 0); ++} ++ + static void test_set_put(void) { + _cleanup_set_free_ Set *m = NULL; + +@@ -64,6 +82,7 @@ static void test_set_put(void) { + int main(int argc, const char *argv[]) { + test_set_steal_first(); + test_set_free_with_destructor(); ++ test_set_free_with_hash_ops(); + test_set_put(); + + return 0; diff --git a/SOURCES/0738-man-document-the-new-sysctl.d-prefix.patch b/SOURCES/0738-man-document-the-new-sysctl.d-prefix.patch new file mode 100644 index 0000000..d80ae9a --- /dev/null +++ b/SOURCES/0738-man-document-the-new-sysctl.d-prefix.patch @@ -0,0 +1,27 @@ +From b1b5f4625bda683871e8120d2c7b4a59b3ad3951 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:24:11 +0200 +Subject: [PATCH] man: document the new sysctl.d/ - prefix + +(cherry picked from commit e08be64937293e3aa8adb08048497520d58445c6) + +Related: #2037807 +--- + man/sysctl.d.xml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml +index 7c8fde0dba..61820f2c4b 100644 +--- a/man/sysctl.d.xml ++++ b/man/sysctl.d.xml +@@ -60,6 +60,10 @@ + /proc/sys/net/ipv4/conf/enp3s0.200/forwarding. + + ++ If a variable assignment is prefixed with a single - character, any attempts to ++ set it that fail will be ignored (though are logged). Moreover, any access permission errors, and ++ attempts to write variables not defined on the local system are ignored (and logged) too. ++ + The settings configured with sysctl.d + files will be applied early on boot. The network + interface-specific options will also be applied individually for diff --git a/SOURCES/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch b/SOURCES/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch new file mode 100644 index 0000000..a71c655 --- /dev/null +++ b/SOURCES/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch @@ -0,0 +1,196 @@ +From 516fc73142e803a7a6cbd126c338e1c3c73d6843 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 21 Jan 2022 12:10:45 +0100 +Subject: [PATCH] sysctl: if options are prefixed with "-" ignore write errors + +(cherry picked from commit dec02d6e1993d420a0a94c7fec294605df55e88e) + +Resolves: #2037807 +--- + src/sysctl/sysctl.c | 115 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 80 insertions(+), 35 deletions(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 0151f7dabe..7b0528877c 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -26,25 +26,71 @@ static char **arg_prefixes = NULL; + static bool arg_cat_config = false; + static bool arg_no_pager = false; + ++typedef struct Option { ++ char *key; ++ char *value; ++ bool ignore_failure; ++} Option; ++ ++static Option *option_free(Option *o) { ++ if (!o) ++ return NULL; ++ ++ free(o->key); ++ free(o->value); ++ ++ return mfree(o); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Option*, option_free); ++DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(option_hash_ops, char, string_hash_func, string_compare_func, Option, option_free); ++ ++static Option *option_new( ++ const char *key, ++ const char *value, ++ bool ignore_failure) { ++ ++ _cleanup_(option_freep) Option *o = NULL; ++ ++ assert(key); ++ assert(value); ++ ++ o = new(Option, 1); ++ if (!o) ++ return NULL; ++ ++ *o = (Option) { ++ .key = strdup(key), ++ .value = strdup(value), ++ .ignore_failure = ignore_failure, ++ }; ++ ++ if (!o->key || !o->value) ++ return NULL; ++ ++ return TAKE_PTR(o); ++} ++ + static int apply_all(OrderedHashmap *sysctl_options) { +- char *property, *value; ++ Option *option; + Iterator i; + int r = 0; + +- ORDERED_HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) { ++ ORDERED_HASHMAP_FOREACH(option, sysctl_options, i) { + int k; + +- k = sysctl_write(property, value); ++ k = sysctl_write(option->key, option->value); + if (k < 0) { +- /* If the sysctl is not available in the kernel or we are running with reduced privileges and +- * cannot write it, then log about the issue at LOG_NOTICE level, and proceed without +- * failing. (EROFS is treated as a permission problem here, since that's how container managers +- * usually protected their sysctls.) In all other cases log an error and make the tool fail. */ +- +- if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT)) +- log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", value, property); ++ /* If the sysctl is not available in the kernel or we are running with reduced ++ * privileges and cannot write it, then log about the issue at LOG_NOTICE level, and ++ * proceed without failing. (EROFS is treated as a permission problem here, since ++ * that's how container managers usually protected their sysctls.) In all other cases ++ * log an error and make the tool fail. */ ++ ++ if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT) || option->ignore_failure) ++ log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); + else { +- log_error_errno(k, "Couldn't write '%s' to '%s': %m", value, property); ++ log_error_errno(k, "Couldn't write '%s' to '%s': %m", option->value, option->key); + if (r == 0) + r = k; + } +@@ -90,9 +136,11 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + log_debug("Parsing %s", path); + for (;;) { +- char *p, *value, *new_value, *property, *existing; ++ _cleanup_(option_freep) Option *new_option = NULL; + _cleanup_free_ char *l = NULL; +- void *v; ++ bool ignore_failure; ++ Option *existing; ++ char *p, *value; + int k; + + k = read_line(f, LONG_LINE_MAX, &l); +@@ -122,39 +170,37 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + *value = 0; + value++; + +- p = sysctl_normalize(strstrip(p)); ++ p = strstrip(p); ++ ignore_failure = p[0] == '-'; ++ if (ignore_failure) ++ p++; ++ ++ p = sysctl_normalize(p); + value = strstrip(value); + + if (!test_prefix(p)) + continue; + +- existing = ordered_hashmap_get2(sysctl_options, p, &v); ++ existing = ordered_hashmap_get(sysctl_options, p); + if (existing) { +- if (streq(value, existing)) ++ if (streq(value, existing->value)) { ++ existing->ignore_failure = existing->ignore_failure || ignore_failure; + continue; ++ } + + log_debug("Overwriting earlier assignment of %s at '%s:%u'.", p, path, c); +- free(ordered_hashmap_remove(sysctl_options, p)); +- free(v); ++ option_free(ordered_hashmap_remove(sysctl_options, p)); + } + +- property = strdup(p); +- if (!property) ++ new_option = option_new(p, value, ignore_failure); ++ if (!new_option) + return log_oom(); + +- new_value = strdup(value); +- if (!new_value) { +- free(property); +- return log_oom(); +- } ++ k = ordered_hashmap_put(sysctl_options, new_option->key, new_option); ++ if (k < 0) ++ return log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", p); + +- k = ordered_hashmap_put(sysctl_options, property, new_value); +- if (k < 0) { +- log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", property); +- free(property); +- free(new_value); +- return k; +- } ++ TAKE_PTR(new_option); + } + + return r; +@@ -251,7 +297,7 @@ static int parse_argv(int argc, char *argv[]) { + } + + int main(int argc, char *argv[]) { +- OrderedHashmap *sysctl_options = NULL; ++ _cleanup_(ordered_hashmap_freep) OrderedHashmap *sysctl_options = NULL; + int r = 0, k; + + r = parse_argv(argc, argv); +@@ -264,7 +310,7 @@ int main(int argc, char *argv[]) { + + umask(0022); + +- sysctl_options = ordered_hashmap_new(&path_hash_ops); ++ sysctl_options = ordered_hashmap_new(&option_hash_ops); + if (!sysctl_options) { + r = log_oom(); + goto finish; +@@ -311,7 +357,6 @@ int main(int argc, char *argv[]) { + finish: + pager_close(); + +- ordered_hashmap_free_free_free(sysctl_options); + strv_free(arg_prefixes); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/SOURCES/0740-sysctl-fix-segfault.patch b/SOURCES/0740-sysctl-fix-segfault.patch new file mode 100644 index 0000000..6c5ec3d --- /dev/null +++ b/SOURCES/0740-sysctl-fix-segfault.patch @@ -0,0 +1,27 @@ +From b30c37b500cbe0587656d5092a95fa695772cd0e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 6 Feb 2020 19:13:11 +0900 +Subject: [PATCH] sysctl: fix segfault + +Fixes #14801. + +(cherry picked from commit db99904bc8482efe556bb010a8b203a3e60ee37f) + +Resolves: #2037807 +--- + src/sysctl/sysctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 7b0528877c..4c85d6887f 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -183,7 +183,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + existing = ordered_hashmap_get(sysctl_options, p); + if (existing) { +- if (streq(value, existing->value)) { ++ if (streq_ptr(value, existing->value)) { + existing->ignore_failure = existing->ignore_failure || ignore_failure; + continue; + } diff --git a/SOURCES/0741-ci-drop-CentOS-8-CI.patch b/SOURCES/0741-ci-drop-CentOS-8-CI.patch new file mode 100644 index 0000000..cce92a8 --- /dev/null +++ b/SOURCES/0741-ci-drop-CentOS-8-CI.patch @@ -0,0 +1,26 @@ +From 2347478a64329b2777ae0838be51c8b017a84960 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 8 Feb 2022 11:24:20 +0100 +Subject: [PATCH] ci: drop CentOS 8 CI + +since it went EOL and we should use only Stream 8 from now on. + +rhel-only +Related: #2017033 +--- + .github/workflows/unit_tests.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index b363118be8..87b162fa71 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -10,7 +10,7 @@ jobs: + strategy: + fail-fast: false + matrix: +- image: [centos8, stream8] ++ image: [stream8] + phase: [GCC, GCC_ASAN] + env: + CONT_NAME: "systemd-centos8-ci" diff --git a/SOURCES/0742-test-adapt-to-the-new-capsh-format.patch b/SOURCES/0742-test-adapt-to-the-new-capsh-format.patch new file mode 100644 index 0000000..aa43697 --- /dev/null +++ b/SOURCES/0742-test-adapt-to-the-new-capsh-format.patch @@ -0,0 +1,108 @@ +From 9070c6d48645b948d996f9c26bc590c07d46ca1f Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 4 Feb 2020 13:49:01 +0100 +Subject: [PATCH] test: adapt to the new capsh format + +Since libcap v2.29 the format of cap_to_text() has been changed which +makes certain `test-execute` subtest fail. Let's remove the offending +part of the output (dropped capabilities) to make it compatible with +both the old and the new libcap. + +(cherry picked from commit 9569e385036c05c0bf9fbccdbf3d131161398e2e) + +Related: #2017033 +--- + test/test-execute/exec-capabilityboundingset-invert.service | 3 ++- + .../exec-privatedevices-no-capability-mknod.service | 3 ++- + .../exec-privatedevices-no-capability-sys-rawio.service | 3 ++- + .../exec-privatedevices-yes-capability-mknod.service | 3 ++- + .../exec-privatedevices-yes-capability-sys-rawio.service | 3 ++- + .../exec-protectkernelmodules-no-capabilities.service | 3 ++- + .../exec-protectkernelmodules-yes-capabilities.service | 3 ++- + 7 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/test/test-execute/exec-capabilityboundingset-invert.service b/test/test-execute/exec-capabilityboundingset-invert.service +index 1abe390601..5f37427603 100644 +--- a/test/test-execute/exec-capabilityboundingset-invert.service ++++ b/test/test-execute/exec-capabilityboundingset-invert.service +@@ -2,6 +2,7 @@ + Description=Test for CapabilityBoundingSet + + [Service] +-ExecStart=/bin/sh -x -c '! capsh --print | grep "^Bounding set .*cap_chown"' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep "^Bounding set .*cap_chown"' + Type=oneshot + CapabilityBoundingSet=~CAP_CHOWN +diff --git a/test/test-execute/exec-privatedevices-no-capability-mknod.service b/test/test-execute/exec-privatedevices-no-capability-mknod.service +index 6d39469da8..4d61d9ffaa 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-no-capability-mknod.service +@@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_mknod' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +index e7f529c44c..f7f7a16736 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_rawio' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-mknod.service b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +index fb1fc2875a..5bcace0845 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +@@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_mknod' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +index cebc493a7a..a246f950c1 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_rawio' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-no-capabilities.service b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +index b2f2cd6b8a..8d7e2b52d4 100644 +--- a/test/test-execute/exec-protectkernelmodules-no-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no + + [Service] + ProtectKernelModules=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_module' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +index 84bf39be56..fe2ae208dd 100644 +--- a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes + + [Service] + ProtectKernelModules=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_module' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' + Type=oneshot diff --git a/SOURCES/0743-test-ignore-IAB-capabilities-in-test-execute.patch b/SOURCES/0743-test-ignore-IAB-capabilities-in-test-execute.patch new file mode 100644 index 0000000..36ebc93 --- /dev/null +++ b/SOURCES/0743-test-ignore-IAB-capabilities-in-test-execute.patch @@ -0,0 +1,129 @@ +From 68c487956659bb0bc3e04be4c8f0687d46d23248 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 9 Mar 2020 11:00:58 +0100 +Subject: [PATCH] test: ignore IAB capabilities in `test-execute` + +libcap v2.33 introduces a new capability set called IAB[0] which is shown +in the output of `capsh --print` and interferes with the test checks. Let's +drop the IAB set from the output, for now, to mitigate this. + +This could be (and probably should be) replaced in the future by the +newly introduced testing options[1][2] in libcap v2.32, namely: + --has-p=xxx + --has-i=xxx + --has-a=xxx + +but this needs to wait until the respective libcap version gets a wider +adoption. Until then, let's stick with the relatively ugly sed. + +Fixes: #15046 + +[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=943b011b5e53624eb9cab4e96c1985326e077cdd +[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=588d0439cb6495b03f0ab9f213f0b6b339e7d4b7 +[2] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=e7709bbc1c4712f2ddfc6e6f42892928a8a03782 + +(cherry picked from commit e9cdcbed77971da3cb0b98b3eb91081142c91eb7) + +Related: #2017033 +--- + test/test-execute/exec-capabilityboundingset-invert.service | 4 ++-- + .../exec-privatedevices-no-capability-mknod.service | 4 ++-- + .../exec-privatedevices-no-capability-sys-rawio.service | 4 ++-- + .../exec-privatedevices-yes-capability-mknod.service | 4 ++-- + .../exec-privatedevices-yes-capability-sys-rawio.service | 4 ++-- + .../exec-protectkernelmodules-no-capabilities.service | 4 ++-- + .../exec-protectkernelmodules-yes-capabilities.service | 4 ++-- + 7 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/test/test-execute/exec-capabilityboundingset-invert.service b/test/test-execute/exec-capabilityboundingset-invert.service +index 5f37427603..4486f6c25d 100644 +--- a/test/test-execute/exec-capabilityboundingset-invert.service ++++ b/test/test-execute/exec-capabilityboundingset-invert.service +@@ -2,7 +2,7 @@ + Description=Test for CapabilityBoundingSet + + [Service] +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep "^Bounding set .*cap_chown"' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep "^Bounding set .*cap_chown"' + Type=oneshot + CapabilityBoundingSet=~CAP_CHOWN +diff --git a/test/test-execute/exec-privatedevices-no-capability-mknod.service b/test/test-execute/exec-privatedevices-no-capability-mknod.service +index 4d61d9ffaa..8f135be0b5 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-no-capability-mknod.service +@@ -3,6 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +index f7f7a16736..30ce549254 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-mknod.service b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +index 5bcace0845..b98cfb5c7e 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +@@ -3,6 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +index a246f950c1..5b0c0700f2 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-no-capabilities.service b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +index 8d7e2b52d4..1b73656305 100644 +--- a/test/test-execute/exec-protectkernelmodules-no-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no + + [Service] + ProtectKernelModules=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_module' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +index fe2ae208dd..e43e72733c 100644 +--- a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes + + [Service] + ProtectKernelModules=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_module' + Type=oneshot diff --git a/SOURCES/0744-core-disallow-using-.service-as-a-service-name.patch b/SOURCES/0744-core-disallow-using-.service-as-a-service-name.patch new file mode 100644 index 0000000..2e5cf37 --- /dev/null +++ b/SOURCES/0744-core-disallow-using-.service-as-a-service-name.patch @@ -0,0 +1,133 @@ +From a4e9cf5b5c5e4c4a6f05825cd9c159283a425ae2 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Fri, 4 Oct 2019 16:03:04 -0700 +Subject: [PATCH] core: disallow using '-.service' as a service name + +-.service.d will become a special top level drop in so don't let it be a +usable service name (otherwise the interaction gets complicated). + +(cherry picked from commit e23d911664b4fd86eb2c24b64233cb9f23cffdd1) + +Resolves: #2051520 +--- + src/basic/special.h | 4 ++++ + src/basic/unit-name.c | 25 +++++++++++++++++++++++++ + src/basic/unit-name.h | 2 ++ + src/core/service.c | 5 +++++ + src/test/test-unit-name.c | 19 +++++++++++++++++++ + 5 files changed, 55 insertions(+) + +diff --git a/src/basic/special.h b/src/basic/special.h +index 379a3d7979..2915122929 100644 +--- a/src/basic/special.h ++++ b/src/basic/special.h +@@ -103,3 +103,7 @@ + + /* The root directory. */ + #define SPECIAL_ROOT_MOUNT "-.mount" ++ ++/* Used to apply settings to all services through drop-ins. ++ * Should not exist as an actual service. */ ++#define SPECIAL_ROOT_SERVICE "-.service" +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 614eb8649b..82a666a481 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -668,6 +668,31 @@ good: + return 0; + } + ++bool service_unit_name_is_valid(const char *name) { ++ _cleanup_free_ char *prefix = NULL, *s = NULL; ++ const char *e, *service_name = name; ++ ++ if (!unit_name_is_valid(name, UNIT_NAME_ANY)) ++ return false; ++ ++ e = endswith(name, ".service"); ++ if (!e) ++ return false; ++ ++ /* If it's a template or instance, get the prefix as a service name. */ ++ if (unit_name_is_valid(name, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)) { ++ assert_se(unit_name_to_prefix(name, &prefix) == 0); ++ assert_se(s = strjoin(prefix, ".service")); ++ service_name = s; ++ } ++ ++ /* Reject reserved service name(s). */ ++ if (streq(service_name, SPECIAL_ROOT_SERVICE)) ++ return false; ++ ++ return true; ++} ++ + int slice_build_parent_slice(const char *slice, char **ret) { + char *s, *dash; + int r; +diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h +index 61abcd585b..21729cba83 100644 +--- a/src/basic/unit-name.h ++++ b/src/basic/unit-name.h +@@ -60,6 +60,8 @@ static inline int unit_name_mangle(const char *name, UnitNameMangle flags, char + return unit_name_mangle_with_suffix(name, flags, ".service", ret); + } + ++bool service_unit_name_is_valid(const char *name); ++ + int slice_build_parent_slice(const char *slice, char **ret); + int slice_build_subslice(const char *slice, const char*name, char **subslice); + bool slice_name_is_valid(const char *name); +diff --git a/src/core/service.c b/src/core/service.c +index e8ae1a5772..b7eb10c044 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -556,6 +556,11 @@ static int service_verify(Service *s) { + } + } + ++ if (!service_unit_name_is_valid(UNIT(s)->id)) { ++ log_unit_error(UNIT(s), "Service name is invalid or reserved. Refusing."); ++ return -ENOEXEC; ++ } ++ + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] + && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { + /* FailureAction= only makes sense if one of the start or stop commands is specified. +diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c +index 2b00ef8cb7..b629df5aea 100644 +--- a/src/test/test-unit-name.c ++++ b/src/test/test-unit-name.c +@@ -347,6 +347,24 @@ static void test_unit_name_build(void) { + free(t); + } + ++static void test_service_unit_name_is_valid(void) { ++ assert_se(service_unit_name_is_valid("foo.service")); ++ assert_se(service_unit_name_is_valid("foo@bar.service")); ++ assert_se(service_unit_name_is_valid("foo@bar@bar.service")); ++ assert_se(service_unit_name_is_valid("--.service")); ++ assert_se(service_unit_name_is_valid(".-.service")); ++ assert_se(service_unit_name_is_valid("-foo-bar.service")); ++ assert_se(service_unit_name_is_valid("-foo-bar-.service")); ++ assert_se(service_unit_name_is_valid("foo-bar-.service")); ++ ++ assert_se(!service_unit_name_is_valid("-.service")); ++ assert_se(!service_unit_name_is_valid("")); ++ assert_se(!service_unit_name_is_valid("foo.slice")); ++ assert_se(!service_unit_name_is_valid("@.service")); ++ assert_se(!service_unit_name_is_valid("@bar.service")); ++ assert_se(!service_unit_name_is_valid("-@.service")); ++} ++ + static void test_slice_name_is_valid(void) { + assert_se( slice_name_is_valid(SPECIAL_ROOT_SLICE)); + assert_se( slice_name_is_valid("foo.slice")); +@@ -833,6 +851,7 @@ int main(int argc, char* argv[]) { + test_unit_prefix_is_valid(); + test_unit_name_change_suffix(); + test_unit_name_build(); ++ test_service_unit_name_is_valid(); + test_slice_name_is_valid(); + test_build_subslice(); + test_build_parent_slice(); diff --git a/SOURCES/0745-shared-dropin-support-.service.d-top-level-drop-in-f.patch b/SOURCES/0745-shared-dropin-support-.service.d-top-level-drop-in-f.patch new file mode 100644 index 0000000..3a25ff5 --- /dev/null +++ b/SOURCES/0745-shared-dropin-support-.service.d-top-level-drop-in-f.patch @@ -0,0 +1,190 @@ +From adc0a99b18153535ef73cf1b6ce2bc64ca501c81 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Fri, 4 Oct 2019 17:39:34 -0700 +Subject: [PATCH] shared/dropin: support -.service.d/ top level drop-in for + service units + +(cherry picked from commit 272467882c9c3c3d4faca5fd7a1f44c5ef2f064) + +Resolves: #2051520 +--- + man/systemd.service.xml | 13 +++++++++++++ + man/systemd.special.xml | 9 +++++++++ + man/systemd.unit.xml | 4 ++++ + src/basic/unit-name.c | 9 +++++++-- + src/core/service.c | 2 +- + src/shared/dropin.c | 29 ++++++++++++++++++++++++++--- + test/TEST-15-DROPIN/test-dropin.sh | 15 ++++++++++++++- + 7 files changed, 74 insertions(+), 7 deletions(-) + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 1e30a564df..4164402d0e 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -62,6 +62,19 @@ + about the incompatibilities, see the Incompatibilities + with SysV document. ++ ++ In addition to the various drop-in behaviors described in ++ systemd.unit5, ++ services also support a top-level drop-in with -.service.d/ that allows ++ altering or adding to the settings of all services on the system. ++ The formatting and precedence of applying drop-in configurations follow what is defined in ++ systemd.unit5. ++ However, configurations in -.service.d/ have the lowest precedence compared to settings ++ in the service specific override directories. For example, for foo-bar-baz.service, ++ drop-ins in foo-bar-baz.service.d/ override the ones in ++ foo-bar-.service.d/, which override the ones foo-.service.d/, ++ which override the ones in -.service.d/. ++ + + + +diff --git a/man/systemd.special.xml b/man/systemd.special.xml +index fe6324a4a0..06798cd9e2 100644 +--- a/man/systemd.special.xml ++++ b/man/systemd.special.xml +@@ -117,6 +117,15 @@ + + + ++ ++ -.service ++ ++ This is a reserved unit name used to support top-level drop-ins for services. See ++ systemd.service5 ++ for details. ++ ++ ++ + + basic.target + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index e80c760dd6..5aa3bd1699 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -190,6 +190,10 @@ + over unit files wherever located. Multiple drop-in files with different names are applied in + lexicographic order, regardless of which of the directories they reside in. + ++ Service units also support a top-level drop-in directory for modifying the settings of all service units. See ++ systemd.service5 ++ for details. ++ + + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 82a666a481..078628d6e8 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -681,8 +681,13 @@ bool service_unit_name_is_valid(const char *name) { + + /* If it's a template or instance, get the prefix as a service name. */ + if (unit_name_is_valid(name, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)) { +- assert_se(unit_name_to_prefix(name, &prefix) == 0); +- assert_se(s = strjoin(prefix, ".service")); ++ if (unit_name_to_prefix(name, &prefix) < 0) ++ return false; ++ ++ s = strjoin(prefix, ".service"); ++ if (!s) ++ return false; ++ + service_name = s; + } + +diff --git a/src/core/service.c b/src/core/service.c +index b7eb10c044..b3ef79228f 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -558,7 +558,7 @@ static int service_verify(Service *s) { + + if (!service_unit_name_is_valid(UNIT(s)->id)) { + log_unit_error(UNIT(s), "Service name is invalid or reserved. Refusing."); +- return -ENOEXEC; ++ return -EINVAL; + } + + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index 357c66d800..78ca7f4452 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -19,6 +19,7 @@ + #include "mkdir.h" + #include "path-util.h" + #include "set.h" ++#include "special.h" + #include "string-util.h" + #include "strv.h" + #include "unit-name.h" +@@ -232,15 +233,37 @@ int unit_file_find_dropin_paths( + char ***ret) { + + _cleanup_strv_free_ char **dirs = NULL; +- char *t, **p; ++ UnitType type = _UNIT_TYPE_INVALID; ++ char *name, **p; + Iterator i; + int r; + + assert(ret); + +- SET_FOREACH(t, names, i) ++ /* All the names in the unit are of the same type so just grab one. */ ++ name = (char*) set_first(names); ++ if (name) { ++ type = unit_name_to_type(name); ++ if (type < 0) ++ return log_error_errno(EINVAL, ++ "Failed to to derive unit type from unit name: %s", ++ name); ++ } ++ ++ /* Special drop in for -.service. Add this first as it's the most generic ++ * and should be able to be overridden by more specific drop-ins. */ ++ if (type == UNIT_SERVICE) ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, ++ unit_path_cache, ++ *p, ++ SPECIAL_ROOT_SERVICE, ++ dir_suffix, ++ &dirs); ++ ++ SET_FOREACH(name, names, i) + STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, unit_path_cache, *p, t, dir_suffix, &dirs); ++ (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); + + if (strv_isempty(dirs)) { + *ret = NULL; +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index ab0a58caea..def2e03304 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -102,7 +102,20 @@ test_basic_dropins () { + check_ok b Wants c.service + systemctl stop a c + +- clear_services a b c ++ echo "*** test -.service.d/ top level drop-in" ++ create_services a b ++ check_ko a ExecCondition "/bin/echo a" ++ check_ko b ExecCondition "/bin/echo b" ++ mkdir -p /usr/lib/systemd/system/-.service.d ++ cat >/usr/lib/systemd/system/-.service.d/override.conf < +Date: Mon, 4 Nov 2019 18:29:55 -0800 +Subject: [PATCH] core: change top-level drop-in from -.service.d to service.d + +Discussed in #13743, the -.service semantic conflicts with the +existing root mount and slice names, making this feature not +uniformly extensible to all types. Change the name to be +.d instead. + +Updating to this format also extends the top-level dropin to +unit types. + +(cherry picked from commit 3e1db806b0c18fd6138886ce67fac2655f09caef) + +Resolves: #2051520 +--- + man/systemd.service.xml | 13 ------------- + man/systemd.special.xml | 9 --------- + man/systemd.unit.xml | 11 ++++++++--- + src/basic/special.h | 4 ---- + src/basic/unit-name.c | 30 ------------------------------ + src/basic/unit-name.h | 2 -- + src/core/service.c | 5 ----- + src/shared/dropin.c | 22 ++++++++++++---------- + src/test/test-unit-name.c | 19 ------------------- + test/TEST-15-DROPIN/test-dropin.sh | 8 ++++---- + 10 files changed, 24 insertions(+), 99 deletions(-) + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 4164402d0e..1e30a564df 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -62,19 +62,6 @@ + about the incompatibilities, see the Incompatibilities + with SysV document. +- +- In addition to the various drop-in behaviors described in +- systemd.unit5, +- services also support a top-level drop-in with -.service.d/ that allows +- altering or adding to the settings of all services on the system. +- The formatting and precedence of applying drop-in configurations follow what is defined in +- systemd.unit5. +- However, configurations in -.service.d/ have the lowest precedence compared to settings +- in the service specific override directories. For example, for foo-bar-baz.service, +- drop-ins in foo-bar-baz.service.d/ override the ones in +- foo-bar-.service.d/, which override the ones foo-.service.d/, +- which override the ones in -.service.d/. +- + + + +diff --git a/man/systemd.special.xml b/man/systemd.special.xml +index 06798cd9e2..fe6324a4a0 100644 +--- a/man/systemd.special.xml ++++ b/man/systemd.special.xml +@@ -117,15 +117,6 @@ + + + +- +- -.service +- +- This is a reserved unit name used to support top-level drop-ins for services. See +- systemd.service5 +- for details. +- +- +- + + basic.target + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 5aa3bd1699..6f213ccd56 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -190,9 +190,14 @@ + over unit files wherever located. Multiple drop-in files with different names are applied in + lexicographic order, regardless of which of the directories they reside in. + +- Service units also support a top-level drop-in directory for modifying the settings of all service units. See +- systemd.service5 +- for details. ++ Units also support a top-level drop-in with type.d/, ++ where type may be e.g. service or socket, ++ that allows altering or adding to the settings of all corresponding unit files on the system. ++ The formatting and precedence of applying drop-in configurations follow what is defined above. ++ Configurations in type.d/ have the lowest precedence ++ compared to settings in the name specific override directories. So the contents of ++ foo-.service.d/10-override.conf would override ++ service.d/10-override.conf. + + +diff --git a/src/basic/special.h b/src/basic/special.h +index 2915122929..379a3d7979 100644 +--- a/src/basic/special.h ++++ b/src/basic/special.h +@@ -103,7 +103,3 @@ + + /* The root directory. */ + #define SPECIAL_ROOT_MOUNT "-.mount" +- +-/* Used to apply settings to all services through drop-ins. +- * Should not exist as an actual service. */ +-#define SPECIAL_ROOT_SERVICE "-.service" +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 078628d6e8..614eb8649b 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -668,36 +668,6 @@ good: + return 0; + } + +-bool service_unit_name_is_valid(const char *name) { +- _cleanup_free_ char *prefix = NULL, *s = NULL; +- const char *e, *service_name = name; +- +- if (!unit_name_is_valid(name, UNIT_NAME_ANY)) +- return false; +- +- e = endswith(name, ".service"); +- if (!e) +- return false; +- +- /* If it's a template or instance, get the prefix as a service name. */ +- if (unit_name_is_valid(name, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)) { +- if (unit_name_to_prefix(name, &prefix) < 0) +- return false; +- +- s = strjoin(prefix, ".service"); +- if (!s) +- return false; +- +- service_name = s; +- } +- +- /* Reject reserved service name(s). */ +- if (streq(service_name, SPECIAL_ROOT_SERVICE)) +- return false; +- +- return true; +-} +- + int slice_build_parent_slice(const char *slice, char **ret) { + char *s, *dash; + int r; +diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h +index 21729cba83..61abcd585b 100644 +--- a/src/basic/unit-name.h ++++ b/src/basic/unit-name.h +@@ -60,8 +60,6 @@ static inline int unit_name_mangle(const char *name, UnitNameMangle flags, char + return unit_name_mangle_with_suffix(name, flags, ".service", ret); + } + +-bool service_unit_name_is_valid(const char *name); +- + int slice_build_parent_slice(const char *slice, char **ret); + int slice_build_subslice(const char *slice, const char*name, char **subslice); + bool slice_name_is_valid(const char *name); +diff --git a/src/core/service.c b/src/core/service.c +index b3ef79228f..e8ae1a5772 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -556,11 +556,6 @@ static int service_verify(Service *s) { + } + } + +- if (!service_unit_name_is_valid(UNIT(s)->id)) { +- log_unit_error(UNIT(s), "Service name is invalid or reserved. Refusing."); +- return -EINVAL; +- } +- + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] + && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { + /* FailureAction= only makes sense if one of the start or stop commands is specified. +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index 78ca7f4452..bd2a3c0feb 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -19,7 +19,6 @@ + #include "mkdir.h" + #include "path-util.h" + #include "set.h" +-#include "special.h" + #include "string-util.h" + #include "strv.h" + #include "unit-name.h" +@@ -170,6 +169,10 @@ static int unit_file_find_dirs( + return r; + } + ++ /* Return early for top level drop-ins. */ ++ if (unit_type_from_string(name) >= 0) ++ return 0; ++ + /* Let's see if there's a "-" prefix for this unit name. If so, let's invoke ourselves for it. This will then + * recursively do the same for all our prefixes. i.e. this means given "foo-bar-waldo.service" we'll also + * search "foo-bar-.service" and "foo-.service". +@@ -250,16 +253,15 @@ int unit_file_find_dropin_paths( + name); + } + +- /* Special drop in for -.service. Add this first as it's the most generic ++ /* Special top level drop in for ".". Add this first as it's the most generic + * and should be able to be overridden by more specific drop-ins. */ +- if (type == UNIT_SERVICE) +- STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, +- unit_path_cache, +- *p, +- SPECIAL_ROOT_SERVICE, +- dir_suffix, +- &dirs); ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, ++ unit_path_cache, ++ *p, ++ unit_type_to_string(type), ++ dir_suffix, ++ &dirs); + + SET_FOREACH(name, names, i) + STRV_FOREACH(p, lookup_path) +diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c +index b629df5aea..2b00ef8cb7 100644 +--- a/src/test/test-unit-name.c ++++ b/src/test/test-unit-name.c +@@ -347,24 +347,6 @@ static void test_unit_name_build(void) { + free(t); + } + +-static void test_service_unit_name_is_valid(void) { +- assert_se(service_unit_name_is_valid("foo.service")); +- assert_se(service_unit_name_is_valid("foo@bar.service")); +- assert_se(service_unit_name_is_valid("foo@bar@bar.service")); +- assert_se(service_unit_name_is_valid("--.service")); +- assert_se(service_unit_name_is_valid(".-.service")); +- assert_se(service_unit_name_is_valid("-foo-bar.service")); +- assert_se(service_unit_name_is_valid("-foo-bar-.service")); +- assert_se(service_unit_name_is_valid("foo-bar-.service")); +- +- assert_se(!service_unit_name_is_valid("-.service")); +- assert_se(!service_unit_name_is_valid("")); +- assert_se(!service_unit_name_is_valid("foo.slice")); +- assert_se(!service_unit_name_is_valid("@.service")); +- assert_se(!service_unit_name_is_valid("@bar.service")); +- assert_se(!service_unit_name_is_valid("-@.service")); +-} +- + static void test_slice_name_is_valid(void) { + assert_se( slice_name_is_valid(SPECIAL_ROOT_SLICE)); + assert_se( slice_name_is_valid("foo.slice")); +@@ -851,7 +833,6 @@ int main(int argc, char* argv[]) { + test_unit_prefix_is_valid(); + test_unit_name_change_suffix(); + test_unit_name_build(); +- test_service_unit_name_is_valid(); + test_slice_name_is_valid(); + test_build_subslice(); + test_build_parent_slice(); +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index def2e03304..7836c6535d 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -102,18 +102,18 @@ test_basic_dropins () { + check_ok b Wants c.service + systemctl stop a c + +- echo "*** test -.service.d/ top level drop-in" ++ echo "*** test service.d/ top level drop-in" + create_services a b + check_ko a ExecCondition "/bin/echo a" + check_ko b ExecCondition "/bin/echo b" +- mkdir -p /usr/lib/systemd/system/-.service.d +- cat >/usr/lib/systemd/system/-.service.d/override.conf </usr/lib/systemd/system/service.d/override.conf < +Date: Tue, 17 Dec 2019 15:47:37 +0200 +Subject: [PATCH] shared/dropin: fix assert for invalid drop-in + +Don't try to show top level drop-in for non-existent units or when trying to +instantiate non-instantiated units: + +$ systemctl cat nonexistent@.service +Assertion 'name' failed at src/shared/dropin.c:143, function unit_file_find_dirs(). Aborting. +$ systemctl cat systemd-journald@.service +Assertion 'name' failed at src/shared/dropin.c:143, function unit_file_find_dirs(). Aborting. + +(cherry picked from commit 7a670b1dd981c645064f69faf85b04620aadbafb) + +Resolves: #2051520 +--- + src/shared/dropin.c | 23 ++++++++++++----------- + test/TEST-15-DROPIN/test-dropin.sh | 14 ++++++++++++++ + 2 files changed, 26 insertions(+), 11 deletions(-) + +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index bd2a3c0feb..11ed4c7184 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -236,7 +236,6 @@ int unit_file_find_dropin_paths( + char ***ret) { + + _cleanup_strv_free_ char **dirs = NULL; +- UnitType type = _UNIT_TYPE_INVALID; + char *name, **p; + Iterator i; + int r; +@@ -246,22 +245,24 @@ int unit_file_find_dropin_paths( + /* All the names in the unit are of the same type so just grab one. */ + name = (char*) set_first(names); + if (name) { ++ UnitType type = _UNIT_TYPE_INVALID; ++ + type = unit_name_to_type(name); + if (type < 0) + return log_error_errno(EINVAL, + "Failed to to derive unit type from unit name: %s", + name); +- } + +- /* Special top level drop in for ".". Add this first as it's the most generic +- * and should be able to be overridden by more specific drop-ins. */ +- STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, +- unit_path_cache, +- *p, +- unit_type_to_string(type), +- dir_suffix, +- &dirs); ++ /* Special top level drop in for ".". Add this first as it's the most generic ++ * and should be able to be overridden by more specific drop-ins. */ ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, ++ unit_path_cache, ++ *p, ++ unit_type_to_string(type), ++ dir_suffix, ++ &dirs); ++ } + + SET_FOREACH(name, names, i) + STRV_FOREACH(p, lookup_path) +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 7836c6535d..5419169f7b 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -289,9 +289,23 @@ EOF + clear_services a b + } + ++test_invalid_dropins () { ++ echo "Testing invalid dropins..." ++ # Assertion failed on earlier versions, command exits unsuccessfully on later versions ++ systemctl cat nonexistent@.service || true ++ create_services a ++ systemctl daemon-reload ++ # Assertion failed on earlier versions, command exits unsuccessfully on later versions ++ systemctl cat a@.service || true ++ systemctl stop a ++ clear_services a ++ return 0 ++} ++ + test_basic_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins ++test_invalid_dropins + + touch /testok diff --git a/SOURCES/0748-udev-fix-slot-based-network-names-on-s390.patch b/SOURCES/0748-udev-fix-slot-based-network-names-on-s390.patch new file mode 100644 index 0000000..338ccc2 --- /dev/null +++ b/SOURCES/0748-udev-fix-slot-based-network-names-on-s390.patch @@ -0,0 +1,132 @@ +From 2e7f41bd0632312d00d472a73a312218a29ce65b Mon Sep 17 00:00:00 2001 +From: Viktor Mihajlovski +Date: Thu, 18 Mar 2021 11:03:34 +0100 +Subject: [PATCH] udev: fix slot based network names on s390 + +The s390 PCI driver assigns the hotplug slot name from the +function_id attribute of the PCI device using a 8 char hexadecimal +format to match the underlying firmware/hypervisor notation. + +Further, there's always a one-to-one mapping between a PCI +function and a hotplug slot, as individual functions can +hot plugged even for multi-function devices. + +As the generic matching code will always try to parse the slot +name in /sys/bus/pci/slots as a positive decimal number, either +a wrong value might be produced for ID_NET_NAME_SLOT if +the slot name consists of decimal numbers only, or none at all +if a character in the range from 'a' to 'f' is encountered. + +Additionally, the generic code assumes that two interfaces +share a hotplug slot, if they differ only in the function part +of the PCI address. E.g., for an interface with the PCI address +dddd:bb:aa.f, it will match the device to the first slot with +an address dddd:bb:aa. As more than one slot may have this address +for the s390 PCI driver, the wrong slot may be selected. + +To resolve this we're adding a new naming schema version with the +flag NAMING_SLOT_FUNCTION_ID, which enables the correct matching +of hotplug slots if the device has an attribute named function_id. +The ID_NET_NAME_SLOT property will only be produced if there's +a file /sys/bus/pci/slots/ where matches +the value of /sys/bus/pci/devices/.../function_id in 8 char +hex notation. + +Fixes #19016 +See also #19078 + +Related: #1939914 + +(cherry picked from commit a496a238e8ee66ce25ad13a3f46549b2e2e979fc) +--- + man/systemd.net-naming-scheme.xml | 10 +++++++++ + src/udev/udev-builtin-net_id.c | 34 +++++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index fe1aa4b654..e42c93eaad 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -313,6 +313,16 @@ + Same as naming scheme rhel-8.4. + + ++ ++ rhel-8.7 ++ ++ PCI hotplug slot names for the s390 PCI driver are a hexadecimal representation ++ of the function_id device attribute. This attribute is now used to build the ++ ID_NET_NAME_SLOT. Before that, all slot names were parsed as decimal ++ numbers, which could either result in an incorrect value of the ID_NET_NAME_SLOT ++ property or none at all. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 386d74ca5e..b57227a09f 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -126,6 +126,7 @@ typedef enum NamingSchemeFlags { + NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ + NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ + NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */ ++ NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */ + + /* And now the masks that combine the features above */ + NAMING_V238 = 0, +@@ -137,6 +138,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + NAMING_RHEL_8_5 = NAMING_RHEL_8_4, + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, ++ NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -156,6 +158,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.4", NAMING_RHEL_8_4 }, + { "rhel-8.5", NAMING_RHEL_8_5 }, + { "rhel-8.6", NAMING_RHEL_8_6 }, ++ { "rhel-8.7", NAMING_RHEL_8_7 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + +@@ -477,6 +480,37 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + hotplug_slot_dev = names->pcidev; + while (hotplug_slot_dev) { ++ if (!udev_device_get_sysname(hotplug_slot_dev)) ++ continue; ++ ++ /* The /function_id attribute is unique to the s390 PCI driver. ++ If present, we know that the slot's directory name for this device is ++ /sys/bus/pci/XXXXXXXX/ where XXXXXXXX is the fixed length 8 hexadecimal ++ character string representation of function_id. ++ Therefore we can short cut here and just check for the existence of ++ the slot directory. As this directory has to exist, we're emitting a ++ debug message for the unlikely case it's not found. ++ Note that the domain part of doesn't belong to the slot name here ++ because there's a 1-to-1 relationship between PCI function and its hotplug ++ slot. ++ */ ++ if (naming_scheme_has(NAMING_SLOT_FUNCTION_ID)) { ++ attr = udev_device_get_sysattr_value(hotplug_slot_dev, "function_id"); ++ if (attr) { ++ int function_id; ++ _cleanup_free_ char *str; ++ ++ if (safe_atoi(attr, &function_id) >= 0 && ++ asprintf(&str, "%s/%08x/", slots, function_id) >= 0 && ++ access(str, R_OK) == 0) { ++ hotplug_slot = function_id; ++ domain = 0; ++ } else ++ log_debug("No matching slot for function_id (%s).", attr); ++ break; ++ } ++ } ++ + FOREACH_DIRENT_ALL(dent, dir, break) { + int i, r; + char str[PATH_MAX]; diff --git a/SOURCES/0749-udev-add-missing-initialization-to-fix-freeing-inval.patch b/SOURCES/0749-udev-add-missing-initialization-to-fix-freeing-inval.patch new file mode 100644 index 0000000..234cd72 --- /dev/null +++ b/SOURCES/0749-udev-add-missing-initialization-to-fix-freeing-inval.patch @@ -0,0 +1,26 @@ +From e6def2e6be6a1cb87874cf8589ccdcb6ee3eec1e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 7 Apr 2021 19:09:50 +0900 +Subject: [PATCH] udev: add missing initialization to fix freeing invalid + address + +Releated: #1939914 + +(cherry picked from commit b08c3fbe0e3f310b520d17be92110b4cb96a5f2c) +--- + src/udev/udev-builtin-net_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index b57227a09f..816661fb93 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -498,7 +498,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + attr = udev_device_get_sysattr_value(hotplug_slot_dev, "function_id"); + if (attr) { + int function_id; +- _cleanup_free_ char *str; ++ _cleanup_free_ char *str = NULL; + + if (safe_atoi(attr, &function_id) >= 0 && + asprintf(&str, "%s/%08x/", slots, function_id) >= 0 && diff --git a/SOURCES/0750-udev-it-is-not-necessary-that-the-path-is-readable.patch b/SOURCES/0750-udev-it-is-not-necessary-that-the-path-is-readable.patch new file mode 100644 index 0000000..bc6dc29 --- /dev/null +++ b/SOURCES/0750-udev-it-is-not-necessary-that-the-path-is-readable.patch @@ -0,0 +1,25 @@ +From 100324ef0d911913e09db71e030a5ba137ac357e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 7 Apr 2021 19:19:45 +0900 +Subject: [PATCH] udev: it is not necessary that the path is readable + +Related: #1939914 + +(cherry picked from commit 70c35e4bfd64f24c7cb3536bdf63af537e0f2971) +--- + src/udev/udev-builtin-net_id.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 816661fb93..ba7638fcb8 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -502,7 +502,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + if (safe_atoi(attr, &function_id) >= 0 && + asprintf(&str, "%s/%08x/", slots, function_id) >= 0 && +- access(str, R_OK) == 0) { ++ access(str, F_OK) == 0) { + hotplug_slot = function_id; + domain = 0; + } else diff --git a/SOURCES/0751-udev-allow-onboard-index-up-to-65535.patch b/SOURCES/0751-udev-allow-onboard-index-up-to-65535.patch new file mode 100644 index 0000000..61c9d74 --- /dev/null +++ b/SOURCES/0751-udev-allow-onboard-index-up-to-65535.patch @@ -0,0 +1,100 @@ +From 033998c21f01e7b7d91e4aa51a358f8016f3740a Mon Sep 17 00:00:00 2001 +From: Viktor Mihajlovski +Date: Tue, 27 Apr 2021 15:25:16 +0200 +Subject: [PATCH] udev: allow onboard index up to 65535 + +The maximum allowed value of the sysfs device index entry was limited to +16383 (2^14-1) to avoid the generation of unreasonable onboard interface +names. +For s390 the index can assume a value of up to 65535 (2^16-1) which is +now allowed depending on the new naming flag NAMING_16BIT_INDEX. +Larger index values are considered unreasonable and remain to be +ignored. + +Related: #1939914 + +(cherry picked from commit 5a7eb46c0206411d380543021291b4bca0b6f59f) +--- + man/systemd.net-naming-scheme.xml | 7 ++++++- + src/udev/udev-builtin-net_id.c | 22 +++++++++++++++------- + 2 files changed, 21 insertions(+), 8 deletions(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index e42c93eaad..a567483995 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -320,7 +320,12 @@ + of the function_id device attribute. This attribute is now used to build the + ID_NET_NAME_SLOT. Before that, all slot names were parsed as decimal + numbers, which could either result in an incorrect value of the ID_NET_NAME_SLOT +- property or none at all. ++ property or none at all. ++ ++ Some firmware and hypervisor implementations report unreasonable high numbers for the onboard ++ index. To prevent the generation of bogus onbard interface names, index numbers greater than 16381 ++ (2^14-1) were ignored. For s390 PCI devices index values up to 65535 (2^16-1) are valid. To account ++ for that, the limit is increased to now 65535. + + + Note that latest may be used to denote the latest scheme known to this +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ba7638fcb8..df84acf27c 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -104,7 +104,8 @@ + #include "udev.h" + #include "udev-util.h" + +-#define ONBOARD_INDEX_MAX (16*1024-1) ++#define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) ++#define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) + + /* So here's the deal: net_id is supposed to be an excercise in providing stable names for network devices. However, we + * also want to keep updating the naming scheme used in future versions of net_id. These two goals of course are +@@ -127,6 +128,7 @@ typedef enum NamingSchemeFlags { + NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ + NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */ + NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */ ++ NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */ + + /* And now the masks that combine the features above */ + NAMING_V238 = 0, +@@ -138,7 +140,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + NAMING_RHEL_8_5 = NAMING_RHEL_8_4, + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, +- NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID, ++ NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -326,6 +328,16 @@ out_unref: + return r; + } + ++static bool is_valid_onboard_index(unsigned long idx) { ++ /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to ++ * report for example). Let's define a cut-off where we don't consider the index reliable anymore. We ++ * pick some arbitrary cut-off, which is somewhere beyond the realistic number of physical network ++ * interface a system might have. Ideally the kernel would already filter this crap for us, but it ++ * doesn't currently. The initial cut-off value (2^14-1) was too conservative for s390 PCI which ++ * allows for index values up 2^16-1 which is now enabled with the NAMING_16BIT_INDEX naming flag. */ ++ return idx <= (naming_scheme_has(NAMING_16BIT_INDEX) ? ONBOARD_16BIT_INDEX_MAX : ONBOARD_14BIT_INDEX_MAX); ++} ++ + /* retrieve on-board index number and label from firmware */ + static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { + unsigned dev_port = 0; +@@ -346,11 +358,7 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { + if (idx <= 0) + return -EINVAL; + +- /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to report for +- * example). Let's define a cut-off where we don't consider the index reliable anymore. We pick some arbitrary +- * cut-off, which is somewhere beyond the realistic number of physical network interface a system might +- * have. Ideally the kernel would already filter his crap for us, but it doesn't currently. */ +- if (idx > ONBOARD_INDEX_MAX) ++ if (!is_valid_onboard_index(idx)) + return -ENOENT; + + /* kernel provided port index for multiple ports on a single PCI function */ diff --git a/SOURCES/0752-Revert-basic-use-comma-as-separator-in-cpuset-cgroup.patch b/SOURCES/0752-Revert-basic-use-comma-as-separator-in-cpuset-cgroup.patch new file mode 100644 index 0000000..e4bfbc1 --- /dev/null +++ b/SOURCES/0752-Revert-basic-use-comma-as-separator-in-cpuset-cgroup.patch @@ -0,0 +1,98 @@ +From 1ad8be47cd41f017faa5a9ca9614cbcbe784d43b Mon Sep 17 00:00:00 2001 +From: Jacek Migacz +Date: Mon, 25 Apr 2022 21:12:40 +0200 +Subject: [PATCH] Revert "basic: use comma as separator in cpuset cgroup cpu + ranges" + +This reverts commit 9fe3b9c7165afeedcf9f31959c436bcec233bb4d. + +RHEL-only + +Resolves: #1858220 +--- + src/basic/cpu-set-util.c | 45 ---------------------------------------- + src/basic/cpu-set-util.h | 1 - + src/core/cgroup.c | 2 +- + 3 files changed, 1 insertion(+), 47 deletions(-) + +diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c +index 1922c95864..db2e1d6c97 100644 +--- a/src/basic/cpu-set-util.c ++++ b/src/basic/cpu-set-util.c +@@ -88,51 +88,6 @@ char *cpu_set_to_range_string(const CPUSet *set) { + return TAKE_PTR(str) ?: strdup(""); + } + +-/* XXX(msekleta): this is the workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1819152, remove in 8.3 */ +-char *cpu_set_to_range_string_kernel(const CPUSet *set) { +- unsigned range_start = 0, range_end; +- _cleanup_free_ char *str = NULL; +- size_t allocated = 0, len = 0; +- bool in_range = false; +- int r; +- +- for (unsigned i = 0; i < set->allocated * 8; i++) +- if (CPU_ISSET_S(i, set->allocated, set->set)) { +- if (in_range) +- range_end++; +- else { +- range_start = range_end = i; +- in_range = true; +- } +- } else if (in_range) { +- in_range = false; +- +- if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) +- return NULL; +- +- if (range_end > range_start) +- r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); +- else +- r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); +- assert_se(r > 0); +- len += r; +- } +- +- if (in_range) { +- if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) +- return NULL; +- +- if (range_end > range_start) +- r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); +- else +- r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); +- assert_se(r > 0); +- } +- +- return TAKE_PTR(str) ?: strdup(""); +-} +- +- + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { + size_t need; + +diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h +index 795be807af..406b08ee11 100644 +--- a/src/basic/cpu-set-util.h ++++ b/src/basic/cpu-set-util.h +@@ -27,7 +27,6 @@ int cpu_set_add_all(CPUSet *a, const CPUSet *b); + + char* cpu_set_to_string(const CPUSet *a); + char *cpu_set_to_range_string(const CPUSet *a); +-char *cpu_set_to_range_string_kernel(const CPUSet *a); + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus); + + int parse_cpu_set_full( +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f02cc31c6e..f89bce3d61 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -687,7 +687,7 @@ static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) + _cleanup_free_ char *buf = NULL; + int r; + +- buf = cpu_set_to_range_string_kernel(&cpus); ++ buf = cpu_set_to_range_string(&cpus); + if (!buf) + return; + diff --git a/SOURCES/0753-acpi-fpdt-mark-structures-as-packed.patch b/SOURCES/0753-acpi-fpdt-mark-structures-as-packed.patch new file mode 100644 index 0000000..075c84e --- /dev/null +++ b/SOURCES/0753-acpi-fpdt-mark-structures-as-packed.patch @@ -0,0 +1,51 @@ +From 45670b65ccc1d41a32b83217ba9a78c9eed5fc02 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 23 Apr 2020 08:49:10 +0200 +Subject: [PATCH] acpi-fpdt: mark structures as packed + +Let's make sure the alignment doesn't matter. + +(cherry picked from commit 49490c1d353bc920cbf73f4c71e9c35d2e3eb8b1) + +Related: #2047373 +--- + src/shared/acpi-fpdt.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/shared/acpi-fpdt.c b/src/shared/acpi-fpdt.c +index d565ebd43e..38c464c912 100644 +--- a/src/shared/acpi-fpdt.c ++++ b/src/shared/acpi-fpdt.c +@@ -23,7 +23,7 @@ struct acpi_table_header { + uint32_t oem_revision; + char asl_compiler_id[4]; + uint32_t asl_compiler_revision; +-}; ++} _packed_; + + enum { + ACPI_FPDT_TYPE_BOOT = 0, +@@ -36,12 +36,12 @@ struct acpi_fpdt_header { + uint8_t revision; + uint8_t reserved[4]; + uint64_t ptr; +-}; ++} _packed_; + + struct acpi_fpdt_boot_header { + char signature[4]; + uint32_t length; +-}; ++} _packed_; + + enum { + ACPI_FPDT_S3PERF_RESUME_REC = 0, +@@ -59,7 +59,7 @@ struct acpi_fpdt_boot { + uint64_t startup_start; + uint64_t exit_services_entry; + uint64_t exit_services_exit; +-}; ++} _packed; + + int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) { + _cleanup_free_ char *buf = NULL; diff --git a/SOURCES/0754-core-slice-make-slice_freezer_action-return-0-if-fre.patch b/SOURCES/0754-core-slice-make-slice_freezer_action-return-0-if-fre.patch new file mode 100644 index 0000000..15e1d43 --- /dev/null +++ b/SOURCES/0754-core-slice-make-slice_freezer_action-return-0-if-fre.patch @@ -0,0 +1,46 @@ +From 1f4af2e456675c6226857ee0c8127ff4b3d1d18a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 6 May 2022 14:01:22 +0900 +Subject: [PATCH] core/slice: make slice_freezer_action() return 0 if freezing + state is unchanged + +Fixes #23278. + +(cherry picked from commit d171e72e7afa11b238ba20758384d223b0c76e39) + +Related: #2047373 +--- + src/core/slice.c | 6 +----- + src/core/unit.c | 2 ++ + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/core/slice.c b/src/core/slice.c +index c10e830917..34f3c84bf9 100644 +--- a/src/core/slice.c ++++ b/src/core/slice.c +@@ -395,11 +395,7 @@ static int slice_freezer_action(Unit *s, FreezerAction action) { + return r; + } + +- r = unit_cgroup_freezer_action(s, action); +- if (r < 0) +- return r; +- +- return 1; ++ return unit_cgroup_freezer_action(s, action); + } + + static int slice_freeze(Unit *s) { +diff --git a/src/core/unit.c b/src/core/unit.c +index e2c61ce866..bd79578255 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5622,6 +5622,8 @@ static int unit_freezer_action(Unit *u, FreezerAction action) { + if (r <= 0) + return r; + ++ assert(IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)); ++ + return 1; + } + diff --git a/SOURCES/0755-core-unit-fix-use-after-free.patch b/SOURCES/0755-core-unit-fix-use-after-free.patch new file mode 100644 index 0000000..fbb9dd7 --- /dev/null +++ b/SOURCES/0755-core-unit-fix-use-after-free.patch @@ -0,0 +1,29 @@ +From f307c633acd12d59800a760b1c45fad8c79b6f49 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 9 May 2022 00:56:05 +0900 +Subject: [PATCH] core/unit: fix use-after-free + +Fixes #23312. + +(cherry picked from commit 734582830b58e000a26e18807ea277c18778573c) + +Related: #2047373 +--- + src/core/unit.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index bd79578255..68affa2c0e 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -580,8 +580,8 @@ void unit_free(Unit *u) { + + unit_dequeue_rewatch_pids(u); + +- sd_bus_slot_unref(u->match_bus_slot); +- sd_bus_track_unref(u->bus_track); ++ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); ++ u->bus_track = sd_bus_track_unref(u->bus_track); + u->deserialized_refs = strv_free(u->deserialized_refs); + u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); + diff --git a/SOURCES/0756-sd-bus-fix-reference-counter-to-be-incremented.patch b/SOURCES/0756-sd-bus-fix-reference-counter-to-be-incremented.patch new file mode 100644 index 0000000..16390d0 --- /dev/null +++ b/SOURCES/0756-sd-bus-fix-reference-counter-to-be-incremented.patch @@ -0,0 +1,58 @@ +From 39e9bd0412bef0c37d487834b8be3a78e28cb804 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:05:07 +0900 +Subject: [PATCH] sd-bus: fix reference counter to be incremented + +Fixes #23097. + +(cherry picked from commit b21f237d996c8c18991a68e1204f060d07dc4745) + +[msekleta: This commit also contains the hunk from c2d7dd35d2 +(in sd_bus_track_remove_name). I've decided to not backport that commit +fully because of conflicts and because its was made largely irrelevant +by 7f40cb7c86] + +Related: #2047373 +--- + src/libsystemd/sd-bus/bus-track.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index 16bf615f50..b1ec5ecbbb 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -208,12 +208,12 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (i) { + if (track->recursive) { +- unsigned k = track->n_ref + 1; ++ unsigned k = i->n_ref + 1; + +- if (k < track->n_ref) /* Check for overflow */ ++ if (k < i->n_ref) /* Check for overflow */ + return -EOVERFLOW; + +- track->n_ref = k; ++ i->n_ref = k; + } + + bus_track_remove_from_queue(track); +@@ -281,14 +281,13 @@ _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (!i) + return -EUNATCH; +- if (i->n_ref <= 0) +- return -EUNATCH; +- +- i->n_ref--; + +- if (i->n_ref <= 0) ++ assert(i->n_ref >=1); ++ if (i->n_ref <= 1) + return bus_track_remove_name_fully(track, name); + ++ i->n_ref--; ++ + return 1; + } + diff --git a/SOURCES/0757-sd-bus-do-not-read-unused-value.patch b/SOURCES/0757-sd-bus-do-not-read-unused-value.patch new file mode 100644 index 0000000..18346e1 --- /dev/null +++ b/SOURCES/0757-sd-bus-do-not-read-unused-value.patch @@ -0,0 +1,32 @@ +From 480658d6c79f494e820eb3da59a1818b5b7c3c8b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:25:09 +0900 +Subject: [PATCH] sd-bus: do not read unused value + +(cherry picked from commit 6a7ca27740be4229b4c9f540cd610b205ca5752c) + +Related: #2047373 +--- + src/libsystemd/sd-bus/bus-track.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index b1ec5ecbbb..b9965d9d64 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -182,13 +182,13 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { + + static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) { + sd_bus_track *track = userdata; +- const char *name, *old, *new; ++ const char *name; + int r; + + assert(message); + assert(track); + +- r = sd_bus_message_read(message, "sss", &name, &old, &new); ++ r = sd_bus_message_read(message, "sss", &name, NULL, NULL); + if (r < 0) + return 0; + diff --git a/SOURCES/0758-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch b/SOURCES/0758-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch new file mode 100644 index 0000000..9676e25 --- /dev/null +++ b/SOURCES/0758-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch @@ -0,0 +1,35 @@ +From 805e13f7016f37c882069f43b5f0c0972d5fdf95 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:29:24 +0900 +Subject: [PATCH] sd-bus: do not return negative errno when unknown name is + specified + +When 'recursive' is false, then sd_bus_track_remove_name() does not +return negative errno when unknown name is specified. Let's follow the +same pattern for the case that 'recursive' is true. + +(cherry picked from commit 55bfacc6c33eaf3475762e71172b2ef504be5af8) + +Related: #2047373 +--- + src/libsystemd/sd-bus/bus-track.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index b9965d9d64..8893f190a1 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -275,12 +275,9 @@ _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) { + if (!track) /* Treat a NULL track object as an empty track object */ + return 0; + +- if (!track->recursive) +- return bus_track_remove_name_fully(track, name); +- + i = hashmap_get(track->names, name); + if (!i) +- return -EUNATCH; ++ return 0; + + assert(i->n_ref >=1); + if (i->n_ref <= 1) diff --git a/SOURCES/0759-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch b/SOURCES/0759-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch new file mode 100644 index 0000000..13a748f --- /dev/null +++ b/SOURCES/0759-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch @@ -0,0 +1,48 @@ +From 598eecf5c1c948535ca626833bc5cea59060913f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Apr 2022 22:30:22 +0200 +Subject: [PATCH] sd-bus: switch to a manual overflow check in + sd_bus_track_add_name() + +This is generally used in a directly client controllable way, hence we +should handle ref count overflow gracefully, instead of hitting an +assert(). + +As discussed: + +https://github.com/systemd/systemd/pull/23099#discussion_r854341850 +(cherry picked from commit 7f40cb7c86b0fff3a82096a9499570bad9c19fd2) + +[msekleta: We've never switched to using track_item_ref/unref introduced +in c2d7dd35d2 hence we still had potential undefined behavior related to +overflow check and this commit fixes that.] + +Related: #2047373 +--- + src/libsystemd/sd-bus/bus-track.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index 8893f190a1..b818e93bec 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -208,12 +208,16 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (i) { + if (track->recursive) { +- unsigned k = i->n_ref + 1; ++ assert(i->n_ref > 0); + +- if (k < i->n_ref) /* Check for overflow */ ++ /* Manual oveflow check (instead of a DEFINE_TRIVIAL_REF_FUNC() helper or so), so ++ * that we can return a proper error, given this is almost always called in a ++ * directly client controllable way, and thus better should never hit an assertion ++ * here. */ ++ if (i->n_ref >= UINT_MAX) + return -EOVERFLOW; + +- i->n_ref = k; ++ i->n_ref++; + } + + bus_track_remove_from_queue(track); diff --git a/SOURCES/0760-resolved-let-s-preferably-route-reverse-lookups-for-.patch b/SOURCES/0760-resolved-let-s-preferably-route-reverse-lookups-for-.patch new file mode 100644 index 0000000..922db9a --- /dev/null +++ b/SOURCES/0760-resolved-let-s-preferably-route-reverse-lookups-for-.patch @@ -0,0 +1,194 @@ +From b9844d3dd9d7fdf81d475b81d06a6e9ec821f91d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 9 Nov 2020 22:22:56 +0100 +Subject: [PATCH] resolved: let's preferably route reverse lookups for local + subnets to matching interfaces + +Let's preferably route traffic for reverse lookups to LLMNR/mDNS/DNS on +the matching interface if the IP address is in the local subnet. Also, +if looking up an IP address of our own host, let's avoid doing +LLMNR/mDNS at all. + +This is useful if "~." is a routing domain to DNS, as it means, local +reverse lookups still go to LLMNR/mDNS, too. + +(cherry picked from commit 13eb76ef06f5d50bbeb58df1744057e41ef2647e) + +Resolves #1739689 +--- + src/resolve/resolved-dns-scope.c | 85 +++++++++++++++++++++++++++++++- + src/resolve/resolved-link.c | 12 +++-- + src/resolve/resolved-link.h | 1 + + 3 files changed, 92 insertions(+), 6 deletions(-) + +diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c +index 38ea7fea0a..8b65813428 100644 +--- a/src/resolve/resolved-dns-scope.c ++++ b/src/resolve/resolved-dns-scope.c +@@ -417,6 +417,65 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add + return dns_scope_socket(s, SOCK_STREAM, family, address, server, port, ret_socket_address); + } + ++static DnsScopeMatch match_subnet_reverse_lookups( ++ DnsScope *s, ++ const char *domain, ++ bool exclude_own) { ++ ++ union in_addr_union ia; ++ LinkAddress *a; ++ int f, r; ++ ++ assert(s); ++ assert(domain); ++ ++ /* Checks whether the specified domain is a reverse address domain (i.e. in the .in-addr.arpa or ++ * .ip6.arpa area), and if so, whether the address matches any of the local subnets of the link the ++ * scope is associated with. If so, our scope should consider itself relevant for any lookup in the ++ * domain, since it apparently refers to hosts on this link's subnet. ++ * ++ * If 'exclude_own' is true this will return DNS_SCOPE_NO for any IP addresses assigned locally. This ++ * is useful for LLMNR/mDNS as we never want to look up our own hostname on LLMNR/mDNS but always use ++ * the locally synthesized one. */ ++ ++ if (!s->link) ++ return _DNS_SCOPE_INVALID; /* No link, hence no local addresses to check */ ++ ++ r = dns_name_address(domain, &f, &ia); ++ if (r < 0) ++ log_debug_errno(r, "Failed to determine whether '%s' is an address domain: %m", domain); ++ if (r <= 0) ++ return _DNS_SCOPE_INVALID; ++ ++ if (s->family != AF_UNSPEC && f != s->family) ++ return _DNS_SCOPE_INVALID; /* Don't look for IPv4 addresses on LLMNR/mDNS over IPv6 and vice versa */ ++ ++ LIST_FOREACH(addresses, a, s->link->addresses) { ++ ++ if (a->family != f) ++ continue; ++ ++ /* Equals our own address? nah, let's not use this scope. The local synthesizer will pick it up for us. */ ++ if (exclude_own && ++ in_addr_equal(f, &a->in_addr, &ia) > 0) ++ return DNS_SCOPE_NO; ++ ++ if (a->prefixlen == UCHAR_MAX) /* don't know subnet mask */ ++ continue; ++ ++ /* Check if the address is in the local subnet */ ++ r = in_addr_prefix_covers(f, &a->in_addr, a->prefixlen, &ia); ++ if (r < 0) ++ log_debug_errno(r, "Failed to determine whether link address covers lookup address '%s': %m", domain); ++ if (r > 0) ++ /* Note that we only claim zero labels match. This is so that this is at the same ++ * priority a DNS scope with "." as routing domain is. */ ++ return DNS_SCOPE_YES + 0; ++ } ++ ++ return _DNS_SCOPE_INVALID; ++} ++ + DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) { + DnsSearchDomain *d; + +@@ -455,6 +514,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co + + case DNS_PROTOCOL_DNS: { + DnsServer *dns_server; ++ DnsScopeMatch m; + + /* Never route things to scopes that lack DNS servers */ + dns_server = dns_scope_get_dns_server(s); +@@ -485,10 +545,23 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co + dns_name_endswith(domain, "local") == 0) + return DNS_SCOPE_MAYBE; + ++ /* If the IP address to look up matches the local subnet, then implicity synthesizes ++ * DNS_SCOPE_YES_BASE + 0 on this interface, i.e. preferably resolve IP addresses via the DNS ++ * server belonging to this interface. */ ++ m = match_subnet_reverse_lookups(s, domain, false); ++ if (m >= 0) ++ return m; ++ + return DNS_SCOPE_NO; + } + +- case DNS_PROTOCOL_MDNS: ++ case DNS_PROTOCOL_MDNS: { ++ DnsScopeMatch m; ++ ++ m = match_subnet_reverse_lookups(s, domain, true); ++ if (m >= 0) ++ return m; ++ + if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) || + (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) || + (dns_name_endswith(domain, "local") > 0 && /* only resolve names ending in .local via mDNS */ +@@ -497,8 +570,15 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co + return DNS_SCOPE_MAYBE; + + return DNS_SCOPE_NO; ++ } ++ ++ case DNS_PROTOCOL_LLMNR: { ++ DnsScopeMatch m; ++ ++ m = match_subnet_reverse_lookups(s, domain, true); ++ if (m >= 0) ++ return m; + +- case DNS_PROTOCOL_LLMNR: + if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) || + (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0) || + (dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */ +@@ -507,6 +587,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co + return DNS_SCOPE_MAYBE; + + return DNS_SCOPE_NO; ++ } + + default: + assert_not_reached("Unknown scope protocol"); +diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c +index ff2be12415..c42fe5b5f4 100644 +--- a/src/resolve/resolved-link.c ++++ b/src/resolve/resolved-link.c +@@ -776,10 +776,13 @@ int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr + if (!a) + return -ENOMEM; + +- a->family = family; +- a->in_addr = *in_addr; ++ *a = (LinkAddress) { ++ .family = family, ++ .in_addr = *in_addr, ++ .link = l, ++ .prefixlen = UCHAR_MAX, ++ }; + +- a->link = l; + LIST_PREPEND(addresses, l->addresses, a); + l->n_addresses++; + +@@ -1077,7 +1080,8 @@ int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) { + if (r < 0) + return r; + +- sd_rtnl_message_addr_get_scope(m, &a->scope); ++ (void) sd_rtnl_message_addr_get_prefixlen(m, &a->prefixlen); ++ (void) sd_rtnl_message_addr_get_scope(m, &a->scope); + + link_allocate_scopes(a->link); + link_add_rrs(a->link, false); +diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h +index 063d3f35c3..8d52b10950 100644 +--- a/src/resolve/resolved-link.h ++++ b/src/resolve/resolved-link.h +@@ -24,6 +24,7 @@ struct LinkAddress { + + int family; + union in_addr_union in_addr; ++ unsigned char prefixlen; + + unsigned char flags, scope; + diff --git a/SOURCES/0761-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch b/SOURCES/0761-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch new file mode 100644 index 0000000..90565a6 --- /dev/null +++ b/SOURCES/0761-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch @@ -0,0 +1,62 @@ +From a46d3732a4f8baacf1be3e5e0ac152119fe26d4c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Fri, 2 Oct 2020 17:30:35 +0200 +Subject: [PATCH] unit: don't emit PropertiesChanged signal if adding a + dependency to a unit is a no-op + +(cherry picked from commit 5177cb0a9add4ae568cff6e6f7c2b3c77760c343) + +Resolves: #1948480 +--- + src/core/unit.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 68affa2c0e..e3e534ea2e 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2818,6 +2818,9 @@ int unit_add_dependency( + }; + Unit *original_u = u, *original_other = other; + int r; ++ /* Helper to know whether sending a notification is necessary or not: ++ * if the dependency is already there, no need to notify! */ ++ bool noop = true; + + assert(u); + assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX); +@@ -2842,24 +2845,33 @@ int unit_add_dependency( + r = unit_add_dependency_hashmap(u->dependencies + d, other, mask, 0); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) { + r = unit_add_dependency_hashmap(other->dependencies + inverse_table[d], u, 0, mask); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + } + + if (add_reference) { + r = unit_add_dependency_hashmap(u->dependencies + UNIT_REFERENCES, other, mask, 0); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + + r = unit_add_dependency_hashmap(other->dependencies + UNIT_REFERENCED_BY, u, 0, mask); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + } + +- unit_add_to_dbus_queue(u); ++ if (!noop) ++ unit_add_to_dbus_queue(u); + return 0; + } + diff --git a/SOURCES/0762-tests-make-inverted-tests-actually-count.patch b/SOURCES/0762-tests-make-inverted-tests-actually-count.patch new file mode 100644 index 0000000..4b7adaa --- /dev/null +++ b/SOURCES/0762-tests-make-inverted-tests-actually-count.patch @@ -0,0 +1,34 @@ +From f784cdd269ccba28e3e14b24ecd33ab9db148403 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Apr 2021 23:24:25 +0200 +Subject: [PATCH] tests: make inverted tests actually count +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +"! test ..." does not cause the script to fail, even with set -e. +IIUC, bash treats this command as part of an expression line, as it +would if 'test ... && ...' was used. Failing expression lines do not +terminate the script. + +This fixes the obvious cases by changing '! test' → 'test !'. +Then the inversion happens internally in test and bash will propagate +the failure. + +(cherry picked from commit ffa328f060f437f3e1f0f0cb13513ee3dd9c3da5) + +Related: #2087152 +--- + test/TEST-22-TMPFILES/test-01.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/TEST-22-TMPFILES/test-01.sh b/test/TEST-22-TMPFILES/test-01.sh +index d233e37fb2..b10b5aaa1a 100755 +--- a/test/TEST-22-TMPFILES/test-01.sh ++++ b/test/TEST-22-TMPFILES/test-01.sh +@@ -10,4 +10,4 @@ rm -fr /tmp/test + + echo "e /tmp/test - root root 1d" | systemd-tmpfiles --create - + +-! test -e /tmp/test ++test ! -e /tmp/test diff --git a/SOURCES/0763-TEST-make-failure-tests-actually-fail-on-failure.patch b/SOURCES/0763-TEST-make-failure-tests-actually-fail-on-failure.patch new file mode 100644 index 0000000..c2e8e26 --- /dev/null +++ b/SOURCES/0763-TEST-make-failure-tests-actually-fail-on-failure.patch @@ -0,0 +1,123 @@ +From d153f9ff573b191076b843118e825f71227dbc01 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 8 Apr 2021 01:27:33 +0200 +Subject: [PATCH] TEST-*: make failure tests actually fail on failure + +Here the intent was actually correct, and the tests still pass when the check +is made effective. + +(cherry picked from commit 4e20fe27950e14e8a082a74515f347546a9371d0) + +Related: #2087152 +--- + test/TEST-03-JOBS/test-jobs.sh | 8 ++++---- + test/TEST-04-JOURNAL/test-journal.sh | 4 ++-- + test/TEST-18-FAILUREACTION/testsuite.sh | 2 +- + test/TEST-20-MAINPIDGAMES/testsuite.sh | 14 ++++++++++++-- + test/TEST-23-TYPE-EXEC/testsuite.sh | 4 ++-- + 5 files changed, 21 insertions(+), 11 deletions(-) + +diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/TEST-03-JOBS/test-jobs.sh +index 42190cf478..4ff53e0ade 100755 +--- a/test/TEST-03-JOBS/test-jobs.sh ++++ b/test/TEST-03-JOBS/test-jobs.sh +@@ -18,7 +18,7 @@ systemctl start --job-mode=ignore-dependencies hello + END_SEC=$(date -u '+%s') + ELAPSED=$(($END_SEC-$START_SEC)) + +-[ "$ELAPSED" -lt 3 ] ++test "$ELAPSED" -lt 3 + + # sleep should still be running, hello not. + systemctl list-jobs > /root/list-jobs.txt +@@ -27,11 +27,11 @@ grep 'hello\.service' /root/list-jobs.txt && exit 1 + systemctl stop sleep.service hello-after-sleep.target + + # Some basic testing that --show-transaction does something useful +-! systemctl is-active systemd-importd ++systemctl is-active systemd-importd && { echo 'unexpected success'; exit 1; } + systemctl -T start systemd-importd + systemctl is-active systemd-importd + systemctl --show-transaction stop systemd-importd +-! systemctl is-active systemd-importd ++systemctl is-active systemd-importd && { echo 'unexpected success'; exit 1; } + + # Test for a crash when enqueuing a JOB_NOP when other job already exists + systemctl start --no-block hello-after-sleep.target +@@ -79,7 +79,7 @@ ELAPSED=$(($END_SEC-$START_SEC)) + + # wait5fail fails, so systemctl should fail + START_SEC=$(date -u '+%s') +-! systemctl start --wait wait2.service wait5fail.service || exit 1 ++systemctl start --wait wait2.service wait5fail.service && { echo 'unexpected success'; exit 1; } + END_SEC=$(date -u '+%s') + ELAPSED=$(($END_SEC-$START_SEC)) + [[ "$ELAPSED" -ge 5 ]] && [[ "$ELAPSED" -le 7 ]] || exit 1 +diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh +index 52a6ee84d1..a3db1a7472 100755 +--- a/test/TEST-04-JOURNAL/test-journal.sh ++++ b/test/TEST-04-JOURNAL/test-journal.sh +@@ -60,8 +60,8 @@ journalctl -b -o export --output-fields=MESSAGE,FOO --output-fields=PRIORITY,MES + grep -q '^__CURSOR=' /output + grep -q '^MESSAGE=foo$' /output + grep -q '^PRIORITY=6$' /output +-! grep -q '^FOO=' /output +-! grep -q '^SYSLOG_FACILITY=' /output ++grep '^FOO=' /output && { echo 'unexpected success'; exit 1; } ++grep '^SYSLOG_FACILITY=' /output && { echo 'unexpected success'; exit 1; } + + # https://github.com/systemd/systemd/issues/13708 + ID=$(journalctl --new-id128 | sed -n 2p) +diff --git a/test/TEST-18-FAILUREACTION/testsuite.sh b/test/TEST-18-FAILUREACTION/testsuite.sh +index 1867cc3c47..21b055d6ef 100755 +--- a/test/TEST-18-FAILUREACTION/testsuite.sh ++++ b/test/TEST-18-FAILUREACTION/testsuite.sh +@@ -5,7 +5,7 @@ set -ex + set -o pipefail + + systemd-run --wait -p FailureAction=poweroff true +-! systemd-run --wait -p SuccessAction=poweroff false ++systemd-run --wait -p SuccessAction=poweroff false && { echo 'unexpected success'; exit 1; } + + if test -f /firstphase ; then + echo OK > /firstphase +diff --git a/test/TEST-20-MAINPIDGAMES/testsuite.sh b/test/TEST-20-MAINPIDGAMES/testsuite.sh +index 0e1a116b07..d1bfdd7a2d 100755 +--- a/test/TEST-20-MAINPIDGAMES/testsuite.sh ++++ b/test/TEST-20-MAINPIDGAMES/testsuite.sh +@@ -128,8 +128,18 @@ test -f /run/mainpidsh3/pid + EOF + chmod 755 /dev/shm/mainpid3.sh + +-# This has to fail, as we shouldn't accept the dangerous PID file, and then inotify-wait on it to be corrected which we never do +-! systemd-run --unit=mainpidsh3.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh3 -p PIDFile=/run/mainpidsh3/pid -p DynamicUser=1 -p TimeoutStartSec=2s /dev/shm/mainpid3.sh ++# This has to fail, as we shouldn't accept the dangerous PID file, and then ++# inotify-wait on it to be corrected which we never do. ++systemd-run --unit=mainpidsh3.service \ ++ -p StandardOutput=tty \ ++ -p StandardError=tty \ ++ -p Type=forking \ ++ -p RuntimeDirectory=mainpidsh3 \ ++ -p PIDFile=/run/mainpidsh3/pid \ ++ -p DynamicUser=1 \ ++ -p TimeoutStartSec=2s \ ++ /dev/shm/mainpid3.sh \ ++ && { echo 'unexpected success'; exit 1; } + + # Test that this failed due to timeout, and not some other error + test `systemctl show -p Result --value mainpidsh3.service` = timeout +diff --git a/test/TEST-23-TYPE-EXEC/testsuite.sh b/test/TEST-23-TYPE-EXEC/testsuite.sh +index e0c34cfd04..beb7fd2e38 100755 +--- a/test/TEST-23-TYPE-EXEC/testsuite.sh ++++ b/test/TEST-23-TYPE-EXEC/testsuite.sh +@@ -18,8 +18,8 @@ systemd-run --unit=three -p Type=simple /tmp/brokenbinary + + # And now, do the same with Type=exec, where the latter two should fail + systemd-run --unit=four -p Type=exec /bin/sleep infinity +-! systemd-run --unit=five -p Type=exec -p User=idontexist /bin/sleep infinity +-! systemd-run --unit=six -p Type=exec /tmp/brokenbinary ++systemd-run --unit=five -p Type=exec -p User=idontexist /bin/sleep infinity && { echo 'unexpected success'; exit 1; } ++systemd-run --unit=six -p Type=exec /tmp/brokenbinary && { echo 'unexpected success'; exit 1; } + + # For issue #20933 + diff --git a/SOURCES/0764-ci-Mergify-configuration-update.patch b/SOURCES/0764-ci-Mergify-configuration-update.patch new file mode 100644 index 0000000..7d0a006 --- /dev/null +++ b/SOURCES/0764-ci-Mergify-configuration-update.patch @@ -0,0 +1,69 @@ +From cd8518b7f4ebfda9955bf0b649cf759c45e729f1 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 6 Jun 2022 15:40:20 +0200 +Subject: [PATCH] ci(Mergify): configuration update + +Add rules for needs-ci label management + +RHEL-only + +Related: #2087152 +--- + .mergify.yml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + create mode 100644 .mergify.yml + +diff --git a/.mergify.yml b/.mergify.yml +new file mode 100644 +index 0000000000..6fa400effd +--- /dev/null ++++ b/.mergify.yml +@@ -0,0 +1,48 @@ ++# doc: https://docs.mergify.com ++--- ++ ++pull_request_rules: ++ - name: Add `needs-ci` label on CI fail ++ conditions: ++ - or: ++ # Unit tests ++ - -check-success=build (stream8, GCC) ++ - -check-success=build (stream8, GCC_ASAN) ++ # CentOS Stream CI ++ - -check-success=CentOS CI (CentOS Stream 8) ++ # LGTM ++ - and: ++ - "-check-success=LGTM analysis: JavaScript" ++ - "-check-neutral=LGTM analysis: JavaScript" ++ - and: ++ - "-check-success=LGTM analysis: Python" ++ - "-check-neutral=LGTM analysis: Python" ++ - and: ++ - "-check-success=LGTM analysis: C/C++" ++ - "-check-neutral=LGTM analysis: C/C++" ++ actions: ++ label: ++ add: ++ - needs-ci ++ ++ - name: Remove `needs-ci` label on CI success ++ conditions: ++ # Unit tests ++ - check-success=build (stream8, GCC) ++ - check-success=build (stream8, GCC_ASAN) ++ # CentOS Stream CI ++ - check-success=CentOS CI (CentOS Stream 8) ++ # LGTM ++ - or: ++ - "check-success=LGTM analysis: JavaScript" ++ - "check-neutral=LGTM analysis: JavaScript" ++ - or: ++ - "check-success=LGTM analysis: Python" ++ - "check-neutral=LGTM analysis: Python" ++ - or: ++ - "check-success=LGTM analysis: C/C++" ++ - "check-neutral=LGTM analysis: C/C++" ++ actions: ++ label: ++ remove: ++ - needs-ci diff --git a/SOURCES/0765-core-propagate-triggered-unit-in-more-load-states.patch b/SOURCES/0765-core-propagate-triggered-unit-in-more-load-states.patch new file mode 100644 index 0000000..5459390 --- /dev/null +++ b/SOURCES/0765-core-propagate-triggered-unit-in-more-load-states.patch @@ -0,0 +1,122 @@ +From e5121fbb839a36055e5fdab1b9d92dc42f495f29 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 11 Sep 2020 19:49:33 +0200 +Subject: [PATCH] core: propagate triggered unit in more load states + +In 4c2ef3276735ad9f7fccf33f5bdcbe7d8751e7ec we enabled propagating +triggered unit state to the triggering unit for service units in more +load states, so that we don't accidentally stop tracking state +correctly. + +Do the same for our other triggering unit states: automounts, paths, and +timers. + +Also, make this an assertion rather than a simple test. After all it +should never happen that we get called for half-loaded units or units of +the wrong type. The load routines should already have made this +impossible. + +(cherry picked from commit 0377cd2936ae5cac0c9d76a4b58889f121c097c4) + +Related: #2065322 +--- + src/core/automount.c | 4 ++-- + src/core/path.c | 7 +++---- + src/core/socket.c | 4 ++-- + src/core/timer.c | 4 ++-- + src/core/transaction.c | 2 +- + src/core/unit.h | 4 ++++ + 6 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index f212620c8f..c1c513d4a5 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -492,8 +492,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) { + assert(other); + + /* Filter out invocations with bogus state */ +- if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT) +- return; ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); ++ assert(other->type == UNIT_MOUNT); + + /* Don't propagate state changes from the mount if we are already down */ + if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)) +diff --git a/src/core/path.c b/src/core/path.c +index 58f490589d..a7c2e0b7c1 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -696,11 +696,10 @@ static void path_trigger_notify(Unit *u, Unit *other) { + assert(u); + assert(other); + +- /* Invoked whenever the unit we trigger changes state or gains +- * or loses a job */ ++ /* Invoked whenever the unit we trigger changes state or gains or loses a job */ + +- if (other->load_state != UNIT_LOADED) +- return; ++ /* Filter out invocations with bogus state */ ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + + if (p->state == PATH_RUNNING && + UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { +diff --git a/src/core/socket.c b/src/core/socket.c +index 3589300e68..74c1cc70cb 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -3190,8 +3190,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) { + assert(other); + + /* Filter out invocations with bogus state */ +- if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE) +- return; ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); ++ assert(other->type == UNIT_SERVICE); + + /* Don't propagate state changes from the service if we are already down */ + if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING)) +diff --git a/src/core/timer.c b/src/core/timer.c +index 684180bf99..990f05fee4 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -745,8 +745,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) { + assert(u); + assert(other); + +- if (other->load_state != UNIT_LOADED) +- return; ++ /* Filter out invocations with bogus state */ ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + + /* Reenable all timers that depend on unit state */ + LIST_FOREACH(value, v, t->values) +diff --git a/src/core/transaction.c b/src/core/transaction.c +index ee5b39fef4..8196aba927 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -915,7 +915,7 @@ int transaction_add_job_and_dependencies( + + /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set + * temporarily. */ +- if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED)) ++ if (!UNIT_IS_LOAD_COMPLETE(unit->load_state)) + return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); + + if (type != JOB_STOP) { +diff --git a/src/core/unit.h b/src/core/unit.h +index 0cd259411f..b8b914711f 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -47,6 +47,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) { + return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED); + } + ++static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) { ++ return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED; ++} ++ + /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We + * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be + * created as a result of multiple "reasons", hence the bitmask. */ diff --git a/SOURCES/0766-core-propagate-unit-start-limit-hit-state-to-trigger.patch b/SOURCES/0766-core-propagate-unit-start-limit-hit-state-to-trigger.patch new file mode 100644 index 0000000..1cf791d --- /dev/null +++ b/SOURCES/0766-core-propagate-unit-start-limit-hit-state-to-trigger.patch @@ -0,0 +1,68 @@ +From afb5e76925f7f4992252cc392dac4dda6c4faf69 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 11 Sep 2020 19:57:09 +0200 +Subject: [PATCH] core: propagate unit start limit hit state to triggering path + unit + +We already do this for socket and automount units, do it for path units +too: if the triggered service keeps hitting the start limit, then fail +the triggering unit too, so that we don#t busy loop forever. + +(Note that this leaves only timer units out in the cold for this kind of +protection, but it shouldn't matter there, as they are naturally +protected against busy loops: they are scheduled by time anyway). + +Fixes: #16669 +(cherry picked from commit 47ab8f73e3468b6e5a48218eacdb830e978d2cfd) + +Related: #2065322 +--- + src/core/path.c | 15 +++++++++++++++ + src/core/path.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/src/core/path.c b/src/core/path.c +index a7c2e0b7c1..c2facf0b16 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -701,6 +701,20 @@ static void path_trigger_notify(Unit *u, Unit *other) { + /* Filter out invocations with bogus state */ + assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + ++ /* Don't propagate state changes from the triggered unit if we are already down */ ++ if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING)) ++ return; ++ ++ /* Propagate start limit hit state */ ++ if (other->start_limit_hit) { ++ path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT); ++ return; ++ } ++ ++ /* Don't propagate anything if there's still a job queued */ ++ if (other->job) ++ return; ++ + if (p->state == PATH_RUNNING && + UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { + log_unit_debug(UNIT(p), "Got notified about unit deactivation."); +@@ -752,6 +766,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = { + [PATH_SUCCESS] = "success", + [PATH_FAILURE_RESOURCES] = "resources", + [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 4d4b6236c2..8a69f06c13 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -45,6 +45,7 @@ typedef enum PathResult { + PATH_SUCCESS, + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, ++ PATH_FAILURE_UNIT_START_LIMIT_HIT, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; diff --git a/SOURCES/0767-core-Move-r-variable-declaration-to-start-of-unit_st.patch b/SOURCES/0767-core-Move-r-variable-declaration-to-start-of-unit_st.patch new file mode 100644 index 0000000..1200bd3 --- /dev/null +++ b/SOURCES/0767-core-Move-r-variable-declaration-to-start-of-unit_st.patch @@ -0,0 +1,31 @@ +From 3392b2fb9e4920e9238a09c774252dc0d0183903 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Sat, 30 Oct 2021 22:12:06 +0100 +Subject: [PATCH] core: Move 'r' variable declaration to start of unit_start() + +(cherry picked from commit 5f37c1a955e399756c4137d22f7f0f45a619f425) + +Related: #2065322 +--- + src/core/unit.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index e3e534ea2e..4fd9af87b7 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1725,12 +1725,13 @@ static bool unit_verify_deps(Unit *u) { + int unit_start(Unit *u) { + UnitActiveState state; + Unit *following; ++ int r; + + assert(u); + + /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ + if (UNIT_VTABLE(u)->can_start) { +- int r = UNIT_VTABLE(u)->can_start(u); ++ r = UNIT_VTABLE(u)->can_start(u); + if (r < 0) + return r; + } diff --git a/SOURCES/0768-core-Delay-start-rate-limit-check-when-starting-a-un.patch b/SOURCES/0768-core-Delay-start-rate-limit-check-when-starting-a-un.patch new file mode 100644 index 0000000..243f795 --- /dev/null +++ b/SOURCES/0768-core-Delay-start-rate-limit-check-when-starting-a-un.patch @@ -0,0 +1,49 @@ +From 8c81776212d0aa44f5ae20635079bd6ce76d16ac Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 19 Oct 2021 10:45:48 +0100 +Subject: [PATCH] core: Delay start rate limit check when starting a unit + +Doing start rate limit checks before doing condition checks made +condition check failures count towards the start rate limit which +broke existing assumptions (see #21025). Run the rate limit checks +after the condition checks again to restore the previous behaviour. + +(cherry picked from commit ce2146f5256659c7fb53a7d5b9dc551252e27e7e) + +Related: #2065322 +--- + src/core/unit.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4fd9af87b7..b825e2418c 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1729,13 +1729,6 @@ int unit_start(Unit *u) { + + assert(u); + +- /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ +- if (UNIT_VTABLE(u)->can_start) { +- r = UNIT_VTABLE(u)->can_start(u); +- if (r < 0) +- return r; +- } +- + /* If this is already started, then this will succeed. Note that this will even succeed if this unit + * is not startable by the user. This is relied on to detect when we need to wait for units and when + * waiting is finished. */ +@@ -1790,6 +1783,13 @@ int unit_start(Unit *u) { + return unit_start(following); + } + ++ /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->can_start) { ++ r = UNIT_VTABLE(u)->can_start(u); ++ if (r < 0) ++ return r; ++ } ++ + /* If it is stopped, but we cannot start it, then fail */ + if (!UNIT_VTABLE(u)->start) + return -EBADR; diff --git a/SOURCES/0769-core-Propagate-condition-failed-state-to-triggering-.patch b/SOURCES/0769-core-Propagate-condition-failed-state-to-triggering-.patch new file mode 100644 index 0000000..14f13a7 --- /dev/null +++ b/SOURCES/0769-core-Propagate-condition-failed-state-to-triggering-.patch @@ -0,0 +1,258 @@ +From 2820f1706275acd787c72d9a57892200566f0bbe Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Mon, 18 Oct 2021 14:17:02 +0200 +Subject: [PATCH] core: Propagate condition failed state to triggering units. + +Alternative to https://github.com/systemd/systemd/pull/20531. + +Whenever a service triggered by another unit fails condition checks, +stop the triggering unit to prevent systemd busy looping trying to +start the triggered unit. + +(cherry picked from commit 12ab94a1e4961a39c32efb60b71866ab588d3ea2) + +Resolves: #2065322 +--- + src/core/automount.c | 14 ++++++++++---- + src/core/automount.h | 1 + + src/core/path.c | 16 +++++++++++----- + src/core/path.h | 1 + + src/core/socket.c | 28 +++++++++++++++++++--------- + src/core/socket.h | 1 + + src/core/timer.c | 12 +++++++++--- + src/core/timer.h | 1 + + src/core/unit.c | 10 ++++++++++ + src/core/unit.h | 2 ++ + 10 files changed, 65 insertions(+), 21 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index c1c513d4a5..bac3b2fab7 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -776,6 +776,11 @@ static void automount_enter_running(Automount *a) { + goto fail; + } + ++ if (unit_has_failed_condition_or_assert(trigger)) { ++ automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED); ++ return; ++ } ++ + r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); +@@ -1087,10 +1092,11 @@ static int automount_can_start(Unit *u) { + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +- [AUTOMOUNT_SUCCESS] = "success", +- [AUTOMOUNT_FAILURE_RESOURCES] = "resources", +- [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", ++ [AUTOMOUNT_SUCCESS] = "success", ++ [AUTOMOUNT_FAILURE_RESOURCES] = "resources", ++ [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", ++ [AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED] = "mount-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); +diff --git a/src/core/automount.h b/src/core/automount.h +index 21dd1c0774..a7417d195c 100644 +--- a/src/core/automount.h ++++ b/src/core/automount.h +@@ -10,6 +10,7 @@ typedef enum AutomountResult { + AUTOMOUNT_FAILURE_RESOURCES, + AUTOMOUNT_FAILURE_START_LIMIT_HIT, + AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT, ++ AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED, + _AUTOMOUNT_RESULT_MAX, + _AUTOMOUNT_RESULT_INVALID = -1 + } AutomountResult; +diff --git a/src/core/path.c b/src/core/path.c +index c2facf0b16..bf7e1bf3c2 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -453,7 +453,7 @@ static void path_enter_dead(Path *p, PathResult f) { + else + unit_log_failure(UNIT(p), path_result_to_string(p->result)); + +- path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); ++ path_set_state(p, p->result == PATH_SUCCESS ? PATH_DEAD : PATH_FAILED); + } + + static void path_enter_running(Path *p) { +@@ -711,6 +711,11 @@ static void path_trigger_notify(Unit *u, Unit *other) { + return; + } + ++ if (unit_has_failed_condition_or_assert(other)) { ++ path_enter_dead(p, PATH_FAILURE_UNIT_CONDITION_FAILED); ++ return; ++ } ++ + /* Don't propagate anything if there's still a job queued */ + if (other->job) + return; +@@ -763,10 +768,11 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); + + static const char* const path_result_table[_PATH_RESULT_MAX] = { +- [PATH_SUCCESS] = "success", +- [PATH_FAILURE_RESOURCES] = "resources", +- [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", ++ [PATH_SUCCESS] = "success", ++ [PATH_FAILURE_RESOURCES] = "resources", ++ [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", ++ [PATH_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 8a69f06c13..0ad6bd12c6 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -46,6 +46,7 @@ typedef enum PathResult { + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, + PATH_FAILURE_UNIT_START_LIMIT_HIT, ++ PATH_FAILURE_UNIT_CONDITION_FAILED, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; +diff --git a/src/core/socket.c b/src/core/socket.c +index 74c1cc70cb..6f9a0f7575 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2272,6 +2272,15 @@ static void socket_enter_running(Socket *s, int cfd) { + goto refuse; + } + ++ if (UNIT_ISSET(s->service) && cfd < 0) { ++ Unit *service = UNIT_DEREF(s->service); ++ ++ if (unit_has_failed_condition_or_assert(service)) { ++ socket_enter_dead(s, SOCKET_FAILURE_SERVICE_CONDITION_FAILED); ++ return; ++ } ++ } ++ + if (cfd < 0) { + bool pending = false; + Unit *other; +@@ -3287,15 +3296,16 @@ static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); + + static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { +- [SOCKET_SUCCESS] = "success", +- [SOCKET_FAILURE_RESOURCES] = "resources", +- [SOCKET_FAILURE_TIMEOUT] = "timeout", +- [SOCKET_FAILURE_EXIT_CODE] = "exit-code", +- [SOCKET_FAILURE_SIGNAL] = "signal", +- [SOCKET_FAILURE_CORE_DUMP] = "core-dump", +- [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", +- [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit" ++ [SOCKET_SUCCESS] = "success", ++ [SOCKET_FAILURE_RESOURCES] = "resources", ++ [SOCKET_FAILURE_TIMEOUT] = "timeout", ++ [SOCKET_FAILURE_EXIT_CODE] = "exit-code", ++ [SOCKET_FAILURE_SIGNAL] = "signal", ++ [SOCKET_FAILURE_CORE_DUMP] = "core-dump", ++ [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", ++ [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit", ++ [SOCKET_FAILURE_SERVICE_CONDITION_FAILED] = "service-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); +diff --git a/src/core/socket.h b/src/core/socket.h +index 2409dbf2a0..b171b94316 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -39,6 +39,7 @@ typedef enum SocketResult { + SOCKET_FAILURE_START_LIMIT_HIT, + SOCKET_FAILURE_TRIGGER_LIMIT_HIT, + SOCKET_FAILURE_SERVICE_START_LIMIT_HIT, ++ SOCKET_FAILURE_SERVICE_CONDITION_FAILED, + _SOCKET_RESULT_MAX, + _SOCKET_RESULT_INVALID = -1 + } SocketResult; +diff --git a/src/core/timer.c b/src/core/timer.c +index 990f05fee4..3c8d89771d 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -567,6 +567,11 @@ static void timer_enter_running(Timer *t) { + return; + } + ++ if (unit_has_failed_condition_or_assert(trigger)) { ++ timer_enter_dead(t, TIMER_FAILURE_UNIT_CONDITION_FAILED); ++ return; ++ } ++ + r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; +@@ -850,9 +855,10 @@ static const char* const timer_base_table[_TIMER_BASE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); + + static const char* const timer_result_table[_TIMER_RESULT_MAX] = { +- [TIMER_SUCCESS] = "success", +- [TIMER_FAILURE_RESOURCES] = "resources", +- [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [TIMER_SUCCESS] = "success", ++ [TIMER_FAILURE_RESOURCES] = "resources", ++ [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [TIMER_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); +diff --git a/src/core/timer.h b/src/core/timer.h +index 833aadb0b8..d23e19d622 100644 +--- a/src/core/timer.h ++++ b/src/core/timer.h +@@ -32,6 +32,7 @@ typedef enum TimerResult { + TIMER_SUCCESS, + TIMER_FAILURE_RESOURCES, + TIMER_FAILURE_START_LIMIT_HIT, ++ TIMER_FAILURE_UNIT_CONDITION_FAILED, + _TIMER_RESULT_MAX, + _TIMER_RESULT_INVALID = -1 + } TimerResult; +diff --git a/src/core/unit.c b/src/core/unit.c +index b825e2418c..c00d30e837 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5657,6 +5657,16 @@ int unit_thaw_vtable_common(Unit *u) { + return unit_cgroup_freezer_action(u, FREEZER_THAW); + } + ++bool unit_has_failed_condition_or_assert(Unit *u) { ++ if (dual_timestamp_is_set(&u->condition_timestamp) && !u->condition_result) ++ return true; ++ ++ if (dual_timestamp_is_set(&u->assert_timestamp) && !u->assert_result) ++ return true; ++ ++ return false; ++} ++ + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index b8b914711f..a924bd2e83 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -847,6 +847,8 @@ void unit_thawed(Unit *u); + int unit_freeze_vtable_common(Unit *u); + int unit_thaw_vtable_common(Unit *u); + ++bool unit_has_failed_condition_or_assert(Unit *u); ++ + /* Macros which append UNIT= or USER_UNIT= to the message */ + + #define log_unit_full(unit, level, error, ...) \ diff --git a/SOURCES/0770-unit-check-for-mount-rate-limiting-before-checking-a.patch b/SOURCES/0770-unit-check-for-mount-rate-limiting-before-checking-a.patch new file mode 100644 index 0000000..eca0afc --- /dev/null +++ b/SOURCES/0770-unit-check-for-mount-rate-limiting-before-checking-a.patch @@ -0,0 +1,52 @@ +From 4dbe6568d5bcc082b13f3ef4d323d1669f16095c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 30 May 2022 11:55:41 +0200 +Subject: [PATCH] unit: check for mount rate limiting before checking active + state + +Having this check as part of mount_can_start() is too late because +UNIT(u)->can_start() virtual method is called after checking the active +state of unit in unit_start(). + +We need to hold off running mount start jobs when /p/s/mountinfo monitor +is rate limited even when given mount unit is already active. + +Fixes #20329 + +(cherry picked from commit b161bc394b2cc8b271dda9208e310cc2af0cc29d) + +Resolves: #2095744 +--- + src/core/mount.c | 3 --- + src/core/unit.c | 4 ++++ + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 9547cb9b29..d37b5731f8 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1999,9 +1999,6 @@ static int mount_can_start(Unit *u) { + + assert(m); + +- if (sd_event_source_is_ratelimited(u->manager->mount_event_source)) +- return -EAGAIN; +- + r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); +diff --git a/src/core/unit.c b/src/core/unit.c +index c00d30e837..0810bf5a58 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1729,6 +1729,10 @@ int unit_start(Unit *u) { + + assert(u); + ++ /* Let's hold off running start jobs for mount units when /proc/self/mountinfo monitor is rate limited. */ ++ if (u->type == UNIT_MOUNT && sd_event_source_is_ratelimited(u->manager->mount_event_source)) ++ return -EAGAIN; ++ + /* If this is already started, then this will succeed. Note that this will even succeed if this unit + * is not startable by the user. This is relied on to detect when we need to wait for units and when + * waiting is finished. */ diff --git a/SOURCES/0771-mkosi-Add-gnutls-package.patch b/SOURCES/0771-mkosi-Add-gnutls-package.patch new file mode 100644 index 0000000..c8e174b --- /dev/null +++ b/SOURCES/0771-mkosi-Add-gnutls-package.patch @@ -0,0 +1,24 @@ +From 3cdbda49a4eca0dc28f1ebc7923c387bc9b69a9f Mon Sep 17 00:00:00 2001 +From: Jacek Migacz +Date: Sun, 26 Jun 2022 22:11:55 +0200 +Subject: [PATCH] mkosi: Add gnutls package + +RHEL-only + +Resolves: #2101227 +--- + .mkosi/mkosi.fedora | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.mkosi/mkosi.fedora b/.mkosi/mkosi.fedora +index 63027d9fc7..b0451adec2 100644 +--- a/.mkosi/mkosi.fedora ++++ b/.mkosi/mkosi.fedora +@@ -61,6 +61,7 @@ BuildPackages= + + Packages= + libidn2 ++ gnutls + + BuildDirectory=mkosi.builddir + Cache=mkosi.cache diff --git a/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch b/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch new file mode 100644 index 0000000..aa8bb9c --- /dev/null +++ b/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch @@ -0,0 +1,181 @@ +From e3e479fc9c51e0b6f2c21087e2e78e7c6f55169c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 May 2020 00:34:58 +0200 +Subject: [PATCH] unit-name: tighten checks for building valid unit names + +Let's be more thorough that whenever we build a unit name based on +parameters, that the result is actually a valid user name. If it isn't +fail early. + +This should allows us to catch various issues earlier, in particular +when we synthesize mount units from /proc/self/mountinfo: instead of +actually attempting to allocate a mount unit we will fail much earlier +when we build the name to synthesize the unit under. Failing early is a +good thing generally. + +(cherry picked from commit ab19db01ae1826efb3cbdf6dcb6a14412f8844d4) + +Related: #1940973 +--- + src/basic/unit-name.c | 61 ++++++++++++++++++++++++++++++------------- + 1 file changed, 43 insertions(+), 18 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 614eb8649b..f9b3fafd4d 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -207,8 +207,9 @@ UnitType unit_name_to_type(const char *n) { + } + + int unit_name_change_suffix(const char *n, const char *suffix, char **ret) { +- char *e, *s; ++ _cleanup_free_ char *s = NULL; + size_t a, b; ++ char *e; + + assert(n); + assert(suffix); +@@ -230,8 +231,12 @@ int unit_name_change_suffix(const char *n, const char *suffix, char **ret) { + return -ENOMEM; + + strcpy(mempcpy(s, n, a), suffix); +- *ret = s; + ++ /* Make sure the name is still valid (i.e. didn't grow too large due to longer suffix) */ ++ if (!unit_name_is_valid(s, UNIT_NAME_ANY)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -253,8 +258,8 @@ int unit_name_build(const char *prefix, const char *instance, const char *suffix + } + + int unit_name_build_from_type(const char *prefix, const char *instance, UnitType type, char **ret) { ++ _cleanup_free_ char *s = NULL; + const char *ut; +- char *s; + + assert(prefix); + assert(type >= 0); +@@ -264,19 +269,23 @@ int unit_name_build_from_type(const char *prefix, const char *instance, UnitType + if (!unit_prefix_is_valid(prefix)) + return -EINVAL; + +- if (instance && !unit_instance_is_valid(instance)) +- return -EINVAL; +- + ut = unit_type_to_string(type); + +- if (!instance) +- s = strjoin(prefix, ".", ut); +- else ++ if (instance) { ++ if (!unit_instance_is_valid(instance)) ++ return -EINVAL; ++ + s = strjoin(prefix, "@", instance, ".", ut); ++ } else ++ s = strjoin(prefix, ".", ut); + if (!s) + return -ENOMEM; + +- *ret = s; ++ /* Verify that this didn't grow too large (or otherwise is invalid) */ ++ if (!unit_name_is_valid(s, instance ? UNIT_NAME_INSTANCE : UNIT_NAME_PLAIN)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -445,8 +454,8 @@ int unit_name_path_unescape(const char *f, char **ret) { + } + + int unit_name_replace_instance(const char *f, const char *i, char **ret) { ++ _cleanup_free_ char *s = NULL; + const char *p, *e; +- char *s; + size_t a, b; + + assert(f); +@@ -470,7 +479,11 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret) { + + strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e); + +- *ret = s; ++ /* Make sure the resulting name still is valid, i.e. didn't grow too large */ ++ if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -501,8 +514,7 @@ int unit_name_template(const char *f, char **ret) { + } + + int unit_name_from_path(const char *path, const char *suffix, char **ret) { +- _cleanup_free_ char *p = NULL; +- char *s = NULL; ++ _cleanup_free_ char *p = NULL, *s = NULL; + int r; + + assert(path); +@@ -520,7 +532,11 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (!s) + return -ENOMEM; + +- *ret = s; ++ /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -548,6 +564,10 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha + if (!s) + return -ENOMEM; + ++ /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) ++ return -EINVAL; ++ + *ret = s; + return 0; + } +@@ -601,7 +621,7 @@ static bool do_escape_mangle(const char *f, bool allow_globs, char *t) { + * If @allow_globs, globs characters are preserved. Otherwise, they are escaped. + */ + int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret) { +- char *s; ++ _cleanup_free_ char *s = NULL; + int r; + bool mangled; + +@@ -656,7 +676,12 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const c + if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0) + strcat(s, suffix); + +- *ret = s; ++ /* Make sure mangling didn't grow this too large (but don't do this check if globbing is allowed, ++ * since globs generally do not qualify as valid unit names) */ ++ if (!FLAGS_SET(flags, UNIT_NAME_MANGLE_GLOB) && !unit_name_is_valid(s, UNIT_NAME_ANY)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 1; + + good: +@@ -664,7 +689,7 @@ good: + if (!s) + return -ENOMEM; + +- *ret = s; ++ *ret = TAKE_PTR(s); + return 0; + } + diff --git a/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch b/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch new file mode 100644 index 0000000..7705a2c --- /dev/null +++ b/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch @@ -0,0 +1,275 @@ +From f62231a54abff6566415ea82aa8773e61f5688d6 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 15 Mar 2022 19:02:05 +0100 +Subject: [PATCH] core: shorten long unit names that are based on paths and + append path hash at the end + +Fixes #18077 + +(cherry picked from commit 1d0727e76fd5e9a07cc9991ec9a10ea1d78a99c7) + +Resolves: #1940973 +--- + src/basic/string-util.h | 23 +++++----- + src/basic/unit-name.c | 88 ++++++++++++++++++++++++++++++++++++++- + src/basic/unit-name.h | 3 ++ + src/core/mount.c | 3 ++ + src/test/test-unit-name.c | 25 ++++++++++- + 5 files changed, 129 insertions(+), 13 deletions(-) + +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index 742b566932..0d406ff64a 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -9,17 +9,18 @@ + #include "macro.h" + + /* What is interpreted as whitespace? */ +-#define WHITESPACE " \t\n\r" +-#define NEWLINE "\n\r" +-#define QUOTES "\"\'" +-#define COMMENTS "#;" +-#define GLOB_CHARS "*?[" +-#define DIGITS "0123456789" +-#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +-#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +-#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS +-#define ALPHANUMERICAL LETTERS DIGITS +-#define HEXDIGITS DIGITS "abcdefABCDEF" ++#define WHITESPACE " \t\n\r" ++#define NEWLINE "\n\r" ++#define QUOTES "\"\'" ++#define COMMENTS "#;" ++#define GLOB_CHARS "*?[" ++#define DIGITS "0123456789" ++#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" ++#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS ++#define ALPHANUMERICAL LETTERS DIGITS ++#define HEXDIGITS DIGITS "abcdefABCDEF" ++#define LOWERCASE_HEXDIGITS DIGITS "abcdef" + + #define streq(a,b) (strcmp((a),(b)) == 0) + #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index f9b3fafd4d..65ed979e39 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -6,11 +6,17 @@ + #include + #include + ++#include "sd-id128.h" ++ + #include "alloc-util.h" + #include "glob-util.h" + #include "hexdecoct.h" + #include "path-util.h" ++#include "random-util.h" ++#include "siphash24.h" ++#include "sparse-endian.h" + #include "special.h" ++#include "stdio-util.h" + #include "string-util.h" + #include "strv.h" + #include "unit-name.h" +@@ -31,6 +37,9 @@ + VALID_CHARS_WITH_AT \ + "[]!-*?" + ++#define LONG_UNIT_NAME_HASH_KEY SD_ID128_MAKE(ec,f2,37,fb,58,32,4a,32,84,9f,06,9b,0d,21,eb,9a) ++#define UNIT_NAME_HASH_LENGTH_CHARS 16 ++ + bool unit_name_is_valid(const char *n, UnitNameFlags flags) { + const char *e, *i, *at; + +@@ -513,6 +522,68 @@ int unit_name_template(const char *f, char **ret) { + return 0; + } + ++bool unit_name_is_hashed(const char *name) { ++ char *s; ++ ++ if (!unit_name_is_valid(name, UNIT_NAME_PLAIN)) ++ return false; ++ ++ assert_se(s = strrchr(name, '.')); ++ ++ if (s - name < UNIT_NAME_HASH_LENGTH_CHARS + 1) ++ return false; ++ ++ s -= UNIT_NAME_HASH_LENGTH_CHARS; ++ if (s[-1] != '_') ++ return false; ++ ++ for (size_t i = 0; i < UNIT_NAME_HASH_LENGTH_CHARS; i++) ++ if (!strchr(LOWERCASE_HEXDIGITS, s[i])) ++ return false; ++ ++ return true; ++} ++ ++int unit_name_hash_long(const char *name, char **ret) { ++ _cleanup_free_ char *n = NULL, *hash = NULL; ++ char *suffix; ++ le64_t h; ++ size_t len; ++ ++ if (strlen(name) < UNIT_NAME_MAX) ++ return -EMSGSIZE; ++ ++ suffix = strrchr(name, '.'); ++ if (!suffix) ++ return -EINVAL; ++ ++ if (unit_type_from_string(suffix+1) < 0) ++ return -EINVAL; ++ ++ h = htole64(siphash24(name, strlen(name) + 1, LONG_UNIT_NAME_HASH_KEY.bytes)); ++ ++ hash = hexmem(&h, sizeof(h)); ++ if (!hash) ++ return -ENOMEM; ++ ++ assert_se(strlen(hash) == UNIT_NAME_HASH_LENGTH_CHARS); ++ ++ len = UNIT_NAME_MAX - 1 - strlen(suffix+1) - UNIT_NAME_HASH_LENGTH_CHARS - 2; ++ assert(len > 0 && len < UNIT_NAME_MAX); ++ ++ n = strndup(name, len); ++ if (!n) ++ return -ENOMEM; ++ ++ if (!strextend(&n, "_", hash, suffix, NULL)) ++ return -ENOMEM; ++ assert_se(unit_name_is_valid(n, UNIT_NAME_PLAIN)); ++ ++ *ret = TAKE_PTR(n); ++ ++ return 0; ++} ++ + int unit_name_from_path(const char *path, const char *suffix, char **ret) { + _cleanup_free_ char *p = NULL, *s = NULL; + int r; +@@ -532,7 +603,19 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (!s) + return -ENOMEM; + +- /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (strlen(s) >= UNIT_NAME_MAX) { ++ _cleanup_free_ char *n = NULL; ++ ++ log_debug("Unit name \"%s\" too long, falling back to hashed unit name.", s); ++ ++ r = unit_name_hash_long(s, &n); ++ if (r < 0) ++ return r; ++ ++ free_and_replace(s, n); ++ } ++ ++ /* Refuse if this for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) + return -EINVAL; + +@@ -582,6 +665,9 @@ int unit_name_to_path(const char *name, char **ret) { + if (r < 0) + return r; + ++ if (unit_name_is_hashed(name)) ++ return -ENAMETOOLONG; ++ + return unit_name_path_unescape(prefix, ret); + } + +diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h +index 61abcd585b..602295af8f 100644 +--- a/src/basic/unit-name.h ++++ b/src/basic/unit-name.h +@@ -45,6 +45,9 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret); + + int unit_name_template(const char *f, char **ret); + ++int unit_name_hash_long(const char *name, char **ret); ++bool unit_name_is_hashed(const char *name); ++ + int unit_name_from_path(const char *path, const char *suffix, char **ret); + int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret); + int unit_name_to_path(const char *name, char **ret); +diff --git a/src/core/mount.c b/src/core/mount.c +index d37b5731f8..e69ecb7ce3 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -572,6 +572,9 @@ static int mount_add_extras(Mount *m) { + + if (!m->where) { + r = unit_name_to_path(u->id, &m->where); ++ if (r == -ENAMETOOLONG) ++ log_unit_error_errno(u, r, "Failed to derive mount point path from unit name, because unit name is hashed. " ++ "Set \"Where=\" in the unit file explicitly."); + if (r < 0) + return r; + } +diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c +index 2b00ef8cb7..35cfaafd30 100644 +--- a/src/test/test-unit-name.c ++++ b/src/test/test-unit-name.c +@@ -82,6 +82,7 @@ static void test_unit_name_replace_instance(void) { + + static void test_unit_name_from_path_one(const char *path, const char *suffix, const char *expected, int ret) { + _cleanup_free_ char *t = NULL; ++ int r; + + assert_se(unit_name_from_path(path, suffix, &t) == ret); + puts(strna(t)); +@@ -89,12 +90,31 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c + + if (t) { + _cleanup_free_ char *k = NULL; +- assert_se(unit_name_to_path(t, &k) == 0); ++ ++ /* We don't support converting hashed unit names back to paths */ ++ r = unit_name_to_path(t, &k); ++ if (r == -ENAMETOOLONG) ++ return; ++ assert(r == 0); ++ + puts(strna(k)); + assert_se(path_equal(k, empty_to_root(path))); + } + } + ++static void test_unit_name_is_hashed(void) { ++ assert_se(!unit_name_is_hashed("")); ++ assert_se(!unit_name_is_hashed("foo@bar.service")); ++ assert_se(!unit_name_is_hashed("foo@.service")); ++ assert_se(unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736D9ED33C2EC55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!7736d9ed33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9gd33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@waldo.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@.mount")); ++} ++ + static void test_unit_name_from_path(void) { + puts("-------------------------------------------------"); + test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0); +@@ -105,6 +125,8 @@ static void test_unit_name_from_path(void) { + test_unit_name_from_path_one("///", ".mount", "-.mount", 0); + test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL); + test_unit_name_from_path_one("/foo/./bar", ".mount", NULL, -EINVAL); ++ test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", ++ "waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount", 0); + } + + static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) { +@@ -824,6 +846,7 @@ int main(int argc, char* argv[]) { + + test_unit_name_is_valid(); + test_unit_name_replace_instance(); ++ test_unit_name_is_hashed(); + test_unit_name_from_path(); + test_unit_name_from_path_instance(); + test_unit_name_mangle(); diff --git a/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch b/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch new file mode 100644 index 0000000..635a2a0 --- /dev/null +++ b/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch @@ -0,0 +1,162 @@ +From 2b390a10d826f060a672d9f01c6ad43714691274 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Tue, 8 Jun 2021 00:04:35 -0700 +Subject: [PATCH] test: add extended test for triggering mount rate limit + +It's hard to trigger the failure to exit the rate limit state in +isolation as it needs multiple event sources in order to show that it +gets stuck in the queue. Hence why this is an extended test. + +(cherry picked from commit 0c81900965a72b29eb76e0737ed899b925ee75b6) + +Related: #1940973 +--- + test/TEST-60-MOUNT-RATELIMIT/Makefile | 1 + + test/TEST-60-MOUNT-RATELIMIT/test.sh | 48 +++++++++++++++ + test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 73 +++++++++++++++++++++++ + 3 files changed, 122 insertions(+) + create mode 120000 test/TEST-60-MOUNT-RATELIMIT/Makefile + create mode 100755 test/TEST-60-MOUNT-RATELIMIT/test.sh + create mode 100755 test/TEST-60-MOUNT-RATELIMIT/testsuite.sh + +diff --git a/test/TEST-60-MOUNT-RATELIMIT/Makefile b/test/TEST-60-MOUNT-RATELIMIT/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-60-MOUNT-RATELIMIT/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-60-MOUNT-RATELIMIT/test.sh b/test/TEST-60-MOUNT-RATELIMIT/test.sh +new file mode 100755 +index 0000000000..e3c9288546 +--- /dev/null ++++ b/test/TEST-60-MOUNT-RATELIMIT/test.sh +@@ -0,0 +1,48 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Test that mount/unmount storms can enter/exit rate limit state and will not leak units" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service </testok ++ ++exit 0 diff --git a/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch b/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch new file mode 100644 index 0000000..197b19b --- /dev/null +++ b/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch @@ -0,0 +1,42 @@ +From 1c2a0bde1bc3510d9bdc07410ff90429ebed391f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 23 Mar 2022 13:35:44 +0100 +Subject: [PATCH] tests: add test case for long unit names + +(cherry picked from commit 2ef0101e0b2813e8c99fc8f137dbaa763ca16057) + +Related: #1940973 +--- + test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +index 8158754667..6211050faf 100755 +--- a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh ++++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +@@ -7,6 +7,25 @@ systemd-analyze log-target journal + + NUM_DIRS=20 + ++# make sure we can handle mounts at very long paths such that mount unit name must be hashed to fall within our unit name limit ++LONGPATH="$(printf "/$(printf "x%0.s" {1..255})%0.s" {1..7})" ++LONGMNT="$(systemd-escape --suffix=mount --path "$LONGPATH")" ++TS="$(date '+%H:%M:%S')" ++ ++mkdir -p "$LONGPATH" ++mount -t tmpfs tmpfs "$LONGPATH" ++systemctl daemon-reload ++ ++# check that unit is active(mounted) ++systemctl --no-pager show -p SubState --value "$LONGPATH" | grep -q mounted ++ ++# check that relevant part of journal doesn't contain any errors related to unit ++[ "$(journalctl -b --since="$TS" --priority=err | grep -c "$LONGMNT")" = "0" ] ++ ++# check that we can successfully stop the mount unit ++systemctl stop "$LONGPATH" ++rm -rf "$LONGPATH" ++ + # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting + + for ((i = 0; i < NUM_DIRS; i++)); do diff --git a/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch b/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch new file mode 100644 index 0000000..1753f0c --- /dev/null +++ b/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch @@ -0,0 +1,33 @@ +From 9ba5d8811630a3d2af90fdc52f4fd6b03ee9e692 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 21 May 2019 19:26:12 +0200 +Subject: [PATCH] core: unset HOME=/ that the kernel gives us + +Partially fixes #12389. + +%h would return "/" in a machine, but "/root" in a container. Let's fix +this by resetting $HOME to the expected value. + +(cherry picked from commit 9d48671c62de133a2b9fe7c31e70c0ff8e68f2db) + +Resolves: #2056527 +--- + src/core/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index d897155644..08a4df3c97 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1307,6 +1307,11 @@ static int fixup_environment(void) { + if (setenv("TERM", t, 1) < 0) + return -errno; + ++ /* The kernels sets HOME=/ for init. Let's undo this. */ ++ if (path_equal_ptr(getenv("HOME"), "/") && ++ unsetenv("HOME") < 0) ++ log_warning_errno(errno, "Failed to unset $HOME: %m"); ++ + return 0; + } + diff --git a/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch b/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch new file mode 100644 index 0000000..e4a1e2d --- /dev/null +++ b/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch @@ -0,0 +1,94 @@ +From c20e06c1c0319e3759a11bf9051a8041898f79b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 7 Mar 2021 12:08:06 +0100 +Subject: [PATCH] journal-remote: check return value from + MHD_add_response_header + +Sadly, the API does not allow us to distinguish oom from invalid settings. +If the call fails, let's assume oom happened. + +Coverity CID#1444714. + +(cherry picked from commit 60d9c4f3b972ce70dfadc0a3f1a478a056c2ea7a) + +Resolves: #2051981 +--- + src/journal-remote/journal-gatewayd.c | 22 ++++++++++++++++------ + src/journal-remote/microhttpd-util.c | 3 ++- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c +index 3a167ab890..54446ff7b5 100644 +--- a/src/journal-remote/journal-gatewayd.c ++++ b/src/journal-remote/journal-gatewayd.c +@@ -492,7 +492,9 @@ static int request_handler_entries( + if (!response) + return respond_oom(connection); + +- MHD_add_response_header(response, "Content-Type", mime_types[m->mode]); ++ if (MHD_add_response_header(response, "Content-Type", mime_types[m->mode]) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -627,7 +629,9 @@ static int request_handler_fields( + if (!response) + return respond_oom(connection); + +- MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]); ++ if (MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -650,8 +654,10 @@ static int request_handler_redirect( + return respond_oom(connection); + } + +- MHD_add_response_header(response, "Content-Type", "text/html"); +- MHD_add_response_header(response, "Location", target); ++ if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO || ++ MHD_add_response_header(response, "Location", target) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response); + } + +@@ -680,7 +686,9 @@ static int request_handler_file( + return respond_oom(connection); + TAKE_FD(fd); + +- MHD_add_response_header(response, "Content-Type", mime_type); ++ if (MHD_add_response_header(response, "Content-Type", mime_type) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -781,7 +789,9 @@ static int request_handler_machine( + return respond_oom(connection); + TAKE_PTR(json); + +- MHD_add_response_header(response, "Content-Type", "application/json"); ++ if (MHD_add_response_header(response, "Content-Type", "application/json") == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c +index 2ae5172fe9..fdfeaeb2f5 100644 +--- a/src/journal-remote/microhttpd-util.c ++++ b/src/journal-remote/microhttpd-util.c +@@ -40,7 +40,8 @@ static int mhd_respond_internal(struct MHD_Connection *connection, + return MHD_NO; + + log_debug("Queueing response %u: %s", code, buffer); +- MHD_add_response_header(response, "Content-Type", "text/plain"); ++ if (MHD_add_response_header(response, "Content-Type", "text/plain") == MHD_NO) ++ return MHD_NO; + return MHD_queue_response(connection, code, response); + } + diff --git a/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch b/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch new file mode 100644 index 0000000..6d0cf4d --- /dev/null +++ b/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch @@ -0,0 +1,117 @@ +From 67d3aade15bede6b162e8bfe88db60311efb0d1f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 24 Oct 2018 21:49:52 +0200 +Subject: [PATCH] journalctl: in --follow mode watch stdout for POLLHUP/POLLERR + and exit + +Fixes: #9374 +(cherry picked from commit 2a1e0f2228bbdfbc18635e959f47df7da50b62fe) + +Resolves: #2003236 +--- + src/journal/journalctl.c | 65 +++++++++++++++++++++++++++++----------- + 1 file changed, 48 insertions(+), 17 deletions(-) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index 56b1be530d..fa83dce562 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -2064,14 +2064,46 @@ static int sync_journal(void) { + return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced"); + } + +-int main(int argc, char *argv[]) { ++static int wait_for_change(sd_journal *j, int poll_fd) { ++ struct pollfd pollfds[] = { ++ { .fd = poll_fd, .events = POLLIN }, ++ { .fd = STDOUT_FILENO }, ++ }; ++ ++ struct timespec ts; ++ usec_t timeout; + int r; ++ ++ assert(j); ++ assert(poll_fd >= 0); ++ ++ /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, ++ * i.e. when it is closed. */ ++ ++ r = sd_journal_get_timeout(j, &timeout); ++ if (r < 0) ++ return log_error_errno(r, "Failed to determine journal waiting time: %m"); ++ ++ if (ppoll(pollfds, ELEMENTSOF(pollfds), timeout == USEC_INFINITY ? NULL : timespec_store(&ts, timeout), NULL) < 0) ++ return log_error_errno(errno, "Couldn't wait for journal event: %m"); ++ ++ if (pollfds[1].revents & (POLLHUP|POLLERR)) { /* STDOUT has been closed? */ ++ log_debug("Standard output has been closed."); ++ return -ECANCELED; ++ } ++ ++ r = sd_journal_process(j); ++ if (r < 0) ++ return log_error_errno(r, "Failed to process journal events: %m"); ++ ++ return 0; ++} ++ ++int main(int argc, char *argv[]) { ++ bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false; + _cleanup_(sd_journal_closep) sd_journal *j = NULL; +- bool need_seek = false; + sd_id128_t previous_boot_id; +- bool previous_boot_id_valid = false, first_line = true; +- int n_shown = 0; +- bool ellipsized = false; ++ int n_shown = 0, r, poll_fd = -1; + + setlocale(LC_ALL, ""); + log_parse_environment(); +@@ -2391,15 +2423,15 @@ int main(int argc, char *argv[]) { + + /* Opening the fd now means the first sd_journal_wait() will actually wait */ + if (arg_follow) { +- r = sd_journal_get_fd(j); +- if (r == -EMFILE) { +- log_warning("Insufficent watch descriptors available. Reverting to -n."); ++ poll_fd = sd_journal_get_fd(j); ++ if (poll_fd == -EMFILE) { ++ log_warning_errno(poll_fd, "Insufficent watch descriptors available. Reverting to -n."); + arg_follow = false; +- } else if (r == -EMEDIUMTYPE) { +- log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN."); ++ } else if (poll_fd == -EMEDIUMTYPE) { ++ log_error_errno(poll_fd, "The --follow switch is not supported in conjunction with reading from STDIN."); + goto finish; +- } else if (r < 0) { +- log_error_errno(r, "Failed to get journal fd: %m"); ++ } else if (poll_fd < 0) { ++ log_error_errno(poll_fd, "Failed to get journal fd: %m"); + goto finish; + } + } +@@ -2621,7 +2653,7 @@ int main(int argc, char *argv[]) { + need_seek = true; + if (r == -EADDRNOTAVAIL) + break; +- else if (r < 0 || ferror(stdout)) ++ else if (r < 0) + goto finish; + + n_shown++; +@@ -2659,11 +2691,10 @@ int main(int argc, char *argv[]) { + } + + fflush(stdout); +- r = sd_journal_wait(j, (uint64_t) -1); +- if (r < 0) { +- log_error_errno(r, "Couldn't wait for journal event: %m"); ++ ++ r = wait_for_change(j, poll_fd); ++ if (r < 0) + goto finish; +- } + + first_line = false; + } diff --git a/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch b/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch new file mode 100644 index 0000000..02d9904 --- /dev/null +++ b/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch @@ -0,0 +1,182 @@ +From 3022d49ba2276eb5634d84a89a078aa3c357b70a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 13 Jul 2018 17:38:47 +0900 +Subject: [PATCH] sd-bus: make BUS_DEFAULT_TIMEOUT configurable + +This adds sd_bus_{get,set}_method_call_timeout(). +If the timeout is not set or set to 0, then the timeout value is +parsed from $SYSTEMD_BUS_TIMEOUT= environment variable. If the +environment variable is not set, then built-in timeout is used. + +(cherry picked from commit 385b2eb262a99373f09d01b7f5571dd71a14dc98) + +Resolves: #2039461 +--- + doc/ENVIRONMENT.md | 5 ++++ + src/libsystemd/libsystemd.sym | 7 ++++- + src/libsystemd/sd-bus/bus-internal.h | 9 ++++--- + src/libsystemd/sd-bus/bus-message.c | 7 +++-- + src/libsystemd/sd-bus/sd-bus.c | 40 ++++++++++++++++++++++++++-- + src/systemd/sd-bus.h | 3 +++ + 6 files changed, 62 insertions(+), 9 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 8d7ce6ae2c..d1a79eaa4f 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -50,6 +50,11 @@ All tools: + this only controls use of Unicode emoji glyphs, and has no effect on other + Unicode glyphs. + ++* `$SYSTEMD_BUS_TIMEOUT=SECS` — specifies the maximum time to wait for method call ++ completion. If no time unit is specified, assumes seconds. The usual other units ++ are understood, too (us, ms, s, min, h, d, w, month, y). If it is not set or set ++ to 0, then the built-in default is used. ++ + systemctl: + + * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index f4a1426248..3b55fc6473 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -573,12 +573,17 @@ global: + sd_event_source_disable_unref; + } LIBSYSTEMD_238; + ++LIBSYSTEMD_240 { ++ sd_bus_set_method_call_timeout; ++ sd_bus_get_method_call_timeout; ++} LIBSYSTEMD_239; ++ + LIBSYSTEMD_248 { + global: + sd_event_source_set_ratelimit; + sd_event_source_get_ratelimit; + sd_event_source_is_ratelimited; +-} LIBSYSTEMD_239; ++} LIBSYSTEMD_240; + + LIBSYSTEMD_250 { + global: +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 06bd7862cb..88415ae678 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -319,6 +319,9 @@ struct sd_bus { + + int *inotify_watches; + size_t n_inotify_watches; ++ ++ /* zero means use value specified by $SYSTEMD_BUS_TIMEOUT= environment variable or built-in default */ ++ usec_t method_call_timeout; + }; + + /* For method calls we time-out at 25s, like in the D-Bus reference implementation */ +@@ -340,8 +343,7 @@ struct sd_bus { + + #define BUS_CONTAINER_DEPTH 128 + +-/* Defined by the specification as maximum size of an array in +- * bytes */ ++/* Defined by the specification as maximum size of an array in bytes */ + #define BUS_ARRAY_MAX_SIZE 67108864 + + #define BUS_FDS_MAX 1024 +@@ -392,8 +394,7 @@ void bus_close_io_fds(sd_bus *b); + _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/')) + + /* If we are invoking callbacks of a bus object, ensure unreffing the +- * bus from the callback doesn't destroy the object we are working +- * on */ ++ * bus from the callback doesn't destroy the object we are working on */ + #define BUS_DONT_DESTROY(bus) \ + _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 7fe8929f82..3ffe559b8d 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5882,8 +5882,11 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { + return r; + + timeout = (*m)->timeout; +- if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) +- timeout = BUS_DEFAULT_TIMEOUT; ++ if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) { ++ r = sd_bus_get_method_call_timeout(bus, &timeout); ++ if (r < 0) ++ return r; ++ } + + r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout); + if (r < 0) +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index c65e24b2d1..803f3f50d6 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -1651,8 +1651,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { + return 0; + } + +- if (timeout == 0) +- timeout = BUS_DEFAULT_TIMEOUT; ++ if (timeout == 0) { ++ r = sd_bus_get_method_call_timeout(b, &timeout); ++ if (r < 0) ++ return r; ++ } + + if (!m->sender && b->patch_sender) { + r = sd_bus_message_set_sender(m, b->patch_sender); +@@ -4141,3 +4144,36 @@ _public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) { + bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus); + return 0; + } ++ ++_public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) { ++ assert_return(bus, -EINVAL); ++ assert_return(bus = bus_resolve(bus), -ENOPKG); ++ ++ bus->method_call_timeout = usec; ++ return 0; ++} ++ ++_public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) { ++ const char *e; ++ usec_t usec; ++ ++ assert_return(bus, -EINVAL); ++ assert_return(bus = bus_resolve(bus), -ENOPKG); ++ assert_return(ret, -EINVAL); ++ ++ if (bus->method_call_timeout != 0) { ++ *ret = bus->method_call_timeout; ++ return 0; ++ } ++ ++ e = secure_getenv("SYSTEMD_BUS_TIMEOUT"); ++ if (e && parse_sec(e, &usec) >= 0 && usec != 0) { ++ /* Save the parsed value to avoid multiple parsing. To change the timeout value, ++ * use sd_bus_set_method_call_timeout() instead of setenv(). */ ++ *ret = bus->method_call_timeout = usec; ++ return 0; ++ } ++ ++ *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT; ++ return 0; ++} +diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h +index 9ba757b13d..8b6f70bd68 100644 +--- a/src/systemd/sd-bus.h ++++ b/src/systemd/sd-bus.h +@@ -207,6 +207,9 @@ sd_event *sd_bus_get_event(sd_bus *bus); + int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret); + int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret); + ++int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec); ++int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret); ++ + int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata); + int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata); + int sd_bus_add_match_async(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); diff --git a/SOURCES/0780-fstab-generator-fix-debug-log.patch b/SOURCES/0780-fstab-generator-fix-debug-log.patch new file mode 100644 index 0000000..f8318f9 --- /dev/null +++ b/SOURCES/0780-fstab-generator-fix-debug-log.patch @@ -0,0 +1,25 @@ +From bbf71447d5de3b2cb86623a870cad21bbf114390 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 18 Feb 2019 11:29:45 +0900 +Subject: [PATCH] fstab-generator: fix debug log + +(cherry picked from commit 7731c1c20aeba4f1042f6076408db1f107d0706c) + +Resolves: #2101433 +--- + src/fstab-generator/fstab-generator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 482229b4a5..f24c1d29da 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -561,7 +561,7 @@ static int parse_fstab(bool initrd) { + noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0"); + nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0"); + +- log_debug("Found entry what=%s where=%s type=%s makefs=%s nofail=%s noauto=%s", ++ log_debug("Found entry what=%s where=%s type=%s makefs=%s noauto=%s nofail=%s", + what, where, me->mnt_type, + yes_no(makefs), + yes_no(noauto), yes_no(nofail)); diff --git a/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch b/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch new file mode 100644 index 0000000..c024d91 --- /dev/null +++ b/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch @@ -0,0 +1,123 @@ +From 54a8d932442d02f5a7dbf6038c8f557ce41f468b Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 10 Jun 2022 15:07:01 +0200 +Subject: [PATCH] logind-session-dbus: allow to set display name via dbus + +Currently, the only way to set display name of a graphical session is to +pass it to CreateSession(). But modern display managers like gdm start +the display server as part of the user session, which means that the +display name isn't known yet when the session is being created. Hence, +let's make it possible to set it later. + +(cherry picked from commit 4885d7490b23e08d8444e5a68927ce9ce8727e5a) + +Resolves: #1857969 +--- + src/login/logind-session-dbus.c | 26 ++++++++++++++++++++++++++ + src/login/logind-session.c | 20 ++++++++++++++++++++ + src/login/logind-session.h | 1 + + src/login/org.freedesktop.login1.conf | 4 ++++ + 4 files changed, 51 insertions(+) + +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index 03585b7f8e..c935959e02 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -381,6 +381,31 @@ static int method_release_control(sd_bus_message *message, void *userdata, sd_bu + return sd_bus_reply_method_return(message, NULL); + } + ++static int method_set_display(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ Session *s = userdata; ++ const char *display; ++ int r; ++ ++ assert(message); ++ assert(s); ++ ++ r = sd_bus_message_read(message, "s", &display); ++ if (r < 0) ++ return r; ++ ++ if (!session_is_controller(s, sd_bus_message_get_sender(message))) ++ return sd_bus_error_set(error, BUS_ERROR_NOT_IN_CONTROL, "You must be in control of this session to set display"); ++ ++ if (!SESSION_TYPE_IS_GRAPHICAL(s->type)) ++ return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Setting display is only supported for graphical sessions"); ++ ++ r = session_set_display(s, display); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_reply_method_return(message, NULL); ++} ++ + static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Session *s = userdata; + uint32_t major, minor; +@@ -523,6 +548,7 @@ const sd_bus_vtable session_vtable[] = { + SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDisplay", "s", NULL, method_set_display, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_SIGNAL("PauseDevice", "uus", 0), + SD_BUS_SIGNAL("ResumeDevice", "uuh", 0), +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index e4c8bb36f6..1143a834a4 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -953,6 +953,26 @@ void session_set_locked_hint(Session *s, bool b) { + session_send_changed(s, "LockedHint", NULL); + } + ++int session_set_display(Session *s, const char *display) { ++ int r; ++ ++ assert(s); ++ assert(display); ++ ++ if (streq(s->display, display)) ++ return 0; ++ ++ r = free_and_strdup(&s->display, display); ++ if (r < 0) ++ return r; ++ ++ session_save(s); ++ ++ session_send_changed(s, "Display", NULL); ++ ++ return 1; ++} ++ + static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) { + Session *s = userdata; + +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 7d17d9a25f..9bd0c96a03 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -123,6 +123,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t); + void session_set_idle_hint(Session *s, bool b); + int session_get_locked_hint(Session *s); + void session_set_locked_hint(Session *s, bool b); ++int session_set_display(Session *s, const char *display); + int session_create_fifo(Session *s); + int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); + int session_stop(Session *s, bool force); +diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf +index dcde0c22c6..b780ae08cf 100644 +--- a/src/login/org.freedesktop.login1.conf ++++ b/src/login/org.freedesktop.login1.conf +@@ -314,6 +314,10 @@ + send_interface="org.freedesktop.login1.User" + send_member="Kill"/> + ++ ++ + + + diff --git a/SOURCES/0782-Allow-restart-for-oneshot-units.patch b/SOURCES/0782-Allow-restart-for-oneshot-units.patch new file mode 100644 index 0000000..fbf2bed --- /dev/null +++ b/SOURCES/0782-Allow-restart-for-oneshot-units.patch @@ -0,0 +1,160 @@ +From ffc616d9c4d2c64d211c9e63601a321524fe2d31 Mon Sep 17 00:00:00 2001 +From: Claudio Zumbo +Date: Tue, 8 Oct 2019 15:04:29 -0700 +Subject: [PATCH] Allow restart for oneshot units + +Picked up from https://github.com/systemd/systemd/pull/7474 , so +coauthored by @robermorales. + +(cherry picked from commit 10e72727eeeeb1a495303ec406fa8d1e1a83dc6e) + +Resolves: #2042896 +--- + man/systemd.service.xml | 7 ++-- + src/core/service.c | 5 +-- + test/TEST-41-ONESHOT-RESTART/Makefile | 9 +++++ + test/TEST-41-ONESHOT-RESTART/test.sh | 44 +++++++++++++++++++++++ + test/TEST-41-ONESHOT-RESTART/testsuite.sh | 33 +++++++++++++++++ + 5 files changed, 93 insertions(+), 5 deletions(-) + create mode 100644 test/TEST-41-ONESHOT-RESTART/Makefile + create mode 100755 test/TEST-41-ONESHOT-RESTART/test.sh + create mode 100755 test/TEST-41-ONESHOT-RESTART/testsuite.sh + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 1e30a564df..133296d386 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -1276,9 +1276,10 @@ WantedBy=multi-user.target + + Type= are the + only service units that may have more than one +- ExecStart= specified. They will be executed +- in order until either they are all successful or one of them +- fails. ++ ExecStart= specified. For units with multiple ++ commands (Type=oneshot), all commands will be run again. ++ For Type=oneshot, Restart= ++ and Restart= are not allowed. + + + +diff --git a/src/core/service.c b/src/core/service.c +index e8ae1a5772..e05d0e0514 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -581,8 +581,9 @@ static int service_verify(Service *s) { + return -ENOEXEC; + } + +- if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) { +- log_unit_error(UNIT(s), "Service has Restart= setting other than no, which isn't allowed for Type=oneshot services. Refusing."); ++ if (s->type == SERVICE_ONESHOT ++ && !IN_SET(s->restart, SERVICE_RESTART_NO, SERVICE_RESTART_ON_FAILURE, SERVICE_RESTART_ON_ABNORMAL, SERVICE_RESTART_ON_WATCHDOG, SERVICE_RESTART_ON_ABORT)) { ++ log_unit_error(UNIT(s), "Service has Restart= set to either always or on-success, which isn't allowed for Type=oneshot services. Refusing."); + return -ENOEXEC; + } + +diff --git a/test/TEST-41-ONESHOT-RESTART/Makefile b/test/TEST-41-ONESHOT-RESTART/Makefile +new file mode 100644 +index 0000000000..45e9bfc67c +--- /dev/null ++++ b/test/TEST-41-ONESHOT-RESTART/Makefile +@@ -0,0 +1,9 @@ ++BUILD_DIR=$(shell ../../tools/find-build-dir.sh) ++ ++all setup run: ++ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ ++ ++clean clean-again: ++ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean ++ ++.PHONY: all setup run clean clean-again +diff --git a/test/TEST-41-ONESHOT-RESTART/test.sh b/test/TEST-41-ONESHOT-RESTART/test.sh +new file mode 100755 +index 0000000000..35de08b1e9 +--- /dev/null ++++ b/test/TEST-41-ONESHOT-RESTART/test.sh +@@ -0,0 +1,44 @@ ++#!/bin/bash ++set -e ++TEST_DESCRIPTION="Test oneshot unit restart on failure" ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service <> $TMP_FILE\"" /bin/bash -c "exit 1" ++ ++sleep 5 ++ ++if [[ $(cat $TMP_FILE) != "aaa" ]]; then ++ exit 1 ++fi ++ ++systemd-analyze log-level info ++ ++echo OK > /testok ++ ++exit 0 diff --git a/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch b/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch new file mode 100644 index 0000000..44eef8b --- /dev/null +++ b/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch @@ -0,0 +1,76 @@ +From a7375d12da80d633dfa802f2b66d2361c70c62f5 Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Thu, 17 Oct 2019 11:06:18 -0400 +Subject: [PATCH] test: correct TEST-41 StartLimitBurst test + +TEST-41 verifies that the StartLimitBurst property will correctly +limit the number of unit restarts, but the test currently doesn't +adjust the StartLimitIntervalSec which defaults to 10 seconds. + +On Ubuntu CI, running under un-accelerated qemu, it can take more than +10 seconds to perform all 3 restarts, which avoids the burst limit, +and fails the test. + +Instead, specify a long StartLimitIntervalSec in the test, so we can +be sure to correctly test StartLimitBurst even on slow testbeds. + +Fixes #13794. + +(cherry picked from commit dfec314d41159117c28dffc2b980d3bdd67c3dcb) + +Related: #2042896 +--- + test/TEST-41-ONESHOT-RESTART/testsuite.sh | 26 ++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/test/TEST-41-ONESHOT-RESTART/testsuite.sh b/test/TEST-41-ONESHOT-RESTART/testsuite.sh +index f7423dbf9a..4465614ff3 100755 +--- a/test/TEST-41-ONESHOT-RESTART/testsuite.sh ++++ b/test/TEST-41-ONESHOT-RESTART/testsuite.sh +@@ -2,14 +2,19 @@ + set -ex + set -o pipefail + ++# wait this many secs for each test service to succeed in what is being tested ++MAX_SECS=60 ++ + systemd-analyze log-level debug + systemd-analyze log-target console + +-# These three commands should succeed. ++# test one: Restart=on-failure should restart the service + ! systemd-run --unit=one -p Type=oneshot -p Restart=on-failure /bin/bash -c "exit 1" + +-sleep 5 +- ++for ((secs=0; secs<$MAX_SECS; secs++)); do ++ [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]] || break ++ sleep 1 ++done + if [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]]; then + exit 1 + fi +@@ -18,10 +23,21 @@ TMP_FILE="/test-41-oneshot-restart-test" + + touch $TMP_FILE + +-! systemd-run --unit=two -p StartLimitBurst=3 -p Type=oneshot -p Restart=on-failure -p ExecStart="/bin/bash -c \"printf a >> $TMP_FILE\"" /bin/bash -c "exit 1" ++# test two: make sure StartLimitBurst correctly limits the number of restarts ++# and restarts execution of the unit from the first ExecStart= ++! systemd-run --unit=two -p StartLimitIntervalSec=120 -p StartLimitBurst=3 -p Type=oneshot -p Restart=on-failure -p ExecStart="/bin/bash -c \"printf a >> $TMP_FILE\"" /bin/bash -c "exit 1" + +-sleep 5 ++# wait for at least 3 restarts ++for ((secs=0; secs<$MAX_SECS; secs++)); do ++ [[ $(cat $TMP_FILE) != "aaa" ]] || break ++ sleep 1 ++done ++if [[ $(cat $TMP_FILE) != "aaa" ]]; then ++ exit 1 ++fi + ++# wait for 5 more seconds to make sure there aren't excess restarts ++sleep 5 + if [[ $(cat $TMP_FILE) != "aaa" ]]; then + exit 1 + fi diff --git a/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch b/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch new file mode 100644 index 0000000..20ab06d --- /dev/null +++ b/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch @@ -0,0 +1,29 @@ +From 32ef99e27ca6242cd86e06b7f63ba49562a77335 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 12:56:06 +0900 +Subject: [PATCH] core: fix assert() about number of built environment + variables + +Follow-up for 4b58153dd22172d817055d2a09a0cdf3f4bd9db3 and +fd63e712b2025d235ce4bfbb512fada10e2690b5. + +(cherry picked from commit 76a9460d44b03a86691a8481544f4525bb43610a) + +Related: #2049788 +--- + src/core/execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index a104294966..c842b14ce7 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1733,7 +1733,7 @@ static int build_environment( + } + + our_env[n_env++] = NULL; +- assert(n_env <= 12); ++ assert(n_env <= 14); + + *ret = TAKE_PTR(our_env); + diff --git a/SOURCES/0785-core-add-one-more-assert.patch b/SOURCES/0785-core-add-one-more-assert.patch new file mode 100644 index 0000000..b8dc682 --- /dev/null +++ b/SOURCES/0785-core-add-one-more-assert.patch @@ -0,0 +1,24 @@ +From 09b6ae4da2d8b60d3619dcd0e6712e1a106efba0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:18:33 +0900 +Subject: [PATCH] core: add one more assert() + +(cherry picked from commit 7c1cb6f1989074e144b1625607950fce80c951ec) + +Related: #2049788 +--- + src/core/execute.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/core/execute.c b/src/core/execute.c +index c842b14ce7..3ff1a51aa1 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1624,6 +1624,7 @@ static int build_environment( + + assert(u); + assert(c); ++ assert(p); + assert(ret); + + our_env = new0(char*, 14); diff --git a/SOURCES/0786-strv-introduce-strv_join_prefix.patch b/SOURCES/0786-strv-introduce-strv_join_prefix.patch new file mode 100644 index 0000000..8275c5b --- /dev/null +++ b/SOURCES/0786-strv-introduce-strv_join_prefix.patch @@ -0,0 +1,69 @@ +From 23ef6c470418b50119dc0bf13b681bfeae820352 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:22:31 +0900 +Subject: [PATCH] strv: introduce strv_join_prefix() + +(cherry picked from commit 2b9a7d2e96f5f852cdf8cc704930ea2ee456f6a1) + +Related: #2049788 +--- + src/basic/strv.c | 10 +++++++--- + src/basic/strv.h | 5 ++++- + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/basic/strv.c b/src/basic/strv.c +index b3716233b5..f1605e4fbb 100644 +--- a/src/basic/strv.c ++++ b/src/basic/strv.c +@@ -335,21 +335,22 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract + return (int) n; + } + +-char *strv_join(char **l, const char *separator) { ++char *strv_join_prefix(char **l, const char *separator, const char *prefix) { + char *r, *e; + char **s; +- size_t n, k; ++ size_t n, k, m; + + if (!separator) + separator = " "; + + k = strlen(separator); ++ m = strlen_ptr(prefix); + + n = 0; + STRV_FOREACH(s, l) { + if (s != l) + n += k; +- n += strlen(*s); ++ n += m + strlen(*s); + } + + r = new(char, n+1); +@@ -361,6 +362,9 @@ char *strv_join(char **l, const char *separator) { + if (s != l) + e = stpcpy(e, separator); + ++ if (prefix) ++ e = stpcpy(e, prefix); ++ + e = stpcpy(e, *s); + } + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index a09d76706d..9285bc2642 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -71,7 +71,10 @@ char **strv_split_newlines(const char *s); + + int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags); + +-char *strv_join(char **l, const char *separator); ++char *strv_join_prefix(char **l, const char *separator, const char *prefix); ++static inline char *strv_join(char **l, const char *separator) { ++ return strv_join_prefix(l, separator, NULL); ++} + + char **strv_parse_nulstr(const char *s, size_t l); + char **strv_split_nulstr(const char *s); diff --git a/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch b/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch new file mode 100644 index 0000000..28533b3 --- /dev/null +++ b/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch @@ -0,0 +1,63 @@ +From d829e7163f6a98547cef3b0106a6a98728275065 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:35:27 +0900 +Subject: [PATCH] test: add tests for strv_join_prefix() + +(cherry picked from commit 474a595af7544a670de70e1eb873bcee1bb00044) + +Related: #2049788 +--- + src/test/test-strv.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 79d999d3ed..9e7d98500f 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -158,6 +158,38 @@ static void test_strv_join(void) { + assert_se(streq(w, "")); + } + ++static void test_strv_join_prefix(void) { ++ _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL; ++ ++ p = strv_join_prefix((char **)input_table_multiple, ", ", "foo"); ++ assert_se(p); ++ assert_se(streq(p, "fooone, footwo, foothree")); ++ ++ q = strv_join_prefix((char **)input_table_multiple, ";", "foo"); ++ assert_se(q); ++ assert_se(streq(q, "fooone;footwo;foothree")); ++ ++ r = strv_join_prefix((char **)input_table_multiple, NULL, "foo"); ++ assert_se(r); ++ assert_se(streq(r, "fooone footwo foothree")); ++ ++ s = strv_join_prefix((char **)input_table_one, ", ", "foo"); ++ assert_se(s); ++ assert_se(streq(s, "fooone")); ++ ++ t = strv_join_prefix((char **)input_table_none, ", ", "foo"); ++ assert_se(t); ++ assert_se(streq(t, "")); ++ ++ v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo"); ++ assert_se(v); ++ assert_se(streq(v, "foo, foo")); ++ ++ w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo"); ++ assert_se(w); ++ assert_se(streq(w, "foo")); ++} ++ + static void test_strv_unquote(const char *quoted, char **list) { + _cleanup_strv_free_ char **s; + _cleanup_free_ char *j; +@@ -722,6 +754,7 @@ int main(int argc, char *argv[]) { + test_strv_find_prefix(); + test_strv_find_startswith(); + test_strv_join(); ++ test_strv_join_prefix(); + + test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz")); + test_strv_unquote("", STRV_MAKE_EMPTY); diff --git a/SOURCES/0788-test-replace-swear-words-by-hoge.patch b/SOURCES/0788-test-replace-swear-words-by-hoge.patch new file mode 100644 index 0000000..c8c8083 --- /dev/null +++ b/SOURCES/0788-test-replace-swear-words-by-hoge.patch @@ -0,0 +1,54 @@ +From 48b22b82853c6697669b078de5eae35728fbba30 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:41:09 +0900 +Subject: [PATCH] test: replace swear words by 'hoge' + +(cherry picked from commit a2917d3d2a3ce926f74b63aa60a47f838a8e1f83) + +Related: #2049788 +--- + src/test/test-cgroup-util.c | 2 +- + src/test/test-strv.c | 10 +++++----- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c +index 60d7bb19cb..2cb93ad0be 100644 +--- a/src/test/test-cgroup-util.c ++++ b/src/test/test-cgroup-util.c +@@ -296,7 +296,7 @@ static void test_shift_path(void) { + test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo"); + test_shift_path_one("/foobar/waldo", "", "/foobar/waldo"); + test_shift_path_one("/foobar/waldo", "/foobar", "/waldo"); +- test_shift_path_one("/foobar/waldo", "/fuckfuck", "/foobar/waldo"); ++ test_shift_path_one("/foobar/waldo", "/hogehoge", "/foobar/waldo"); + } + + static void test_mask_supported(void) { +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 9e7d98500f..165a5de91d 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -279,18 +279,18 @@ static void test_strv_split_nulstr(void) { + + static void test_strv_parse_nulstr(void) { + _cleanup_strv_free_ char **l = NULL; +- const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx"; ++ const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx"; + + l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1); + assert_se(l); + puts("Parse nulstr:"); + strv_print(l); + +- assert_se(streq(l[0], "fuck")); +- assert_se(streq(l[1], "fuck2")); +- assert_se(streq(l[2], "fuck3")); ++ assert_se(streq(l[0], "hoge")); ++ assert_se(streq(l[1], "hoge2")); ++ assert_se(streq(l[2], "hoge3")); + assert_se(streq(l[3], "")); +- assert_se(streq(l[4], "fuck5")); ++ assert_se(streq(l[4], "hoge5")); + assert_se(streq(l[5], "")); + assert_se(streq(l[6], "xxx")); + } diff --git a/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch b/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch new file mode 100644 index 0000000..ca2f947 --- /dev/null +++ b/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch @@ -0,0 +1,124 @@ +From f41927c026d65e9005c0ba418c6bfff511055bd2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:05:08 +0900 +Subject: [PATCH] core: add new environment variable $RUNTIME_DIRECTORY= or + friends + +The variable is generated from RuntimeDirectory= or friends. +If multiple directories are set, then they are concatenated with +the separator ':'. + +(cherry picked from commit fb2042dd55de5019f55931b4f20a44700ec1222b) + +Resolves: #2049788 +--- + TODO | 9 --------- + src/core/execute.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 44 insertions(+), 11 deletions(-) + +diff --git a/TODO b/TODO +index 0705b6b08e..c52f9b25f3 100644 +--- a/TODO ++++ b/TODO +@@ -214,15 +214,6 @@ Features: + for all units. It should be both a way to pin units into memory as well as a + wait to retrieve their exit data. + +-* maybe set a new set of env vars for services, based on RuntimeDirectory=, +- StateDirectory=, LogsDirectory=, CacheDirectory= and ConfigurationDirectory= +- automatically. For example, there could be $RUNTIME_DIRECTORY, +- $STATE_DIRECTORY, $LOGS_DIRECTORY=, $CACHE_DIRECTORY and +- $CONFIGURATION_DIRECTORY or so. This could be useful to write services that +- can adapt to varying directories for these purposes. Special care has to be +- taken if multiple dirs are configured. Maybe avoid setting the env vars in +- that case? +- + * expose IO accounting data on the bus, show it in systemd-run --wait and log + about it in the resource log message + +diff --git a/src/core/execute.c b/src/core/execute.c +index 3ff1a51aa1..9cbb678ac4 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1606,6 +1606,8 @@ static void do_idle_pipe_dance(int idle_pipe[4]) { + idle_pipe[3] = safe_close(idle_pipe[3]); + } + ++static const char *exec_directory_env_name_to_string(ExecDirectoryType t); ++ + static int build_environment( + const Unit *u, + const ExecContext *c, +@@ -1619,6 +1621,7 @@ static int build_environment( + char ***ret) { + + _cleanup_strv_free_ char **our_env = NULL; ++ ExecDirectoryType t; + size_t n_env = 0; + char *x; + +@@ -1627,7 +1630,7 @@ static int build_environment( + assert(p); + assert(ret); + +- our_env = new0(char*, 14); ++ our_env = new0(char*, 14 + _EXEC_DIRECTORY_TYPE_MAX); + if (!our_env) + return -ENOMEM; + +@@ -1733,8 +1736,37 @@ static int build_environment( + our_env[n_env++] = x; + } + ++ for (t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) { ++ _cleanup_free_ char *pre = NULL, *joined = NULL; ++ const char *n; ++ ++ if (!p->prefix[t]) ++ continue; ++ ++ if (strv_isempty(c->directories[t].paths)) ++ continue; ++ ++ n = exec_directory_env_name_to_string(t); ++ if (!n) ++ continue; ++ ++ pre = strjoin(p->prefix[t], "/"); ++ if (!pre) ++ return -ENOMEM; ++ ++ joined = strv_join_prefix(c->directories[t].paths, ":", pre); ++ if (!joined) ++ return -ENOMEM; ++ ++ x = strjoin(n, "=", joined); ++ if (!x) ++ return -ENOMEM; ++ ++ our_env[n_env++] = x; ++ } ++ + our_env[n_env++] = NULL; +- assert(n_env <= 14); ++ assert(n_env <= 14 + _EXEC_DIRECTORY_TYPE_MAX); + + *ret = TAKE_PTR(our_env); + +@@ -5197,6 +5229,16 @@ static const char* const exec_directory_type_table[_EXEC_DIRECTORY_TYPE_MAX] = { + + DEFINE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType); + ++static const char* const exec_directory_env_name_table[_EXEC_DIRECTORY_TYPE_MAX] = { ++ [EXEC_DIRECTORY_RUNTIME] = "RUNTIME_DIRECTORY", ++ [EXEC_DIRECTORY_STATE] = "STATE_DIRECTORY", ++ [EXEC_DIRECTORY_CACHE] = "CACHE_DIRECTORY", ++ [EXEC_DIRECTORY_LOGS] = "LOGS_DIRECTORY", ++ [EXEC_DIRECTORY_CONFIGURATION] = "CONFIGURATION_DIRECTORY", ++}; ++ ++DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(exec_directory_env_name, ExecDirectoryType); ++ + static const char* const exec_keyring_mode_table[_EXEC_KEYRING_MODE_MAX] = { + [EXEC_KEYRING_INHERIT] = "inherit", + [EXEC_KEYRING_PRIVATE] = "private", diff --git a/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch b/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch new file mode 100644 index 0000000..ec10dec --- /dev/null +++ b/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch @@ -0,0 +1,76 @@ +From 5226df888c28ede9219d7f018af02cca1d1f6d2a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:07:53 +0900 +Subject: [PATCH] test-execute: add tests for $RUNTIME_DIRECTORY= or friends + +(cherry picked from commit 6088662d57bbd81167bd272d385fdd1044b287ec) + +Related: #2049788 +--- + .../test-execute/exec-dynamicuser-statedir-migrate-step1.service | 1 + + .../test-execute/exec-dynamicuser-statedir-migrate-step2.service | 1 + + test/test-execute/exec-dynamicuser-statedir.service | 1 + + test/test-execute/exec-runtimedirectory-mode.service | 1 + + test/test-execute/exec-runtimedirectory.service | 1 + + 5 files changed, 5 insertions(+) + +diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service +index 72e6d7686f..5efc5483b8 100644 +--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service ++++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service +@@ -10,6 +10,7 @@ ExecStart=test -d /var/lib/test-dynamicuser-migrate + ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge + ExecStart=touch /var/lib/test-dynamicuser-migrate/yay + ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay ++ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"' + + Type=oneshot + DynamicUser=no +diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service +index edb0be7ef8..c72302ffd5 100644 +--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service ++++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service +@@ -18,6 +18,7 @@ ExecStart=touch /var/lib/test-dynamicuser-migrate/yay + ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay + ExecStart=touch /var/lib/private/test-dynamicuser-migrate/yay + ExecStart=touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay ++ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"' + + Type=oneshot + DynamicUser=yes +diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service +index f459f3c1eb..2fb7b8660b 100644 +--- a/test/test-execute/exec-dynamicuser-statedir.service ++++ b/test/test-execute/exec-dynamicuser-statedir.service +@@ -10,6 +10,7 @@ ExecStart=test -f /var/lib/waldo/yay + ExecStart=test -f /var/lib/quux/pief/yayyay + ExecStart=test -f /var/lib/private/waldo/yay + ExecStart=test -f /var/lib/private/quux/pief/yayyay ++ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/waldo:%S/quux/pief"' + + # Make sure that /var/lib/private/waldo is really the only writable directory besides the obvious candidates + ExecStart=sh -x -c 'test $$(find / \( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o -path /sys/fs/bpf \) -prune -o -type d -writable -print 2>/dev/null | sort -u | tr -d '\\\\n') = /var/lib/private/quux/pief/var/lib/private/waldo' +diff --git a/test/test-execute/exec-runtimedirectory-mode.service b/test/test-execute/exec-runtimedirectory-mode.service +index 480f904155..85ae5161c4 100644 +--- a/test/test-execute/exec-runtimedirectory-mode.service ++++ b/test/test-execute/exec-runtimedirectory-mode.service +@@ -3,6 +3,7 @@ Description=Test for RuntimeDirectoryMode + + [Service] + ExecStart=/bin/sh -x -c 'mode=$$(stat -c %%a %t/test-exec_runtimedirectory-mode); test "$$mode" = "750"' ++ExecStart=/bin/sh -x -c 'test "$$RUNTIME_DIRECTORY" = "%t/test-exec_runtimedirectory-mode"' + Type=oneshot + RuntimeDirectory=test-exec_runtimedirectory-mode + RuntimeDirectoryMode=0750 +diff --git a/test/test-execute/exec-runtimedirectory.service b/test/test-execute/exec-runtimedirectory.service +index 6a4383110f..a33044d23c 100644 +--- a/test/test-execute/exec-runtimedirectory.service ++++ b/test/test-execute/exec-runtimedirectory.service +@@ -4,6 +4,7 @@ Description=Test for RuntimeDirectory + [Service] + ExecStart=/bin/sh -x -c 'test -d %t/test-exec_runtimedirectory' + ExecStart=/bin/sh -x -c 'test -d %t/test-exec_runtimedirectory2/hogehoge' ++ExecStart=/bin/sh -x -c 'test "$$RUNTIME_DIRECTORY" = "%t/test-exec_runtimedirectory:%t/test-exec_runtimedirectory2/hogehoge"' + Type=oneshot + RuntimeDirectory=test-exec_runtimedirectory + RuntimeDirectory=./test-exec_runtimedirectory2///./hogehoge/. diff --git a/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch b/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch new file mode 100644 index 0000000..863c21b --- /dev/null +++ b/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch @@ -0,0 +1,85 @@ +From a729ea1a59b63c5f3e7fdce6a6c4e2ce12faa972 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:24:47 +0900 +Subject: [PATCH] man: document RUNTIME_DIRECTORY= or friends + +(cherry picked from commit d491e65e74a92898d6e7f95032b5b037c6e3cb60) + +Related: #2049788 +--- + man/systemd.exec.xml | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 696438c4ef..dc88cf9781 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -820,15 +820,18 @@ CapabilityBoundingSet=~CAP_B CAP_C + These options take a whitespace-separated list of directory names. The specified directory + names must be relative, and may not include ... If set, one or more + directories by the specified names will be created (including their parents) below the locations +- defined in the following table, when the unit is started. ++ defined in the following table, when the unit is started. Also, the corresponding environment variable ++ is defined with the full path of directories. If multiple directories are set, then int the environment variable ++ the paths are concatenated with colon (:). + +- Automatic directory creation +- ++ Automatic directory creation and environment variables ++ + + + Locations + for system + for users ++ Environment variable + + + +@@ -836,26 +839,31 @@ CapabilityBoundingSet=~CAP_B CAP_C + RuntimeDirectory= + /run + $XDG_RUNTIME_DIR ++ $RUNTIME_DIRECTORY + + + StateDirectory= + /var/lib + $XDG_CONFIG_HOME ++ $STATE_DIRECTORY + + + CacheDirectory= + /var/cache + $XDG_CACHE_HOME ++ $CACHE_DIRECTORY + + + LogsDirectory= + /var/log + $XDG_CONFIG_HOME/log ++ $LOGS_DIRECTORY + + + ConfigurationDirectory= + /etc + $XDG_CONFIG_HOME ++ $CONFIGURATION_DIRECTORY + + + +@@ -905,7 +913,13 @@ CapabilityBoundingSet=~CAP_B CAP_C + /run/foo/bar, and /run/baz. The directories + /run/foo/bar and /run/baz except /run/foo are + owned by the user and group specified in User= and Group=, and removed +- when the service is stopped. ++ when the service is stopped. ++ ++ Example: if a system service unit has the following, ++ RuntimeDirectory=foo/bar ++StateDirectory=aaa/bbb ccc ++ then the environment variable RUNTIME_DIRECTORY is set with /run/foo/bar, and ++ STATE_DIRECTORY is set with /var/lib/aaa/bbb:/var/lib/ccc. + + + diff --git a/SOURCES/0792-ci-bump-the-worker-Ubuntu-version-to-Jammy.patch b/SOURCES/0792-ci-bump-the-worker-Ubuntu-version-to-Jammy.patch new file mode 100644 index 0000000..7791008 --- /dev/null +++ b/SOURCES/0792-ci-bump-the-worker-Ubuntu-version-to-Jammy.patch @@ -0,0 +1,24 @@ +From 3a35fcaad4bb3831808280854eb84f68975279a1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 19 Jul 2022 22:44:07 +0200 +Subject: [PATCH] ci: bump the worker Ubuntu version to Jammy + +rhel-only +Related: #2087152 +--- + .github/workflows/unit_tests.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index 87b162fa71..f397e8ed6e 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -6,7 +6,7 @@ on: [pull_request] + + jobs: + build: +- runs-on: ubuntu-20.04 ++ runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: diff --git a/SOURCES/0793-test-make-test-execute-pass-on-Linux-5.15.patch b/SOURCES/0793-test-make-test-execute-pass-on-Linux-5.15.patch new file mode 100644 index 0000000..9bc14ce --- /dev/null +++ b/SOURCES/0793-test-make-test-execute-pass-on-Linux-5.15.patch @@ -0,0 +1,43 @@ +From 434b4b64d17e16ed23f90c99c26dbd0e4ce6cd88 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 24 Nov 2021 15:58:50 +0100 +Subject: [PATCH] test: make test-execute pass on Linux 5.15 + +Linux 5.15 broke kernel API: + +https://github.com/torvalds/linux/commit/e70344c05995a190a56bbd1a23dc2218bcc8c924 + +Previously setting IOPRIO_CLASS_NONE for a process would then report +IOPRIO_CLASS_NONE back. But since 5.15 it reports IOPRIO_CLASS_BE +instead. Since IOPRIO_CLASS_NONE is an alias for a special setting of +IOPRIO_CLASS_BE this makes some sense, but it's also a kernel API +breakage that our testsuite trips up on. + +(I made some minimal effort to inform the kernel people about this API +breakage during the 5.15 rc phase, but noone was interested.) + +Either way let's hadle this gracefully in our test suite and accept +"best-effort" too when "none" was set. + +(This is only triggable if the tests are run on 5.15 with full privs) + +(cherry picked from commit d9b8771108cf2955efc3852b477391017d2c599a) + +Related: #2087152 +--- + test/test-execute/exec-ioschedulingclass-none.service | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test/test-execute/exec-ioschedulingclass-none.service b/test/test-execute/exec-ioschedulingclass-none.service +index b6af122a1e..8f917d345d 100644 +--- a/test/test-execute/exec-ioschedulingclass-none.service ++++ b/test/test-execute/exec-ioschedulingclass-none.service +@@ -2,6 +2,7 @@ + Description=Test for IOSchedulingClass=none + + [Service] +-ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "none"' ++# Old kernels might report "none" here, new kernels "best-effort". ++ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "none" -o "$${c%%:*}" = "best-effort"' + Type=oneshot + IOSchedulingClass=none diff --git a/SOURCES/0794-ci-install-iputils.patch b/SOURCES/0794-ci-install-iputils.patch new file mode 100644 index 0000000..97881f9 --- /dev/null +++ b/SOURCES/0794-ci-install-iputils.patch @@ -0,0 +1,25 @@ +From 128d784dacb456f9ea675911e88d4b47925bda0d Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 20 Jul 2022 10:24:36 +0200 +Subject: [PATCH] ci: install iputils + +Required by test-bpf. + +rhel-only +Related: #2087152 +--- + .github/workflows/unit_tests.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index c1311310fb..3859433720 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -11,6 +11,7 @@ ADDITIONAL_DEPS=( + dnsmasq + e2fsprogs + hostname ++ iputils + libasan + libubsan + nc diff --git a/SOURCES/0795-ci-Mergify-Add-ci-waived-logic.patch b/SOURCES/0795-ci-Mergify-Add-ci-waived-logic.patch new file mode 100644 index 0000000..4841062 --- /dev/null +++ b/SOURCES/0795-ci-Mergify-Add-ci-waived-logic.patch @@ -0,0 +1,63 @@ +From 0feaf0be515c02a10ca12f726b4a8424262cf09c Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 19 Jul 2022 12:43:43 +0200 +Subject: [PATCH] ci(Mergify): Add `ci-waived` logic + +RHEL-only + +Related: #2087152 +--- + .mergify.yml | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +diff --git a/.mergify.yml b/.mergify.yml +index 6fa400effd..3afd04f18e 100644 +--- a/.mergify.yml ++++ b/.mergify.yml +@@ -4,6 +4,7 @@ + pull_request_rules: + - name: Add `needs-ci` label on CI fail + conditions: ++ - label!=ci-waived + - or: + # Unit tests + - -check-success=build (stream8, GCC) +@@ -27,21 +28,24 @@ pull_request_rules: + + - name: Remove `needs-ci` label on CI success + conditions: +- # Unit tests +- - check-success=build (stream8, GCC) +- - check-success=build (stream8, GCC_ASAN) +- # CentOS Stream CI +- - check-success=CentOS CI (CentOS Stream 8) +- # LGTM + - or: +- - "check-success=LGTM analysis: JavaScript" +- - "check-neutral=LGTM analysis: JavaScript" +- - or: +- - "check-success=LGTM analysis: Python" +- - "check-neutral=LGTM analysis: Python" +- - or: +- - "check-success=LGTM analysis: C/C++" +- - "check-neutral=LGTM analysis: C/C++" ++ - label=ci-waived ++ - and: ++ # Unit tests ++ - check-success=build (stream8, GCC) ++ - check-success=build (stream8, GCC_ASAN) ++ # CentOS Stream CI ++ - check-success=CentOS CI (CentOS Stream 8) ++ # LGTM ++ - or: ++ - "check-success=LGTM analysis: JavaScript" ++ - "check-neutral=LGTM analysis: JavaScript" ++ - or: ++ - "check-success=LGTM analysis: Python" ++ - "check-neutral=LGTM analysis: Python" ++ - or: ++ - "check-success=LGTM analysis: C/C++" ++ - "check-neutral=LGTM analysis: C/C++" + actions: + label: + remove: diff --git a/SOURCES/0796-sd-event-don-t-invalidate-source-type-on-disconnect.patch b/SOURCES/0796-sd-event-don-t-invalidate-source-type-on-disconnect.patch new file mode 100644 index 0000000..1c94030 --- /dev/null +++ b/SOURCES/0796-sd-event-don-t-invalidate-source-type-on-disconnect.patch @@ -0,0 +1,33 @@ +From e48586dcfa66731a353ecc832e43fab75559e2cf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 30 Oct 2019 16:37:42 +0100 +Subject: [PATCH] sd-event: don't invalidate source type on disconnect + +This fixes fd closing if fd ownership is requested. + +(cherry picked from commit f59825595182d70b9ead238d1e885d0db99cc201) + +Resolves: #2115396 +--- + src/libsystemd/sd-event/sd-event.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 0adfdd9e1a..09d4584bf9 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1104,11 +1104,13 @@ static void source_disconnect(sd_event_source *s) { + + event = s->event; + +- s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID; + s->event = NULL; + LIST_REMOVE(sources, event->sources, s); + event->n_sources--; + ++ /* Note that we don't invalidate the type here, since we still need it in order to close the fd or ++ * pidfd associated with this event source, which we'll do only on source_free(). */ ++ + if (!s->floating) + sd_event_unref(event); + } diff --git a/SOURCES/0797-tests-make-sure-we-delay-running-mount-start-jobs-wh.patch b/SOURCES/0797-tests-make-sure-we-delay-running-mount-start-jobs-wh.patch new file mode 100644 index 0000000..eb18da9 --- /dev/null +++ b/SOURCES/0797-tests-make-sure-we-delay-running-mount-start-jobs-wh.patch @@ -0,0 +1,98 @@ +From e6cd875a767ba23b218cdca395307ac6fb7fd882 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 30 May 2022 14:50:05 +0200 +Subject: [PATCH] tests: make sure we delay running mount start jobs when + /p/s/mountinfo is rate limited + +(cherry picked from commit 9e15be6c8d55abd800bf33f9776dd0e307ed37bc) + +Related: #2095744 +--- + test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 53 +++++++++++++++++++++++ + test/test-functions | 2 +- + 2 files changed, 54 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +index 6211050faf..84fe9640e1 100755 +--- a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh ++++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +@@ -2,6 +2,56 @@ + set -eux + set -o pipefail + ++test_issue_20329() { ++ local tmpdir unit ++ tmpdir="$(mktemp -d)" ++ unit=$(systemd-escape --suffix mount --path "$tmpdir") ++ ++ # Set up test mount unit ++ cat > /run/systemd/system/"$unit" <&2 "Test mount \"$unit\" unit isn't mounted" ++ return 1 ++ } ++ mountpoint -q "$tmpdir" ++ ++ trap 'systemctl stop $unit' RETURN ++ ++ # Trigger the mount ratelimiting ++ cd "$(mktemp -d)" ++ mkdir foo ++ for ((i=0;i<50;++i)); do ++ mount --bind foo foo ++ umount foo ++ done ++ ++ # Unmount the test mount and start it immediately again via systemd ++ umount "$tmpdir" ++ systemctl start "$unit" ++ ++ # Make sure it is seen as mounted by systemd and it actually is mounted ++ [[ "$(systemctl show --property SubState --value "$unit")" = "mounted" ]] || { ++ echo >&2 "Test mount \"$unit\" unit isn't in \"mounted\" state" ++ return 1 ++ } ++ ++ mountpoint -q "$tmpdir" || { ++ echo >&2 "Test mount \"$unit\" is in \"mounted\" state, actually is not mounted" ++ return 1 ++ } ++} ++ + systemd-analyze log-level debug + systemd-analyze log-target journal + +@@ -85,6 +135,9 @@ if systemctl list-units -t mount tmp-meow* | grep -q tmp-meow; then + exit 42 + fi + ++# test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited ++test_issue_20329 ++ + systemd-analyze log-level info + + echo OK >/testok +diff --git a/test/test-functions b/test/test-functions +index 4d7832b1fb..ed8ab98173 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0798-core-drop-references-to-StandardOutputFileToCreate.patch b/SOURCES/0798-core-drop-references-to-StandardOutputFileToCreate.patch new file mode 100644 index 0000000..b789e1f --- /dev/null +++ b/SOURCES/0798-core-drop-references-to-StandardOutputFileToCreate.patch @@ -0,0 +1,29 @@ +From 0bf1df5c35c310c3efe49c7a3cb8c3be3e33492b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:05:37 +0100 +Subject: [PATCH] core: drop references to 'StandardOutputFileToCreate' + +This property never existed, let's drop any reference to it. + +(cherry picked from commit 922ce049d1ed37ce77e3322711e29f256d9e5959) + +Related: #2093479 +--- + src/core/dbus-execute.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 2e64f0baf4..05134851c5 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1809,8 +1809,8 @@ int bus_exec_context_set_transient_property( + + } else if (STR_IN_SET(name, + "StandardInputFile", +- "StandardOutputFile", "StandardOutputFileToCreate", "StandardOutputFileToAppend", +- "StandardErrorFile", "StandardErrorFileToCreate", "StandardErrorFileToAppend")) { ++ "StandardOutputFile", "StandardOutputFileToAppend", ++ "StandardErrorFile", "StandardErrorFileToAppend")) { + const char *s; + + r = sd_bus_message_read(message, "s", &s); diff --git a/SOURCES/0799-dbus-execute-fix-indentation.patch b/SOURCES/0799-dbus-execute-fix-indentation.patch new file mode 100644 index 0000000..741b756 --- /dev/null +++ b/SOURCES/0799-dbus-execute-fix-indentation.patch @@ -0,0 +1,29 @@ +From 2ba82e6b7e9a7b138c985561dd7d26b9e4111fbe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:06:19 +0100 +Subject: [PATCH] dbus-execute: fix indentation + +(cherry picked from commit dbe6c4b657aa5c58bfc049d869b94f00b41b7d95) + +Related: #2093479 +--- + src/core/dbus-execute.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 05134851c5..fc433cc96f 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1858,9 +1858,9 @@ int bus_exec_context_set_transient_property( + c->std_error = EXEC_OUTPUT_FILE; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); + } else { +- assert(streq(name, "StandardErrorFileToAppend")); +- c->std_error = EXEC_OUTPUT_FILE_APPEND; +- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); ++ assert(streq(name, "StandardErrorFileToAppend")); ++ c->std_error = EXEC_OUTPUT_FILE_APPEND; ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); + } + } + } diff --git a/SOURCES/0800-dbus-execute-generate-the-correct-transient-unit-set.patch b/SOURCES/0800-dbus-execute-generate-the-correct-transient-unit-set.patch new file mode 100644 index 0000000..c84dea6 --- /dev/null +++ b/SOURCES/0800-dbus-execute-generate-the-correct-transient-unit-set.patch @@ -0,0 +1,30 @@ +From 4fbd505c5a15f2b6078dc43e5a1ff999993e8b23 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:07:06 +0100 +Subject: [PATCH] dbus-execute: generate the correct transient unit setting + +(cherry picked from commit 1704fba92f7b2c92238b0833943669045374daf9) + +Related: #2093479 +--- + src/core/dbus-execute.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index fc433cc96f..00f4aeacef 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -1856,11 +1856,11 @@ int bus_exec_context_set_transient_property( + + if (streq(name, "StandardErrorFile")) { + c->std_error = EXEC_OUTPUT_FILE; +- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s); + } else { + assert(streq(name, "StandardErrorFileToAppend")); + c->std_error = EXEC_OUTPUT_FILE_APPEND; +- unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); ++ unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s); + } + } + } diff --git a/SOURCES/0801-bus-unit-util-properly-accept-StandardOutput-append-.patch b/SOURCES/0801-bus-unit-util-properly-accept-StandardOutput-append-.patch new file mode 100644 index 0000000..004b1fa --- /dev/null +++ b/SOURCES/0801-bus-unit-util-properly-accept-StandardOutput-append-.patch @@ -0,0 +1,33 @@ +From b06347d1e85c98507ba386b24e6c7159edf4784f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:07:39 +0100 +Subject: [PATCH] =?UTF-8?q?bus-unit-util:=20properly=20accept=20StandardOu?= + =?UTF-8?q?tput=3Dappend:=E2=80=A6=20settings?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +(cherry picked from commit 8d33232ef1ad051b5ed00bd7b5fffb5a19bb83ae) + +Resolves: #2093479 +--- + src/shared/bus-unit-util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 9010448aaf..3910dfa812 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -894,9 +894,11 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con + } else if ((n = startswith(eq, "file:"))) { + appended = strjoina(field, "File"); + r = sd_bus_message_append(m, "(sv)", appended, "s", n); ++ } else if ((n = startswith(eq, "append:"))) { ++ appended = strjoina(field, "FileToAppend"); ++ r = sd_bus_message_append(m, "(sv)", appended, "s", n); + } else + r = sd_bus_message_append(m, "(sv)", field, "s", eq); +- + if (r < 0) + return bus_log_create_error(r); + diff --git a/SOURCES/0802-core-be-more-careful-when-inheriting-stdout-fds-to-s.patch b/SOURCES/0802-core-be-more-careful-when-inheriting-stdout-fds-to-s.patch new file mode 100644 index 0000000..68ef399 --- /dev/null +++ b/SOURCES/0802-core-be-more-careful-when-inheriting-stdout-fds-to-s.patch @@ -0,0 +1,68 @@ +From d6ffd324cc933efec946a3ffbed6fccfe7077203 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:07:48 +0100 +Subject: [PATCH] core: be more careful when inheriting stdout fds to stderr + +We need to compare the fd name/file name if we inherit an fd from stdout +to stderr. Let's do that. + +Fixes: #10875 +(cherry picked from commit 41fc585a7a3b8ae857cad5fdad1bc70cdacfa8e5) + +Related: #2093479 +--- + src/core/execute.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index 9cbb678ac4..b1d8dceb32 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -545,6 +545,30 @@ static int setup_input( + } + } + ++static bool can_inherit_stderr_from_stdout( ++ const ExecContext *context, ++ ExecOutput o, ++ ExecOutput e) { ++ ++ assert(context); ++ ++ /* Returns true, if given the specified STDERR and STDOUT output we can directly dup() the stdout fd to the ++ * stderr fd */ ++ ++ if (e == EXEC_OUTPUT_INHERIT) ++ return true; ++ if (e != o) ++ return false; ++ ++ if (e == EXEC_OUTPUT_NAMED_FD) ++ return streq_ptr(context->stdio_fdname[STDOUT_FILENO], context->stdio_fdname[STDERR_FILENO]); ++ ++ if (IN_SET(e, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND)) ++ return streq_ptr(context->stdio_file[STDOUT_FILENO], context->stdio_file[STDERR_FILENO]); ++ ++ return true; ++} ++ + static int setup_output( + const Unit *unit, + const ExecContext *context, +@@ -603,7 +627,7 @@ static int setup_output( + return fileno; + + /* Duplicate from stdout if possible */ +- if ((e == o && e != EXEC_OUTPUT_NAMED_FD) || e == EXEC_OUTPUT_INHERIT) ++ if (can_inherit_stderr_from_stdout(context, o, e)) + return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno; + + o = e; +@@ -694,7 +718,6 @@ static int setup_output( + flags |= O_APPEND; + + fd = acquire_path(context->stdio_file[fileno], flags, 0666 & ~context->umask); +- + if (fd < 0) + return fd; + diff --git a/SOURCES/0803-test-add-a-test-for-StandardError-file.patch b/SOURCES/0803-test-add-a-test-for-StandardError-file.patch new file mode 100644 index 0000000..ed9f18d --- /dev/null +++ b/SOURCES/0803-test-add-a-test-for-StandardError-file.patch @@ -0,0 +1,136 @@ +From 2bbaa4b647c8a60a6c6a591f71313b0667447246 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 26 Nov 2018 21:09:07 +0100 +Subject: [PATCH] =?UTF-8?q?test:=20add=20a=20test=20for=20StandardError=3D?= + =?UTF-8?q?file:=E2=80=A6?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This deserves a test of its, given how broken on so many levels this +previously was. + +(cherry picked from commit 196b0a11f306b8041e35316feb05ed1f00380957) + +Related: #2093479 +--- + test/TEST-27-STDOUTFILE/Makefile | 1 + + test/TEST-27-STDOUTFILE/test.sh | 52 ++++++++++++++++++++++++++++ + test/TEST-27-STDOUTFILE/testsuite.sh | 40 +++++++++++++++++++++ + 3 files changed, 93 insertions(+) + create mode 120000 test/TEST-27-STDOUTFILE/Makefile + create mode 100755 test/TEST-27-STDOUTFILE/test.sh + create mode 100755 test/TEST-27-STDOUTFILE/testsuite.sh + +diff --git a/test/TEST-27-STDOUTFILE/Makefile b/test/TEST-27-STDOUTFILE/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-27-STDOUTFILE/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-27-STDOUTFILE/test.sh b/test/TEST-27-STDOUTFILE/test.sh +new file mode 100755 +index 0000000000..724dbef231 +--- /dev/null ++++ b/test/TEST-27-STDOUTFILE/test.sh +@@ -0,0 +1,52 @@ ++#!/bin/bash ++# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- ++# ex: ts=8 sw=4 sts=4 et filetype=sh ++set -e ++TEST_DESCRIPTION="test StandardOutput=file:" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ inst_binary cmp ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service <&2' ++cmp /tmp/stdout <&2' ++cmp /tmp/stdout <&2' ++cmp /tmp/stdout < /testok ++ ++exit 0 diff --git a/SOURCES/0804-tree-wide-allow-ASCII-fallback-for-in-logs.patch b/SOURCES/0804-tree-wide-allow-ASCII-fallback-for-in-logs.patch new file mode 100644 index 0000000..d4e5b2c --- /dev/null +++ b/SOURCES/0804-tree-wide-allow-ASCII-fallback-for-in-logs.patch @@ -0,0 +1,260 @@ +From aa93c2acd6c9ed4eb0152be9002f59ecd9cc277e Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 24 Jun 2022 09:13:42 +0200 +Subject: [PATCH] =?UTF-8?q?tree-wide:=20allow=20ASCII=20fallback=20for=20?= + =?UTF-8?q?=E2=86=92=20in=20logs?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +(cherry picked from commit e2341b6bc325932b3f9f10874956952cbdbd6361) + +Resolves: #2093479 +--- + src/basic/mount-util.c | 5 +++-- + src/core/dbus.c | 4 +++- + src/core/namespace.c | 7 +++++-- + src/core/socket.c | 4 +++- + src/libsystemd/sd-bus/sd-bus.c | 4 +++- + src/login/logind-acl.c | 5 +++-- + src/resolve/resolved-dns-query.c | 11 +++++++++-- + src/shared/dns-domain.c | 9 ++++++--- + src/tmpfiles/tmpfiles.c | 4 +++- + 9 files changed, 38 insertions(+), 15 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 0c709001be..e7f9e514c2 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -18,6 +18,7 @@ + #include "fileio.h" + #include "fs-util.h" + #include "hashmap.h" ++#include "locale-util.h" + #include "mount-util.h" + #include "parse-util.h" + #include "path-util.h" +@@ -844,8 +845,8 @@ int mount_verbose( + log_debug("Bind-mounting %s on %s (%s \"%s\")...", + what, where, strnull(fl), strempty(o)); + else if (f & MS_MOVE) +- log_debug("Moving mount %s → %s (%s \"%s\")...", +- what, where, strnull(fl), strempty(o)); ++ log_debug("Moving mount %s %s %s (%s \"%s\")...", ++ what, special_glyph(ARROW), where, strnull(fl), strempty(o)); + else + log_debug("Mounting %s on %s (%s \"%s\")...", + strna(type), where, strnull(fl), strempty(o)); +diff --git a/src/core/dbus.c b/src/core/dbus.c +index 584a8a1b01..66d838cdb4 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -31,6 +31,7 @@ + #include "dbus.h" + #include "fd-util.h" + #include "fs-util.h" ++#include "locale-util.h" + #include "log.h" + #include "missing.h" + #include "mkdir.h" +@@ -751,7 +752,8 @@ static int manager_dispatch_sync_bus_names(sd_event_source *es, void *userdata) + assert(s); + + if (!streq_ptr(s->bus_name, name)) { +- log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name); ++ log_unit_warning(u, "Bus name has changed from %s %s %s, ignoring.", ++ s->bus_name, special_glyph(ARROW), name); + continue; + } + +diff --git a/src/core/namespace.c b/src/core/namespace.c +index e4930db15c..3566795d46 100644 +--- a/src/core/namespace.c ++++ b/src/core/namespace.c +@@ -15,6 +15,7 @@ + #include "fd-util.h" + #include "fs-util.h" + #include "label.h" ++#include "locale-util.h" + #include "loop-util.h" + #include "loopback-setup.h" + #include "missing.h" +@@ -841,7 +842,8 @@ static int follow_symlink( + return -ELOOP; + } + +- log_debug("Followed mount entry path symlink %s → %s.", mount_entry_path(m), target); ++ log_debug("Followed mount entry path symlink %s %s %s.", ++ mount_entry_path(m), special_glyph(ARROW), target); + + free_and_replace(m->path_malloc, target); + m->has_prefix = true; +@@ -920,7 +922,8 @@ static int apply_mount( + if (r < 0) + return log_debug_errno(r, "Failed to follow symlinks on %s: %m", mount_entry_source(m)); + +- log_debug("Followed source symlinks %s → %s.", mount_entry_source(m), chased); ++ log_debug("Followed source symlinks %s %s %s.", ++ mount_entry_source(m), special_glyph(ARROW), chased); + + free_and_replace(m->source_malloc, chased); + +diff --git a/src/core/socket.c b/src/core/socket.c +index 6f9a0f7575..bdfeb43a70 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -25,6 +25,7 @@ + #include "in-addr-util.h" + #include "io-util.h" + #include "label.h" ++#include "locale-util.h" + #include "log.h" + #include "missing.h" + #include "mkdir.h" +@@ -1355,7 +1356,8 @@ static int socket_symlink(Socket *s) { + } + + if (r < 0) +- log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s → %s, ignoring: %m", p, *i); ++ log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s %s %s, ignoring: %m", ++ p, special_glyph(ARROW), *i); + } + + return 0; +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 803f3f50d6..21e54591f7 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -31,6 +31,7 @@ + #include "cgroup-util.h" + #include "def.h" + #include "fd-util.h" ++#include "locale-util.h" + #include "hexdecoct.h" + #include "hostname-util.h" + #include "macro.h" +@@ -518,7 +519,8 @@ void bus_set_state(sd_bus *bus, enum bus_state state) { + if (state == bus->state) + return; + +- log_debug("Bus %s: changing state %s → %s", strna(bus->description), table[bus->state], table[state]); ++ log_debug("Bus %s: changing state %s %s %s", strna(bus->description), ++ table[bus->state], special_glyph(ARROW), table[state]); + bus->state = state; + } + +diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c +index cafeb8822f..fe17eac0e6 100644 +--- a/src/login/logind-acl.c ++++ b/src/login/logind-acl.c +@@ -9,6 +9,7 @@ + #include "escape.h" + #include "fd-util.h" + #include "format-util.h" ++#include "locale-util.h" + #include "logind-acl.h" + #include "set.h" + #include "string-util.h" +@@ -260,8 +261,8 @@ int devnode_acl_all(struct udev *udev, + SET_FOREACH(n, nodes, i) { + int k; + +- log_debug("Changing ACLs at %s for seat %s (uid "UID_FMT"→"UID_FMT"%s%s)", +- n, seat, old_uid, new_uid, ++ log_debug("Changing ACLs at %s for seat %s (uid "UID_FMT"%s"UID_FMT"%s%s)", ++ n, seat, old_uid, special_glyph(ARROW), new_uid, + del ? " del" : "", add ? " add" : ""); + + k = devnode_acl(n, flush, del, old_uid, add, new_uid); +diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c +index c921fe841f..573e27d662 100644 +--- a/src/resolve/resolved-dns-query.c ++++ b/src/resolve/resolved-dns-query.c +@@ -3,6 +3,7 @@ + #include "alloc-util.h" + #include "dns-domain.h" + #include "dns-type.h" ++#include "locale-util.h" + #include "hostname-util.h" + #include "local-addresses.h" + #include "resolved-dns-query.h" +@@ -942,7 +943,10 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname) + if (r < 0) + return r; + else if (r > 0) +- log_debug("Following CNAME/DNAME %s → %s.", dns_question_first_name(q->question_idna), dns_question_first_name(nq_idna)); ++ log_debug("Following CNAME/DNAME %s %s %s.", ++ dns_question_first_name(q->question_idna), ++ special_glyph(ARROW), ++ dns_question_first_name(nq_idna)); + + k = dns_question_is_equal(q->question_idna, q->question_utf8); + if (k < 0) +@@ -956,7 +960,10 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname) + if (k < 0) + return k; + else if (k > 0) +- log_debug("Following UTF8 CNAME/DNAME %s → %s.", dns_question_first_name(q->question_utf8), dns_question_first_name(nq_utf8)); ++ log_debug("Following UTF8 CNAME/DNAME %s %s %s.", ++ dns_question_first_name(q->question_utf8), ++ special_glyph(ARROW), ++ dns_question_first_name(nq_utf8)); + } + + if (r == 0 && k == 0) /* No actual cname happened? */ +diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c +index de2fcca8b2..59799dec56 100644 +--- a/src/shared/dns-domain.c ++++ b/src/shared/dns-domain.c +@@ -17,6 +17,7 @@ + + #include "alloc-util.h" + #include "dns-domain.h" ++#include "locale-util.h" + #include "hashmap.h" + #include "hexdecoct.h" + #include "in-addr-util.h" +@@ -1260,7 +1261,7 @@ int dns_name_apply_idna(const char *name, char **ret) { + + r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t, + IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL); +- log_debug("idn2_lookup_u8: %s → %s", name, t); ++ log_debug("idn2_lookup_u8: %s %s %s", name, special_glyph(ARROW), t); + if (r == IDN2_OK) { + if (!startswith(name, "xn--")) { + _cleanup_free_ char *s = NULL; +@@ -1273,8 +1274,10 @@ int dns_name_apply_idna(const char *name, char **ret) { + } + + if (!streq_ptr(name, s)) { +- log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.", +- name, t, s); ++ log_debug("idn2 roundtrip failed: \"%s\" %s \"%s\" %s \"%s\", ignoring.", ++ name, special_glyph(ARROW), t, ++ special_glyph(ARROW), s); ++ *ret = NULL; + return 0; + } + } +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 50fada99dd..b3c2aac746 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -36,6 +36,7 @@ + #include "fs-util.h" + #include "glob-util.h" + #include "io-util.h" ++#include "locale-util.h" + #include "label.h" + #include "log.h" + #include "macro.h" +@@ -2143,7 +2144,8 @@ static int patch_var_run(const char *fname, unsigned line, char **path) { + * there's no immediate need for action by the user. However, in the interest of making things less confusing + * to the user, let's still inform the user that these snippets should really be updated. */ + +- log_notice("[%s:%u] Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", fname, line, *path, n); ++ log_notice("[%s:%u] Line references path below legacy directory /var/run/, updating %s %s %s; please update the tmpfiles.d/ drop-in file accordingly.", ++ fname, line, *path, special_glyph(ARROW), n); + + free(*path); + *path = n; diff --git a/SOURCES/0805-tree-wide-allow-ASCII-fallback-for-in-logs.patch b/SOURCES/0805-tree-wide-allow-ASCII-fallback-for-in-logs.patch new file mode 100644 index 0000000..19fb968 --- /dev/null +++ b/SOURCES/0805-tree-wide-allow-ASCII-fallback-for-in-logs.patch @@ -0,0 +1,129 @@ +From f27568d24a29590b34fec3a96a5b3b5d290ba3d8 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 24 Jun 2022 09:59:44 +0200 +Subject: [PATCH] =?UTF-8?q?tree-wide:=20allow=20ASCII=20fallback=20for=20?= + =?UTF-8?q?=E2=80=A6=20in=20logs?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +(cherry picked from commit 28e5e1e97f47067bce190ea6b3404907d63e4320) + +Related: #2093479 +--- + src/core/manager.c | 5 +++-- + src/shared/vlan-util.c | 3 ++- + src/sysusers/sysusers.c | 5 +++-- + src/tmpfiles/tmpfiles.c | 6 +++--- + 4 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 845c26f498..5873e5b6d7 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -49,6 +49,7 @@ + #include "io-util.h" + #include "label.h" + #include "locale-setup.h" ++#include "locale-util.h" + #include "log.h" + #include "macro.h" + #include "manager.h" +@@ -1404,7 +1405,7 @@ static void manager_coldplug(Manager *m) { + + assert(m); + +- log_debug("Invoking unit coldplug() handlers…"); ++ log_debug("Invoking unit coldplug() handlers%s", special_glyph(ELLIPSIS)); + + /* Let's place the units back into their deserialized state */ + HASHMAP_FOREACH_KEY(u, k, m->units, i) { +@@ -1426,7 +1427,7 @@ static void manager_catchup(Manager *m) { + + assert(m); + +- log_debug("Invoking unit catchup() handlers…"); ++ log_debug("Invoking unit catchup() handlers%s", special_glyph(ELLIPSIS)); + + /* Let's catch up on any state changes that happened while we were reloading/reexecing */ + HASHMAP_FOREACH_KEY(u, k, m->units, i) { +diff --git a/src/shared/vlan-util.c b/src/shared/vlan-util.c +index 400994a354..9301dacbe2 100644 +--- a/src/shared/vlan-util.c ++++ b/src/shared/vlan-util.c +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "conf-parser.h" ++#include "locale-util.h" + #include "parse-util.h" + #include "string-util.h" + #include "vlan-util.h" +@@ -67,7 +68,7 @@ int config_parse_vlanid( + + r = parse_vlanid(rvalue, id); + if (r == -ERANGE) { +- log_syntax(unit, LOG_ERR, filename, line, r, "VLAN identifier outside of valid range 0…4094, ignoring: %s", rvalue); ++ log_syntax(unit, LOG_ERR, filename, line, r, "VLAN identifier outside of valid range 0%s4094, ignoring: %s", special_glyph(ELLIPSIS), rvalue); + return 0; + } + if (r < 0) { +diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c +index a374ebaaf4..f547388151 100644 +--- a/src/sysusers/sysusers.c ++++ b/src/sysusers/sysusers.c +@@ -12,6 +12,7 @@ + #include "format-util.h" + #include "fs-util.h" + #include "hashmap.h" ++#include "locale-util.h" + #include "pager.h" + #include "path-util.h" + #include "selinux-util.h" +@@ -1890,13 +1891,13 @@ static int read_config_files(char **args) { + + STRV_FOREACH(f, files) + if (p && path_equal(*f, p)) { +- log_debug("Parsing arguments at position \"%s\"…", *f); ++ log_debug("Parsing arguments at position \"%s\"%s", *f, special_glyph(ELLIPSIS)); + + r = parse_arguments(args); + if (r < 0) + return r; + } else { +- log_debug("Reading config file \"%s\"…", *f); ++ log_debug("Reading config file \"%s\"%s", *f, special_glyph(ELLIPSIS)); + + /* Just warn, ignore result otherwise */ + (void) read_config_file(*f, true); +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index b3c2aac746..8da525120b 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2654,7 +2654,7 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + assert(fn); + + if (streq(fn, "-")) { +- log_debug("Reading config from stdin…"); ++ log_debug("Reading config from stdin%s", special_glyph(ELLIPSIS)); + fn = ""; + f = stdin; + } else { +@@ -2667,7 +2667,7 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + + return log_error_errno(r, "Failed to open '%s': %m", fn); + } +- log_debug("Reading config file \"%s\"…", fn); ++ log_debug("Reading config file \"%s\"%s", fn, special_glyph(ELLIPSIS)); + f = _f; + } + +@@ -2765,7 +2765,7 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf + + STRV_FOREACH(f, files) + if (p && path_equal(*f, p)) { +- log_debug("Parsing arguments at position \"%s\"…", *f); ++ log_debug("Parsing arguments at position \"%s\"%s", *f, special_glyph(ELLIPSIS)); + + r = parse_arguments(config_dirs, args, invalid_config); + if (r < 0) diff --git a/SOURCES/0806-core-allow-to-set-default-timeout-for-devices.patch b/SOURCES/0806-core-allow-to-set-default-timeout-for-devices.patch new file mode 100644 index 0000000..a730ce9 --- /dev/null +++ b/SOURCES/0806-core-allow-to-set-default-timeout-for-devices.patch @@ -0,0 +1,115 @@ +From 207f51115c18c668982ef8bdb8a024fccaeb87f0 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Sat, 16 Jul 2022 09:49:12 +0200 +Subject: [PATCH] core: allow to set default timeout for devices + +Fixes: #19879 +(cherry picked from commit a0fe19f9f791c05af236265954b1d73e8fcf5468) + +Resolves: #1967245 +--- + src/core/dbus-manager.c | 1 + + src/core/device.c | 2 +- + src/core/main.c | 4 ++++ + src/core/manager.c | 1 + + src/core/manager.h | 1 + + src/core/system.conf.in | 1 + + 6 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 7488f22116..5b1ed3646e 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -2509,6 +2509,7 @@ const sd_bus_vtable bus_manager_vtable[] = { + SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("DefaultDeviceTimeoutUSec", "t", bus_property_get_usec, offsetof(Manager, default_device_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), + /* The following two items are obsolete alias */ +diff --git a/src/core/device.c b/src/core/device.c +index cb8b66dfc5..71b7c1ef81 100644 +--- a/src/core/device.c ++++ b/src/core/device.c +@@ -97,7 +97,7 @@ static void device_init(Unit *u) { + * indefinitely for plugged in devices, something which cannot + * happen for the other units since their operations time out + * anyway. */ +- u->job_running_timeout = u->manager->default_timeout_start_usec; ++ u->job_running_timeout = u->manager->default_device_timeout_usec; + + u->ignore_on_isolate = true; + +diff --git a/src/core/main.c b/src/core/main.c +index 08a4df3c97..bfd4c531a7 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -109,6 +109,7 @@ static usec_t arg_default_restart_usec; + static usec_t arg_default_timeout_start_usec; + static usec_t arg_default_timeout_stop_usec; + static usec_t arg_default_timeout_abort_usec; ++static usec_t arg_default_device_timeout_usec; + static bool arg_default_timeout_abort_set; + static usec_t arg_default_start_limit_interval; + static unsigned arg_default_start_limit_burst; +@@ -687,6 +688,7 @@ static int parse_config_file(void) { + { "Manager", "DefaultStandardError", config_parse_output_restricted,0, &arg_default_std_error }, + { "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_default_timeout_start_usec }, + { "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_default_timeout_stop_usec }, ++ { "Manager", "DefaultDeviceTimeoutSec", config_parse_sec, 0, &arg_default_device_timeout_usec }, + { "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec }, + { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval }, /* obsolete alias */ + { "Manager", "DefaultStartLimitIntervalSec",config_parse_sec, 0, &arg_default_start_limit_interval }, +@@ -754,6 +756,7 @@ static void set_manager_defaults(Manager *m) { + m->default_std_error = arg_default_std_error; + m->default_timeout_start_usec = arg_default_timeout_start_usec; + m->default_timeout_stop_usec = arg_default_timeout_stop_usec; ++ m->default_device_timeout_usec = arg_default_device_timeout_usec; + m->default_restart_usec = arg_default_restart_usec; + m->default_start_limit_interval = arg_default_start_limit_interval; + m->default_start_limit_burst = arg_default_start_limit_burst; +@@ -2077,6 +2080,7 @@ static void reset_arguments(void) { + arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; + arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC; + arg_default_timeout_abort_set = false; ++ arg_default_device_timeout_usec = DEFAULT_TIMEOUT_USEC; + arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL; + arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; + arg_runtime_watchdog = 0; +diff --git a/src/core/manager.c b/src/core/manager.c +index 5873e5b6d7..f4611e6f8f 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -731,6 +731,7 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) { + m->default_tasks_max = UINT64_MAX; + m->default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; + m->default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; ++ m->default_device_timeout_usec = DEFAULT_TIMEOUT_USEC, + m->default_restart_usec = DEFAULT_RESTART_USEC; + m->original_log_level = -1; + m->original_log_target = _LOG_TARGET_INVALID; +diff --git a/src/core/manager.h b/src/core/manager.h +index 7b572c8dfd..3f2cfc5e2e 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -285,6 +285,7 @@ struct Manager { + ExecOutput default_std_output, default_std_error; + + usec_t default_restart_usec, default_timeout_start_usec, default_timeout_stop_usec; ++ usec_t default_device_timeout_usec; + + usec_t default_start_limit_interval; + unsigned default_start_limit_burst; +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index 84246c0e36..2f6852a89f 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -37,6 +37,7 @@ + #DefaultStandardError=inherit + #DefaultTimeoutStartSec=90s + #DefaultTimeoutStopSec=90s ++#DefaultDeviceTimeoutSec=90s + #DefaultRestartSec=100ms + #DefaultStartLimitIntervalSec=10s + #DefaultStartLimitBurst=5 diff --git a/SOURCES/0807-man-document-DefaultDeviceTimeoutSec.patch b/SOURCES/0807-man-document-DefaultDeviceTimeoutSec.patch new file mode 100644 index 0000000..eb248e3 --- /dev/null +++ b/SOURCES/0807-man-document-DefaultDeviceTimeoutSec.patch @@ -0,0 +1,34 @@ +From ba81eba0feaf5c34f52141301e2b7ca93128fed0 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Sat, 16 Jul 2022 10:16:41 +0200 +Subject: [PATCH] man: document DefaultDeviceTimeoutSec= + +(cherry picked from commit 9e69bd4801588c12811c611a1c68b54cecbe1718) + +Related: #1967245 +--- + man/systemd-system.conf.xml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml +index 988c4e7665..3670f34cb5 100644 +--- a/man/systemd-system.conf.xml ++++ b/man/systemd-system.conf.xml +@@ -305,6 +305,17 @@ + 100ms. + + ++ ++ DefaultDeviceTimeoutSec= ++ ++ Configures the default timeout for waiting for devices. It can be changed per ++ device via the x-systemd.device-timeout= option in /etc/fstab ++ and /etc/crypttab (see ++ systemd.mount5, ++ crypttab5). ++ Defaults to 90s. ++ ++ + + DefaultStartLimitIntervalSec= + DefaultStartLimitBurst= diff --git a/SOURCES/0808-Revert-core-Propagate-condition-failed-state-to-trig.patch b/SOURCES/0808-Revert-core-Propagate-condition-failed-state-to-trig.patch new file mode 100644 index 0000000..51df34e --- /dev/null +++ b/SOURCES/0808-Revert-core-Propagate-condition-failed-state-to-trig.patch @@ -0,0 +1,255 @@ +From f1a1ff976ed0787c79a0f57d773bc555ab756b8c Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 17 Dec 2021 19:39:29 +0100 +Subject: [PATCH] Revert "core: Propagate condition failed state to triggering + units." + +This reverts commit 12ab94a1e4961a39c32efb60b71866ab588d3ea2. + +(cherry picked from commit 40f41f34d4af15d0147b5b2525f0b87ff62eae9a) + +Related: #2114005 +--- + src/core/automount.c | 14 ++++---------- + src/core/automount.h | 1 - + src/core/path.c | 16 +++++----------- + src/core/path.h | 1 - + src/core/socket.c | 28 +++++++++------------------- + src/core/socket.h | 1 - + src/core/timer.c | 12 +++--------- + src/core/timer.h | 1 - + src/core/unit.c | 10 ---------- + src/core/unit.h | 2 -- + 10 files changed, 21 insertions(+), 65 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index bac3b2fab7..c1c513d4a5 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -776,11 +776,6 @@ static void automount_enter_running(Automount *a) { + goto fail; + } + +- if (unit_has_failed_condition_or_assert(trigger)) { +- automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED); +- return; +- } +- + r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); +@@ -1092,11 +1087,10 @@ static int automount_can_start(Unit *u) { + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +- [AUTOMOUNT_SUCCESS] = "success", +- [AUTOMOUNT_FAILURE_RESOURCES] = "resources", +- [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", +- [AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED] = "mount-condition-failed", ++ [AUTOMOUNT_SUCCESS] = "success", ++ [AUTOMOUNT_FAILURE_RESOURCES] = "resources", ++ [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); +diff --git a/src/core/automount.h b/src/core/automount.h +index a7417d195c..21dd1c0774 100644 +--- a/src/core/automount.h ++++ b/src/core/automount.h +@@ -10,7 +10,6 @@ typedef enum AutomountResult { + AUTOMOUNT_FAILURE_RESOURCES, + AUTOMOUNT_FAILURE_START_LIMIT_HIT, + AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT, +- AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED, + _AUTOMOUNT_RESULT_MAX, + _AUTOMOUNT_RESULT_INVALID = -1 + } AutomountResult; +diff --git a/src/core/path.c b/src/core/path.c +index bf7e1bf3c2..c2facf0b16 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -453,7 +453,7 @@ static void path_enter_dead(Path *p, PathResult f) { + else + unit_log_failure(UNIT(p), path_result_to_string(p->result)); + +- path_set_state(p, p->result == PATH_SUCCESS ? PATH_DEAD : PATH_FAILED); ++ path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); + } + + static void path_enter_running(Path *p) { +@@ -711,11 +711,6 @@ static void path_trigger_notify(Unit *u, Unit *other) { + return; + } + +- if (unit_has_failed_condition_or_assert(other)) { +- path_enter_dead(p, PATH_FAILURE_UNIT_CONDITION_FAILED); +- return; +- } +- + /* Don't propagate anything if there's still a job queued */ + if (other->job) + return; +@@ -768,11 +763,10 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); + + static const char* const path_result_table[_PATH_RESULT_MAX] = { +- [PATH_SUCCESS] = "success", +- [PATH_FAILURE_RESOURCES] = "resources", +- [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", +- [PATH_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", ++ [PATH_SUCCESS] = "success", ++ [PATH_FAILURE_RESOURCES] = "resources", ++ [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 0ad6bd12c6..8a69f06c13 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -46,7 +46,6 @@ typedef enum PathResult { + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, + PATH_FAILURE_UNIT_START_LIMIT_HIT, +- PATH_FAILURE_UNIT_CONDITION_FAILED, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; +diff --git a/src/core/socket.c b/src/core/socket.c +index bdfeb43a70..9d47ca2616 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2274,15 +2274,6 @@ static void socket_enter_running(Socket *s, int cfd) { + goto refuse; + } + +- if (UNIT_ISSET(s->service) && cfd < 0) { +- Unit *service = UNIT_DEREF(s->service); +- +- if (unit_has_failed_condition_or_assert(service)) { +- socket_enter_dead(s, SOCKET_FAILURE_SERVICE_CONDITION_FAILED); +- return; +- } +- } +- + if (cfd < 0) { + bool pending = false; + Unit *other; +@@ -3298,16 +3289,15 @@ static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); + + static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { +- [SOCKET_SUCCESS] = "success", +- [SOCKET_FAILURE_RESOURCES] = "resources", +- [SOCKET_FAILURE_TIMEOUT] = "timeout", +- [SOCKET_FAILURE_EXIT_CODE] = "exit-code", +- [SOCKET_FAILURE_SIGNAL] = "signal", +- [SOCKET_FAILURE_CORE_DUMP] = "core-dump", +- [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", +- [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit", +- [SOCKET_FAILURE_SERVICE_CONDITION_FAILED] = "service-condition-failed", ++ [SOCKET_SUCCESS] = "success", ++ [SOCKET_FAILURE_RESOURCES] = "resources", ++ [SOCKET_FAILURE_TIMEOUT] = "timeout", ++ [SOCKET_FAILURE_EXIT_CODE] = "exit-code", ++ [SOCKET_FAILURE_SIGNAL] = "signal", ++ [SOCKET_FAILURE_CORE_DUMP] = "core-dump", ++ [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", ++ [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit" + }; + + DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); +diff --git a/src/core/socket.h b/src/core/socket.h +index b171b94316..2409dbf2a0 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -39,7 +39,6 @@ typedef enum SocketResult { + SOCKET_FAILURE_START_LIMIT_HIT, + SOCKET_FAILURE_TRIGGER_LIMIT_HIT, + SOCKET_FAILURE_SERVICE_START_LIMIT_HIT, +- SOCKET_FAILURE_SERVICE_CONDITION_FAILED, + _SOCKET_RESULT_MAX, + _SOCKET_RESULT_INVALID = -1 + } SocketResult; +diff --git a/src/core/timer.c b/src/core/timer.c +index 3c8d89771d..990f05fee4 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -567,11 +567,6 @@ static void timer_enter_running(Timer *t) { + return; + } + +- if (unit_has_failed_condition_or_assert(trigger)) { +- timer_enter_dead(t, TIMER_FAILURE_UNIT_CONDITION_FAILED); +- return; +- } +- + r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; +@@ -855,10 +850,9 @@ static const char* const timer_base_table[_TIMER_BASE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); + + static const char* const timer_result_table[_TIMER_RESULT_MAX] = { +- [TIMER_SUCCESS] = "success", +- [TIMER_FAILURE_RESOURCES] = "resources", +- [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [TIMER_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", ++ [TIMER_SUCCESS] = "success", ++ [TIMER_FAILURE_RESOURCES] = "resources", ++ [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); +diff --git a/src/core/timer.h b/src/core/timer.h +index d23e19d622..833aadb0b8 100644 +--- a/src/core/timer.h ++++ b/src/core/timer.h +@@ -32,7 +32,6 @@ typedef enum TimerResult { + TIMER_SUCCESS, + TIMER_FAILURE_RESOURCES, + TIMER_FAILURE_START_LIMIT_HIT, +- TIMER_FAILURE_UNIT_CONDITION_FAILED, + _TIMER_RESULT_MAX, + _TIMER_RESULT_INVALID = -1 + } TimerResult; +diff --git a/src/core/unit.c b/src/core/unit.c +index 0810bf5a58..dfe0c243ef 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5661,16 +5661,6 @@ int unit_thaw_vtable_common(Unit *u) { + return unit_cgroup_freezer_action(u, FREEZER_THAW); + } + +-bool unit_has_failed_condition_or_assert(Unit *u) { +- if (dual_timestamp_is_set(&u->condition_timestamp) && !u->condition_result) +- return true; +- +- if (dual_timestamp_is_set(&u->assert_timestamp) && !u->assert_result) +- return true; +- +- return false; +-} +- + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index a924bd2e83..b8b914711f 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -847,8 +847,6 @@ void unit_thawed(Unit *u); + int unit_freeze_vtable_common(Unit *u); + int unit_thaw_vtable_common(Unit *u); + +-bool unit_has_failed_condition_or_assert(Unit *u); +- + /* Macros which append UNIT= or USER_UNIT= to the message */ + + #define log_unit_full(unit, level, error, ...) \ diff --git a/SOURCES/0809-core-Check-unit-start-rate-limiting-earlier.patch b/SOURCES/0809-core-Check-unit-start-rate-limiting-earlier.patch new file mode 100644 index 0000000..45f95d4 --- /dev/null +++ b/SOURCES/0809-core-Check-unit-start-rate-limiting-earlier.patch @@ -0,0 +1,137 @@ +From e393372ad5ba67acb9b397f044efdb1c9a100644 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 24 Aug 2021 16:46:47 +0100 +Subject: [PATCH] core: Check unit start rate limiting earlier + +[dtardon: This adds the test that's been left out by commit +471eda89a25a3ceac91a2d05e39a54aae78038ed] + +(cherry picked from commit 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95) + +Related: #2114005 +--- + test/TEST-10-ISSUE-2467/test.sh | 3 ++ + test/TEST-63-ISSUE-17433/Makefile | 1 + + test/TEST-63-ISSUE-17433/test.sh | 42 ++++++++++++++++++++++ + test/TEST-63-ISSUE-17433/test63.path | 2 ++ + test/TEST-63-ISSUE-17433/test63.service | 5 +++ + test/TEST-63-ISSUE-17433/testsuite.service | 17 +++++++++ + 6 files changed, 70 insertions(+) + create mode 120000 test/TEST-63-ISSUE-17433/Makefile + create mode 100755 test/TEST-63-ISSUE-17433/test.sh + create mode 100644 test/TEST-63-ISSUE-17433/test63.path + create mode 100644 test/TEST-63-ISSUE-17433/test63.service + create mode 100644 test/TEST-63-ISSUE-17433/testsuite.service + +diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh +index 0e61236686..a839ef79de 100755 +--- a/test/TEST-10-ISSUE-2467/test.sh ++++ b/test/TEST-10-ISSUE-2467/test.sh +@@ -42,6 +42,9 @@ EOF + [Unit] + Requires=test.socket + ConditionPathExistsGlob=/tmp/nonexistent ++# Make sure we hit the socket trigger limit in the test and not the service start limit. ++StartLimitInterval=1000 ++StartLimitBurst=1000 + + [Service] + ExecStart=/bin/true +diff --git a/test/TEST-63-ISSUE-17433/Makefile b/test/TEST-63-ISSUE-17433/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-63-ISSUE-17433/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-63-ISSUE-17433/test.sh b/test/TEST-63-ISSUE-17433/test.sh +new file mode 100755 +index 0000000000..406a1e214c +--- /dev/null ++++ b/test/TEST-63-ISSUE-17433/test.sh +@@ -0,0 +1,42 @@ ++#!/usr/bin/env bash ++set -e ++ ++TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/17433" ++ ++# shellcheck source=test/test-functions ++. "${TEST_BASE_DIR:?}/test-functions" ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ # Create what will eventually be our root filesystem onto an overlay ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # setup the testsuite service ++ cp testsuite.service $initdir/etc/systemd/system/testsuite.service ++ ++ cp test63.path $initdir/etc/systemd/system/test63.path ++ cp test63.service $initdir/etc/systemd/system/test63.service ++ ++ setup_testsuite ++ ) || return 1 ++ setup_nspawn_root ++ ++ # mask some services that we do not want to run in these tests ++ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ++ ddebug "umount $TESTDIR/root" ++ umount $TESTDIR/root ++} ++ ++do_test "$@" +diff --git a/test/TEST-63-ISSUE-17433/test63.path b/test/TEST-63-ISSUE-17433/test63.path +new file mode 100644 +index 0000000000..a6573bda0a +--- /dev/null ++++ b/test/TEST-63-ISSUE-17433/test63.path +@@ -0,0 +1,2 @@ ++[Path] ++PathExists=/tmp/test63 +diff --git a/test/TEST-63-ISSUE-17433/test63.service b/test/TEST-63-ISSUE-17433/test63.service +new file mode 100644 +index 0000000000..c83801874d +--- /dev/null ++++ b/test/TEST-63-ISSUE-17433/test63.service +@@ -0,0 +1,5 @@ ++[Unit] ++ConditionPathExists=!/tmp/nonexistent ++ ++[Service] ++ExecStart=true +diff --git a/test/TEST-63-ISSUE-17433/testsuite.service b/test/TEST-63-ISSUE-17433/testsuite.service +new file mode 100644 +index 0000000000..d3ca5b002b +--- /dev/null ++++ b/test/TEST-63-ISSUE-17433/testsuite.service +@@ -0,0 +1,17 @@ ++[Unit] ++Description=TEST-63-ISSUE-17433 ++ ++[Service] ++ExecStartPre=rm -f /failed /testok ++Type=oneshot ++ExecStart=rm -f /tmp/nonexistent ++ExecStart=systemctl start test63.path ++ExecStart=touch /tmp/test63 ++# Make sure systemd has sufficient time to hit the start limit for test63.service. ++ExecStart=sleep 2 ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = failed' ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = start-limit-hit' ++# FIXME: The path remains active, which it should not ++# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = failed' ++# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = unit-start-limit-hit' ++ExecStart=sh -x -c 'echo OK >/testok' diff --git a/SOURCES/0810-core-Add-trigger-limit-for-path-units.patch b/SOURCES/0810-core-Add-trigger-limit-for-path-units.patch new file mode 100644 index 0000000..7ddde88 --- /dev/null +++ b/SOURCES/0810-core-Add-trigger-limit-for-path-units.patch @@ -0,0 +1,127 @@ +From 9d3f5e5d222308d29aad9bf7b2bfc440143a8606 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 17 Dec 2021 20:01:31 +0100 +Subject: [PATCH] core: Add trigger limit for path units + +When conditions fail on a service unit, a path unit can cause +PID 1 to busy loop as it keeps trying to activate the service unit. +To avoid this from happening, add a trigger limit to the path unit, +identical to the trigger limit we have for socket units. + +Initially, let's start with a high limit and not make it configurable. +If needed, we can add properties to configure the rate limit similar +to the ones we have for socket units. + +(cherry picked from commit aaae822b37aa3ca39aebb516fdc6bef36d730c25) + +Resolves: #2114005 +--- + src/core/path.c | 10 ++++++++++ + src/core/path.h | 3 +++ + test/TEST-63-ISSUE-17433/test63.service | 2 +- + test/TEST-63-ISSUE-17433/testsuite.service | 21 +++++++++++++++++---- + 4 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/src/core/path.c b/src/core/path.c +index c2facf0b16..b899bde0de 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -238,6 +238,9 @@ static void path_init(Unit *u) { + assert(u->load_state == UNIT_STUB); + + p->directory_mode = 0755; ++ ++ p->trigger_limit.interval = 2 * USEC_PER_SEC; ++ p->trigger_limit.burst = 200; + } + + void path_free_specs(Path *p) { +@@ -467,6 +470,12 @@ static void path_enter_running(Path *p) { + if (unit_stop_pending(UNIT(p))) + return; + ++ if (!ratelimit_below(&p->trigger_limit)) { ++ log_unit_warning(UNIT(p), "Trigger limit hit, refusing further activation."); ++ path_enter_dead(p, PATH_FAILURE_TRIGGER_LIMIT_HIT); ++ return; ++ } ++ + trigger = UNIT_TRIGGER(UNIT(p)); + if (!trigger) { + log_unit_error(UNIT(p), "Unit to trigger vanished."); +@@ -767,6 +776,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = { + [PATH_FAILURE_RESOURCES] = "resources", + [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", + [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", ++ [PATH_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 8a69f06c13..12fd13fbe3 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -46,6 +46,7 @@ typedef enum PathResult { + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, + PATH_FAILURE_UNIT_START_LIMIT_HIT, ++ PATH_FAILURE_TRIGGER_LIMIT_HIT, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; +@@ -63,6 +64,8 @@ struct Path { + mode_t directory_mode; + + PathResult result; ++ ++ RateLimit trigger_limit; + }; + + void path_free_specs(Path *p); +diff --git a/test/TEST-63-ISSUE-17433/test63.service b/test/TEST-63-ISSUE-17433/test63.service +index c83801874d..6292434c5c 100644 +--- a/test/TEST-63-ISSUE-17433/test63.service ++++ b/test/TEST-63-ISSUE-17433/test63.service +@@ -1,5 +1,5 @@ + [Unit] +-ConditionPathExists=!/tmp/nonexistent ++ConditionPathExists=/tmp/nonexistent + + [Service] + ExecStart=true +diff --git a/test/TEST-63-ISSUE-17433/testsuite.service b/test/TEST-63-ISSUE-17433/testsuite.service +index d3ca5b002b..39f9643890 100644 +--- a/test/TEST-63-ISSUE-17433/testsuite.service ++++ b/test/TEST-63-ISSUE-17433/testsuite.service +@@ -4,14 +4,27 @@ Description=TEST-63-ISSUE-17433 + [Service] + ExecStartPre=rm -f /failed /testok + Type=oneshot ++ ++# Test that a path unit continuously triggering a service that fails condition checks eventually fails with ++# the trigger-limit-hit error. + ExecStart=rm -f /tmp/nonexistent + ExecStart=systemctl start test63.path + ExecStart=touch /tmp/test63 +-# Make sure systemd has sufficient time to hit the start limit for test63.service. ++# Make sure systemd has sufficient time to hit the trigger limit for test63.path. + ExecStart=sleep 2 +-ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = failed' +-ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = start-limit-hit' ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = inactive' ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = success' + # FIXME: The path remains active, which it should not + # ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = failed' +-# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = unit-start-limit-hit' ++# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = trigger-limit-hit' ++ ++# Test that starting the service manually doesn't affect the path unit. ++ExecStart=rm -f /tmp/test63 ++ExecStart=systemctl reset-failed ++ExecStart=systemctl start test63.path ++ExecStart=systemctl start test63.service ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = inactive' ++ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = success' ++ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = active' ++ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = success' + ExecStart=sh -x -c 'echo OK >/testok' diff --git a/SOURCES/0811-meson-add-syscall-names-update-target.patch b/SOURCES/0811-meson-add-syscall-names-update-target.patch new file mode 100644 index 0000000..84961ed --- /dev/null +++ b/SOURCES/0811-meson-add-syscall-names-update-target.patch @@ -0,0 +1,680 @@ +From f20ccc0d505eccd59bb3814f59a63ea036be5bd5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 18 Aug 2020 16:27:20 +0200 +Subject: [PATCH] meson: add syscall-names-update target + +The calls to find_program("tools/*") are moved earlier so they can be used +in libshared/ (and it doesn't make sense to split them). + +(cherry picked from commit 47354b440e90626c320d8f142cb742ff569e3a40) + +Related: #2040247 +--- + meson.build | 13 +- + src/shared/meson.build | 6 + + src/shared/syscall-names.text | 597 ++++++++++++++++++++++++++++++++++ + tools/syscall-names-update.sh | 6 + + 4 files changed, 617 insertions(+), 5 deletions(-) + create mode 100644 src/shared/syscall-names.text + create mode 100755 tools/syscall-names-update.sh + +diff --git a/meson.build b/meson.build +index 57de947367..6729a9ea5e 100644 +--- a/meson.build ++++ b/meson.build +@@ -1417,6 +1417,14 @@ install_libsystemd_static = static_library( + + ############################################################ + ++hwdb_update_sh = find_program('tools/meson-hwdb-update.sh') ++make_directive_index_py = find_program('tools/make-directive-index.py') ++make_man_index_py = find_program('tools/make-man-index.py') ++syscall_names_update_sh = find_program('tools/syscall-names-update.sh') ++xml_helper_py = find_program('tools/xml_helper.py') ++ ++############################################################ ++ + # binaries that have --help and are intended for use by humans, + # usually, but not always, installed in /bin. + public_programs = [] +@@ -2721,11 +2729,6 @@ run_target('fuzzers', + + ############################################################ + +-make_directive_index_py = find_program('tools/make-directive-index.py') +-make_man_index_py = find_program('tools/make-man-index.py') +-xml_helper_py = find_program('tools/xml_helper.py') +-hwdb_update_sh = find_program('tools/meson-hwdb-update.sh') +- + subdir('units') + subdir('sysctl.d') + subdir('sysusers.d') +diff --git a/src/shared/meson.build b/src/shared/meson.build +index d0a1bba4c6..c9dd0a3a4e 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -165,3 +165,9 @@ libshared = shared_library( + dependencies : libshared_deps, + install : true, + install_dir : rootlibexecdir) ++ ++############################################################ ++ ++run_target( ++ 'syscall-names-update', ++ command : [syscall_names_update_sh, meson.current_source_dir()]) +diff --git a/src/shared/syscall-names.text b/src/shared/syscall-names.text +new file mode 100644 +index 0000000000..40d18a8894 +--- /dev/null ++++ b/src/shared/syscall-names.text +@@ -0,0 +1,597 @@ ++_llseek ++_newselect ++_sysctl ++accept ++accept4 ++access ++acct ++add_key ++adjtimex ++alarm ++arc_gettls ++arc_settls ++arc_usr_cmpxchg ++arch_prctl ++arm_fadvise64_64 ++arm_sync_file_range ++atomic_barrier ++atomic_cmpxchg_32 ++bdflush ++bfin_spinlock ++bind ++bpf ++brk ++cache_sync ++cachectl ++cacheflush ++capget ++capset ++chdir ++chmod ++chown ++chown32 ++chroot ++clock_adjtime ++clock_adjtime64 ++clock_getres ++clock_getres_time64 ++clock_gettime ++clock_gettime64 ++clock_nanosleep ++clock_nanosleep_time64 ++clock_settime ++clock_settime64 ++clone ++clone2 ++clone3 ++close ++close_range ++connect ++copy_file_range ++creat ++create_module ++delete_module ++dipc ++dup ++dup2 ++dup3 ++epoll_create ++epoll_create1 ++epoll_ctl ++epoll_ctl_old ++epoll_pwait ++epoll_wait ++epoll_wait_old ++eventfd ++eventfd2 ++exec_with_loader ++execv ++execve ++execveat ++exit ++exit_group ++faccessat ++faccessat2 ++fadvise64 ++fadvise64_64 ++fallocate ++fanotify_init ++fanotify_mark ++fchdir ++fchmod ++fchmodat ++fchown ++fchown32 ++fchownat ++fcntl ++fcntl64 ++fdatasync ++fgetxattr ++finit_module ++flistxattr ++flock ++fork ++fp_udfiex_crtl ++fremovexattr ++fsconfig ++fsetxattr ++fsmount ++fsopen ++fspick ++fstat ++fstat64 ++fstatat64 ++fstatfs ++fstatfs64 ++fsync ++ftruncate ++ftruncate64 ++futex ++futex_time64 ++futimesat ++get_kernel_syms ++get_mempolicy ++get_robust_list ++get_thread_area ++getcpu ++getcwd ++getdents ++getdents64 ++getdomainname ++getdtablesize ++getegid ++getegid32 ++geteuid ++geteuid32 ++getgid ++getgid32 ++getgroups ++getgroups32 ++gethostname ++getitimer ++getpagesize ++getpeername ++getpgid ++getpgrp ++getpid ++getpmsg ++getppid ++getpriority ++getrandom ++getresgid ++getresgid32 ++getresuid ++getresuid32 ++getrlimit ++getrusage ++getsid ++getsockname ++getsockopt ++gettid ++gettimeofday ++getuid ++getuid32 ++getunwind ++getxattr ++getxgid ++getxpid ++getxuid ++idle ++init_module ++inotify_add_watch ++inotify_init ++inotify_init1 ++inotify_rm_watch ++io_cancel ++io_destroy ++io_getevents ++io_pgetevents ++io_pgetevents_time64 ++io_setup ++io_submit ++io_uring_enter ++io_uring_register ++io_uring_setup ++ioctl ++ioperm ++iopl ++ioprio_get ++ioprio_set ++ipc ++kcmp ++kern_features ++kexec_file_load ++kexec_load ++keyctl ++kill ++lchown ++lchown32 ++lgetxattr ++link ++linkat ++listen ++listxattr ++llistxattr ++lookup_dcookie ++lremovexattr ++lseek ++lsetxattr ++lstat ++lstat64 ++madvise ++mbind ++membarrier ++memfd_create ++memory_ordering ++migrate_pages ++mincore ++mkdir ++mkdirat ++mknod ++mknodat ++mlock ++mlock2 ++mlockall ++mmap ++mmap2 ++modify_ldt ++mount ++move_mount ++move_pages ++mprotect ++mq_getsetattr ++mq_notify ++mq_open ++mq_timedreceive ++mq_timedreceive_time64 ++mq_timedsend ++mq_timedsend_time64 ++mq_unlink ++mremap ++msgctl ++msgget ++msgrcv ++msgsnd ++msync ++multiplexer ++munlock ++munlockall ++munmap ++name_to_handle_at ++nanosleep ++newfstatat ++nfsservctl ++ni_syscall ++nice ++old_adjtimex ++old_getpagesize ++oldfstat ++oldlstat ++oldolduname ++oldstat ++oldumount ++olduname ++open ++open_by_handle_at ++open_tree ++openat ++openat2 ++or1k_atomic ++osf_adjtime ++osf_afs_syscall ++osf_alt_plock ++osf_alt_setsid ++osf_alt_sigpending ++osf_asynch_daemon ++osf_audcntl ++osf_audgen ++osf_chflags ++osf_execve ++osf_exportfs ++osf_fchflags ++osf_fdatasync ++osf_fpathconf ++osf_fstat ++osf_fstatfs ++osf_fstatfs64 ++osf_fuser ++osf_getaddressconf ++osf_getdirentries ++osf_getdomainname ++osf_getfh ++osf_getfsstat ++osf_gethostid ++osf_getitimer ++osf_getlogin ++osf_getmnt ++osf_getrusage ++osf_getsysinfo ++osf_gettimeofday ++osf_kloadcall ++osf_kmodcall ++osf_lstat ++osf_memcntl ++osf_mincore ++osf_mount ++osf_mremap ++osf_msfs_syscall ++osf_msleep ++osf_mvalid ++osf_mwakeup ++osf_naccept ++osf_nfssvc ++osf_ngetpeername ++osf_ngetsockname ++osf_nrecvfrom ++osf_nrecvmsg ++osf_nsendmsg ++osf_ntp_adjtime ++osf_ntp_gettime ++osf_old_creat ++osf_old_fstat ++osf_old_getpgrp ++osf_old_killpg ++osf_old_lstat ++osf_old_open ++osf_old_sigaction ++osf_old_sigblock ++osf_old_sigreturn ++osf_old_sigsetmask ++osf_old_sigvec ++osf_old_stat ++osf_old_vadvise ++osf_old_vtrace ++osf_old_wait ++osf_oldquota ++osf_pathconf ++osf_pid_block ++osf_pid_unblock ++osf_plock ++osf_priocntlset ++osf_profil ++osf_proplist_syscall ++osf_reboot ++osf_revoke ++osf_sbrk ++osf_security ++osf_select ++osf_set_program_attributes ++osf_set_speculative ++osf_sethostid ++osf_setitimer ++osf_setlogin ++osf_setsysinfo ++osf_settimeofday ++osf_shmat ++osf_signal ++osf_sigprocmask ++osf_sigsendset ++osf_sigstack ++osf_sigwaitprim ++osf_sstk ++osf_stat ++osf_statfs ++osf_statfs64 ++osf_subsys_info ++osf_swapctl ++osf_swapon ++osf_syscall ++osf_sysinfo ++osf_table ++osf_uadmin ++osf_usleep_thread ++osf_uswitch ++osf_utc_adjtime ++osf_utc_gettime ++osf_utimes ++osf_utsname ++osf_wait4 ++osf_waitid ++pause ++pciconfig_iobase ++pciconfig_read ++pciconfig_write ++perf_event_open ++perfctr ++perfmonctl ++personality ++pidfd_getfd ++pidfd_open ++pidfd_send_signal ++pipe ++pipe2 ++pivot_root ++pkey_alloc ++pkey_free ++pkey_mprotect ++poll ++ppoll ++ppoll_time64 ++prctl ++pread64 ++preadv ++preadv2 ++prlimit64 ++process_vm_readv ++process_vm_writev ++pselect6 ++pselect6_time64 ++ptrace ++pwrite64 ++pwritev ++pwritev2 ++query_module ++quotactl ++read ++readahead ++readdir ++readlink ++readlinkat ++readv ++reboot ++recv ++recvfrom ++recvmmsg ++recvmmsg_time64 ++recvmsg ++remap_file_pages ++removexattr ++rename ++renameat ++renameat2 ++request_key ++restart_syscall ++riscv_flush_icache ++rmdir ++rseq ++rt_sigaction ++rt_sigpending ++rt_sigprocmask ++rt_sigqueueinfo ++rt_sigreturn ++rt_sigsuspend ++rt_sigtimedwait ++rt_sigtimedwait_time64 ++rt_tgsigqueueinfo ++rtas ++s390_guarded_storage ++s390_pci_mmio_read ++s390_pci_mmio_write ++s390_runtime_instr ++s390_sthyi ++sched_get_affinity ++sched_get_priority_max ++sched_get_priority_min ++sched_getaffinity ++sched_getattr ++sched_getparam ++sched_getscheduler ++sched_rr_get_interval ++sched_rr_get_interval_time64 ++sched_set_affinity ++sched_setaffinity ++sched_setattr ++sched_setparam ++sched_setscheduler ++sched_yield ++seccomp ++select ++semctl ++semget ++semop ++semtimedop ++semtimedop_time64 ++send ++sendfile ++sendfile64 ++sendmmsg ++sendmsg ++sendto ++set_mempolicy ++set_robust_list ++set_thread_area ++set_tid_address ++setdomainname ++setfsgid ++setfsgid32 ++setfsuid ++setfsuid32 ++setgid ++setgid32 ++setgroups ++setgroups32 ++sethae ++sethostname ++setitimer ++setns ++setpgid ++setpgrp ++setpriority ++setregid ++setregid32 ++setresgid ++setresgid32 ++setresuid ++setresuid32 ++setreuid ++setreuid32 ++setrlimit ++setsid ++setsockopt ++settimeofday ++setuid ++setuid32 ++setxattr ++sgetmask ++shmat ++shmctl ++shmdt ++shmget ++shutdown ++sigaction ++sigaltstack ++signal ++signalfd ++signalfd4 ++sigpending ++sigprocmask ++sigreturn ++sigsuspend ++socket ++socketcall ++socketpair ++splice ++spu_create ++spu_run ++ssetmask ++stat ++stat64 ++statfs ++statfs64 ++statx ++stime ++subpage_prot ++swapcontext ++swapoff ++swapon ++switch_endian ++symlink ++symlinkat ++sync ++sync_file_range ++sync_file_range2 ++syncfs ++sys_debug_setcontext ++syscall ++sysfs ++sysinfo ++syslog ++sysmips ++tee ++tgkill ++time ++timer_create ++timer_delete ++timer_getoverrun ++timer_gettime ++timer_gettime64 ++timer_settime ++timer_settime64 ++timerfd ++timerfd_create ++timerfd_gettime ++timerfd_gettime64 ++timerfd_settime ++timerfd_settime64 ++times ++tkill ++truncate ++truncate64 ++udftrap ++ugetrlimit ++umask ++umount ++umount2 ++uname ++unlink ++unlinkat ++unshare ++uselib ++userfaultfd ++ustat ++utime ++utimensat ++utimensat_time64 ++utimes ++utimesat ++utrap_install ++vfork ++vhangup ++vm86 ++vm86old ++vmsplice ++wait4 ++waitid ++waitpid ++write ++writev +diff --git a/tools/syscall-names-update.sh b/tools/syscall-names-update.sh +new file mode 100755 +index 0000000000..c884b93cda +--- /dev/null ++++ b/tools/syscall-names-update.sh +@@ -0,0 +1,6 @@ ++#!/bin/sh ++set -eu ++ ++cd "$1" ++ ++curl -L -o syscall-names.text 'https://raw.githubusercontent.com/hrw/syscalls-table/master/syscall-names.text' diff --git a/SOURCES/0812-syscall-names-add-process_madvise-which-is-planned-f.patch b/SOURCES/0812-syscall-names-add-process_madvise-which-is-planned-f.patch new file mode 100644 index 0000000..4bd00ec --- /dev/null +++ b/SOURCES/0812-syscall-names-add-process_madvise-which-is-planned-f.patch @@ -0,0 +1,27 @@ +From bcc0f8bfbc0ea220895c1d3a8bf2d3124ddcef16 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 25 Oct 2020 13:54:20 +0100 +Subject: [PATCH] syscall-names: add process_madvise which is planned for 5.10 + +It was added in v5.9-11793-gecb8ac8b1f and is still present in v5.10-rc1, so it +seems likely that it'll be in 5.10 too. + +(cherry picked from commit 397cca2453465d4ad5a51b16ad71acf45a3de352) + +Related: #2040247 +--- + src/shared/syscall-names.text | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/shared/syscall-names.text b/src/shared/syscall-names.text +index 40d18a8894..f1b7e29d50 100644 +--- a/src/shared/syscall-names.text ++++ b/src/shared/syscall-names.text +@@ -392,6 +392,7 @@ pread64 + preadv + preadv2 + prlimit64 ++process_madvise + process_vm_readv + process_vm_writev + pselect6 diff --git a/SOURCES/0813-shared-add-known-syscall-list.patch b/SOURCES/0813-shared-add-known-syscall-list.patch new file mode 100644 index 0000000..eb4f2f4 --- /dev/null +++ b/SOURCES/0813-shared-add-known-syscall-list.patch @@ -0,0 +1,157 @@ +From f3c6abebbe4718085fcf17ed3ab0690e379fbb7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 19 Aug 2020 17:43:23 +0200 +Subject: [PATCH] shared: add @known syscall list + +(cherry picked from commit 95aac01259db689dac7d8e5bfafb60e8c70cd734) + +Related: #2040247 +--- + man/systemd.exec.xml | 4 ++++ + src/shared/generate-syscall-list.py | 5 +++++ + src/shared/meson.build | 11 +++++++++++ + src/shared/seccomp-util.c | 6 ++++++ + src/shared/seccomp-util.h | 3 ++- + src/test/test-seccomp.c | 19 ++++++++++++------- + 6 files changed, 40 insertions(+), 8 deletions(-) + create mode 100755 src/shared/generate-syscall-list.py + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index dc88cf9781..b04b4ba552 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -1556,6 +1556,10 @@ RestrictNamespaces=~cgroup net + @timer + System calls for scheduling operations by time (alarm2, timer_create2, …) + ++ ++ @known ++ All system calls defined by the kernel. This list is defined statically in systemd based on a kernel version that was available when this systmed version was released. It will become progressively more out-of-date as the kernel is updated. ++ + + +
+diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py +new file mode 100755 +index 0000000000..13a6ae9241 +--- /dev/null ++++ b/src/shared/generate-syscall-list.py +@@ -0,0 +1,5 @@ ++#!/usr/bin/env python ++import sys ++ ++for line in open(sys.argv[1]): ++ print('"{}\\0"'.format(line.strip())) +diff --git a/src/shared/meson.build b/src/shared/meson.build +index c9dd0a3a4e..fed08571d1 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -109,6 +109,16 @@ shared_sources = files(''' + test_tables_h = files('test-tables.h') + shared_sources += [test_tables_h] + ++generate_syscall_list = find_program('generate-syscall-list.py') ++fname = 'syscall-list.h' ++syscall_list_h = custom_target( ++ fname, ++ input : 'syscall-names.text', ++ output : fname, ++ command : [generate_syscall_list, ++ '@INPUT@'], ++ capture : true) ++ + if conf.get('HAVE_ACL') == 1 + shared_sources += files('acl-util.c') + endif +@@ -119,6 +129,7 @@ endif + + if conf.get('HAVE_SECCOMP') == 1 + shared_sources += files('seccomp-util.c') ++ shared_sources += syscall_list_h + endif + + if conf.get('HAVE_LIBIPTC') == 1 +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index c57c409433..c2b2f2da92 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -855,6 +855,12 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { + "timerfd_settime\0" + "times\0" + }, ++ [SYSCALL_FILTER_SET_KNOWN] = { ++ .name = "@known", ++ .help = "All known syscalls declared in the kernel", ++ .value = ++#include "syscall-list.h" ++ }, + }; + + const SyscallFilterSet *syscall_filter_set_find(const char *name) { +diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h +index 602f092255..541ba1e067 100644 +--- a/src/shared/seccomp-util.h ++++ b/src/shared/seccomp-util.h +@@ -21,7 +21,7 @@ typedef struct SyscallFilterSet { + } SyscallFilterSet; + + enum { +- /* Please leave DEFAULT first, but sort the rest alphabetically */ ++ /* Please leave DEFAULT first and KNOWN last, but sort the rest alphabetically */ + SYSCALL_FILTER_SET_DEFAULT, + SYSCALL_FILTER_SET_AIO, + SYSCALL_FILTER_SET_BASIC_IO, +@@ -49,6 +49,7 @@ enum { + SYSCALL_FILTER_SET_SYNC, + SYSCALL_FILTER_SET_SYSTEM_SERVICE, + SYSCALL_FILTER_SET_TIMER, ++ SYSCALL_FILTER_SET_KNOWN, + _SYSCALL_FILTER_SET_MAX + }; + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 6ec04c4c55..286f01b5ce 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -106,8 +106,10 @@ static void test_filter_sets(void) { + if (pid == 0) { /* Child? */ + int fd; + +- /* If we look at the default set (or one that includes it), whitelist instead of blacklist */ +- if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE)) ++ /* If we look at the default set (or one that includes it), allow-list instead of deny-list */ ++ if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, ++ SYSCALL_FILTER_SET_SYSTEM_SERVICE, ++ SYSCALL_FILTER_SET_KNOWN)) + r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true); + else + r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true); +@@ -639,20 +641,23 @@ static void test_lock_personality(void) { + } + + static void test_filter_sets_ordered(void) { +- size_t i; +- + /* Ensure "@default" always remains at the beginning of the list */ + assert_se(SYSCALL_FILTER_SET_DEFAULT == 0); + assert_se(streq(syscall_filter_sets[0].name, "@default")); + +- for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { ++ /* Ensure "@known" always remains at the end of the list */ ++ assert_se(SYSCALL_FILTER_SET_KNOWN == _SYSCALL_FILTER_SET_MAX - 1); ++ assert_se(streq(syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].name, "@known")); ++ ++ for (size_t i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { + const char *k, *p = NULL; + + /* Make sure each group has a description */ + assert_se(!isempty(syscall_filter_sets[0].help)); + +- /* Make sure the groups are ordered alphabetically, except for the first entry */ +- assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0); ++ /* Make sure the groups are ordered alphabetically, except for the first and last entries */ ++ assert_se(i < 2 || i == _SYSCALL_FILTER_SET_MAX - 1 || ++ strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0); + + NULSTR_FOREACH(k, syscall_filter_sets[i].value) { + diff --git a/SOURCES/0814-generate-syscall-list-require-python3.patch b/SOURCES/0814-generate-syscall-list-require-python3.patch new file mode 100644 index 0000000..20891a6 --- /dev/null +++ b/SOURCES/0814-generate-syscall-list-require-python3.patch @@ -0,0 +1,24 @@ +From da722bc383c359b77fab671a0e7872fe4c0232ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 22 Aug 2020 16:07:05 +0200 +Subject: [PATCH] generate-syscall-list: require python3 + +Python3.4 works, but 2.7 returns a tuple from os.uname(). + +(cherry picked from commit 8694114b809f92f6a882134f3635aa42bfb41e11) + +Related: #2040247 +--- + src/shared/generate-syscall-list.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py +index 13a6ae9241..0b90d2d276 100755 +--- a/src/shared/generate-syscall-list.py ++++ b/src/shared/generate-syscall-list.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + import sys + + for line in open(sys.argv[1]): diff --git a/SOURCES/0815-shared-seccomp-reduce-scope-of-indexing-variables.patch b/SOURCES/0815-shared-seccomp-reduce-scope-of-indexing-variables.patch new file mode 100644 index 0000000..afd8d57 --- /dev/null +++ b/SOURCES/0815-shared-seccomp-reduce-scope-of-indexing-variables.patch @@ -0,0 +1,82 @@ +From 64705366e134f06438e88f0b7fbef341d0a01431 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 19 Aug 2020 17:43:40 +0200 +Subject: [PATCH] shared/seccomp: reduce scope of indexing variables + +(cherry picked from commit 077e8fc0cad5a4532348d20a1eef8621295dd75a) + +Related: #2040247 +--- + src/shared/seccomp-util.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index c2b2f2da92..4d2ba31d47 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -864,12 +864,10 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { + }; + + const SyscallFilterSet *syscall_filter_set_find(const char *name) { +- unsigned i; +- + if (isempty(name) || name[0] != '@') + return NULL; + +- for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) ++ for (unsigned i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) + if (streq(syscall_filter_sets[i].name, name)) + return syscall_filter_sets + i; + +@@ -1105,7 +1103,6 @@ int seccomp_restrict_namespaces(unsigned long retain) { + + SECCOMP_FOREACH_LOCAL_ARCH(arch) { + _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; +- unsigned i; + + log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch)); + +@@ -1135,7 +1132,7 @@ int seccomp_restrict_namespaces(unsigned long retain) { + continue; + } + +- for (i = 0; namespace_flag_map[i].name; i++) { ++ for (unsigned i = 0; namespace_flag_map[i].name; i++) { + unsigned long f; + + f = namespace_flag_map[i].flag; +@@ -1288,7 +1285,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + return r; + + if (whitelist) { +- int af, first = 0, last = 0; ++ int first = 0, last = 0; + void *afp; + + /* If this is a whitelist, we first block the address families that are out of range and then +@@ -1296,7 +1293,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + * the set. */ + + SET_FOREACH(afp, address_families, i) { +- af = PTR_TO_INT(afp); ++ int af = PTR_TO_INT(afp); + + if (af <= 0 || af >= af_max()) + continue; +@@ -1350,7 +1347,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + } + + /* Block everything between the first and last entry */ +- for (af = 1; af < af_max(); af++) { ++ for (int af = 1; af < af_max(); af++) { + + if (set_contains(address_families, INT_TO_PTR(af))) + continue; +@@ -1378,7 +1375,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + * checks. */ + + SET_FOREACH(af, address_families, i) { +- + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(EAFNOSUPPORT), diff --git a/SOURCES/0816-shared-syscall-list-filter-out-some-obviously-platfo.patch b/SOURCES/0816-shared-syscall-list-filter-out-some-obviously-platfo.patch new file mode 100644 index 0000000..e061a38 --- /dev/null +++ b/SOURCES/0816-shared-syscall-list-filter-out-some-obviously-platfo.patch @@ -0,0 +1,32 @@ +From 2e33a4ffdd54de1f88c3cd37ca5ace94a637b1dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 19 Aug 2020 17:46:30 +0200 +Subject: [PATCH] shared/syscall-list: filter out some obviously + platform-specific syscalls + +(cherry picked from commit 752fedbea7c02c82287c7ff2a4139f528b3f7ba8) + +Related: #2040247 +--- + src/shared/generate-syscall-list.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py +index 0b90d2d276..030c3feec4 100755 +--- a/src/shared/generate-syscall-list.py ++++ b/src/shared/generate-syscall-list.py +@@ -1,5 +1,14 @@ + #!/usr/bin/env python3 + import sys ++import os ++ ++s390 = 's390' in os.uname().machine ++arm = 'arm' in os.uname().machine + + for line in open(sys.argv[1]): ++ if line.startswith('s390_') and not s390: ++ continue ++ if line.startswith('arm_') and not arm: ++ continue ++ + print('"{}\\0"'.format(line.strip())) diff --git a/SOURCES/0817-seccomp-tighten-checking-of-seccomp-filter-creation.patch b/SOURCES/0817-seccomp-tighten-checking-of-seccomp-filter-creation.patch new file mode 100644 index 0000000..8e297c6 --- /dev/null +++ b/SOURCES/0817-seccomp-tighten-checking-of-seccomp-filter-creation.patch @@ -0,0 +1,123 @@ +From 42ed3377b5817f2c1f84e1bdca301ea51ecc3299 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 20 Sep 2018 14:19:41 +0200 +Subject: [PATCH] seccomp: tighten checking of seccomp filter creation + +In seccomp code, the code is changed to propagate errors which are about +anything other than unknown/unimplemented syscalls. I *think* such errors +should not happen in normal usage, but so far we would summarilly ignore all +errors, so that part is uncertain. If it turns out that other errors occur and +should be ignored, this should be added later. + +In nspawn, we would count the number of added filters, but didn't use this for +anything. Drop that part. + +The comments suggested that seccomp_add_syscall_filter_item() returned negative +if the syscall is unknown, but this wasn't true: it returns 0. + +The error at this point can only be if the syscall was known but couldn't be +added. If the error comes from our internal whitelist in nspawn, treat this as +error, because it means that our internal table is wrong. If the error comes +from user arguments, warn and ignore. (If some syscall is not known at current +architecture, it is still silently ignored.) + +(cherry picked from commit 7e86bd73a47f2b8dd3d9a743e69fb0117f450ad8) + +Related: #2040247 +--- + src/nspawn/nspawn-seccomp.c | 14 +++++--------- + src/shared/seccomp-util.c | 26 ++++++++++++++++---------- + 2 files changed, 21 insertions(+), 19 deletions(-) + +diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c +index fba22644da..17abfcec26 100644 +--- a/src/nspawn/nspawn-seccomp.c ++++ b/src/nspawn/nspawn-seccomp.c +@@ -140,7 +140,7 @@ static int seccomp_add_default_syscall_filter( + */ + }; + +- int r, c = 0; ++ int r; + size_t i; + char **p; + +@@ -150,21 +150,17 @@ static int seccomp_add_default_syscall_filter( + + r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false); + if (r < 0) +- /* If the system call is not known on this architecture, then that's fine, let's ignore it */ +- log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", whitelist[i].name, seccomp_arch_to_string(arch)); +- else +- c++; ++ return log_error_errno(r, "Failed to add syscall filter item %s: %m", whitelist[i].name); + } + + STRV_FOREACH(p, syscall_whitelist) { + r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false); + if (r < 0) +- log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch)); +- else +- c++; ++ log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", ++ *p, seccomp_arch_to_string(arch)); + } + +- return c; ++ return 0; + } + + int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **syscall_blacklist) { +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index 4d2ba31d47..710a734715 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -907,9 +907,13 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, + r = seccomp_rule_add_exact(seccomp, action, id, 0); + if (r < 0) { + /* If the system call is not known on this architecture, then that's fine, let's ignore it */ +- if (log_missing) +- log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", +- name, id); ++ bool ignore = r == -EDOM; ++ ++ if (!ignore || log_missing) ++ log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m", ++ name, id, ignore ? ", ignoring" : ""); ++ if (!ignore) ++ return r; + } + + return 0; +@@ -957,10 +961,8 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter + return r; + + r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing); +- if (r < 0) { +- log_debug_errno(r, "Failed to add filter set, ignoring: %m"); +- continue; +- } ++ if (r < 0) ++ return log_debug_errno(r, "Failed to add filter set: %m"); + + r = seccomp_load(seccomp); + if (IN_SET(r, -EPERM, -EACCES)) +@@ -1005,11 +1007,15 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u + if (r < 0) { + /* If the system call is not known on this architecture, then that's fine, let's ignore it */ + _cleanup_free_ char *n = NULL; ++ bool ignore; + + n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id); +- if (log_missing) +- log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", +- strna(n), id); ++ ignore = r == -EDOM; ++ if (!ignore || log_missing) ++ log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m", ++ strna(n), id, ignore ? ", ignoring" : ""); ++ if (!ignore) ++ return r; + } + } + diff --git a/SOURCES/0818-shared-seccomp-util-added-functionality-to-make-list.patch b/SOURCES/0818-shared-seccomp-util-added-functionality-to-make-list.patch new file mode 100644 index 0000000..6dcde52 --- /dev/null +++ b/SOURCES/0818-shared-seccomp-util-added-functionality-to-make-list.patch @@ -0,0 +1,156 @@ +From eaad892c513806801e3d2055788fa202372b3f15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 21 Aug 2020 17:21:04 +0200 +Subject: [PATCH] shared/seccomp-util: added functionality to make list of + filtred syscalls + +While at it, start removing the "seccomp_" prefix from our +own functions. It is used by libseccomp. + +(cherry picked from commit 000c05207d68658b76af9e1caf9aa3a4e3fa697b) + +Related: #2040247 +--- + src/nspawn/nspawn-seccomp.c | 9 +++++++-- + src/shared/seccomp-util.c | 39 ++++++++++++++++++++++++++++++------- + src/shared/seccomp-util.h | 8 +++++++- + 3 files changed, 46 insertions(+), 10 deletions(-) + +diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c +index 17abfcec26..2b4a65e875 100644 +--- a/src/nspawn/nspawn-seccomp.c ++++ b/src/nspawn/nspawn-seccomp.c +@@ -148,13 +148,18 @@ static int seccomp_add_default_syscall_filter( + if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0) + continue; + +- r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false); ++ r = seccomp_add_syscall_filter_item(ctx, ++ whitelist[i].name, ++ SCMP_ACT_ALLOW, ++ syscall_blacklist, ++ false, ++ NULL); + if (r < 0) + return log_error_errno(r, "Failed to add syscall filter item %s: %m", whitelist[i].name); + } + + STRV_FOREACH(p, syscall_whitelist) { +- r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false); ++ r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false, NULL); + if (r < 0) + log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", + *p, seccomp_arch_to_string(arch)); +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index 710a734715..56075d92e0 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -874,15 +874,31 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name) { + return NULL; + } + +-static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, bool log_missing); ++static int add_syscall_filter_set( ++ scmp_filter_ctx seccomp, ++ const SyscallFilterSet *set, ++ uint32_t action, ++ char **exclude, ++ bool log_missing, ++ char ***added); ++ ++int seccomp_add_syscall_filter_item( ++ scmp_filter_ctx *seccomp, ++ const char *name, ++ uint32_t action, ++ char **exclude, ++ bool log_missing, ++ char ***added) { + +-int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude, bool log_missing) { + assert(seccomp); + assert(name); + + if (strv_contains(exclude, name)) + return 0; + ++ /* Any syscalls that are handled are added to the *added strv. The pointer ++ * must be either NULL or point to a valid pre-initialized possibly-empty strv. */ ++ + if (name[0] == '@') { + const SyscallFilterSet *other; + +@@ -892,7 +908,7 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, + return -EINVAL; + } + +- return seccomp_add_syscall_filter_set(seccomp, other, action, exclude, log_missing); ++ return add_syscall_filter_set(seccomp, other, action, exclude, log_missing, added); + + } else { + int id, r; +@@ -916,25 +932,34 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, + return r; + } + ++ if (added) { ++ r = strv_extend(added, name); ++ if (r < 0) ++ return r; ++ } ++ + return 0; + } + } + +-static int seccomp_add_syscall_filter_set( ++static int add_syscall_filter_set( + scmp_filter_ctx seccomp, + const SyscallFilterSet *set, + uint32_t action, + char **exclude, +- bool log_missing) { ++ bool log_missing, ++ char ***added) { + + const char *sys; + int r; + ++ /* Any syscalls that are handled are added to the *added strv. It needs to be initialized. */ ++ + assert(seccomp); + assert(set); + + NULSTR_FOREACH(sys, set->value) { +- r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing); ++ r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing, added); + if (r < 0) + return r; + } +@@ -960,7 +985,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter + if (r < 0) + return r; + +- r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing); ++ r = add_syscall_filter_set(seccomp, set, action, NULL, log_missing, NULL); + if (r < 0) + return log_debug_errno(r, "Failed to add filter set: %m"); + +diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h +index 541ba1e067..291b2bffe0 100644 +--- a/src/shared/seccomp-util.h ++++ b/src/shared/seccomp-util.h +@@ -59,7 +59,13 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name); + + int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); + +-int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude, bool log_missing); ++int seccomp_add_syscall_filter_item( ++ scmp_filter_ctx *ctx, ++ const char *name, ++ uint32_t action, ++ char **exclude, ++ bool log_missing, ++ char ***added); + + int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing); + int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing); diff --git a/SOURCES/0819-nspawn-return-ENOSYS-by-default-EPERM-for-known-call.patch b/SOURCES/0819-nspawn-return-ENOSYS-by-default-EPERM-for-known-call.patch new file mode 100644 index 0000000..7b29f41 --- /dev/null +++ b/SOURCES/0819-nspawn-return-ENOSYS-by-default-EPERM-for-known-call.patch @@ -0,0 +1,77 @@ +From 65d64ba146c30a5f205b650381f331fd8db2eb22 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 21 Aug 2020 17:23:48 +0200 +Subject: [PATCH] nspawn: return ENOSYS by default, EPERM for "known" calls + +(cherry picked from commit 3573e032f26724949e86626eace058d006b8bf70) + +Resolves: #2040247 +--- + src/nspawn/nspawn-seccomp.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c +index 2b4a65e875..563cda140e 100644 +--- a/src/nspawn/nspawn-seccomp.c ++++ b/src/nspawn/nspawn-seccomp.c +@@ -20,7 +20,7 @@ + + #if HAVE_SECCOMP + +-static int seccomp_add_default_syscall_filter( ++static int add_syscall_filters( + scmp_filter_ctx ctx, + uint32_t arch, + uint64_t cap_list_retain, +@@ -140,6 +140,7 @@ static int seccomp_add_default_syscall_filter( + */ + }; + ++ _cleanup_strv_free_ char **added = NULL; + int r; + size_t i; + char **p; +@@ -153,18 +154,25 @@ static int seccomp_add_default_syscall_filter( + SCMP_ACT_ALLOW, + syscall_blacklist, + false, +- NULL); ++ &added); + if (r < 0) + return log_error_errno(r, "Failed to add syscall filter item %s: %m", whitelist[i].name); + } + + STRV_FOREACH(p, syscall_whitelist) { +- r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false, NULL); ++ r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, true, &added); + if (r < 0) + log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", + *p, seccomp_arch_to_string(arch)); + } + ++ /* The default action is ENOSYS. Respond with EPERM to all other "known" but not allow-listed ++ * syscalls. */ ++ r = seccomp_add_syscall_filter_item(ctx, "@known", SCMP_ACT_ERRNO(EPERM), added, true, NULL); ++ if (r < 0) ++ log_warning_errno(r, "Failed to add rule for @known set on %s, ignoring: %m", ++ seccomp_arch_to_string(arch)); ++ + return 0; + } + +@@ -182,11 +190,13 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **sys + + log_debug("Applying whitelist on architecture: %s", seccomp_arch_to_string(arch)); + +- r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(EPERM)); ++ /* We install ENOSYS as the default action, but it will only apply to syscalls which are not ++ * in the @known set, see above. */ ++ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(ENOSYS)); + if (r < 0) + return log_error_errno(r, "Failed to allocate seccomp object: %m"); + +- r = seccomp_add_default_syscall_filter(seccomp, arch, cap_list_retain, syscall_whitelist, syscall_blacklist); ++ r = add_syscall_filters(seccomp, arch, cap_list_retain, syscall_whitelist, syscall_blacklist); + if (r < 0) + return r; + diff --git a/SOURCES/0820-test-procfs-util-skip-test-on-certain-errors.patch b/SOURCES/0820-test-procfs-util-skip-test-on-certain-errors.patch new file mode 100644 index 0000000..55ece1d --- /dev/null +++ b/SOURCES/0820-test-procfs-util-skip-test-on-certain-errors.patch @@ -0,0 +1,75 @@ +From 33305c6801c10b741b11a3f329dc339d2e8c5514 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 18 Aug 2022 16:35:23 +0200 +Subject: [PATCH] test-procfs-util: skip test on certain errors + +Inspired by upstream bf47f71c1c + +RHEL-only +Related: #2087152 +--- + src/shared/tests.c | 12 ++++++++++++ + src/shared/tests.h | 2 ++ + src/test/test-procfs-util.c | 6 ++++-- + 3 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 1da80d653f..b1c71b992f 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -78,6 +78,18 @@ void test_setup_logging(int level) { + log_open(); + } + ++int log_tests_skipped(const char *message) { ++ log_notice("%s: %s, skipping tests.", ++ program_invocation_short_name, message); ++ return EXIT_TEST_SKIP; ++} ++ ++int log_tests_skipped_errno(int r, const char *message) { ++ log_notice_errno(r, "%s: %s, skipping tests: %m", ++ program_invocation_short_name, message); ++ return EXIT_TEST_SKIP; ++} ++ + const char *ci_environment(void) { + /* We return a string because we might want to provide multiple bits of information later on: not + * just the general CI environment type, but also whether we're sanitizing or not, etc. The caller is +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 4f8f349097..d50711338c 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -5,6 +5,8 @@ char* setup_fake_runtime_dir(void); + bool test_is_running_from_builddir(char **exedir); + const char* get_testdata_dir(void); + void test_setup_logging(int level); ++int log_tests_skipped(const char *message); ++int log_tests_skipped_errno(int r, const char *message); + + /* Provide a convenient way to check if we're running in CI. */ + const char *ci_environment(void); +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index d656c4df4f..aba5692e54 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -7,6 +7,7 @@ + #include "procfs-util.h" + #include "process-util.h" + #include "util.h" ++#include "tests.h" + + int main(int argc, char *argv[]) { + char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_BYTES_MAX)]; +@@ -52,8 +53,9 @@ int main(int argc, char *argv[]) { + log_info("Reducing limit by one to %"PRIu64"…", v-1); + + r = procfs_tasks_set_limit(v-1); +- log_info_errno(r, "procfs_tasks_set_limit: %m"); +- assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS); ++ if (IN_SET(r, -ENOENT, -EROFS) || ERRNO_IS_PRIVILEGE(r)) ++ return log_tests_skipped_errno(r, "can't set tasks limit"); ++ assert_se(r >= 0); + + assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(r >= 0 ? w == v - 1 : w == v); diff --git a/SOURCES/0821-Try-stopping-MD-RAID-devices-in-shutdown-too.patch b/SOURCES/0821-Try-stopping-MD-RAID-devices-in-shutdown-too.patch new file mode 100644 index 0000000..bea238f --- /dev/null +++ b/SOURCES/0821-Try-stopping-MD-RAID-devices-in-shutdown-too.patch @@ -0,0 +1,292 @@ +From c7532112a37ffdd3cc9851ae04fdcb543b99ed1c Mon Sep 17 00:00:00 2001 +From: Hubert Kario +Date: Sun, 20 Sep 2020 18:59:58 +0200 +Subject: [PATCH] Try stopping MD RAID devices in shutdown too + +Currently the systemd-shutdown command attempts to stop swaps, DM +(crypt, LVM2) and loop devices, but it doesn't attempt to stop MD +RAID devices, which means that if the RAID is set up on crypt, +loop, etc. device, it won't be able to stop those underlying devices. + +This code extends the shutdown application to also attempt stopping +the MD RAID devices. + +Signed-off-by: Hubert Kario +(cherry picked from commit 0b220a5f2a31844eaa1f5426bab02d41d54f471c) + +Resolves: #1817706 +--- + src/core/shutdown.c | 37 +++++++++---- + src/core/umount.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ + src/core/umount.h | 2 + + 3 files changed, 154 insertions(+), 10 deletions(-) + +diff --git a/src/core/shutdown.c b/src/core/shutdown.c +index 038345b752..b8a983986a 100644 +--- a/src/core/shutdown.c ++++ b/src/core/shutdown.c +@@ -251,7 +251,7 @@ static void sync_with_progress(void) { + } + + int main(int argc, char *argv[]) { +- bool need_umount, need_swapoff, need_loop_detach, need_dm_detach; ++ bool need_umount, need_swapoff, need_loop_detach, need_dm_detach, need_md_detach; + bool in_container, use_watchdog = false, can_initrd; + _cleanup_free_ char *cgroup = NULL; + char *arguments[3]; +@@ -331,6 +331,7 @@ int main(int argc, char *argv[]) { + need_swapoff = !in_container; + need_loop_detach = !in_container; + need_dm_detach = !in_container; ++ need_md_detach = !in_container; + can_initrd = !in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) == 0; + + /* Unmount all mountpoints, swaps, and loopback devices */ +@@ -383,6 +384,18 @@ int main(int argc, char *argv[]) { + log_error_errno(r, "Failed to detach loop devices: %m"); + } + ++ if (need_md_detach) { ++ log_info("Stopping MD devices."); ++ r = md_detach_all(&changed, umount_log_level); ++ if (r == 0) { ++ need_md_detach = false; ++ log_info("All MD devices stopped."); ++ } else if (r > 0) ++ log_info("Not all MD devices stopped, %d left.", r); ++ else ++ log_error_errno(r, "Failed to stop MD devices: %m"); ++ } ++ + if (need_dm_detach) { + log_info("Detaching DM devices."); + r = dm_detach_all(&changed, umount_log_level); +@@ -395,8 +408,9 @@ int main(int argc, char *argv[]) { + log_error_errno(r, "Failed to detach DM devices: %m"); + } + +- if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) { +- log_info("All filesystems, swaps, loop devices and DM devices detached."); ++ if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach ++ && !need_md_detach) { ++ log_info("All filesystems, swaps, loop devices, MD devices and DM devices detached."); + /* Yay, done */ + break; + } +@@ -414,19 +428,21 @@ int main(int argc, char *argv[]) { + /* If in this iteration we didn't manage to + * unmount/deactivate anything, we simply give up */ + if (!changed) { +- log_info("Cannot finalize remaining%s%s%s%s continuing.", ++ log_info("Cannot finalize remaining%s%s%s%s%s continuing.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + break; + } + +- log_debug("Couldn't finalize remaining %s%s%s%s trying again.", ++ log_debug("Couldn't finalize remaining %s%s%s%s%s trying again.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + } + + /* We're done with the watchdog. */ +@@ -455,12 +471,13 @@ int main(int argc, char *argv[]) { + + } + +- if (need_umount || need_swapoff || need_loop_detach || need_dm_detach) +- log_error("Failed to finalize %s%s%s%s ignoring", ++ if (need_umount || need_swapoff || need_loop_detach || need_dm_detach || need_md_detach) ++ log_error("Failed to finalize%s%s%s%s%s ignoring.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + + /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be + * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we +diff --git a/src/core/umount.c b/src/core/umount.c +index 3f02bf141a..ed90c6b1fc 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -5,6 +5,8 @@ + + #include + #include ++#include ++#include + #include + #include + #include +@@ -332,6 +334,66 @@ static int dm_list_get(MountPoint **head) { + return 0; + } + ++static int md_list_get(MountPoint **head) { ++ _cleanup_(udev_enumerate_unrefp) struct udev_enumerate *e = NULL; ++ struct udev_list_entry *item = NULL, *first = NULL; ++ _cleanup_(udev_unrefp) struct udev *udev = NULL; ++ int r; ++ ++ assert(head); ++ ++ udev = udev_new(); ++ if (!udev) ++ return -ENOMEM; ++ ++ e = udev_enumerate_new(udev); ++ if (!e) ++ return -ENOMEM; ++ ++ r = udev_enumerate_add_match_subsystem(e, "block"); ++ if (r < 0) ++ return r; ++ ++ r = udev_enumerate_add_match_sysname(e, "md*"); ++ if (r < 0) ++ return r; ++ ++ first = udev_enumerate_get_list_entry(e); ++ udev_list_entry_foreach(item, first) { ++ _cleanup_(udev_device_unrefp) struct udev_device *d; ++ _cleanup_free_ char *p = NULL; ++ const char *dn; ++ MountPoint *m; ++ dev_t devnum; ++ ++ d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); ++ if (!d) ++ return -ENOMEM; ++ ++ devnum = udev_device_get_devnum(d); ++ dn = udev_device_get_devnode(d); ++ if (major(devnum) == 0 || !dn) ++ continue; ++ ++ p = strdup(dn); ++ if (!p) ++ return -ENOMEM; ++ ++ m = new(MountPoint, 1); ++ if (!m) ++ return -ENOMEM; ++ ++ *m = (MountPoint) { ++ .path = TAKE_PTR(p), ++ .devnum = devnum, ++ }; ++ ++ LIST_PREPEND(mount_point, *head, m); ++ } ++ ++ return 0; ++} ++ + static int delete_loopback(const char *device) { + _cleanup_close_ int fd = -1; + int r; +@@ -379,6 +441,23 @@ static int delete_dm(dev_t devnum) { + return 0; + } + ++static int delete_md(MountPoint *m) { ++ ++ _cleanup_close_ int fd = -1; ++ ++ assert(major(m->devnum) != 0); ++ assert(m->path != 0); ++ ++ fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL); ++ if (fd < 0) ++ return -errno; ++ ++ if (ioctl(fd, STOP_ARRAY, NULL) < 0) ++ return -errno; ++ ++ return 0; ++} ++ + static bool nonunmountable_path(const char *path) { + return path_equal(path, "/") + #if ! HAVE_SPLIT_USR +@@ -618,6 +697,37 @@ static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_lo + return n_failed; + } + ++static int md_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) { ++ MountPoint *m, *n; ++ int n_failed = 0, r; ++ dev_t rootdev = 0; ++ ++ assert(head); ++ assert(changed); ++ ++ (void) get_block_device("/", &rootdev); ++ ++ LIST_FOREACH_SAFE(mount_point, m, n, *head) { ++ if (major(rootdev) != 0 && rootdev == m->devnum) { ++ n_failed ++; ++ continue; ++ } ++ ++ log_info("Stopping MD %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum)); ++ r = delete_md(m); ++ if (r < 0) { ++ log_full_errno(umount_log_level, r, "Could not stop MD %s: %m", m->path); ++ n_failed++; ++ continue; ++ } ++ ++ *changed = true; ++ mount_point_free(head, m); ++ } ++ ++ return n_failed; ++} ++ + static int umount_all_once(bool *changed, int umount_log_level) { + int r; + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); +@@ -696,3 +806,18 @@ int dm_detach_all(bool *changed, int umount_log_level) { + + return dm_points_list_detach(&dm_list_head, changed, umount_log_level); + } ++ ++int md_detach_all(bool *changed, int umount_log_level) { ++ _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, md_list_head); ++ int r; ++ ++ assert(changed); ++ ++ LIST_HEAD_INIT(md_list_head); ++ ++ r = md_list_get(&md_list_head); ++ if (r < 0) ++ return r; ++ ++ return md_points_list_detach(&md_list_head, changed, umount_log_level); ++} +diff --git a/src/core/umount.h b/src/core/umount.h +index 6f2b24d195..b01062484f 100644 +--- a/src/core/umount.h ++++ b/src/core/umount.h +@@ -15,6 +15,8 @@ int loopback_detach_all(bool *changed, int umount_log_level); + + int dm_detach_all(bool *changed, int umount_log_level); + ++int md_detach_all(bool *changed, int umount_log_level); ++ + /* This is exported just for testing */ + typedef struct MountPoint { + char *path; diff --git a/SOURCES/0822-shutdown-get-only-active-md-arrays.patch b/SOURCES/0822-shutdown-get-only-active-md-arrays.patch new file mode 100644 index 0000000..9bd3ce2 --- /dev/null +++ b/SOURCES/0822-shutdown-get-only-active-md-arrays.patch @@ -0,0 +1,70 @@ +From ebb3e759bba99ea85b3be9608258d6a5bb7e907a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 29 Mar 2022 12:49:54 +0200 +Subject: [PATCH] shutdown: get only active md arrays. + +Current md_list_get() implementation filters all block devices, started from +"md*". This is ambiguous because list could contain: +- partitions created upon md device (mdXpY) +- external metadata container- specific type of md array. + +For partitions there is no issue, because they aren't handle STOP_ARRAY +ioctl sent later. It generates misleading errors only. + +Second case is more problematic because containers are not locked in kernel. +They are stopped even if container member array is active. For that reason +reboot or shutdown flow could be blocked because metadata manager cannot be +restarted after switch root on shutdown. + +Add filters to remove partitions and containers from md_list. Partitions +can be excluded by DEVTYPE. Containers are determined by MD_LEVEL +property, we are excluding all with "container" value. + +Signed-off-by: Mariusz Tkaczyk +(cherry picked from commit 3a3b022d2cc112803ea7b9beea98bbcad110368a) + +Related: #1817706 +--- + src/core/umount.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/core/umount.c b/src/core/umount.c +index ed90c6b1fc..b513e91c4d 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -358,11 +358,16 @@ static int md_list_get(MountPoint **head) { + if (r < 0) + return r; + ++ /* Filter out partitions. */ ++ r = udev_enumerate_add_match_property(e, "DEVTYPE", "disk"); ++ if (r < 0) ++ return r; ++ + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + _cleanup_(udev_device_unrefp) struct udev_device *d; + _cleanup_free_ char *p = NULL; +- const char *dn; ++ const char *dn, *md_level; + MountPoint *m; + dev_t devnum; + +@@ -375,6 +380,17 @@ static int md_list_get(MountPoint **head) { + if (major(devnum) == 0 || !dn) + continue; + ++ md_level = udev_device_get_property_value(d, "MD_LEVEL"); ++ if (!m) { ++ log_warning("Failed to get MD_LEVEL property for %s, ignoring", dn); ++ continue; ++ } ++ ++ /* MD "containers" are a special type of MD devices, used for external metadata. ++ * Since it doesn't provide RAID functionality in itself we don't need to stop it. */ ++ if (streq(md_level, "container")) ++ continue; ++ + p = strdup(dn); + if (!p) + return -ENOMEM; diff --git a/SOURCES/0823-scope-allow-unprivileged-delegation-on-scopes.patch b/SOURCES/0823-scope-allow-unprivileged-delegation-on-scopes.patch new file mode 100644 index 0000000..a62f3bc --- /dev/null +++ b/SOURCES/0823-scope-allow-unprivileged-delegation-on-scopes.patch @@ -0,0 +1,347 @@ +From 5b5571de21d1ddf9a00511a6b2f25d630a903f05 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 1 Jun 2022 10:15:06 +0200 +Subject: [PATCH] scope: allow unprivileged delegation on scopes + +Previously it was possible to set delegate property for scope, but you +were not able to allow unprivileged process to manage the scope's cgroup +hierarchy. This is useful when launching manager process that will run +unprivileged but is supposed to manage its own (scope) sub-hierarchy. + +Fixes #21683 + +(cherry picked from commit 03860190fefce8bbea3a6f0e77919b882ade517c) + +Resolves: #2068575 +--- + src/basic/unit-def.c | 1 + + src/basic/unit-def.h | 1 + + src/core/dbus-scope.c | 6 ++ + src/core/scope.c | 135 +++++++++++++++++++++++++---- + src/core/scope.h | 3 + + src/shared/bus-unit-util.c | 5 ++ + test/TEST-19-DELEGATE/testsuite.sh | 13 +++ + 7 files changed, 145 insertions(+), 19 deletions(-) + +diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c +index e79cc73dd3..16c4d38d41 100644 +--- a/src/basic/unit-def.c ++++ b/src/basic/unit-def.c +@@ -160,6 +160,7 @@ DEFINE_STRING_TABLE_LOOKUP(path_state, PathState); + + static const char* const scope_state_table[_SCOPE_STATE_MAX] = { + [SCOPE_DEAD] = "dead", ++ [SCOPE_START_CHOWN] = "start-chown", + [SCOPE_RUNNING] = "running", + [SCOPE_ABANDONED] = "abandoned", + [SCOPE_STOP_SIGTERM] = "stop-sigterm", +diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h +index 8eea379a6d..03d151ec19 100644 +--- a/src/basic/unit-def.h ++++ b/src/basic/unit-def.h +@@ -99,6 +99,7 @@ typedef enum PathState { + + typedef enum ScopeState { + SCOPE_DEAD, ++ SCOPE_START_CHOWN, + SCOPE_RUNNING, + SCOPE_ABANDONED, + SCOPE_STOP_SIGTERM, +diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c +index 0bbf64fff1..534302d188 100644 +--- a/src/core/dbus-scope.c ++++ b/src/core/dbus-scope.c +@@ -178,6 +178,12 @@ int bus_scope_set_property( + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error); + if (r != 0) + return r; ++ ++ if (streq(name, "User")) ++ return bus_set_transient_user_relaxed(u, name, &s->user, message, flags, error); ++ ++ if (streq(name, "Group")) ++ return bus_set_transient_user_relaxed(u, name, &s->group, message, flags, error); + } + + return 0; +diff --git a/src/core/scope.c b/src/core/scope.c +index 5a595c65a6..9cc5f89099 100644 +--- a/src/core/scope.c ++++ b/src/core/scope.c +@@ -5,6 +5,8 @@ + + #include "alloc-util.h" + #include "dbus-scope.h" ++#include "dbus-unit.h" ++#include "exit-status.h" + #include "load-dropin.h" + #include "log.h" + #include "scope.h" +@@ -14,9 +16,11 @@ + #include "strv.h" + #include "unit-name.h" + #include "unit.h" ++#include "user-util.h" + + static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = { + [SCOPE_DEAD] = UNIT_INACTIVE, ++ [SCOPE_START_CHOWN] = UNIT_ACTIVATING, + [SCOPE_RUNNING] = UNIT_ACTIVE, + [SCOPE_ABANDONED] = UNIT_ACTIVE, + [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING, +@@ -34,6 +38,7 @@ static void scope_init(Unit *u) { + + s->timeout_stop_usec = u->manager->default_timeout_stop_usec; + u->ignore_on_isolate = true; ++ s->user = s->group = NULL; + } + + static void scope_done(Unit *u) { +@@ -45,6 +50,9 @@ static void scope_done(Unit *u) { + s->controller_track = sd_bus_track_unref(s->controller_track); + + s->timer_event_source = sd_event_source_unref(s->timer_event_source); ++ ++ s->user = mfree(s->user); ++ s->group = mfree(s->group); + } + + static int scope_arm_timer(Scope *s, usec_t usec) { +@@ -84,7 +92,7 @@ static void scope_set_state(Scope *s, ScopeState state) { + old_state = s->state; + s->state = state; + +- if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL)) ++ if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL, SCOPE_START_CHOWN)) + s->timer_event_source = sd_event_source_unref(s->timer_event_source); + + if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED)) { +@@ -301,26 +309,72 @@ fail: + scope_enter_dead(s, SCOPE_FAILURE_RESOURCES); + } + +-static int scope_start(Unit *u) { +- Scope *s = SCOPE(u); ++static int scope_enter_start_chown(Scope *s) { ++ Unit *u = UNIT(s); ++ pid_t pid; + int r; + + assert(s); ++ assert(s->user); + +- if (unit_has_name(u, SPECIAL_INIT_SCOPE)) +- return -EPERM; ++ r = scope_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), u->manager->default_timeout_start_usec)); ++ if (r < 0) ++ return r; + +- if (s->state == SCOPE_FAILED) +- return -EPERM; ++ r = unit_fork_helper_process(u, "(sd-chown-cgroup)", &pid); ++ if (r < 0) ++ goto fail; + +- /* We can't fulfill this right now, please try again later */ +- if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL)) +- return -EAGAIN; ++ if (r == 0) { ++ uid_t uid = UID_INVALID; ++ gid_t gid = GID_INVALID; + +- assert(s->state == SCOPE_DEAD); ++ if (!isempty(s->user)) { ++ const char *user = s->user; + +- if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) +- return -ENOENT; ++ r = get_user_creds(&user, &uid, &gid, NULL, NULL); ++ if (r < 0) { ++ log_unit_error_errno(UNIT(s), r, "Failed to resolve user \"%s\": %m", user); ++ _exit(EXIT_USER); ++ } ++ } ++ ++ if (!isempty(s->group)) { ++ const char *group = s->group; ++ ++ r = get_group_creds(&group, &gid); ++ if (r < 0) { ++ log_unit_error_errno(UNIT(s), r, "Failed to resolve group \"%s\": %m", group); ++ _exit(EXIT_GROUP); ++ } ++ } ++ ++ r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, uid, gid); ++ if (r < 0) { ++ log_unit_error_errno(UNIT(s), r, "Failed to adjust control group access: %m"); ++ _exit(EXIT_CGROUP); ++ } ++ ++ _exit(EXIT_SUCCESS); ++ } ++ ++ r = unit_watch_pid(UNIT(s), pid, true); ++ if (r < 0) ++ goto fail; ++ ++ scope_set_state(s, SCOPE_START_CHOWN); ++ ++ return 1; ++fail: ++ s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source); ++ return r; ++} ++ ++static int scope_enter_running(Scope *s) { ++ Unit *u = UNIT(s); ++ int r; ++ ++ assert(s); + + (void) bus_scope_track_controller(s); + +@@ -328,11 +382,7 @@ static int scope_start(Unit *u) { + if (r < 0) + return r; + +- (void) unit_realize_cgroup(u); +- (void) unit_reset_cpu_accounting(u); +- (void) unit_reset_ip_accounting(u); +- +- unit_export_state_files(UNIT(s)); ++ unit_export_state_files(u); + + r = unit_attach_pids_to_cgroup(u, UNIT(s)->pids, NULL); + if (r < 0) { +@@ -350,6 +400,38 @@ static int scope_start(Unit *u) { + return 1; + } + ++static int scope_start(Unit *u) { ++ Scope *s = SCOPE(u); ++ ++ assert(s); ++ ++ if (unit_has_name(u, SPECIAL_INIT_SCOPE)) ++ return -EPERM; ++ ++ if (s->state == SCOPE_FAILED) ++ return -EPERM; ++ ++ /* We can't fulfill this right now, please try again later */ ++ if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL)) ++ return -EAGAIN; ++ ++ assert(s->state == SCOPE_DEAD); ++ ++ if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) ++ return -ENOENT; ++ ++ (void) unit_realize_cgroup(u); ++ (void) unit_reset_cpu_accounting(u); ++ (void) unit_reset_ip_accounting(u); ++ ++ /* We check only for User= option to keep behavior consistent with logic for service units, ++ * i.e. having 'Delegate=true Group=foo' w/o specifing User= has no effect. */ ++ if (s->user && unit_cgroup_delegate(u)) ++ return scope_enter_start_chown(s); ++ ++ return scope_enter_running(s); ++} ++ + static int scope_stop(Unit *u) { + Scope *s = SCOPE(u); + +@@ -462,7 +544,17 @@ static void scope_notify_cgroup_empty_event(Unit *u) { + } + + static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) { +- assert(u); ++ Scope *s = SCOPE(u); ++ ++ assert(s); ++ ++ if (s->state == SCOPE_START_CHOWN) { ++ if (!is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL)) ++ scope_enter_dead(s, SCOPE_FAILURE_RESOURCES); ++ else ++ scope_enter_running(s); ++ return; ++ } + + /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to + * watch, under the assumption that we'll sooner or later get a SIGCHLD for them, as the original +@@ -495,6 +587,11 @@ static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *user + scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT); + break; + ++ case SCOPE_START_CHOWN: ++ log_unit_warning(UNIT(s), "User lookup timed out. Entering failed state."); ++ scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT); ++ break; ++ + default: + assert_not_reached("Timeout at wrong time."); + } +diff --git a/src/core/scope.h b/src/core/scope.h +index c38afb5e5d..7bed3eed9e 100644 +--- a/src/core/scope.h ++++ b/src/core/scope.h +@@ -32,6 +32,9 @@ struct Scope { + bool was_abandoned; + + sd_event_source *timer_event_source; ++ ++ char *user; ++ char *group; + }; + + extern const UnitVTable scope_vtable; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index 3910dfa812..c475bbafe0 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -1615,6 +1615,11 @@ static int bus_append_unit_property(sd_bus_message *m, const char *field, const + + return bus_append_parse_sec_rename(m, field, eq); + ++ /* Scope units don't have execution context but we still want to allow setting these two, ++ * so let's handle them separately. */ ++ if (STR_IN_SET(field, "User", "Group")) ++ return bus_append_string(m, field, eq); ++ + if (streq(field, "StartLimitBurst")) + + return bus_append_safe_atou(m, field, eq); +diff --git a/test/TEST-19-DELEGATE/testsuite.sh b/test/TEST-19-DELEGATE/testsuite.sh +index c738bea10e..c4c948cc11 100755 +--- a/test/TEST-19-DELEGATE/testsuite.sh ++++ b/test/TEST-19-DELEGATE/testsuite.sh +@@ -4,6 +4,16 @@ + set -ex + set -o pipefail + ++test_scope_unpriv_delegation() { ++ useradd test ||: ++ trap "userdel -r test" RETURN ++ ++ systemd-run --uid=test -p User=test -p Delegate=yes --slice workload.slice --unit workload0.scope --scope \ ++ test -w /sys/fs/cgroup/workload.slice/workload0.scope -a \ ++ -w /sys/fs/cgroup/workload.slice/workload0.scope/cgroup.procs -a \ ++ -w /sys/fs/cgroup/workload.slice/workload0.scope/cgroup.subtree_control ++} ++ + if grep -q cgroup2 /proc/filesystems ; then + systemd-run --wait --unit=test0.service -p "DynamicUser=1" -p "Delegate=" \ + test -w /sys/fs/cgroup/system.slice/test0.service/ -a \ +@@ -15,6 +25,9 @@ if grep -q cgroup2 /proc/filesystems ; then + + systemd-run --wait --unit=test2.service -p "DynamicUser=1" -p "Delegate=memory pids" \ + grep pids /sys/fs/cgroup/system.slice/test2.service/cgroup.controllers ++ ++ # Check that unprivileged delegation works for scopes ++ test_scope_unpriv_delegation + else + echo "Skipping TEST-19-DELEGATE, as the kernel doesn't actually support cgroupsv2" >&2 + fi diff --git a/SOURCES/0824-resolved-pin-stream-while-calling-callbacks-for-it.patch b/SOURCES/0824-resolved-pin-stream-while-calling-callbacks-for-it.patch new file mode 100644 index 0000000..9b60e51 --- /dev/null +++ b/SOURCES/0824-resolved-pin-stream-while-calling-callbacks-for-it.patch @@ -0,0 +1,39 @@ +From 3f3b00c8753fb591a4cd7b770ce069d455dcc4d6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 4 Dec 2018 22:13:39 +0100 +Subject: [PATCH] resolved: pin stream while calling callbacks for it + +These callbacks might unref the stream, but we still have to access it, +let's hence ref it explicitly. + +Maybe fixes: #10725 + +(cherry picked from commit d973d94dec349fb676fdd844f6fe2ada3538f27c) + +Resolves: #2110549 +--- + src/resolve/resolved-dns-stream.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index 555e200a23..ca0313d1d7 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -42,6 +42,8 @@ static int dns_stream_update_io(DnsStream *s) { + } + + static int dns_stream_complete(DnsStream *s, int error) { ++ _cleanup_(dns_stream_unrefp) _unused_ DnsStream *ref = dns_stream_ref(s); /* Protect stream while we process it */ ++ + assert(s); + + #if ENABLE_DNS_OVER_TLS +@@ -316,7 +318,7 @@ static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) { + } + + static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) { +- DnsStream *s = userdata; ++ _cleanup_(dns_stream_unrefp) DnsStream *s = dns_stream_ref(userdata); /* Protect stream while we process it */ + int r; + + assert(s); diff --git a/SOURCES/0825-ci-functions-Add-useradd-and-userdel.patch b/SOURCES/0825-ci-functions-Add-useradd-and-userdel.patch new file mode 100644 index 0000000..a483ce3 --- /dev/null +++ b/SOURCES/0825-ci-functions-Add-useradd-and-userdel.patch @@ -0,0 +1,28 @@ +From 10758905f159bbe87a10f185f7e9afefbbd21fd4 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 26 Aug 2022 13:06:42 +0200 +Subject: [PATCH] ci(functions): Add `useradd` and `userdel` + +Inspired by upstream commit: +https://github.com/systemd/systemd/commit/9c94ab0f6ff22da4278a6e9a93ddc480607c55ac + +RHEL-only + +Related: #2110549 +--- + test/test-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test-functions b/test/test-functions +index ed8ab98173..19363be858 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0826-logind-optionally-watch-utmp-for-login-data.patch b/SOURCES/0826-logind-optionally-watch-utmp-for-login-data.patch new file mode 100644 index 0000000..dde4151 --- /dev/null +++ b/SOURCES/0826-logind-optionally-watch-utmp-for-login-data.patch @@ -0,0 +1,377 @@ +From d897789b4dc7d115c915842eabf33ed3de20110a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 7 Aug 2018 13:49:34 +0200 +Subject: [PATCH] logind: optionally watch utmp for login data + +This allows us to determine the TTY an ssh session is for, which is +useful to to proper idle detection for ssh sessions. + +Fixes: #9622 +(cherry picked from commit 3d0ef5c7e00155bc74f6f71c34cad518a4ff56ba) + +Related: #2122288 +--- + src/login/logind-core.c | 143 +++++++++++++++++++++++++++++++++++++ + src/login/logind-dbus.c | 5 ++ + src/login/logind-session.c | 24 +++++++ + src/login/logind-session.h | 14 +++- + src/login/logind.c | 10 +++ + src/login/logind.h | 8 +++ + 6 files changed, 203 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index 0ed812a2c8..7e33f8e6aa 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -5,6 +5,9 @@ + #include + #include + #include ++#if ENABLE_UTMP ++#include ++#endif + + #include "alloc-util.h" + #include "bus-error.h" +@@ -14,6 +17,7 @@ + #include "fd-util.h" + #include "logind.h" + #include "parse-util.h" ++#include "path-util.h" + #include "process-util.h" + #include "strv.h" + #include "terminal-util.h" +@@ -692,3 +696,142 @@ bool manager_all_buttons_ignored(Manager *m) { + + return true; + } ++ ++int manager_read_utmp(Manager *m) { ++#if ENABLE_UTMP ++ int r; ++ ++ assert(m); ++ ++ if (utmpxname(_PATH_UTMPX) < 0) ++ return log_error_errno(errno, "Failed to set utmp path to " _PATH_UTMPX ": %m"); ++ ++ setutxent(); ++ ++ for (;;) { ++ _cleanup_free_ char *t = NULL; ++ struct utmpx *u; ++ const char *c; ++ Session *s; ++ ++ errno = 0; ++ u = getutxent(); ++ if (!u) { ++ if (errno != 0) ++ log_warning_errno(errno, "Failed to read " _PATH_UTMPX ", ignoring: %m"); ++ r = 0; ++ break; ++ } ++ ++ if (u->ut_type != USER_PROCESS) ++ continue; ++ ++ if (!pid_is_valid(u->ut_pid)) ++ continue; ++ ++ t = strndup(u->ut_line, sizeof(u->ut_line)); ++ if (!t) { ++ r = log_oom(); ++ break; ++ } ++ ++ c = path_startswith(t, "/dev/"); ++ if (c) { ++ r = free_and_strdup(&t, c); ++ if (r < 0) { ++ log_oom(); ++ break; ++ } ++ } ++ ++ if (isempty(t)) ++ continue; ++ ++ s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(u->ut_pid)); ++ if (!s) ++ continue; ++ ++ if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) { ++ /* This may happen on multiplexed SSH connection (i.e. 'SSH connection sharing'). In ++ * this case PAM and utmp sessions don't match. In such a case let's invalidate the TTY ++ * information and never acquire it again. */ ++ ++ s->tty = mfree(s->tty); ++ s->tty_validity = TTY_UTMP_INCONSISTENT; ++ log_debug("Session '%s' has inconsistent TTY information, dropping TTY information.", s->id); ++ continue; ++ } ++ ++ /* Never override what we figured out once */ ++ if (s->tty || s->tty_validity >= 0) ++ continue; ++ ++ s->tty = TAKE_PTR(t); ++ s->tty_validity = TTY_FROM_UTMP; ++ log_debug("Acquired TTY information '%s' from utmp for session '%s'.", s->tty, s->id); ++ } ++ ++ endutxent(); ++ return r; ++#else ++ return 0 ++#endif ++} ++ ++#if ENABLE_UTMP ++static int manager_dispatch_utmp(sd_event_source *s, const struct inotify_event *event, void *userdata) { ++ Manager *m = userdata; ++ ++ assert(m); ++ ++ /* If there's indication the file itself might have been removed or became otherwise unavailable, then let's ++ * reestablish the watch on whatever there's now. */ ++ if ((event->mask & (IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF|IN_Q_OVERFLOW|IN_UNMOUNT)) != 0) ++ manager_connect_utmp(m); ++ ++ (void) manager_read_utmp(m); ++ return 0; ++} ++#endif ++ ++void manager_connect_utmp(Manager *m) { ++#if ENABLE_UTMP ++ sd_event_source *s = NULL; ++ int r; ++ ++ assert(m); ++ ++ /* Watch utmp for changes via inotify. We do this to deal with tools such as ssh, which will register the PAM ++ * session early, and acquire a TTY only much later for the connection. Thus during PAM the TTY won't be known ++ * yet. ssh will register itself with utmp when it finally acquired the TTY. Hence, let's make use of this, and ++ * watch utmp for the TTY asynchronously. We use the PAM session's leader PID as key, to find the right entry. ++ * ++ * Yes, relying on utmp is pretty ugly, but it's good enough for informational purposes, as well as idle ++ * detection (which, for tty sessions, relies on the TTY used) */ ++ ++ r = sd_event_add_inotify(m->event, &s, _PATH_UTMPX, IN_MODIFY|IN_MOVE_SELF|IN_DELETE_SELF|IN_ATTRIB, manager_dispatch_utmp, m); ++ if (r < 0) ++ log_full_errno(r == -ENOENT ? LOG_DEBUG: LOG_WARNING, r, "Failed to create inotify watch on " _PATH_UTMPX ", ignoring: %m"); ++ else { ++ r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_IDLE); ++ if (r < 0) ++ log_warning_errno(r, "Failed to adjust utmp event source priority, ignoring: %m"); ++ ++ (void) sd_event_source_set_description(s, "utmp"); ++ } ++ ++ sd_event_source_unref(m->utmp_event_source); ++ m->utmp_event_source = s; ++#endif ++} ++ ++void manager_reconnect_utmp(Manager *m) { ++#if ENABLE_UTMP ++ assert(m); ++ ++ if (m->utmp_event_source) ++ return; ++ ++ manager_connect_utmp(m); ++#endif ++} +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 1bb152bc20..0248042308 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -772,6 +772,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + } while (hashmap_get(m->sessions, id)); + } + ++ /* If we are not watching utmp aleady, try again */ ++ manager_reconnect_utmp(m); ++ + r = manager_add_user_by_uid(m, uid, &user); + if (r < 0) + goto fail; +@@ -795,6 +798,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + r = -ENOMEM; + goto fail; + } ++ ++ session->tty_validity = TTY_FROM_PAM; + } + + if (!isempty(display)) { +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 1143a834a4..d666f86d3f 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -56,6 +56,7 @@ int session_new(Session **ret, Manager *m, const char *id) { + .fifo_fd = -1, + .vtfd = -1, + .audit_id = AUDIT_SESSION_INVALID, ++ .tty_validity = _TTY_VALIDITY_INVALID, + }; + + s->state_file = strappend("/run/systemd/sessions/", id); +@@ -219,6 +220,9 @@ int session_save(Session *s) { + if (s->tty) + fprintf(f, "TTY=%s\n", s->tty); + ++ if (s->tty_validity >= 0) ++ fprintf(f, "TTY_VALIDITY=%s\n", tty_validity_to_string(s->tty_validity)); ++ + if (s->display) + fprintf(f, "DISPLAY=%s\n", s->display); + +@@ -355,6 +359,7 @@ static int session_load_devices(Session *s, const char *devices) { + int session_load(Session *s) { + _cleanup_free_ char *remote = NULL, + *seat = NULL, ++ *tty_validity = NULL, + *vtnr = NULL, + *state = NULL, + *position = NULL, +@@ -380,6 +385,7 @@ int session_load(Session *s) { + "FIFO", &s->fifo_path, + "SEAT", &seat, + "TTY", &s->tty, ++ "TTY_VALIDITY", &tty_validity, + "DISPLAY", &s->display, + "REMOTE_HOST", &s->remote_host, + "REMOTE_USER", &s->remote_user, +@@ -456,6 +462,16 @@ int session_load(Session *s) { + seat_claim_position(s->seat, s, npos); + } + ++ if (tty_validity) { ++ TTYValidity v; ++ ++ v = tty_validity_from_string(tty_validity); ++ if (v < 0) ++ log_debug("Failed to parse TTY validity: %s", tty_validity); ++ else ++ s->tty_validity = v; ++ } ++ + if (leader) { + if (parse_pid(leader, &s->leader) >= 0) + (void) audit_session_from_pid(s->leader, &s->audit_id); +@@ -1368,3 +1384,11 @@ static const char* const kill_who_table[_KILL_WHO_MAX] = { + }; + + DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); ++ ++static const char* const tty_validity_table[_TTY_VALIDITY_MAX] = { ++ [TTY_FROM_PAM] = "from-pam", ++ [TTY_FROM_UTMP] = "from-utmp", ++ [TTY_UTMP_INCONSISTENT] = "utmp-inconsistent", ++}; ++ ++DEFINE_STRING_TABLE_LOOKUP(tty_validity, TTYValidity); +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 9bd0c96a03..7da845cea3 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -46,6 +46,14 @@ enum KillWho { + _KILL_WHO_INVALID = -1 + }; + ++typedef enum TTYValidity { ++ TTY_FROM_PAM, ++ TTY_FROM_UTMP, ++ TTY_UTMP_INCONSISTENT, /* may happen on ssh sessions with multiplexed TTYs */ ++ _TTY_VALIDITY_MAX, ++ _TTY_VALIDITY_INVALID = -1, ++} TTYValidity; ++ + struct Session { + Manager *manager; + +@@ -60,8 +68,9 @@ struct Session { + + dual_timestamp timestamp; + +- char *tty; + char *display; ++ char *tty; ++ TTYValidity tty_validity; + + bool remote; + char *remote_user; +@@ -159,6 +168,9 @@ SessionClass session_class_from_string(const char *s) _pure_; + const char *kill_who_to_string(KillWho k) _const_; + KillWho kill_who_from_string(const char *s) _pure_; + ++const char* tty_validity_to_string(TTYValidity t) _const_; ++TTYValidity tty_validity_from_string(const char *s) _pure_; ++ + int session_prepare_vt(Session *s); + void session_restore_vt(Session *s); + void session_leave_vt(Session *s); +diff --git a/src/login/logind.c b/src/login/logind.c +index 6c208c8e89..25de9a6ab2 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -132,6 +132,10 @@ static Manager* manager_unref(Manager *m) { + sd_event_source_unref(m->udev_button_event_source); + sd_event_source_unref(m->lid_switch_ignore_event_source); + ++#if ENABLE_UTMP ++ sd_event_source_unref(m->utmp_event_source); ++#endif ++ + safe_close(m->console_active_fd); + + udev_monitor_unref(m->udev_seat_monitor); +@@ -1095,6 +1099,9 @@ static int manager_startup(Manager *m) { + if (r < 0) + return log_error_errno(r, "Failed to register SIGHUP handler: %m"); + ++ /* Connect to utmp */ ++ manager_connect_utmp(m); ++ + /* Connect to console */ + r = manager_connect_console(m); + if (r < 0) +@@ -1150,6 +1157,9 @@ static int manager_startup(Manager *m) { + /* Reserve the special reserved VT */ + manager_reserve_vt(m); + ++ /* Read in utmp if it exists */ ++ manager_read_utmp(m); ++ + /* And start everything */ + HASHMAP_FOREACH(seat, m->seats, i) + seat_start(seat); +diff --git a/src/login/logind.h b/src/login/logind.h +index d29b01c75b..bb127bf4a5 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -43,6 +43,10 @@ struct Manager { + sd_event_source *udev_vcsa_event_source; + sd_event_source *udev_button_event_source; + ++#if ENABLE_UTMP ++ sd_event_source *utmp_event_source; ++#endif ++ + int console_active_fd; + + unsigned n_autovts; +@@ -150,6 +154,10 @@ bool manager_is_docked_or_external_displays(Manager *m); + bool manager_is_on_external_power(void); + bool manager_all_buttons_ignored(Manager *m); + ++int manager_read_utmp(Manager *m); ++void manager_connect_utmp(Manager *m); ++void manager_reconnect_utmp(Manager *m); ++ + extern const sd_bus_vtable manager_vtable[]; + + int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/SOURCES/0827-logind-add-hashtable-for-finding-session-by-leader-P.patch b/SOURCES/0827-logind-add-hashtable-for-finding-session-by-leader-P.patch new file mode 100644 index 0000000..c506df0 --- /dev/null +++ b/SOURCES/0827-logind-add-hashtable-for-finding-session-by-leader-P.patch @@ -0,0 +1,188 @@ +From fbc394252588325b6e7ecd1ab65ad40b51763c58 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 7 Aug 2018 12:08:24 +0200 +Subject: [PATCH] logind: add hashtable for finding session by leader PID + +This is useful later on, when we quickly want to find the session for a +leader PID. + +(cherry picked from commit 238794b15082e6f61d0ce2943d39205289fff7f0) + +Related: #2122288 +--- + src/login/logind-core.c | 15 ++++++++------ + src/login/logind-dbus.c | 3 +-- + src/login/logind-session.c | 41 +++++++++++++++++++++++++++++++++++--- + src/login/logind-session.h | 1 + + src/login/logind.c | 4 +++- + src/login/logind.h | 1 + + 6 files changed, 53 insertions(+), 12 deletions(-) + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index 7e33f8e6aa..a1943b6f9d 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -339,13 +339,16 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) { + if (!pid_is_valid(pid)) + return -EINVAL; + +- r = cg_pid_get_unit(pid, &unit); +- if (r < 0) +- goto not_found; ++ s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid)); ++ if (!s) { ++ r = cg_pid_get_unit(pid, &unit); ++ if (r < 0) ++ goto not_found; + +- s = hashmap_get(m->session_units, unit); +- if (!s) +- goto not_found; ++ s = hashmap_get(m->session_units, unit); ++ if (!s) ++ goto not_found; ++ } + + if (ret) + *ret = s; +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 0248042308..01bfef4ff7 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -784,9 +784,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + goto fail; + + session_set_user(session, user); ++ session_set_leader(session, leader); + +- session->leader = leader; +- session->audit_id = audit_id; + session->type = t; + session->class = c; + session->remote = remote; +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index d666f86d3f..cc838ca383 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -121,6 +121,9 @@ Session* session_free(Session *s) { + free(s->scope); + } + ++ if (pid_is_valid(s->leader)) ++ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); ++ + free(s->scope_job); + + sd_bus_message_unref(s->create_message); +@@ -149,6 +152,30 @@ void session_set_user(Session *s, User *u) { + user_update_last_session_timer(u); + } + ++int session_set_leader(Session *s, pid_t pid) { ++ int r; ++ ++ assert(s); ++ ++ if (!pid_is_valid(pid)) ++ return -EINVAL; ++ ++ if (s->leader == pid) ++ return 0; ++ ++ r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s); ++ if (r < 0) ++ return r; ++ ++ if (pid_is_valid(s->leader)) ++ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); ++ ++ s->leader = pid; ++ (void) audit_session_from_pid(pid, &s->audit_id); ++ ++ return 1; ++} ++ + static void session_save_devices(Session *s, FILE *f) { + SessionDevice *sd; + Iterator i; +@@ -473,8 +500,16 @@ int session_load(Session *s) { + } + + if (leader) { +- if (parse_pid(leader, &s->leader) >= 0) +- (void) audit_session_from_pid(s->leader, &s->audit_id); ++ pid_t pid; ++ ++ r = parse_pid(leader, &pid); ++ if (r < 0) ++ log_debug_errno(r, "Failed to parse leader PID of session: %s", leader); ++ else { ++ r = session_set_leader(s, pid); ++ if (r < 0) ++ log_warning_errno(r, "Failed to set session leader PID, ignoring: %m"); ++ } + } + + if (type) { +@@ -910,7 +945,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) { + + /* For sessions with a leader but no explicitly configured + * tty, let's check the controlling tty of the leader */ +- if (s->leader > 0) { ++ if (pid_is_valid(s->leader)) { + r = get_process_ctty_atime(s->leader, &atime); + if (r >= 0) + goto found_atime; +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 7da845cea3..8c7d0301f2 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -124,6 +124,7 @@ Session* session_free(Session *s); + DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free); + + void session_set_user(Session *s, User *u); ++int session_set_leader(Session *s, pid_t pid); + bool session_may_gc(Session *s, bool drop_not_started); + void session_add_to_gc_queue(Session *s); + int session_activate(Session *s); +diff --git a/src/login/logind.c b/src/login/logind.c +index 25de9a6ab2..6b576dad0d 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -46,6 +46,7 @@ static int manager_new(Manager **ret) { + m->devices = hashmap_new(&string_hash_ops); + m->seats = hashmap_new(&string_hash_ops); + m->sessions = hashmap_new(&string_hash_ops); ++ m->sessions_by_leader = hashmap_new(NULL); + m->users = hashmap_new(NULL); + m->inhibitors = hashmap_new(&string_hash_ops); + m->buttons = hashmap_new(&string_hash_ops); +@@ -53,7 +54,7 @@ static int manager_new(Manager **ret) { + m->user_units = hashmap_new(&string_hash_ops); + m->session_units = hashmap_new(&string_hash_ops); + +- if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) ++ if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) + return -ENOMEM; + + m->udev = udev_new(); +@@ -112,6 +113,7 @@ static Manager* manager_unref(Manager *m) { + hashmap_free(m->devices); + hashmap_free(m->seats); + hashmap_free(m->sessions); ++ hashmap_free(m->sessions_by_leader); + hashmap_free(m->users); + hashmap_free(m->inhibitors); + hashmap_free(m->buttons); +diff --git a/src/login/logind.h b/src/login/logind.h +index bb127bf4a5..7f94dea2f6 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -26,6 +26,7 @@ struct Manager { + Hashmap *devices; + Hashmap *seats; + Hashmap *sessions; ++ Hashmap *sessions_by_leader; + Hashmap *users; + Hashmap *inhibitors; + Hashmap *buttons; diff --git a/SOURCES/0828-core-load-fragment-move-config_parse_sec_fix_0-to-sr.patch b/SOURCES/0828-core-load-fragment-move-config_parse_sec_fix_0-to-sr.patch new file mode 100644 index 0000000..252084b --- /dev/null +++ b/SOURCES/0828-core-load-fragment-move-config_parse_sec_fix_0-to-sr.patch @@ -0,0 +1,93 @@ +From 69ec7c9170e29fdf745fa282448d051edd1f88b2 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 9 Aug 2022 11:41:04 +0200 +Subject: [PATCH] core/load-fragment: move config_parse_sec_fix_0 to src/shared + +(cherry picked from commit 4ee8176fe33bbcd0971c4583a0e7d1cc2a64ac06) + +Related: #2122288 +--- + src/core/load-fragment.c | 33 --------------------------------- + src/core/load-fragment.h | 1 - + src/shared/conf-parser.c | 2 ++ + src/shared/conf-parser.h | 1 + + 4 files changed, 3 insertions(+), 34 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index c0b1fd4f91..53de7ff5e9 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -1865,39 +1865,6 @@ int config_parse_service_timeout( + return 0; + } + +-int config_parse_sec_fix_0( +- 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) { +- +- usec_t *usec = data; +- int r; +- +- assert(filename); +- assert(lvalue); +- assert(rvalue); +- assert(usec); +- +- /* This is pretty much like config_parse_sec(), except that this treats a time of 0 as infinity, for +- * compatibility with older versions of systemd where 0 instead of infinity was used as indicator to turn off a +- * timeout. */ +- +- r = parse_sec_fix_0(rvalue, usec); +- if (r < 0) { +- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue); +- return 0; +- } +- +- return 0; +-} +- + int config_parse_user_group_compat( + const char *unit, + const char *filename, +diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h +index f9d34d484d..b964737f9e 100644 +--- a/src/core/load-fragment.h ++++ b/src/core/load-fragment.h +@@ -95,7 +95,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_bus_name); + CONFIG_PARSER_PROTOTYPE(config_parse_exec_utmp_mode); + CONFIG_PARSER_PROTOTYPE(config_parse_working_directory); + CONFIG_PARSER_PROTOTYPE(config_parse_fdname); +-CONFIG_PARSER_PROTOTYPE(config_parse_sec_fix_0); + CONFIG_PARSER_PROTOTYPE(config_parse_user_group_compat); + CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv_compat); + CONFIG_PARSER_PROTOTYPE(config_parse_restrict_namespaces); +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index 1f40f00c72..414dde2e3d 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -1286,3 +1286,5 @@ int config_parse_permille(const char* unit, + + return 0; + } ++ ++DEFINE_CONFIG_PARSE_PTR(config_parse_sec_fix_0, parse_sec_fix_0, usec_t, "Failed to parse time value"); +diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h +index 375b2e5a74..56fd302db8 100644 +--- a/src/shared/conf-parser.h ++++ b/src/shared/conf-parser.h +@@ -142,6 +142,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ip_port); + CONFIG_PARSER_PROTOTYPE(config_parse_join_controllers); + CONFIG_PARSER_PROTOTYPE(config_parse_mtu); + CONFIG_PARSER_PROTOTYPE(config_parse_rlimit); ++CONFIG_PARSER_PROTOTYPE(config_parse_sec_fix_0); + + typedef enum Disabled { + DISABLED_CONFIGURATION, diff --git a/SOURCES/0829-sd-event-add-relative-timer-calls.patch b/SOURCES/0829-sd-event-add-relative-timer-calls.patch new file mode 100644 index 0000000..ba40d6e --- /dev/null +++ b/SOURCES/0829-sd-event-add-relative-timer-calls.patch @@ -0,0 +1,123 @@ +From 30f5836253f820086caa24fc9283344615b8fc00 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 28 Jul 2020 11:17:00 +0200 +Subject: [PATCH] sd-event: add relative timer calls + +We frequently want to set a timer relative to the current time. Let's +add an explicit API for this. This not only saves us a few lines of code +everywhere and simplifies things, but also allows us to do correct +overflow checking. + +(cherry picked from commit d6a83dc48ad1981665ff427858ae8e59d4cfd6cb) + +Related: #2122288 +--- + src/libsystemd/libsystemd.sym | 8 +++++- + src/libsystemd/sd-event/sd-event.c | 42 ++++++++++++++++++++++++++++++ + src/systemd/sd-event.h | 2 ++ + 3 files changed, 51 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 3b55fc6473..449918093c 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -578,12 +578,18 @@ LIBSYSTEMD_240 { + sd_bus_get_method_call_timeout; + } LIBSYSTEMD_239; + ++LIBSYSTEMD_247 { ++global: ++ sd_event_add_time_relative; ++ sd_event_source_set_time_relative; ++} LIBSYSTEMD_240; ++ + LIBSYSTEMD_248 { + global: + sd_event_source_set_ratelimit; + sd_event_source_get_ratelimit; + sd_event_source_is_ratelimited; +-} LIBSYSTEMD_240; ++} LIBSYSTEMD_247; + + LIBSYSTEMD_250 { + global: +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 09d4584bf9..2c9d331bf2 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1415,6 +1415,31 @@ fail: + return r; + } + ++_public_ int sd_event_add_time_relative( ++ sd_event *e, ++ sd_event_source **ret, ++ clockid_t clock, ++ uint64_t usec, ++ uint64_t accuracy, ++ sd_event_time_handler_t callback, ++ void *userdata) { ++ ++ usec_t t; ++ int r; ++ ++ /* Same as sd_event_add_time() but operates relative to the event loop's current point in time, and ++ * checks for overflow. */ ++ ++ r = sd_event_now(e, clock, &t); ++ if (r < 0) ++ return r; ++ ++ if (usec >= USEC_INFINITY - t) ++ return -EOVERFLOW; ++ ++ return sd_event_add_time(e, ret, clock, t + usec, accuracy, callback, userdata); ++} ++ + static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { + assert(s); + +@@ -2578,6 +2603,23 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { + return 0; + } + ++_public_ int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec) { ++ usec_t t; ++ int r; ++ ++ assert_return(s, -EINVAL); ++ assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); ++ ++ r = sd_event_now(s->event, event_source_type_to_clock(s->type), &t); ++ if (r < 0) ++ return r; ++ ++ if (usec >= USEC_INFINITY - t) ++ return -EOVERFLOW; ++ ++ return sd_event_source_set_time(s, t + usec); ++} ++ + _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { + assert_return(s, -EINVAL); + assert_return(usec, -EINVAL); +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index c2e9c9614d..960bea1ac4 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -87,6 +87,7 @@ sd_event* sd_event_unref(sd_event *e); + + int sd_event_add_io(sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata); + int sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); ++int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); + int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); + int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); + int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); +@@ -136,6 +137,7 @@ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); + int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); + int sd_event_source_get_time(sd_event_source *s, uint64_t *usec); + int sd_event_source_set_time(sd_event_source *s, uint64_t usec); ++int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec); + int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec); + int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec); + int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); diff --git a/SOURCES/0830-logind-add-option-to-stop-idle-sessions-after-specif.patch b/SOURCES/0830-logind-add-option-to-stop-idle-sessions-after-specif.patch new file mode 100644 index 0000000..891a3da --- /dev/null +++ b/SOURCES/0830-logind-add-option-to-stop-idle-sessions-after-specif.patch @@ -0,0 +1,233 @@ +From 24439b08e3a3437b423553c385cde1d4cddf18f6 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 8 Aug 2022 09:13:50 +0200 +Subject: [PATCH] logind: add option to stop idle sessions after specified + timeout + +Thanks to Jan Pazdziora for providing a patch +which implemeted a PoC of this feature. + +(cherry picked from commit 82325af3ae41bc7efb3d5cd8f56a4652fef498c2) + +Resolves: #2122288 +--- + man/logind.conf.xml | 11 ++++++ + src/login/logind-core.c | 2 + + src/login/logind-dbus.c | 1 + + src/login/logind-gperf.gperf | 1 + + src/login/logind-session.c | 72 +++++++++++++++++++++++++++++++++--- + src/login/logind-session.h | 2 + + src/login/logind.conf.in | 1 + + src/login/logind.h | 2 + + 8 files changed, 86 insertions(+), 6 deletions(-) + +diff --git a/man/logind.conf.xml b/man/logind.conf.xml +index 0cf8a7d1f2..00b5b1f2e8 100644 +--- a/man/logind.conf.xml ++++ b/man/logind.conf.xml +@@ -333,6 +333,17 @@ + are excluded from the effect of this setting. Defaults to no.
+ + ++ ++ StopIdleSessionSec= ++ ++ Specifies a timeout in seconds, or a time span value after which ++ systemd-logind checks the idle state of all sessions. Every session that is idle for ++ longer then the timeout will be stopped. Defaults to infinity ++ (systemd-logind is not checking the idle state of sessions). For details about the syntax ++ of time spans, see ++ systemd.time7. ++ ++ + + + +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index a1943b6f9d..abe6eecffb 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -58,6 +58,8 @@ void manager_reset_config(Manager *m) { + + m->kill_only_users = strv_free(m->kill_only_users); + m->kill_exclude_users = strv_free(m->kill_exclude_users); ++ ++ m->stop_idle_session_usec = USEC_INFINITY; + } + + int manager_parse_config_file(Manager *m) { +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 01bfef4ff7..81aacb4eed 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -2720,6 +2720,7 @@ const sd_bus_vtable manager_vtable[] = { + SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0), + SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), ++ SD_BUS_PROPERTY("StopIdleSessionUSec", "t", NULL, offsetof(Manager, stop_idle_session_usec), SD_BUS_VTABLE_PROPERTY_CONST), + + SD_BUS_METHOD_WITH_NAMES("GetSession", + "s", +diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf +index 8829ce7d85..214ac5c4a3 100644 +--- a/src/login/logind-gperf.gperf ++++ b/src/login/logind-gperf.gperf +@@ -42,3 +42,4 @@ Login.RemoveIPC, config_parse_bool, 0, offse + Login.InhibitorsMax, config_parse_uint64, 0, offsetof(Manager, inhibitors_max) + Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max) + Login.UserTasksMax, config_parse_compat_user_tasks_max, 0, offsetof(Manager, user_tasks_max) ++Login.StopIdleSessionSec, config_parse_sec_fix_0, 0, offsetof(Manager, stop_idle_session_usec) +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index cc838ca383..56f40fbec4 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -29,6 +29,7 @@ + #include "string-table.h" + #include "strv.h" + #include "terminal-util.h" ++#include "time-util.h" + #include "user-util.h" + #include "util.h" + +@@ -139,6 +140,8 @@ Session* session_free(Session *s) { + + free(s->state_file); + ++ sd_event_source_unref(s->stop_on_idle_event_source); ++ + return mfree(s); + } + +@@ -658,6 +661,55 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er + return 0; + } + ++static int session_dispatch_stop_on_idle(sd_event_source *source, uint64_t t, void *userdata) { ++ Session *s = userdata; ++ dual_timestamp ts; ++ int r, idle; ++ ++ assert(s); ++ ++ if (s->stopping) ++ return 0; ++ ++ idle = session_get_idle_hint(s, &ts); ++ if (idle) { ++ log_debug("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->name); ++ ++ return session_stop(s, /* force */ true); ++ } ++ ++ r = sd_event_source_set_time(source, usec_add(ts.monotonic, s->manager->stop_idle_session_usec)); ++ if (r < 0) ++ return log_error_errno(r, "Failed to configure stop on idle session event source: %m"); ++ ++ r = sd_event_source_set_enabled(source, SD_EVENT_ONESHOT); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enable stop on idle session event source: %m"); ++ ++ return 1; ++} ++ ++static int session_setup_stop_on_idle_timer(Session *s) { ++ int r; ++ ++ assert(s); ++ ++ if (s->manager->stop_idle_session_usec == USEC_INFINITY) ++ return 0; ++ ++ r = sd_event_add_time_relative( ++ s->manager->event, ++ &s->stop_on_idle_event_source, ++ CLOCK_MONOTONIC, ++ s->manager->stop_idle_session_usec, ++ 0, ++ session_dispatch_stop_on_idle, s); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add stop on idle session event source: %m"); ++ ++ return 0; ++} ++ + int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) { + int r; + +@@ -680,6 +732,10 @@ int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) { + if (r < 0) + return r; + ++ r = session_setup_stop_on_idle_timer(s); ++ if (r < 0) ++ return r; ++ + log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO, + "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR, + "SESSION_ID=%s", s->id, +@@ -917,7 +973,7 @@ static int get_process_ctty_atime(pid_t pid, usec_t *atime) { + } + + int session_get_idle_hint(Session *s, dual_timestamp *t) { +- usec_t atime = 0, n; ++ usec_t atime = 0, dtime = 0; + int r; + + assert(s); +@@ -961,12 +1017,16 @@ found_atime: + if (t) + dual_timestamp_from_realtime(t, atime); + +- n = now(CLOCK_REALTIME); +- +- if (s->manager->idle_action_usec <= 0) +- return 0; ++ if (s->manager->idle_action_usec > 0 && s->manager->stop_idle_session_usec != USEC_INFINITY) ++ dtime = MIN(s->manager->idle_action_usec, s->manager->stop_idle_session_usec); ++ else if (s->manager->idle_action_usec > 0) ++ dtime = s->manager->idle_action_usec; ++ else if (s->manager->stop_idle_session_usec != USEC_INFINITY) ++ dtime = s->manager->stop_idle_session_usec; ++ else ++ return false; + +- return atime + s->manager->idle_action_usec <= n; ++ return usec_add(atime, dtime) <= now(CLOCK_REALTIME); + } + + void session_set_idle_hint(Session *s, bool b) { +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 8c7d0301f2..6678441bb9 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -112,6 +112,8 @@ struct Session { + Hashmap *devices; + sd_bus_track *track; + ++ sd_event_source *stop_on_idle_event_source; ++ + LIST_FIELDS(Session, sessions_by_user); + LIST_FIELDS(Session, sessions_by_seat); + +diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in +index c7346f9819..a62c2b0b57 100644 +--- a/src/login/logind.conf.in ++++ b/src/login/logind.conf.in +@@ -35,3 +35,4 @@ + #RemoveIPC=no + #InhibitorsMax=8192 + #SessionsMax=8192 ++#StopIdleSessionSec=infinity +diff --git a/src/login/logind.h b/src/login/logind.h +index 7f94dea2f6..606adf4fe6 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -102,6 +102,8 @@ struct Manager { + usec_t idle_action_not_before_usec; + HandleAction idle_action; + ++ usec_t stop_idle_session_usec; ++ + HandleAction handle_power_key; + HandleAction handle_suspend_key; + HandleAction handle_hibernate_key; diff --git a/SOURCES/0831-logind-schedule-idle-check-full-interval-from-now-if.patch b/SOURCES/0831-logind-schedule-idle-check-full-interval-from-now-if.patch new file mode 100644 index 0000000..8a10fc4 --- /dev/null +++ b/SOURCES/0831-logind-schedule-idle-check-full-interval-from-now-if.patch @@ -0,0 +1,29 @@ +From e48edc1b923267a5fcc808c3eb7151bf460a68ba Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 9 Sep 2022 13:38:58 +0200 +Subject: [PATCH] logind: schedule idle check full interval from now if we + couldn't figure out atime timestamp + +(cherry picked from commit 6edf707fd59347024fa6be0342b108527825db1f) + +Related: #2122288 +--- + src/login/logind-session.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 56f40fbec4..18a07efcdb 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -678,7 +678,10 @@ static int session_dispatch_stop_on_idle(sd_event_source *source, uint64_t t, vo + return session_stop(s, /* force */ true); + } + +- r = sd_event_source_set_time(source, usec_add(ts.monotonic, s->manager->stop_idle_session_usec)); ++ r = sd_event_source_set_time( ++ source, ++ usec_add(dual_timestamp_is_set(&ts) ? ts.monotonic : now(CLOCK_MONOTONIC), ++ s->manager->stop_idle_session_usec)); + if (r < 0) + return log_error_errno(r, "Failed to configure stop on idle session event source: %m"); + diff --git a/SOURCES/0832-ci-lint-add-shell-linter-Differential-ShellCheck.patch b/SOURCES/0832-ci-lint-add-shell-linter-Differential-ShellCheck.patch new file mode 100644 index 0000000..d848bfa --- /dev/null +++ b/SOURCES/0832-ci-lint-add-shell-linter-Differential-ShellCheck.patch @@ -0,0 +1,59 @@ +From 5f69ba3919d32ed93c68bb6b8b70a516f2bb56a8 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 16 Aug 2022 14:34:49 +0200 +Subject: [PATCH] ci(lint): add shell linter - Differential ShellCheck + +It performs differential ShellCheck scans and report results directly in +pull request. + +documentation: +https://github.com/redhat-plumbers-in-action/differential-shellcheck + +(inspired by commit + https://github.com/systemd/systemd/commit/3f3c718e79abdac698ae90de5cd4c0560a0a75d4) + +RHEL-only + +Related: #2122499 +--- + .github/workflows/differential-shellcheck.yml | 31 +++++++++++++++++++ + 1 file changed, 31 insertions(+) + create mode 100644 .github/workflows/differential-shellcheck.yml + +diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml +new file mode 100644 +index 0000000000..fa94679b51 +--- /dev/null ++++ b/.github/workflows/differential-shellcheck.yml +@@ -0,0 +1,31 @@ ++--- ++# https://github.com/redhat-plumbers-in-action/differential-shellcheck#readme ++ ++name: Differential ShellCheck ++on: ++ pull_request: ++ branches: ++ - master ++ - rhel-8.*.0 ++ ++permissions: ++ contents: read ++ ++jobs: ++ lint: ++ runs-on: ubuntu-latest ++ ++ permissions: ++ security-events: write ++ pull-requests: write ++ ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v3 ++ with: ++ fetch-depth: 0 ++ ++ - name: Differential ShellCheck ++ uses: redhat-plumbers-in-action/differential-shellcheck@v3 ++ with: ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0833-meson-do-not-compare-objects-of-different-types.patch b/SOURCES/0833-meson-do-not-compare-objects-of-different-types.patch new file mode 100644 index 0000000..234e387 --- /dev/null +++ b/SOURCES/0833-meson-do-not-compare-objects-of-different-types.patch @@ -0,0 +1,34 @@ +From deb09b3bd826571149f6b018f3a3ff8a33cd104b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 28 Jun 2018 16:09:04 +0900 +Subject: [PATCH] meson: do not compare objects of different types + +This fixes the following warning: +``` +meson.build:1140: WARNING: Trying to compare values of different types (DependencyHolder, list) using !=. +The result of this is undefined and will become a hard error in a future Meson release. +``` + +Follow-up for f02582f69fe1e7663a87ba80bd4f90d5d23ee75f(#9410). + +(cherry picked from commit 48f5da19b6e8f0d05f5217bc9856093d354ce5d0) + +Related: #2122499 +--- + meson.build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 6729a9ea5e..af4cf331da 100644 +--- a/meson.build ++++ b/meson.build +@@ -1165,7 +1165,8 @@ substs.set('DEFAULT_DNSSEC_MODE', default_dnssec) + + dns_over_tls = get_option('dns-over-tls') + if dns_over_tls != 'false' +- have = libgnutls != [] and libgnutls.version().version_compare('>=3.5.3') ++ have = (conf.get('HAVE_GNUTLS') == 1 and ++ libgnutls.version().version_compare('>=3.5.3')) + if dns_over_tls == 'true' and not have + error('DNS-over-TLS support was requested, but dependencies are not available') + endif diff --git a/SOURCES/0834-journal-remote-use-MHD_HTTP_CONTENT_TOO_LARGE-as-MHD.patch b/SOURCES/0834-journal-remote-use-MHD_HTTP_CONTENT_TOO_LARGE-as-MHD.patch new file mode 100644 index 0000000..689ad06 --- /dev/null +++ b/SOURCES/0834-journal-remote-use-MHD_HTTP_CONTENT_TOO_LARGE-as-MHD.patch @@ -0,0 +1,48 @@ +From ea9b3a664f5e67d0ee6b0bf6ca362835ae11fedc Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 20 Dec 2021 20:48:32 +0900 +Subject: [PATCH] journal-remote: use MHD_HTTP_CONTENT_TOO_LARGE as + MHD_HTTP_PAYLOAD_TOO_LARGE is deprecated since 0.9.74 + +(cherry picked from commit 30df858f43b14a55c6650b43bea12cbf2cc0bc67) + +Related: #2122499 +--- + src/journal-remote/journal-remote-main.c | 2 +- + src/journal-remote/microhttpd-util.h | 10 +++++++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c +index 47fe9d7433..bcaa370099 100644 +--- a/src/journal-remote/journal-remote-main.c ++++ b/src/journal-remote/journal-remote-main.c +@@ -304,7 +304,7 @@ static int request_handler( + /* When serialized, an entry of maximum size might be slightly larger, + * so this does not correspond exactly to the limit in journald. Oh well. + */ +- return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE, ++ return mhd_respondf(connection, 0, MHD_HTTP_CONTENT_TOO_LARGE, + "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX); + } + +diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h +index 26909082a1..dd0ca1d9bd 100644 +--- a/src/journal-remote/microhttpd-util.h ++++ b/src/journal-remote/microhttpd-util.h +@@ -38,9 +38,13 @@ + # define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE + #endif + +-/* Renamed in µhttpd 0.9.53 */ +-#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE +-# define MHD_HTTP_PAYLOAD_TOO_LARGE MHD_HTTP_REQUEST_ENTITY_TOO_LARGE ++/* Renamed in µhttpd 0.9.74 (8c644fc1f4d498ea489add8d40a68f5d3e5899fa) */ ++#ifndef MHD_HTTP_CONTENT_TOO_LARGE ++# ifdef MHD_HTTP_PAYLOAD_TOO_LARGE ++# define MHD_HTTP_CONTENT_TOO_LARGE MHD_HTTP_PAYLOAD_TOO_LARGE /* 0.9.53 or newer */ ++# else ++# define MHD_HTTP_CONTENT_TOO_LARGE MHD_HTTP_REQUEST_ENTITY_TOO_LARGE ++# endif + #endif + + #if MHD_VERSION < 0x00094203 diff --git a/SOURCES/0835-Fix-build-with-httpd-0.9.71.patch b/SOURCES/0835-Fix-build-with-httpd-0.9.71.patch new file mode 100644 index 0000000..0f8ec58 --- /dev/null +++ b/SOURCES/0835-Fix-build-with-httpd-0.9.71.patch @@ -0,0 +1,71 @@ +From ca86de228e19cea268ec3eeabc9097d7c28fbf24 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 30 Jun 2020 09:56:10 +0200 +Subject: [PATCH] =?UTF-8?q?Fix=20build=20with=20=C2=B5httpd=200.9.71?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The return type of callbacks was changed from int to an enum. + +(cherry picked from commit d17eabb1052e7c8c432331a7a782845e36164f01) + +Related: #2122499 +--- + src/journal-remote/journal-gatewayd.c | 4 ++-- + src/journal-remote/journal-remote-main.c | 2 +- + src/journal-remote/microhttpd-util.h | 6 ++++++ + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c +index 54446ff7b5..3ff05a4d72 100644 +--- a/src/journal-remote/journal-gatewayd.c ++++ b/src/journal-remote/journal-gatewayd.c +@@ -338,7 +338,7 @@ static int request_parse_range( + return 0; + } + +-static int request_parse_arguments_iterator( ++static mhd_result request_parse_arguments_iterator( + void *cls, + enum MHD_ValueKind kind, + const char *key, +@@ -795,7 +795,7 @@ static int request_handler_machine( + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +-static int request_handler( ++static mhd_result request_handler( + void *cls, + struct MHD_Connection *connection, + const char *url, +diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c +index bcaa370099..a1008db6eb 100644 +--- a/src/journal-remote/journal-remote-main.c ++++ b/src/journal-remote/journal-remote-main.c +@@ -241,7 +241,7 @@ static int process_http_upload( + return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK."); + }; + +-static int request_handler( ++static mhd_result request_handler( + void *cls, + struct MHD_Connection *connection, + const char *url, +diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h +index dd0ca1d9bd..792c07ac20 100644 +--- a/src/journal-remote/microhttpd-util.h ++++ b/src/journal-remote/microhttpd-util.h +@@ -51,6 +51,12 @@ + # define MHD_create_response_from_fd_at_offset64 MHD_create_response_from_fd_at_offset + #endif + ++#if MHD_VERSION >= 0x00097002 ++# define mhd_result enum MHD_Result ++#else ++# define mhd_result int ++#endif ++ + void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0); + + /* respond_oom() must be usable with return, hence this form. */ diff --git a/SOURCES/0836-ci-replace-LGTM-with-CodeQL.patch b/SOURCES/0836-ci-replace-LGTM-with-CodeQL.patch new file mode 100644 index 0000000..b24cc6c --- /dev/null +++ b/SOURCES/0836-ci-replace-LGTM-with-CodeQL.patch @@ -0,0 +1,303 @@ +From 2b1dbcab1af1a22f3a46fa23aa551a7394673938 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 15 Sep 2022 15:29:23 +0200 +Subject: [PATCH] ci: replace LGTM with CodeQL + +As LGTM is going to be shut down by EOY, let's use CodeQL instead. + +This is loosely based on upstream's CodeQL configs with some minor +tweaks to avoid backporting tons of unrelated commits. + +rhel-only +Related: #2122499 +--- + .github/codeql-config.yml | 12 ++++ + .github/codeql-custom.qls | 44 ++++++++++++ + .../PotentiallyDangerousFunction.ql | 3 + + .../UninitializedVariableWithCleanup.ql | 16 ++--- + .github/codeql-queries/qlpack.yml | 11 +++ + .github/workflows/codeql.yml | 68 +++++++++++++++++++ + .lgtm.yml | 37 ---------- + 7 files changed, 146 insertions(+), 45 deletions(-) + create mode 100644 .github/codeql-config.yml + create mode 100644 .github/codeql-custom.qls + rename {.lgtm/cpp-queries => .github/codeql-queries}/PotentiallyDangerousFunction.ql (93%) + rename {.lgtm/cpp-queries => .github/codeql-queries}/UninitializedVariableWithCleanup.ql (86%) + create mode 100644 .github/codeql-queries/qlpack.yml + create mode 100644 .github/workflows/codeql.yml + delete mode 100644 .lgtm.yml + +diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml +new file mode 100644 +index 0000000000..7c01d32caa +--- /dev/null ++++ b/.github/codeql-config.yml +@@ -0,0 +1,12 @@ ++--- ++# vi: ts=2 sw=2 et: ++# SPDX-License-Identifier: LGPL-2.1-or-later ++name: "CodeQL config" ++ ++disable-default-queries: false ++ ++queries: ++ - name: Enable possibly useful queries which are disabled by default ++ uses: ./.github/codeql-custom.qls ++ - name: systemd-specific CodeQL queries ++ uses: ./.github/codeql-queries/ +diff --git a/.github/codeql-custom.qls b/.github/codeql-custom.qls +new file mode 100644 +index 0000000000..d35fbe3114 +--- /dev/null ++++ b/.github/codeql-custom.qls +@@ -0,0 +1,44 @@ ++--- ++# vi: ts=2 sw=2 et syntax=yaml: ++# SPDX-License-Identifier: LGPL-2.1-or-later ++# ++# Note: it is not recommended to directly reference the respective queries from ++# the github/codeql repository, so we have to "dance" around it using ++# a custom QL suite ++# See: ++# - https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#running-additional-queries ++# - https://github.com/github/codeql-action/issues/430#issuecomment-806092120 ++# - https://codeql.github.com/docs/codeql-cli/creating-codeql-query-suites/ ++ ++# Note: the codeql/-queries pack name can be found in the CodeQL repo[0] ++# in /ql/src/qlpack.yml. The respective codeql-suites are then ++# under /ql/src/codeql-suites/. ++# ++# [0] https://github.com/github/codeql ++- import: codeql-suites/cpp-lgtm.qls ++ from: codeql/cpp-queries ++- import: codeql-suites/python-lgtm.qls ++ from: codeql/python-queries ++- include: ++ id: ++ - cpp/bad-strncpy-size ++ - cpp/declaration-hides-variable ++ - cpp/include-non-header ++ - cpp/inconsistent-null-check ++ - cpp/mistyped-function-arguments ++ - cpp/nested-loops-with-same-variable ++ - cpp/sizeof-side-effect ++ - cpp/suspicious-pointer-scaling ++ - cpp/suspicious-pointer-scaling-void ++ - cpp/suspicious-sizeof ++ - cpp/unsafe-strcat ++ - cpp/unsafe-strncat ++ - cpp/unsigned-difference-expression-compared-zero ++ - cpp/unused-local-variable ++ tags: ++ - "security" ++ - "correctness" ++ severity: "error" ++- exclude: ++ id: ++ - cpp/fixme-comment +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.github/codeql-queries/PotentiallyDangerousFunction.ql +similarity index 93% +rename from .lgtm/cpp-queries/PotentiallyDangerousFunction.ql +rename to .github/codeql-queries/PotentiallyDangerousFunction.ql +index 39e8dddd13..63fd14e75f 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.github/codeql-queries/PotentiallyDangerousFunction.ql +@@ -46,6 +46,9 @@ predicate potentiallyDangerousFunction(Function f, string message) { + ) or ( + f.getQualifiedName() = "accept" and + message = "Call to accept() is not O_CLOEXEC-safe. Use accept4() instead." ++ ) or ( ++ f.getQualifiedName() = "dirname" and ++ message = "Call dirname() is icky. Use path_extract_directory() instead." + ) + } + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.github/codeql-queries/UninitializedVariableWithCleanup.ql +similarity index 86% +rename from .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +rename to .github/codeql-queries/UninitializedVariableWithCleanup.ql +index 6b3b62f8bc..e514111f28 100644 +--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql ++++ b/.github/codeql-queries/UninitializedVariableWithCleanup.ql +@@ -50,16 +50,16 @@ class UninitialisedLocalReachability extends StackVariableReachability { + * fun(&x); + * puts(x); + * +- * `useOfVarActual()` won't treat this an an uninitialized read even if the callee ++ * `useOfVarActual()` won't treat this as an uninitialized read even if the callee + * doesn't modify the argument, however, `useOfVar()` will + */ + override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVar(v, node) } + + override predicate isBarrier(ControlFlowNode node, StackVariable v) { +- // only report the _first_ possibly uninitialized use ++ /* only report the _first_ possibly uninitialized use */ + useOfVar(v, node) or + ( +- /* If there's an return statement somewhere between the variable declaration ++ /* If there's a return statement somewhere between the variable declaration + * and a possible definition, don't accept is as a valid initialization. + * + * E.g.: +@@ -71,7 +71,7 @@ class UninitialisedLocalReachability extends StackVariableReachability { + * x = malloc(...); + * + * is not a valid initialization, since we might return from the function +- * _before_ the actual iniitialization (emphasis on _might_, since we ++ * _before_ the actual initialization (emphasis on _might_, since we + * don't know if the return statement might ever evaluate to true). + */ + definitionBarrier(v, node) and +@@ -92,14 +92,14 @@ predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosing + * for this check to exclude them. + */ + VariableAccess commonException() { +- // If the uninitialized use we've found is in a macro expansion, it's +- // typically something like va_start(), and we don't want to complain. ++ /* If the uninitialized use we've found is in a macro expansion, it's ++ * typically something like va_start(), and we don't want to complain. */ + result.getParent().isInMacroExpansion() + or + result.getParent() instanceof BuiltInOperation + or +- // Finally, exclude functions that contain assembly blocks. It's +- // anyone's guess what happens in those. ++ /* Finally, exclude functions that contain assembly blocks. It's ++ * anyone's guess what happens in those. */ + containsInlineAssembly(result.getEnclosingFunction()) + } + +diff --git a/.github/codeql-queries/qlpack.yml b/.github/codeql-queries/qlpack.yml +new file mode 100644 +index 0000000000..a1a2dec6d6 +--- /dev/null ++++ b/.github/codeql-queries/qlpack.yml +@@ -0,0 +1,11 @@ ++--- ++# vi: ts=2 sw=2 et syntax=yaml: ++# SPDX-License-Identifier: LGPL-2.1-or-later ++ ++library: false ++name: systemd/cpp-queries ++version: 0.0.1 ++dependencies: ++ codeql/cpp-all: "*" ++ codeql/suite-helpers: "*" ++extractor: cpp +diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml +new file mode 100644 +index 0000000000..c5426d5686 +--- /dev/null ++++ b/.github/workflows/codeql.yml +@@ -0,0 +1,68 @@ ++--- ++# vi: ts=2 sw=2 et: ++# SPDX-License-Identifier: LGPL-2.1-or-later ++# ++name: "CodeQL" ++ ++on: ++ pull_request: ++ branches: ++ - master ++ - rhel-* ++ paths: ++ - '**/meson.build' ++ - '.github/**/codeql*' ++ - 'src/**' ++ - 'test/**' ++ - 'tools/**' ++ push: ++ branches: ++ - master ++ - rhel-* ++ ++permissions: ++ contents: read ++ ++jobs: ++ analyze: ++ name: Analyze ++ runs-on: ubuntu-22.04 ++ concurrency: ++ group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }} ++ cancel-in-progress: true ++ permissions: ++ actions: read ++ security-events: write ++ ++ strategy: ++ fail-fast: false ++ matrix: ++ language: ['cpp', 'python'] ++ ++ steps: ++ - name: Checkout repository ++ uses: actions/checkout@v3 ++ ++ - name: Initialize CodeQL ++ uses: github/codeql-action/init@v2 ++ with: ++ languages: ${{ matrix.language }} ++ config-file: ./.github/codeql-config.yml ++ ++ - name: Install dependencies ++ if: matrix.language == 'cpp' ++ run: | ++ echo "deb-src http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs) main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list ++ sudo apt-get -y update ++ sudo apt-get -y build-dep systemd ++ sudo apt-get -y install libfdisk-dev libpwquality-dev libqrencode-dev libssl-dev libxkbcommon-dev libzstd-dev ++ ++ - name: Build ++ if: matrix.language == 'cpp' ++ run: | ++ # EL 8 systemd fails to build with newer gnu-efi (3.0.13 on Ubuntu Jammy ATTOW) ++ meson build -Dlibiptc=false -Dgnu-efi=false ++ ninja -C build -v ++ ++ - name: Perform CodeQL Analysis ++ uses: github/codeql-action/analyze@v2 +diff --git a/.lgtm.yml b/.lgtm.yml +deleted file mode 100644 +index fe93957b67..0000000000 +--- a/.lgtm.yml ++++ /dev/null +@@ -1,37 +0,0 @@ +---- +-# vi: ts=2 sw=2 et: +- +-# Explicitly enable certain checks which are hidden by default +-queries: +- - include: cpp/bad-strncpy-size +- - include: cpp/declaration-hides-variable +- - include: cpp/inconsistent-null-check +- - include: cpp/mistyped-function-arguments +- - include: cpp/nested-loops-with-same-variable +- - include: cpp/sizeof-side-effect +- - include: cpp/suspicious-pointer-scaling +- - include: cpp/suspicious-pointer-scaling-void +- - include: cpp/suspicious-sizeof +- - include: cpp/unsafe-strcat +- - include: cpp/unsafe-strncat +- - include: cpp/unsigned-difference-expression-compared-zero +- - include: cpp/unused-local-variable +- - include: +- tags: +- - "security" +- - "correctness" +- severity: "error" +- +-extraction: +- cpp: +- prepare: +- packages: +- - python3-pip +- - python3-setuptools +- - python3-wheel +- after_prepare: +- - pip3 install meson +- - export PATH="$HOME/.local/bin/:$PATH" +- python: +- python_setup: +- version: 3 diff --git a/SOURCES/0837-ci-mergify-Update-policy-Drop-LGTM-checks.patch b/SOURCES/0837-ci-mergify-Update-policy-Drop-LGTM-checks.patch new file mode 100644 index 0000000..b7603f0 --- /dev/null +++ b/SOURCES/0837-ci-mergify-Update-policy-Drop-LGTM-checks.patch @@ -0,0 +1,71 @@ +From 4c241b812ea79f3faa02c45f95834842c7847b76 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Wed, 21 Sep 2022 15:14:26 +0200 +Subject: [PATCH] ci(mergify): Update policy - Drop LGTM checks + +rhel-only + +Related: #2122499 +--- + .github/workflows/differential-shellcheck.yml | 1 + + .mergify.yml | 28 ++++++------------- + 2 files changed, 9 insertions(+), 20 deletions(-) + +diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml +index fa94679b51..4399f0bc64 100644 +--- a/.github/workflows/differential-shellcheck.yml ++++ b/.github/workflows/differential-shellcheck.yml +@@ -13,6 +13,7 @@ permissions: + + jobs: + lint: ++ name: Differential ShellCheck + runs-on: ubuntu-latest + + permissions: +diff --git a/.mergify.yml b/.mergify.yml +index 3afd04f18e..a5eed6a82a 100644 +--- a/.mergify.yml ++++ b/.mergify.yml +@@ -11,16 +11,10 @@ pull_request_rules: + - -check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - -check-success=CentOS CI (CentOS Stream 8) +- # LGTM +- - and: +- - "-check-success=LGTM analysis: JavaScript" +- - "-check-neutral=LGTM analysis: JavaScript" +- - and: +- - "-check-success=LGTM analysis: Python" +- - "-check-neutral=LGTM analysis: Python" +- - and: +- - "-check-success=LGTM analysis: C/C++" +- - "-check-neutral=LGTM analysis: C/C++" ++ # CodeQL ++ - -check-success=CodeQL ++ # Other ++ - -check-success=Differential ShellCheck + actions: + label: + add: +@@ -36,16 +30,10 @@ pull_request_rules: + - check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - check-success=CentOS CI (CentOS Stream 8) +- # LGTM +- - or: +- - "check-success=LGTM analysis: JavaScript" +- - "check-neutral=LGTM analysis: JavaScript" +- - or: +- - "check-success=LGTM analysis: Python" +- - "check-neutral=LGTM analysis: Python" +- - or: +- - "check-success=LGTM analysis: C/C++" +- - "check-neutral=LGTM analysis: C/C++" ++ # CodeQL ++ - check-success=CodeQL ++ # Other ++ - check-success=Differential ShellCheck + actions: + label: + remove: diff --git a/SOURCES/0838-time-util-fix-buffer-over-run.patch b/SOURCES/0838-time-util-fix-buffer-over-run.patch new file mode 100644 index 0000000..c63ae79 --- /dev/null +++ b/SOURCES/0838-time-util-fix-buffer-over-run.patch @@ -0,0 +1,44 @@ +From a521f942d5c304bca7c61bacb3c79e565853718e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 7 Jul 2022 18:27:02 +0900 +Subject: [PATCH] time-util: fix buffer-over-run + +Fixes #23928. + +(cherry picked from commit 9102c625a673a3246d7e73d8737f3494446bad4e) + +Resolves: #2139391 +--- + src/basic/time-util.c | 2 +- + src/test/test-time-util.c | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/basic/time-util.c b/src/basic/time-util.c +index c36e462193..d46d884be5 100644 +--- a/src/basic/time-util.c ++++ b/src/basic/time-util.c +@@ -515,7 +515,7 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { + t = b; + } + +- n = MIN((size_t) k, l); ++ n = MIN((size_t) k, l-1); + + l -= n; + p += n; +diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c +index 354a01dd1a..6ebde4153c 100644 +--- a/src/test/test-time-util.c ++++ b/src/test/test-time-util.c +@@ -187,6 +187,11 @@ static void test_format_timespan(usec_t accuracy) { + test_format_timespan_one(500 * USEC_PER_MSEC, accuracy); + test_format_timespan_one(9*USEC_PER_YEAR/5 - 23, accuracy); + test_format_timespan_one(USEC_INFINITY, accuracy); ++ ++ /* See issue #23928. */ ++ _cleanup_free_ char *buf; ++ assert_se(buf = new(char, 5)); ++ assert_se(buf == format_timespan(buf, 5, 100005, 1000)); + } + + static void test_timezone_is_valid(void) { diff --git a/SOURCES/0839-basic-recognize-pdfs-filesystem-as-a-network-filesys.patch b/SOURCES/0839-basic-recognize-pdfs-filesystem-as-a-network-filesys.patch new file mode 100644 index 0000000..c7f889f --- /dev/null +++ b/SOURCES/0839-basic-recognize-pdfs-filesystem-as-a-network-filesys.patch @@ -0,0 +1,32 @@ +From 2fe9fb3e844d7991105c40d4363eed9069a6837d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 18 Nov 2022 16:16:36 +0100 +Subject: [PATCH] basic: recognize pdfs filesystem as a network filesystem + +Fujitsu advises their users to always use _netdev mount option with pdfs +mounts. Hence it makes sense to simply consider pdfs mounts as network +filesystem mounts. + +https://software.fujitsu.com/jp/manual/manualfiles/m130027/j2ul1563/02enz200/j1563-02-06-02-02.html + +RHEL-only + +Resolves: #2094661 +--- + src/basic/mount-util.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index e7f9e514c2..983566b46b 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -634,7 +634,8 @@ bool fstype_is_network(const char *fstype) { + "glusterfs", + "pvfs2", /* OrangeFS */ + "ocfs2", +- "lustre"); ++ "lustre", ++ "pdfs"); + } + + bool fstype_is_api_vfs(const char *fstype) { diff --git a/SOURCES/0840-core-move-reset_arguments-to-the-end-of-main-s-finis.patch b/SOURCES/0840-core-move-reset_arguments-to-the-end-of-main-s-finis.patch new file mode 100644 index 0000000..a2696f8 --- /dev/null +++ b/SOURCES/0840-core-move-reset_arguments-to-the-end-of-main-s-finis.patch @@ -0,0 +1,49 @@ +From 4bb425eea9f3037a583a23d99f15aa71562f2481 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Thu, 17 Sep 2020 01:49:17 -0700 +Subject: [PATCH] core: move reset_arguments() to the end of main's finish + +Fixes #16991 + +fb39af4ce42d7ef9af63009f271f404038703704 replaced `free_arguments()` with +`reset_arguments()`, which frees arg_* variables as before, but also resets all +of them to the default values. `reset_arguments()` was positioned +in such a way that it overrode some arg_* values still in use at shutdown. + +To avoid further unintentional resets, I moved `reset_arguments()` +right before the return, when nothing else will be using the arg_* variables. + +(cherry picked from commit 7d9eea2bd3d4f83668c7a78754d201b226acbf1e) + +Resolves: #2127131 +--- + src/core/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index bfd4c531a7..cfa6fec930 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2631,7 +2631,6 @@ finish: + m = manager_free(m); + } + +- reset_arguments(); + mac_selinux_finish(); + + if (reexecute) +@@ -2656,6 +2655,7 @@ finish: + * in become_shutdown() so normally we cannot free them yet. */ + watchdog_free_device(); + arg_watchdog_device = mfree(arg_watchdog_device); ++ reset_arguments(); + return retval; + } + #endif +@@ -2677,5 +2677,6 @@ finish: + freeze_or_reboot(); + } + ++ reset_arguments(); + return retval; + } diff --git a/SOURCES/0841-manager-move-inc.-of-n_reloading-into-a-function.patch b/SOURCES/0841-manager-move-inc.-of-n_reloading-into-a-function.patch new file mode 100644 index 0000000..799bd04 --- /dev/null +++ b/SOURCES/0841-manager-move-inc.-of-n_reloading-into-a-function.patch @@ -0,0 +1,91 @@ +From 708c394b7ca35fe2328fa0760696ff95caab8ff8 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 29 Nov 2022 16:15:47 +0100 +Subject: [PATCH] manager: move inc. of n_reloading into a function + +[dtardon: This is inspired by commit d147e2b66b4d6b71db1bc59b62286b2eb9c3d29f , +but it does just the minimal change needed for the next commit.] + +Related: #2136869 +--- + src/core/main.c | 2 +- + src/core/manager.c | 12 ++++++++---- + src/core/manager.h | 1 + + 3 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index cfa6fec930..c3e2ce8956 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1131,7 +1131,7 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching + return log_error_errno(r, "Failed to create serialization file: %m"); + + /* Make sure nothing is really destructed when we shut down */ +- m->n_reloading++; ++ manager_reloading_start(m); + bus_manager_send_reloading(m, true); + + fds = fdset_new(); +diff --git a/src/core/manager.c b/src/core/manager.c +index f4611e6f8f..f923cbce37 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1578,6 +1578,10 @@ static void manager_preset_all(Manager *m) { + log_info("Populated /etc with preset unit settings."); + } + ++void manager_reloading_start(Manager *m) { ++ m->n_reloading++; ++} ++ + int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + int r; + +@@ -1609,7 +1613,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + * this is already known, so we increase the counter here + * already */ + if (serialization) +- m->n_reloading++; ++ manager_reloading_start(m); + + /* First, enumerate what we can from all config files */ + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_START); +@@ -3093,7 +3097,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { + assert(f); + assert(fds); + +- m->n_reloading++; ++ manager_reloading_start(m); + + fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id); + fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs); +@@ -3211,7 +3215,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + + log_debug("Deserializing state..."); + +- m->n_reloading++; ++ manager_reloading_start(m); + + for (;;) { + _cleanup_free_ char *line = NULL; +@@ -3455,7 +3459,7 @@ int manager_reload(Manager *m) { + if (r < 0) + return r; + +- m->n_reloading++; ++ manager_reloading_start(m); + bus_manager_send_reloading(m, true); + + fds = fdset_new(); +diff --git a/src/core/manager.h b/src/core/manager.h +index 3f2cfc5e2e..adbbb518cb 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -386,6 +386,7 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m); + Manager* manager_free(Manager *m); + DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); + ++void manager_reloading_start(Manager *m); + int manager_startup(Manager *m, FILE *serialization, FDSet *fds); + + Job *manager_get_job(Manager *m, uint32_t id); diff --git a/SOURCES/0842-core-Add-new-DBUS-properties-UnitsReloadStartTimesta.patch b/SOURCES/0842-core-Add-new-DBUS-properties-UnitsReloadStartTimesta.patch new file mode 100644 index 0000000..dd27bfa --- /dev/null +++ b/SOURCES/0842-core-Add-new-DBUS-properties-UnitsReloadStartTimesta.patch @@ -0,0 +1,59 @@ +From 22eb8fbdab14e5b1b11a4d84c83bef97317e1d2a Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 2 Sep 2021 16:37:13 +0200 +Subject: [PATCH] core: Add new DBUS properties UnitsReloadStartTimestamp and + UnitsLoadTimestampMontonic + +(cherry picked from commit 49fbe940a429c3d8807bacdfce03af834275257c) + +Related: #2136869 +--- + src/core/dbus-manager.c | 1 + + src/core/manager.c | 2 ++ + src/core/manager.h | 1 + + 3 files changed, 4 insertions(+) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 5b1ed3646e..8a41eda4a6 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -2486,6 +2486,7 @@ const sd_bus_vtable bus_manager_vtable[] = { + BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), ++ BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0), + SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0), + SD_BUS_PROPERTY("NNames", "u", property_get_hashmap_size, offsetof(Manager, units), 0), +diff --git a/src/core/manager.c b/src/core/manager.c +index f923cbce37..8aa398cac8 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1580,6 +1580,7 @@ static void manager_preset_all(Manager *m) { + + void manager_reloading_start(Manager *m) { + m->n_reloading++; ++ dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD); + } + + int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { +@@ -4622,6 +4623,7 @@ static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = { + [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish", + [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start", + [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish", ++ [MANAGER_TIMESTAMP_UNITS_LOAD] = "units-load", + }; + + DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp); +diff --git a/src/core/manager.h b/src/core/manager.h +index adbbb518cb..98d381bc5b 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -67,6 +67,7 @@ typedef enum ManagerTimestamp { + MANAGER_TIMESTAMP_GENERATORS_FINISH, + MANAGER_TIMESTAMP_UNITS_LOAD_START, + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH, ++ MANAGER_TIMESTAMP_UNITS_LOAD, + _MANAGER_TIMESTAMP_MAX, + _MANAGER_TIMESTAMP_INVALID = -1, + } ManagerTimestamp; diff --git a/SOURCES/0843-core-Indicate-the-time-when-the-manager-started-load.patch b/SOURCES/0843-core-Indicate-the-time-when-the-manager-started-load.patch new file mode 100644 index 0000000..4a05d20 --- /dev/null +++ b/SOURCES/0843-core-Indicate-the-time-when-the-manager-started-load.patch @@ -0,0 +1,29 @@ +From f2de5398b0a1ebb3e6390506368c11329b843524 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 2 Sep 2021 16:50:50 +0200 +Subject: [PATCH] core: Indicate the time when the manager started loading + units the last time + +(cherry picked from commit 15b9243c0d7f6d1531fa65dbc01bd11e8e6c12ca) + +Resolves: #2136869 +--- + src/core/manager.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/core/manager.c b/src/core/manager.c +index 8aa398cac8..a9cd51b624 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -3554,6 +3554,11 @@ int manager_reload(Manager *m) { + /* Let's finally catch up with any changes that took place while we were reloading/reexecing */ + manager_catchup(m); + ++ /* Create a file which will indicate when the manager started loading units the last time. */ ++ (void) touch_file("/run/systemd/systemd-units-load", false, ++ m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME), ++ UID_INVALID, GID_INVALID, 0444); ++ + /* Sync current state of bus names with our set of listening units */ + q = manager_enqueue_sync_bus_names(m); + if (q < 0 && r >= 0) diff --git a/SOURCES/0844-core-do-not-touch-run-systemd-systemd-units-load-fro.patch b/SOURCES/0844-core-do-not-touch-run-systemd-systemd-units-load-fro.patch new file mode 100644 index 0000000..db62e35 --- /dev/null +++ b/SOURCES/0844-core-do-not-touch-run-systemd-systemd-units-load-fro.patch @@ -0,0 +1,34 @@ +From 3c2d2345814935cea8525e802e764fb2949eb3df Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Mon, 27 Dec 2021 18:22:43 +0000 +Subject: [PATCH] core: do not touch /run/systemd/systemd-units-load from user + session instances + +Follow-up for: https://github.com/systemd/systemd/commit/15b9243c0d7f6d1531fa65dbc01bd11e8e6c12ca +Fixes: https://github.com/systemd/systemd/issues/21911 + +(cherry picked from commit 4b3ad81bfafcd97acb06db463495e348d159d8e6) + +Related: #2136869 +--- + src/core/manager.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index a9cd51b624..e083596e58 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -3555,9 +3555,10 @@ int manager_reload(Manager *m) { + manager_catchup(m); + + /* Create a file which will indicate when the manager started loading units the last time. */ +- (void) touch_file("/run/systemd/systemd-units-load", false, +- m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME), +- UID_INVALID, GID_INVALID, 0444); ++ if (MANAGER_IS_SYSTEM(m)) ++ (void) touch_file("/run/systemd/systemd-units-load", false, ++ m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME), ++ UID_INVALID, GID_INVALID, 0444); + + /* Sync current state of bus names with our set of listening units */ + q = manager_enqueue_sync_bus_names(m); diff --git a/SOURCES/0845-sysctl-downgrade-message-when-we-have-no-permission.patch b/SOURCES/0845-sysctl-downgrade-message-when-we-have-no-permission.patch new file mode 100644 index 0000000..9e3d1e8 --- /dev/null +++ b/SOURCES/0845-sysctl-downgrade-message-when-we-have-no-permission.patch @@ -0,0 +1,49 @@ +From ffe4233155085b479c69abe844a34de212b8e5e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 16 Jan 2020 14:45:28 +0100 +Subject: [PATCH] sysctl: downgrade message when we have no permission + +We need to run sysctl also in containers, because the network +subtree is namespaces and may legitimately be writable. But logging +all "errors" at notice level creates unwanted noise. + +Also downgrade message about missing sysctls to log_info. This might also be +relatively common when configuration is targeted at different kernel +versions. With log_debug it'll still end up in the logs, but isn't really worth +of "notice" most of the time. + +https://bugzilla.redhat.com/show_bug.cgi?id=1609806 +(cherry picked from commit 32458cc9687c1b60ff0f22c0e71da93ce78b1534) + +Resolves: #2158160 +--- + src/sysctl/sysctl.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 4c85d6887f..dc14e1aaf1 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -82,13 +82,15 @@ static int apply_all(OrderedHashmap *sysctl_options) { + k = sysctl_write(option->key, option->value); + if (k < 0) { + /* If the sysctl is not available in the kernel or we are running with reduced +- * privileges and cannot write it, then log about the issue at LOG_NOTICE level, and +- * proceed without failing. (EROFS is treated as a permission problem here, since +- * that's how container managers usually protected their sysctls.) In all other cases +- * log an error and make the tool fail. */ +- +- if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT) || option->ignore_failure) +- log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); ++ * privileges and cannot write it, then log about the issue, and proceed without ++ * failing. (EROFS is treated as a permission problem here, since that's how ++ * container managers usually protected their sysctls.) In all other cases log an ++ * error and make the tool fail. */ ++ ++ if (option->ignore_failure || k == -EROFS || ERRNO_IS_PRIVILEGE(k)) ++ log_debug_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); ++ else if (k == -ENOENT) ++ log_info_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); + else { + log_error_errno(k, "Couldn't write '%s' to '%s': %m", option->value, option->key); + if (r == 0) diff --git a/SOURCES/0846-core-respect-SELinuxContext-for-socket-creation.patch b/SOURCES/0846-core-respect-SELinuxContext-for-socket-creation.patch new file mode 100644 index 0000000..dbdd058 --- /dev/null +++ b/SOURCES/0846-core-respect-SELinuxContext-for-socket-creation.patch @@ -0,0 +1,53 @@ +From 1f408c8d9739b1038012eeec7bf0f918c8095bc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Fri, 23 Sep 2022 19:00:22 +0200 +Subject: [PATCH] core: respect SELinuxContext= for socket creation + +On socket creation respect the SELinuxContext= setting of the associated +service, such that the initial created socket has the same label as the +future process accepting the connection (since w.r.t SELinux sockets +normally have the same label as the owning process). + +Triggered by #24702 + +(cherry picked from commit 599b384924bbef9f8f7fa5700c6fa35a404d9a98) + +Related: #2136738 +--- + src/core/socket.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/core/socket.c b/src/core/socket.c +index 9d47ca2616..d1ca0a07c5 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1427,6 +1427,7 @@ fail: + static int socket_determine_selinux_label(Socket *s, char **ret) { + Service *service; + ExecCommand *c; ++ const char *exec_context; + _cleanup_free_ char *path = NULL; + int r; + +@@ -1448,8 +1449,20 @@ static int socket_determine_selinux_label(Socket *s, char **ret) { + + if (!UNIT_ISSET(s->service)) + goto no_label; +- + service = SERVICE(UNIT_DEREF(s->service)); ++ ++ exec_context = service->exec_context.selinux_context; ++ if (exec_context) { ++ char *con; ++ ++ con = strdup(exec_context); ++ if (!con) ++ return -ENOMEM; ++ ++ *ret = TAKE_PTR(con); ++ return 0; ++ } ++ + c = service->exec_command[SERVICE_EXEC_START]; + if (!c) + goto no_label; diff --git a/SOURCES/0847-manager-use-target-process-context-to-set-socket-con.patch b/SOURCES/0847-manager-use-target-process-context-to-set-socket-con.patch new file mode 100644 index 0000000..d10bdca --- /dev/null +++ b/SOURCES/0847-manager-use-target-process-context-to-set-socket-con.patch @@ -0,0 +1,128 @@ +From 3f90090e70a5fa81bced17792fe08d9c46324da9 Mon Sep 17 00:00:00 2001 +From: "Ted X. Toth" +Date: Thu, 13 Oct 2022 12:58:26 -0700 +Subject: [PATCH] manager: use target process context to set socket context + +Use target process context to set socket context when using SELinuxContextFromNet +not systemd's context. Currently when using the SELinuxContextFromNet option for +a socket activated services, systemd calls getcon_raw which returns init_t and +uses the resulting context to compute the context to be passed to the +setsockcreatecon call. A socket of type init_t is created and listened on and +this means that SELinux policy cannot be written to control which processes +(SELinux types) can connect to the socket since the ref policy allows all +'types' to connect to sockets of the type init_t. When security accessors see +that any process can connect to a socket this raises serious concerns. I have +spoken with SELinux contributors in person and on the mailing list and the +consensus is that the best solution is to use the target executables context +when computing the sockets context in all cases. + +[zjs review/comment: + +This removes the branch that was added in 16115b0a7b7cdf08fb38084d857d572d8a9088dc. +16115b0a7b7cdf08fb38084d857d572d8a9088dc did two things: it had the branch here +in 'socket_determine_selinux_label()' and a code in 'exec_child()' to call +'label_get_child_mls_label(socket_fd, command->path, &label)'. + +Before this patch, the flow was: +''' +mac_selinux_get_child_mls_label: + peercon = getpeercon_raw(socket_fd); + if (!exec_label) + exec_label = getfilecon_raw(exe); + +socket_open_fds: + if (params->selinux_context_net) # + label = mac_selinux_get_our_label(); # this part is removed + else # + label = mac_selinux_get_create_label_from_exe(path); + socket_address_listen_in_cgroup(s, &p->address, label); + +exec_child(): + exec_context = mac_selinux_get_child_mls_label(fd, executable, context->selinux_context); + setexeccon(exec_context); +''' +] + +(cherry picked from commit 29dbc62d74f7b7881dc3136e68e03a03ea055b36) + +Resolves: #2136738 +--- + src/core/socket.c | 58 ++++++++++++++++++++--------------------------- + 1 file changed, 24 insertions(+), 34 deletions(-) + +diff --git a/src/core/socket.c b/src/core/socket.c +index d1ca0a07c5..8aa5463b25 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1434,47 +1434,37 @@ static int socket_determine_selinux_label(Socket *s, char **ret) { + assert(s); + assert(ret); + +- if (s->selinux_context_from_net) { +- /* If this is requested, get label from the network label */ +- +- r = mac_selinux_get_our_label(ret); +- if (r == -EOPNOTSUPP) +- goto no_label; +- +- } else { +- /* Otherwise, get it from the executable we are about to start */ +- r = socket_instantiate_service(s); +- if (r < 0) +- return r; ++ r = socket_instantiate_service(s); ++ if (r < 0) ++ return r; + +- if (!UNIT_ISSET(s->service)) +- goto no_label; +- service = SERVICE(UNIT_DEREF(s->service)); ++ if (!UNIT_ISSET(s->service)) ++ goto no_label; ++ service = SERVICE(UNIT_DEREF(s->service)); + +- exec_context = service->exec_context.selinux_context; +- if (exec_context) { +- char *con; ++ exec_context = service->exec_context.selinux_context; ++ if (exec_context) { ++ char *con; + +- con = strdup(exec_context); +- if (!con) +- return -ENOMEM; ++ con = strdup(exec_context); ++ if (!con) ++ return -ENOMEM; + +- *ret = TAKE_PTR(con); +- return 0; +- } ++ *ret = TAKE_PTR(con); ++ return 0; ++ } + +- c = service->exec_command[SERVICE_EXEC_START]; +- if (!c) +- goto no_label; ++ c = service->exec_command[SERVICE_EXEC_START]; ++ if (!c) ++ goto no_label; + +- r = chase_symlinks(c->path, service->exec_context.root_directory, CHASE_PREFIX_ROOT, &path); +- if (r < 0) +- goto no_label; ++ r = chase_symlinks(c->path, service->exec_context.root_directory, CHASE_PREFIX_ROOT, &path); ++ if (r < 0) ++ goto no_label; + +- r = mac_selinux_get_create_label_from_exe(path, ret); +- if (IN_SET(r, -EPERM, -EOPNOTSUPP)) +- goto no_label; +- } ++ r = mac_selinux_get_create_label_from_exe(path, ret); ++ if (IN_SET(r, -EPERM, -EOPNOTSUPP)) ++ goto no_label; + + return r; + diff --git a/SOURCES/0848-virt-detect-Amazon-EC2-Nitro-instance.patch b/SOURCES/0848-virt-detect-Amazon-EC2-Nitro-instance.patch new file mode 100644 index 0000000..fc3d0bd --- /dev/null +++ b/SOURCES/0848-virt-detect-Amazon-EC2-Nitro-instance.patch @@ -0,0 +1,142 @@ +From 6ffd3de2ccc5901974f292c9694829e25441060d Mon Sep 17 00:00:00 2001 +From: Bertrand Jacquin +Date: Sun, 11 Oct 2020 21:25:00 +0100 +Subject: [PATCH] virt: detect Amazon EC2 Nitro instance + +Amazon EC2 Nitro hypervisor is technically based on KVM[1], which +systemd-detect-virt identify propely from CPUID. However the lack of +CPUID on aarch64 (A1, T4 instance type) prevents a correct +identification, impacting hostnamectl and systemd-random-seed. Instead +it's possible to identify virtualization from DMI vendor ID. + +Prior to this commit: + # hostnamectl + Static hostname: n/a + Transient hostname: ip-10-97-8-12 + Icon name: computer + Machine ID: 8e3772fbcfa3dd6f330a12ff5df5a63b + Boot ID: b7b7e2fe0079448db664839df59f9817 + Operating System: Gentoo/Linux + Kernel: Linux 5.4.69-longterm + Architecture: arm64 + +After this commit: + # hostnamectl + Static hostname: n/a + Transient hostname: ip-10-97-8-12 + Icon name: computer-vm + Chassis: vm + Machine ID: 8e3772fbcfa3dd6f330a12ff5df5a63b + Boot ID: bd04da57084e41078f20541101867113 + Virtualization: amazon + Operating System: Gentoo/Linux + Kernel: Linux 5.4.69-longterm + Architecture: arm64 + +[1] https://aws.amazon.com/ec2/faqs/ + +(cherry picked from commit b6eca3731dd92b009b182f188936e1c2544574da) + +Resolves: #2117948 +--- + man/systemd-detect-virt.xml | 7 ++++++- + man/systemd.unit.xml | 1 + + src/basic/virt.c | 8 +++++--- + src/basic/virt.h | 1 + + src/test/test-condition.c | 1 + + 5 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml +index 6beb2c2aa1..61c210e24d 100644 +--- a/man/systemd-detect-virt.xml ++++ b/man/systemd-detect-virt.xml +@@ -72,7 +72,12 @@ + + + kvm +- Linux KVM kernel virtual machine, with whatever software, except Oracle Virtualbox ++ Linux KVM kernel virtual machine, in combination with QEMU. Not used for other virtualizers using the KVM interfaces, such as Oracle VirtualBox or Amazon EC2 Nitro, see below. ++ ++ ++ ++ amazon ++ Amazon EC2 Nitro using Linux KVM + + + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 6f213ccd56..5207a5bb3c 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -1068,6 +1068,7 @@ + virtualization solution, or one of + qemu, + kvm, ++ amazon, + zvm, + vmware, + microsoft, +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 8d862b6d67..78c68d66e0 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -147,6 +147,7 @@ static int detect_vm_dmi(void) { + int id; + } dmi_vendor_table[] = { + { "KVM", VIRTUALIZATION_KVM }, ++ { "Amazon EC2", VIRTUALIZATION_AMAZON }, + { "QEMU", VIRTUALIZATION_QEMU }, + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + { "VMware", VIRTUALIZATION_VMWARE }, +@@ -339,8 +340,8 @@ int detect_vm(void) { + + /* We have to use the correct order here: + * +- * → First, try to detect Oracle Virtualbox, even if it uses KVM, as well as Xen even if it cloaks as Microsoft +- * Hyper-V. ++ * → First, try to detect Oracle Virtualbox and Amazon EC2 Nitro, even if they use KVM, as well as Xen even if ++ * it cloaks as Microsoft Hyper-V. + * + * → Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is + * overwritten. +@@ -348,7 +349,7 @@ int detect_vm(void) { + * → Third, try to detect from DMI. */ + + dmi = detect_vm_dmi(); +- if (IN_SET(dmi, VIRTUALIZATION_ORACLE, VIRTUALIZATION_XEN)) { ++ if (IN_SET(dmi, VIRTUALIZATION_ORACLE, VIRTUALIZATION_XEN, VIRTUALIZATION_AMAZON)) { + r = dmi; + goto finish; + } +@@ -631,6 +632,7 @@ int running_in_chroot(void) { + static const char *const virtualization_table[_VIRTUALIZATION_MAX] = { + [VIRTUALIZATION_NONE] = "none", + [VIRTUALIZATION_KVM] = "kvm", ++ [VIRTUALIZATION_AMAZON] = "amazon", + [VIRTUALIZATION_QEMU] = "qemu", + [VIRTUALIZATION_BOCHS] = "bochs", + [VIRTUALIZATION_XEN] = "xen", +diff --git a/src/basic/virt.h b/src/basic/virt.h +index 640b3ed779..ed4ff063e0 100644 +--- a/src/basic/virt.h ++++ b/src/basic/virt.h +@@ -10,6 +10,7 @@ enum { + + VIRTUALIZATION_VM_FIRST, + VIRTUALIZATION_KVM = VIRTUALIZATION_VM_FIRST, ++ VIRTUALIZATION_AMAZON, + VIRTUALIZATION_QEMU, + VIRTUALIZATION_BOCHS, + VIRTUALIZATION_XEN, +diff --git a/src/test/test-condition.c b/src/test/test-condition.c +index 24395dafc6..29ea63c4ff 100644 +--- a/src/test/test-condition.c ++++ b/src/test/test-condition.c +@@ -510,6 +510,7 @@ static void test_condition_test_virtualization(void) { + + NULSTR_FOREACH(virt, + "kvm\0" ++ "amazon\0" + "qemu\0" + "bochs\0" + "xen\0" diff --git a/SOURCES/0849-machine-id-setup-generate-machine-id-from-DMI-produc.patch b/SOURCES/0849-machine-id-setup-generate-machine-id-from-DMI-produc.patch new file mode 100644 index 0000000..12f1b77 --- /dev/null +++ b/SOURCES/0849-machine-id-setup-generate-machine-id-from-DMI-produc.patch @@ -0,0 +1,37 @@ +From e320f72150829228f10ec24f3fba34d5377c5120 Mon Sep 17 00:00:00 2001 +From: Bertrand Jacquin +Date: Sun, 11 Oct 2020 22:25:56 +0100 +Subject: [PATCH] machine-id-setup: generate machine-id from DMI product ID on + Amazon EC2 + +Amazon EC2 Nitro hypervisor is technically based on KVM[1]. + +[1] https://aws.amazon.com/ec2/faqs/ + +(cherry picked from commit 382a46d129899ca9027b07c325102cab173dd563) + +Related: #2117948 +--- + src/core/machine-id-setup.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c +index 11528f83c4..fe2abc4e68 100644 +--- a/src/core/machine-id-setup.c ++++ b/src/core/machine-id-setup.c +@@ -57,11 +57,11 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) { + return 0; + } + +- } else if (detect_vm() == VIRTUALIZATION_KVM) { ++ } else if (IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_AMAZON, VIRTUALIZATION_QEMU)) { + +- /* If we are not running in a container, see if we are +- * running in qemu/kvm and a machine ID was passed in +- * via -uuid on the qemu/kvm command line */ ++ /* If we are not running in a container, see if we are running in a VM that provides ++ * a system UUID via the SMBIOS/DMI interfaces. Such environments include QEMU/KVM ++ * with the -uuid on the qemu command line or the Amazon EC2 Nitro hypervisor. */ + + if (id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, ret) >= 0) { + log_info("Initializing machine ID from KVM UUID."); diff --git a/SOURCES/0850-virt-use-string-table-to-detect-VM-or-container.patch b/SOURCES/0850-virt-use-string-table-to-detect-VM-or-container.patch new file mode 100644 index 0000000..f0990a6 --- /dev/null +++ b/SOURCES/0850-virt-use-string-table-to-detect-VM-or-container.patch @@ -0,0 +1,134 @@ +From efa2cdb699df3e5d5d7180e50f3ebfff74788c5c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 7 Jan 2020 11:49:39 +0900 +Subject: [PATCH] virt: use string table to detect VM or container + +(cherry picked from commit 735ea55f5cd87a82757a8911edd80fba799b46ee) + +Related: #2117948 +--- + src/basic/virt.c | 73 ++++++++++++++++++++++-------------------------- + 1 file changed, 33 insertions(+), 40 deletions(-) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 78c68d66e0..6e4c702051 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -22,27 +22,26 @@ + #include "string-util.h" + #include "virt.h" + ++static const char *const vm_table[_VIRTUALIZATION_MAX] = { ++ [VIRTUALIZATION_XEN] = "XenVMMXenVMM", ++ [VIRTUALIZATION_KVM] = "KVMKVMKVM", ++ [VIRTUALIZATION_QEMU] = "TCGTCGTCGTCG", ++ /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ ++ [VIRTUALIZATION_VMWARE] = "VMwareVMware", ++ /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ ++ [VIRTUALIZATION_MICROSOFT] = "Microsoft Hv", ++ /* https://wiki.freebsd.org/bhyve */ ++ [VIRTUALIZATION_BHYVE] = "bhyve bhyve ", ++ [VIRTUALIZATION_QNX] = "QNXQVMBSQG", ++}; ++ ++DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(vm, int); ++ + static int detect_vm_cpuid(void) { + + /* CPUID is an x86 specific interface. */ + #if defined(__i386__) || defined(__x86_64__) + +- static const struct { +- const char *cpuid; +- int id; +- } cpuid_vendor_table[] = { +- { "XenVMMXenVMM", VIRTUALIZATION_XEN }, +- { "KVMKVMKVM", VIRTUALIZATION_KVM }, +- { "TCGTCGTCGTCG", VIRTUALIZATION_QEMU }, +- /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ +- { "VMwareVMware", VIRTUALIZATION_VMWARE }, +- /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ +- { "Microsoft Hv", VIRTUALIZATION_MICROSOFT }, +- /* https://wiki.freebsd.org/bhyve */ +- { "bhyve bhyve ", VIRTUALIZATION_BHYVE }, +- { "QNXQVMBSQG", VIRTUALIZATION_QNX }, +- }; +- + uint32_t eax, ebx, ecx, edx; + bool hypervisor; + +@@ -59,7 +58,7 @@ static int detect_vm_cpuid(void) { + uint32_t sig32[3]; + char text[13]; + } sig = {}; +- unsigned j; ++ int v; + + /* There is a hypervisor, see what it is */ + __cpuid(0x40000000U, eax, ebx, ecx, edx); +@@ -70,11 +69,11 @@ static int detect_vm_cpuid(void) { + + log_debug("Virtualization found, CPUID=%s", sig.text); + +- for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++) +- if (streq(sig.text, cpuid_vendor_table[j].cpuid)) +- return cpuid_vendor_table[j].id; ++ v = vm_from_string(sig.text); ++ if (v < 0) ++ return VIRTUALIZATION_VM_OTHER; + +- return VIRTUALIZATION_VM_OTHER; ++ return v; + } + #endif + log_debug("No virtualization found in CPUID"); +@@ -434,22 +433,20 @@ finish: + return r; + } + +-int detect_container(void) { +- static const struct { +- const char *value; +- int id; +- } value_table[] = { +- { "lxc", VIRTUALIZATION_LXC }, +- { "lxc-libvirt", VIRTUALIZATION_LXC_LIBVIRT }, +- { "systemd-nspawn", VIRTUALIZATION_SYSTEMD_NSPAWN }, +- { "docker", VIRTUALIZATION_DOCKER }, +- { "rkt", VIRTUALIZATION_RKT }, +- }; ++static const char *const container_table[_VIRTUALIZATION_MAX] = { ++ [VIRTUALIZATION_LXC] = "lxc", ++ [VIRTUALIZATION_LXC_LIBVIRT] = "lxc-libvirt", ++ [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn", ++ [VIRTUALIZATION_DOCKER] = "docker", ++ [VIRTUALIZATION_RKT] = "rkt", ++}; ++ ++DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int); + ++int detect_container(void) { + static thread_local int cached_found = _VIRTUALIZATION_INVALID; + _cleanup_free_ char *m = NULL; + const char *e = NULL; +- unsigned j; + int r; + + if (cached_found >= 0) +@@ -522,13 +519,9 @@ int detect_container(void) { + goto finish; + + translate_name: +- for (j = 0; j < ELEMENTSOF(value_table); j++) +- if (streq(e, value_table[j].value)) { +- r = value_table[j].id; +- goto finish; +- } +- +- r = VIRTUALIZATION_CONTAINER_OTHER; ++ r = container_from_string(e); ++ if (r < 0) ++ r = VIRTUALIZATION_CONTAINER_OTHER; + + finish: + log_debug("Found container virtualization %s.", virtualization_to_string(r)); diff --git a/SOURCES/0851-fileio-introduce-read_full_virtual_file-for-reading-.patch b/SOURCES/0851-fileio-introduce-read_full_virtual_file-for-reading-.patch new file mode 100644 index 0000000..84b09c9 --- /dev/null +++ b/SOURCES/0851-fileio-introduce-read_full_virtual_file-for-reading-.patch @@ -0,0 +1,194 @@ +From 7a3843972ea290daf1bec5e1133db654749b8c02 Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Tue, 22 Oct 2019 16:09:21 +0200 +Subject: [PATCH] fileio: introduce read_full_virtual_file() for reading + virtual files in sysfs, procfs + +Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work +with two sorts of virtual files. + +One sort uses "seq_file", and the results of the first read are buffered for +the second read. The other sort uses "raw" reads which always go direct to the +device. + +In the later case, the content of the virtual file must be retrieved with a +single read otherwise subsequent read might get the new value instead of +finding EOF immediately. That's the reason why the usage of fread(3) is +prohibited in this case as it always performs a second call to read(2) looking +for EOF which is subject to the race described previously. + +Fixes: #13585. +(cherry picked from commit 21b40f16622f171a9969dc334d74fb5eb2f575c2) + +Related: #2117948 +--- + src/basic/fileio.c | 115 ++++++++++++++++++++++++++- + src/basic/fileio.h | 1 + + src/libsystemd/sd-device/sd-device.c | 2 +- + 3 files changed, 113 insertions(+), 5 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 6b0bad5b71..733fb42463 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -276,6 +276,113 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { + return 1; + } + ++int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) { ++ _cleanup_free_ char *buf = NULL; ++ _cleanup_close_ int fd = -1; ++ struct stat st; ++ size_t n, size; ++ int n_retries; ++ char *p; ++ ++ assert(ret_contents); ++ ++ /* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work ++ * with two sorts of virtual files. One sort uses "seq_file", and the results of ++ * the first read are buffered for the second read. The other sort uses "raw" ++ * reads which always go direct to the device. In the latter case, the content of ++ * the virtual file must be retrieved with a single read otherwise a second read ++ * might get the new value instead of finding EOF immediately. That's the reason ++ * why the usage of fread(3) is prohibited in this case as it always performs a ++ * second call to read(2) looking for EOF. See issue 13585. */ ++ ++ fd = open(filename, O_RDONLY|O_CLOEXEC); ++ if (fd < 0) ++ return -errno; ++ ++ /* Start size for files in /proc which usually report a file size of 0. */ ++ size = LINE_MAX / 2; ++ ++ /* Limit the number of attempts to read the number of bytes returned by fstat(). */ ++ n_retries = 3; ++ ++ for (;;) { ++ if (n_retries <= 0) ++ return -EIO; ++ ++ if (fstat(fd, &st) < 0) ++ return -errno; ++ ++ if (!S_ISREG(st.st_mode)) ++ return -EBADF; ++ ++ /* Be prepared for files from /proc which generally report a file size of 0. */ ++ if (st.st_size > 0) { ++ size = st.st_size; ++ n_retries--; ++ } else ++ size = size * 2; ++ ++ if (size > READ_FULL_BYTES_MAX) ++ return -E2BIG; ++ ++ p = realloc(buf, size + 1); ++ if (!p) ++ return -ENOMEM; ++ buf = TAKE_PTR(p); ++ ++ for (;;) { ++ ssize_t k; ++ ++ /* Read one more byte so we can detect whether the content of the ++ * file has already changed or the guessed size for files from /proc ++ * wasn't large enough . */ ++ k = read(fd, buf, size + 1); ++ if (k >= 0) { ++ n = k; ++ break; ++ } ++ ++ if (errno != -EINTR) ++ return -errno; ++ } ++ ++ /* Consider a short read as EOF */ ++ if (n <= size) ++ break; ++ ++ /* Hmm... either we read too few bytes from /proc or less likely the content ++ * of the file might have been changed (and is now bigger) while we were ++ * processing, let's try again either with a bigger guessed size or the new ++ * file size. */ ++ ++ if (lseek(fd, 0, SEEK_SET) < 0) ++ return -errno; ++ } ++ ++ if (n < size) { ++ p = realloc(buf, n + 1); ++ if (!p) ++ return -ENOMEM; ++ buf = TAKE_PTR(p); ++ } ++ ++ if (!ret_size) { ++ /* Safety check: if the caller doesn't want to know the size of what we ++ * just read it will rely on the trailing NUL byte. But if there's an ++ * embedded NUL byte, then we should refuse operation as otherwise ++ * there'd be ambiguity about what we just read. */ ++ ++ if (memchr(buf, 0, n)) ++ return -EBADMSG; ++ } else ++ *ret_size = n; ++ ++ buf[n] = 0; ++ *ret_contents = TAKE_PTR(buf); ++ ++ return 0; ++} ++ + int read_full_stream(FILE *f, char **contents, size_t *size) { + _cleanup_free_ char *buf = NULL; + struct stat st; +@@ -300,9 +407,9 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { + if (st.st_size > READ_FULL_BYTES_MAX) + return -E2BIG; + +- /* Start with the right file size, but be prepared for files from /proc which generally report a file +- * size of 0. Note that we increase the size to read here by one, so that the first read attempt +- * already makes us notice the EOF. */ ++ /* Start with the right file size. Note that we increase the size ++ * to read here by one, so that the first read attempt already ++ * makes us notice the EOF. */ + if (st.st_size > 0) + n = st.st_size + 1; + } +@@ -986,7 +1093,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin + assert(pattern); + assert(field); + +- r = read_full_file(filename, &status, NULL); ++ r = read_full_virtual_file(filename, &status, NULL); + if (r < 0) + return r; + +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 77e6206e95..c6ad375b8d 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -38,6 +38,7 @@ int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *f + int read_one_line_file(const char *fn, char **line); + int read_full_file(const char *fn, char **contents, size_t *size); + int read_full_stream(FILE *f, char **contents, size_t *size); ++int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); + + int verify_file(const char *fn, const char *blob, bool accept_extra_nl); + +diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c +index be29053f8c..49750ba9d7 100644 +--- a/src/libsystemd/sd-device/sd-device.c ++++ b/src/libsystemd/sd-device/sd-device.c +@@ -1798,7 +1798,7 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, + size_t size; + + /* read attribute value */ +- r = read_full_file(path, &value, &size); ++ r = read_full_virtual_file(path, &value, &size); + if (r < 0) + return r; + diff --git a/SOURCES/0852-Use-BIOS-characteristics-to-distinguish-EC2-bare-met.patch b/SOURCES/0852-Use-BIOS-characteristics-to-distinguish-EC2-bare-met.patch new file mode 100644 index 0000000..bf84a18 --- /dev/null +++ b/SOURCES/0852-Use-BIOS-characteristics-to-distinguish-EC2-bare-met.patch @@ -0,0 +1,118 @@ +From 44cbd79562ed55a8b0f2e5b5dc708265568ed9f8 Mon Sep 17 00:00:00 2001 +From: Noah Meyerhans +Date: Fri, 30 Apr 2021 09:30:52 -0700 +Subject: [PATCH] Use BIOS characteristics to distinguish EC2 bare-metal from + VMs + +DMI vendor information fields do not provide enough information for us to +distinguish between Amazon EC2 virtual machines and bare-metal instances. +SMBIOS provides a BIOS Information +table (https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.4.0.pdf +Ch. 7) that provides a field to indicate that the current machine is a virtual +machine. On EC2 virtual machine instances, this field is set, while bare-metal +instances leave this unset, so we inspect the field via the kernel's +/sys/firemware/dmi/entries interface. + +Fixes #18929 + +(cherry picked from commit ce35037928f4c4c931088256853f07804ec7d235) + +Related: #2117948 +--- + src/basic/virt.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 61 insertions(+), 4 deletions(-) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 6e4c702051..00d1c894e6 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -22,6 +22,12 @@ + #include "string-util.h" + #include "virt.h" + ++enum { ++ SMBIOS_VM_BIT_SET, ++ SMBIOS_VM_BIT_UNSET, ++ SMBIOS_VM_BIT_UNKNOWN, ++}; ++ + static const char *const vm_table[_VIRTUALIZATION_MAX] = { + [VIRTUALIZATION_XEN] = "XenVMMXenVMM", + [VIRTUALIZATION_KVM] = "KVMKVMKVM", +@@ -131,9 +137,8 @@ static int detect_vm_device_tree(void) { + #endif + } + +-static int detect_vm_dmi(void) { + #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) +- ++static int detect_vm_dmi_vendor(void) { + static const char *const dmi_vendors[] = { + "/sys/class/dmi/id/product_name", /* Test this before sys_vendor to detect KVM over QEMU */ + "/sys/class/dmi/id/sys_vendor", +@@ -179,11 +184,63 @@ static int detect_vm_dmi(void) { + return dmi_vendor_table[j].id; + } + } +-#endif ++ return VIRTUALIZATION_NONE; ++} ++ ++static int detect_vm_smbios(void) { ++ /* The SMBIOS BIOS Charateristics Extension Byte 2 (Section 2.1.2.2 of ++ * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.4.0.pdf), specifies that ++ * the 4th bit being set indicates a VM. The BIOS Characteristics table is exposed via the kernel in ++ * /sys/firmware/dmi/entries/0-0. Note that in the general case, this bit being unset should not ++ * imply that the system is running on bare-metal. For example, QEMU 3.1.0 (with or without KVM) ++ * with SeaBIOS does not set this bit. */ ++ _cleanup_free_ char *s = NULL; ++ size_t readsize; ++ int r; ++ ++ r = read_full_virtual_file("/sys/firmware/dmi/entries/0-0/raw", &s, &readsize); ++ if (r < 0) { ++ log_debug_errno(r, "Unable to read /sys/firmware/dmi/entries/0-0/raw, ignoring: %m"); ++ return SMBIOS_VM_BIT_UNKNOWN; ++ } ++ if (readsize < 20 || s[1] < 20) { ++ /* The spec indicates that byte 1 contains the size of the table, 0x12 + the number of ++ * extension bytes. The data we're interested in is in extension byte 2, which would be at ++ * 0x13. If we didn't read that much data, or if the BIOS indicates that we don't have that ++ * much data, we don't infer anything from the SMBIOS. */ ++ log_debug("Only read %zu bytes from /sys/firmware/dmi/entries/0-0/raw (expected 20)", readsize); ++ return SMBIOS_VM_BIT_UNKNOWN; ++ } + +- log_debug("No virtualization found in DMI"); ++ uint8_t byte = (uint8_t) s[19]; ++ if (byte & (1U<<4)) { ++ log_debug("DMI BIOS Extension table indicates virtualization"); ++ return SMBIOS_VM_BIT_SET; ++ } ++ log_debug("DMI BIOS Extension table does not indicate virtualization"); ++ return SMBIOS_VM_BIT_UNSET; ++} ++#endif /* defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) */ ++ ++static int detect_vm_dmi(void) { ++#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) ++ ++ int r; ++ r = detect_vm_dmi_vendor(); + ++ /* The DMI vendor tables in /sys/class/dmi/id don't help us distinguish between Amazon EC2 ++ * virtual machines and bare-metal instances, so we need to look at SMBIOS. */ ++ if (r == VIRTUALIZATION_AMAZON && detect_vm_smbios() == SMBIOS_VM_BIT_UNSET) ++ return VIRTUALIZATION_NONE; ++ ++ /* If we haven't identified a VM, but the firmware indicates that there is one, indicate as much. We ++ * have no further information about what it is. */ ++ if (r == VIRTUALIZATION_NONE && detect_vm_smbios() == SMBIOS_VM_BIT_SET) ++ return VIRTUALIZATION_VM_OTHER; ++ return r; ++#else + return VIRTUALIZATION_NONE; ++#endif + } + + static int detect_vm_xen(void) { diff --git a/SOURCES/0853-device-drop-refuse_after.patch b/SOURCES/0853-device-drop-refuse_after.patch new file mode 100644 index 0000000..80e5c62 --- /dev/null +++ b/SOURCES/0853-device-drop-refuse_after.patch @@ -0,0 +1,37 @@ +From bb9d00035c00b8590c389e66b5d94334bbb7379d Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Mon, 30 Mar 2020 10:49:29 +0200 +Subject: [PATCH] device: drop refuse_after + +Scheduling devices after a given unit can be useful to start device *jobs* at a +specific time in the transaction, see commit 4195077ab4c823c. + +This (hidden) change was introduced by commit eef85c4a3f8054d2. + +(cherry picked from commit b862c25716520d9381d5a841dba0f0c14e9c970a) + +[dtardon: This picks just the minimal relevant change from +c80a9a33d04fb4381327a69ce929c94a9f1d0e6c and +b862c25716520d9381d5a841dba0f0c14e9c970a] + +Resolves: #2043524 +--- + src/core/unit.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index dfe0c243ef..9be2a0c326 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2841,8 +2841,9 @@ int unit_add_dependency( + return 0; + } + +- if ((d == UNIT_BEFORE && other->type == UNIT_DEVICE) || +- (d == UNIT_AFTER && u->type == UNIT_DEVICE)) { ++ /* Note that ordering a device unit after a unit is permitted since it ++ * allows to start its job running timeout at a specific time. */ ++ if (d == UNIT_BEFORE && other->type == UNIT_DEVICE) { + log_unit_warning(u, "Dependency Before=%s ignored (.device units cannot be delayed)", other->id); + return 0; + } diff --git a/SOURCES/0854-manager-limit-access-to-private-dbus-socket.patch b/SOURCES/0854-manager-limit-access-to-private-dbus-socket.patch new file mode 100644 index 0000000..42ff3fa --- /dev/null +++ b/SOURCES/0854-manager-limit-access-to-private-dbus-socket.patch @@ -0,0 +1,44 @@ +From 004130ae74688eb321aadc05192bab69fe5cbcbf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 22 Jul 2022 11:45:12 +0200 +Subject: [PATCH] manager: limit access to private dbus socket + +For the system manager, /run/systemd/private is publicly accessible, because +/run/systemd is 0755, and /run/systemd/private is 0777. For the user manager, +/run/user/ is 0700, and /run/user//systemd/private is 0777. This +does not directly cause any security issue because we check the sender in +bus_check_peercred (ucred.uid != 0 && ucred.uid != geteuid()). + +But it makes sense to limit access to the socket to avoid wasting time in PID1. +Somebody could send messages there that'd we'd reject anyway. It also makes +things more explicit. + +(cherry picked from commit df1cbd1adf26071aab41d96e054452a3d66103a4) + +Resolves: #2119405 +--- + src/core/dbus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/core/dbus.c b/src/core/dbus.c +index 66d838cdb4..ec6c52cb85 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -42,6 +42,7 @@ + #include "string-util.h" + #include "strv.h" + #include "strxcpyx.h" ++#include "umask-util.h" + #include "user-util.h" + + #define CONNECTIONS_MAX 4096 +@@ -1019,7 +1020,8 @@ int bus_init_private(Manager *m) { + if (fd < 0) + return log_error_errno(errno, "Failed to allocate private socket: %m"); + +- r = bind(fd, &sa.sa, salen); ++ RUN_WITH_UMASK(0077) ++ r = bind(fd, &sa.sa, salen); + if (r < 0) + return log_error_errno(errno, "Failed to bind private socket: %m"); + diff --git a/SOURCES/0855-journalctl-do-not-treat-EINTR-as-an-error-when-waiti.patch b/SOURCES/0855-journalctl-do-not-treat-EINTR-as-an-error-when-waiti.patch new file mode 100644 index 0000000..d53c85d --- /dev/null +++ b/SOURCES/0855-journalctl-do-not-treat-EINTR-as-an-error-when-waiti.patch @@ -0,0 +1,35 @@ +From b0574acc0bddceb0af47f6cce327a87041ab4b52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 11 Nov 2018 12:33:06 +0100 +Subject: [PATCH] journalctl: do not treat EINTR as an error when waiting for + events + +Fixup for 2a1e0f2228bbdfbc18635e959f47df7da50b62fe. Fixes #10724. + +Reproducer: start 'journalctl -f' in a terminal window, change window size. +(cherry picked from commit 8e143a123276a9636987b08f555603927ca9e186) + +Resolves: #2161683 +--- + src/journal/journalctl.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index fa83dce562..228cfe7e49 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -2084,8 +2084,13 @@ static int wait_for_change(sd_journal *j, int poll_fd) { + if (r < 0) + return log_error_errno(r, "Failed to determine journal waiting time: %m"); + +- if (ppoll(pollfds, ELEMENTSOF(pollfds), timeout == USEC_INFINITY ? NULL : timespec_store(&ts, timeout), NULL) < 0) ++ if (ppoll(pollfds, ELEMENTSOF(pollfds), ++ timeout == USEC_INFINITY ? NULL : timespec_store(&ts, timeout), NULL) < 0) { ++ if (errno == EINTR) ++ return 0; ++ + return log_error_errno(errno, "Couldn't wait for journal event: %m"); ++ } + + if (pollfds[1].revents & (POLLHUP|POLLERR)) { /* STDOUT has been closed? */ + log_debug("Standard output has been closed."); diff --git a/SOURCES/0856-core-bring-manager_startup-and-manager_reload-more-i.patch b/SOURCES/0856-core-bring-manager_startup-and-manager_reload-more-i.patch new file mode 100644 index 0000000..e785fdf --- /dev/null +++ b/SOURCES/0856-core-bring-manager_startup-and-manager_reload-more-i.patch @@ -0,0 +1,76 @@ +From b9dd7ee5f4d0f6d51899d7e14ac7ef2fd2840b8f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 17:37:57 +0200 +Subject: [PATCH] core: bring manager_startup() and manager_reload() more + inline + +Both functions do partly the same, let's make sure they do it in the +same order, and that we don't miss some calls. + +This makes a number of changes: + +1. Moves exec_runtime_vacuum() two calls down in manager_startup(). This + should not have any effect but makes manager_startup() more like + manager_reload(). + +2. Calls manager_recheck_journal(), manager_recheck_dbus(), + manager_enqueue_sync_bus_names() in manager_startup() too. This is a + good idea since during reeexec we pass through manager_startup() and + hence can't assume dbus and journald weren't up yet, hence let's + check if they are ready to be connected to. + +3. Include manager_enumerate_perpetual() in manager_reload(), too. This + is not strictly necessary, since these units are included in the + serialization anyway, but it's still a nice thing, in particular as + theoretically the deserialization could fail. + +(cherry picked from commit 3ad2afb6a204513c7834c64ab864e40169874390) + +Resolves: #2059633 +--- + src/core/manager.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/core/manager.c b/src/core/manager.c +index e083596e58..4a9f9bfcf9 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -1665,12 +1665,12 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + /* Release any dynamic users no longer referenced */ + dynamic_user_vacuum(m, true); + +- exec_runtime_vacuum(m); +- + /* Release any references to UIDs/GIDs no longer referenced, and destroy any IPC owned by them */ + manager_vacuum_uid_refs(m); + manager_vacuum_gid_refs(m); + ++ exec_runtime_vacuum(m); ++ + if (serialization) { + assert(m->n_reloading > 0); + m->n_reloading--; +@@ -1681,6 +1681,13 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + m->send_reloading_done = true; + } + ++ /* It might be safe to log to the journal now and connect to dbus */ ++ manager_recheck_journal(m); ++ manager_recheck_dbus(m); ++ ++ /* Sync current state of bus names with our set of listening units */ ++ (void) manager_enqueue_sync_bus_names(m); ++ + /* Let's finally catch up with any changes that took place while we were reloading/reexecing */ + manager_catchup(m); + +@@ -3505,7 +3512,8 @@ int manager_reload(Manager *m) { + lookup_paths_reduce(&m->lookup_paths); + manager_build_unit_path_cache(m); + +- /* First, enumerate what we can from all config files */ ++ /* First, enumerate what we can from kernel and suchlike */ ++ manager_enumerate_perpetual(m); + manager_enumerate(m); + + /* Second, deserialize our stored data */ diff --git a/SOURCES/0857-pam-add-a-call-to-pam_namespace.patch b/SOURCES/0857-pam-add-a-call-to-pam_namespace.patch new file mode 100644 index 0000000..8825e9e --- /dev/null +++ b/SOURCES/0857-pam-add-a-call-to-pam_namespace.patch @@ -0,0 +1,35 @@ +From b1b7aaf83414c5b0bed6e61d38aefe29a21fdbcf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Nov 2022 16:09:56 +0100 +Subject: [PATCH] pam: add a call to pam_namespace + +A call to pam_namespace is required so that children of user@.service end up in +a namespace as expected. pam_namespace gets called as part of the stack that +creates a session (login, sshd, gdm, etc.) and those processes end up in a +namespace, but it also needs to be called from our stack which is parallel and +descends from pid1 itself. + +The call to pam_namespace is similar to the call to pam_keyinit that was added +in ab79099d1684457d040ee7c28b2012e8c1ea9a4f. The pam stack for user@.service +creates a new session which is disconnected from the parent environment. Both +calls are not suitable for inclusion in the shared part of the stack (e.g. +@system-auth on Fedora/RHEL systems), because for example su/sudo/runuser +should not include them. + +(cherry picked from commit 0ef48896d9f23b9fd547a532a4e6e6b8f8b12901) + +Resolves: #1861836 +--- + src/login/systemd-user.m4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/login/systemd-user.m4 b/src/login/systemd-user.m4 +index 20c8999331..eb291beaed 100644 +--- a/src/login/systemd-user.m4 ++++ b/src/login/systemd-user.m4 +@@ -9,4 +9,5 @@ session required pam_selinux.so nottys open + )m4_dnl + session required pam_loginuid.so + session optional pam_keyinit.so force revoke ++session required pam_namespace.so + session optional pam_systemd.so diff --git a/SOURCES/0858-virt-Support-detection-for-ARM64-Hyper-V-guests.patch b/SOURCES/0858-virt-Support-detection-for-ARM64-Hyper-V-guests.patch new file mode 100644 index 0000000..8f71336 --- /dev/null +++ b/SOURCES/0858-virt-Support-detection-for-ARM64-Hyper-V-guests.patch @@ -0,0 +1,31 @@ +From 4b573adbcc040fa50f1130cb8cf1bdb9559565cf Mon Sep 17 00:00:00 2001 +From: Boqun Feng +Date: Wed, 13 Oct 2021 11:32:09 +0800 +Subject: [PATCH] virt: Support detection for ARM64 Hyper-V guests + +The detection of Microsoft Hyper-V VMs is done by cpuid currently, +however there is no cpuid on ARM64. And since ARM64 is now a supported +architecture for Microsoft Hyper-V guests[1], then use DMI tables to +detect a Hyper-V guest, which is more generic and works for ARM64. + +[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7aff79e297ee1aa0126924921fd87a4ae59d2467 + +(cherry picked from commit 506bbc8569014253ea8614b680ccbc4fc2513a87) + +Resolves: #2158307 +--- + src/basic/virt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 00d1c894e6..cc95097101 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -162,6 +162,7 @@ static int detect_vm_dmi_vendor(void) { + { "Parallels", VIRTUALIZATION_PARALLELS }, + /* https://wiki.freebsd.org/bhyve */ + { "BHYVE", VIRTUALIZATION_BHYVE }, ++ { "Microsoft", VIRTUALIZATION_MICROSOFT }, + }; + unsigned i; + int r; diff --git a/SOURCES/0859-virt-Fix-the-detection-for-Hyper-V-VMs.patch b/SOURCES/0859-virt-Fix-the-detection-for-Hyper-V-VMs.patch new file mode 100644 index 0000000..8a91e30 --- /dev/null +++ b/SOURCES/0859-virt-Fix-the-detection-for-Hyper-V-VMs.patch @@ -0,0 +1,41 @@ +From e732bc987f2f779e89f30193bf694e0456ab7ce0 Mon Sep 17 00:00:00 2001 +From: Boqun Feng +Date: Tue, 23 Nov 2021 15:09:26 +0800 +Subject: [PATCH] virt: Fix the detection for Hyper-V VMs + +Use product_version instead of product_name in DMI table and the string +"Hyper-V" to avoid misdetection. + +Fixes: #21468 + +Signed-off-by: Boqun Feng +(cherry picked from commit 76eec0649936d9ae2f9087769f463feaf0cf5cb4) + +Related: #2158307 +--- + src/basic/virt.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index cc95097101..f750a0463f 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -143,7 +143,8 @@ static int detect_vm_dmi_vendor(void) { + "/sys/class/dmi/id/product_name", /* Test this before sys_vendor to detect KVM over QEMU */ + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", +- "/sys/class/dmi/id/bios_vendor" ++ "/sys/class/dmi/id/bios_vendor", ++ "/sys/class/dmi/id/product_version" /* For Hyper-V VMs test */ + }; + + static const struct { +@@ -162,7 +163,7 @@ static int detect_vm_dmi_vendor(void) { + { "Parallels", VIRTUALIZATION_PARALLELS }, + /* https://wiki.freebsd.org/bhyve */ + { "BHYVE", VIRTUALIZATION_BHYVE }, +- { "Microsoft", VIRTUALIZATION_MICROSOFT }, ++ { "Hyper-V", VIRTUALIZATION_MICROSOFT }, + }; + unsigned i; + int r; diff --git a/SOURCES/0860-basic-add-STRERROR-wrapper-for-strerror_r.patch b/SOURCES/0860-basic-add-STRERROR-wrapper-for-strerror_r.patch new file mode 100644 index 0000000..4d1c5e5 --- /dev/null +++ b/SOURCES/0860-basic-add-STRERROR-wrapper-for-strerror_r.patch @@ -0,0 +1,98 @@ +From 9c95d8dda42de288a57638a44dd5ea967469063d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 7 Oct 2022 12:28:31 +0200 +Subject: [PATCH] basic: add STRERROR() wrapper for strerror_r() + +(cherry picked from commit 2c5d05b3cd986568105d67891e4010b868dea24f) + +Related: #2155520 +--- + src/basic/util.h | 10 ++++++++++ + src/test/test-util.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 76b76d7e91..195f02cf5f 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -153,6 +153,16 @@ static inline void _reset_errno_(int *saved_errno) { + errno = *saved_errno; + } + ++/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */ ++#define ERRNO_BUF_LEN 1024 ++ ++/* Note: the lifetime of the compound literal is the immediately surrounding block, ++ * see C11 §6.5.2.5, and ++ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks ++ * ++ * Note that we use the GNU variant of strerror_r() here. */ ++#define STRERROR(errnum) strerror_r(abs(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN) ++ + #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno + + #define UNPROTECT_ERRNO \ +diff --git a/src/test/test-util.c b/src/test/test-util.c +index df60d89115..c93eaf7fc6 100644 +--- a/src/test/test-util.c ++++ b/src/test/test-util.c +@@ -12,6 +12,7 @@ + #include "process-util.h" + #include "raw-clone.h" + #include "rm-rf.h" ++#include "stdio-util.h" + #include "string-util.h" + #include "util.h" + +@@ -321,6 +322,42 @@ static void test_system_tasks_max_scale(void) { + assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX); + } + ++static void test_strerror_not_threadsafe(void) { ++ /* Just check that strerror really is not thread-safe. */ ++ log_info("strerror(%d) → %s", 200, strerror(200)); ++ log_info("strerror(%d) → %s", 201, strerror(201)); ++ log_info("strerror(%d) → %s", INT_MAX, strerror(INT_MAX)); ++ ++ log_info("strerror(%d), strerror(%d) → %p, %p", 200, 201, strerror(200), strerror(201)); ++ ++ /* This call is not allowed, because the first returned string becomes invalid when ++ * we call strerror the second time: ++ * ++ * log_info("strerror(%d), strerror(%d) → %s, %s", 200, 201, strerror(200), strerror(201)); ++ */ ++} ++ ++static void test_STRERROR(void) { ++ /* Just check that STRERROR really is thread-safe. */ ++ log_info("STRERROR(%d) → %s", 200, STRERROR(200)); ++ log_info("STRERROR(%d) → %s", 201, STRERROR(201)); ++ log_info("STRERROR(%d), STRERROR(%d) → %s, %s", 200, 201, STRERROR(200), STRERROR(201)); ++ ++ const char *a = STRERROR(200), *b = STRERROR(201); ++ assert_se(strstr(a, "200")); ++ assert_se(strstr(b, "201")); ++ ++ /* Check with negative values */ ++ assert_se(streq(a, STRERROR(-200))); ++ assert_se(streq(b, STRERROR(-201))); ++ ++ const char *c = STRERROR(INT_MAX); ++ char buf[DECIMAL_STR_MAX(int)]; ++ xsprintf(buf, "%d", INT_MAX); /* INT_MAX is hexadecimal, use printf to convert to decimal */ ++ log_info("STRERROR(%d) → %s", INT_MAX, c); ++ assert_se(strstr(c, buf)); ++} ++ + int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); +@@ -340,5 +377,8 @@ int main(int argc, char *argv[]) { + test_system_tasks_max(); + test_system_tasks_max_scale(); + ++ test_strerror_not_threadsafe(); ++ test_STRERROR(); ++ + return 0; + } diff --git a/SOURCES/0861-coredump-put-context-array-into-a-struct.patch b/SOURCES/0861-coredump-put-context-array-into-a-struct.patch new file mode 100644 index 0000000..75029e7 --- /dev/null +++ b/SOURCES/0861-coredump-put-context-array-into-a-struct.patch @@ -0,0 +1,529 @@ +From f53c6620c55488e2a3bd92957b21b6b95a7a3d35 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 12 Jan 2023 15:47:09 +0100 +Subject: [PATCH] coredump: put context array into a struct + +[dtardon: This is based on commit f46c706bdd4316ae8ed6baf7a8c382b90b84f648 , +but does just the minimal change to introduce the Context struct that is +needed by the following commit.] + +Related: #2155520 +--- + src/coredump/coredump.c | 208 +++++++++++++++++++++------------------- + 1 file changed, 108 insertions(+), 100 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index fb3a6ecfe9..ebc56d8342 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -91,6 +91,10 @@ enum { + _CONTEXT_MAX + }; + ++typedef struct Context { ++ const char *meta[_CONTEXT_MAX]; ++} Context; ++ + typedef enum CoredumpStorage { + COREDUMP_STORAGE_NONE, + COREDUMP_STORAGE_EXTERNAL, +@@ -184,7 +188,7 @@ static int fix_acl(int fd, uid_t uid) { + return 0; + } + +-static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) { ++static int fix_xattr(int fd, const Context *context) { + + static const char * const xattrs[_CONTEXT_MAX] = { + [CONTEXT_PID] = "user.coredump.pid", +@@ -209,10 +213,10 @@ static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) { + for (i = 0; i < _CONTEXT_MAX; i++) { + int k; + +- if (isempty(context[i]) || !xattrs[i]) ++ if (isempty(context->meta[i]) || !xattrs[i]) + continue; + +- k = fsetxattr(fd, xattrs[i], context[i], strlen(context[i]), XATTR_CREATE); ++ k = fsetxattr(fd, xattrs[i], context->meta[i], strlen(context->meta[i]), XATTR_CREATE); + if (k < 0 && r == 0) + r = -errno; + } +@@ -230,7 +234,7 @@ static int fix_permissions( + int fd, + const char *filename, + const char *target, +- const char *context[_CONTEXT_MAX], ++ const Context *context, + uid_t uid) { + + int r; +@@ -273,18 +277,18 @@ static int maybe_remove_external_coredump(const char *filename, uint64_t size) { + return 1; + } + +-static int make_filename(const char *context[_CONTEXT_MAX], char **ret) { ++static int make_filename(const Context *context, char **ret) { + _cleanup_free_ char *c = NULL, *u = NULL, *p = NULL, *t = NULL; + sd_id128_t boot = {}; + int r; + + assert(context); + +- c = filename_escape(context[CONTEXT_COMM]); ++ c = filename_escape(context->meta[CONTEXT_COMM]); + if (!c) + return -ENOMEM; + +- u = filename_escape(context[CONTEXT_UID]); ++ u = filename_escape(context->meta[CONTEXT_UID]); + if (!u) + return -ENOMEM; + +@@ -292,11 +296,11 @@ static int make_filename(const char *context[_CONTEXT_MAX], char **ret) { + if (r < 0) + return r; + +- p = filename_escape(context[CONTEXT_PID]); ++ p = filename_escape(context->meta[CONTEXT_PID]); + if (!p) + return -ENOMEM; + +- t = filename_escape(context[CONTEXT_TIMESTAMP]); ++ t = filename_escape(context->meta[CONTEXT_TIMESTAMP]); + if (!t) + return -ENOMEM; + +@@ -313,7 +317,7 @@ static int make_filename(const char *context[_CONTEXT_MAX], char **ret) { + } + + static int save_external_coredump( +- const char *context[_CONTEXT_MAX], ++ const Context *context, + int input_fd, + char **ret_filename, + int *ret_node_fd, +@@ -334,19 +338,19 @@ static int save_external_coredump( + assert(ret_data_fd); + assert(ret_size); + +- r = parse_uid(context[CONTEXT_UID], &uid); ++ r = parse_uid(context->meta[CONTEXT_UID], &uid); + if (r < 0) + return log_error_errno(r, "Failed to parse UID: %m"); + +- r = safe_atou64(context[CONTEXT_RLIMIT], &rlimit); ++ r = safe_atou64(context->meta[CONTEXT_RLIMIT], &rlimit); + if (r < 0) +- return log_error_errno(r, "Failed to parse resource limit: %s", context[CONTEXT_RLIMIT]); ++ return log_error_errno(r, "Failed to parse resource limit: %s", context->meta[CONTEXT_RLIMIT]); + if (rlimit < page_size()) { + /* Is coredumping disabled? Then don't bother saving/processing the coredump. + * Anything below PAGE_SIZE cannot give a readable coredump (the kernel uses + * ELF_EXEC_PAGESIZE which is not easily accessible, but is usually the same as PAGE_SIZE. */ + log_info("Resource limits disable core dumping for process %s (%s).", +- context[CONTEXT_PID], context[CONTEXT_COMM]); ++ context->meta[CONTEXT_PID], context->meta[CONTEXT_COMM]); + return -EBADSLT; + } + +@@ -371,7 +375,7 @@ static int save_external_coredump( + + r = copy_bytes(input_fd, fd, max_size, 0); + if (r < 0) { +- log_error_errno(r, "Cannot store coredump of %s (%s): %m", context[CONTEXT_PID], context[CONTEXT_COMM]); ++ log_error_errno(r, "Cannot store coredump of %s (%s): %m", context->meta[CONTEXT_PID], context->meta[CONTEXT_COMM]); + goto fail; + } + *ret_truncated = r == 1; +@@ -659,12 +663,12 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) { + return 1; + } + +-static int change_uid_gid(const char *context[]) { ++static int change_uid_gid(const Context *context) { + uid_t uid; + gid_t gid; + int r; + +- r = parse_uid(context[CONTEXT_UID], &uid); ++ r = parse_uid(context->meta[CONTEXT_UID], &uid); + if (r < 0) + return r; + +@@ -677,7 +681,7 @@ static int change_uid_gid(const char *context[]) { + uid = gid = 0; + } + } else { +- r = parse_gid(context[CONTEXT_GID], &gid); ++ r = parse_gid(context->meta[CONTEXT_GID], &gid); + if (r < 0) + return r; + } +@@ -685,23 +689,23 @@ static int change_uid_gid(const char *context[]) { + return drop_privileges(uid, gid, 0); + } + +-static bool is_journald_crash(const char *context[_CONTEXT_MAX]) { ++static bool is_journald_crash(const Context *context) { + assert(context); + +- return streq_ptr(context[CONTEXT_UNIT], SPECIAL_JOURNALD_SERVICE); ++ return streq_ptr(context->meta[CONTEXT_UNIT], SPECIAL_JOURNALD_SERVICE); + } + +-static bool is_pid1_crash(const char *context[_CONTEXT_MAX]) { ++static bool is_pid1_crash(const Context *context) { + assert(context); + +- return streq_ptr(context[CONTEXT_UNIT], SPECIAL_INIT_SCOPE) || +- streq_ptr(context[CONTEXT_PID], "1"); ++ return streq_ptr(context->meta[CONTEXT_UNIT], SPECIAL_INIT_SCOPE) || ++ streq_ptr(context->meta[CONTEXT_PID], "1"); + } + + #define SUBMIT_COREDUMP_FIELDS 4 + + static int submit_coredump( +- const char *context[_CONTEXT_MAX], ++ Context *context, + struct iovec *iovec, + size_t n_iovec_allocated, + size_t n_iovec, +@@ -760,11 +764,11 @@ static int submit_coredump( + if (coredump_size <= arg_process_size_max) { + _cleanup_free_ char *stacktrace = NULL; + +- r = coredump_make_stack_trace(coredump_fd, context[CONTEXT_EXE], &stacktrace); ++ r = coredump_make_stack_trace(coredump_fd, context->meta[CONTEXT_EXE], &stacktrace); + if (r >= 0) +- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], +- " (", context[CONTEXT_COMM], ") of user ", +- context[CONTEXT_UID], " dumped core.", ++ core_message = strjoin("MESSAGE=Process ", context->meta[CONTEXT_PID], ++ " (", context->meta[CONTEXT_COMM], ") of user ", ++ context->meta[CONTEXT_UID], " dumped core.", + journald_crash ? "\nCoredump diverted to " : "", + journald_crash ? filename : "", + "\n\n", stacktrace); +@@ -779,9 +783,9 @@ static int submit_coredump( + if (!core_message) + #endif + log: +- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], +- " (", context[CONTEXT_COMM], ") of user ", +- context[CONTEXT_UID], " dumped core.", ++ core_message = strjoin("MESSAGE=Process ", context->meta[CONTEXT_PID], ++ " (", context->meta[CONTEXT_COMM], ") of user ", ++ context->meta[CONTEXT_UID], " dumped core.", + journald_crash && filename ? "\nCoredump diverted to " : NULL, + journald_crash && filename ? filename : NULL); + if (!core_message) +@@ -826,7 +830,7 @@ log: + return 0; + } + +-static void map_context_fields(const struct iovec *iovec, const char* context[]) { ++static void map_context_fields(const struct iovec *iovec, Context *context) { + + static const char * const context_field_names[] = { + [CONTEXT_PID] = "COREDUMP_PID=", +@@ -857,7 +861,7 @@ static void map_context_fields(const struct iovec *iovec, const char* context[]) + + /* Note that these strings are NUL terminated, because we made sure that a trailing NUL byte is in the + * buffer, though not included in the iov_len count. (see below) */ +- context[i] = p; ++ context->meta[i] = p; + break; + } + } +@@ -866,7 +870,7 @@ static int process_socket(int fd) { + _cleanup_close_ int coredump_fd = -1; + struct iovec *iovec = NULL; + size_t n_iovec = 0, n_allocated = 0, i, k; +- const char *context[_CONTEXT_MAX] = {}; ++ Context context = {}; + int r; + + assert(fd >= 0); +@@ -950,7 +954,7 @@ static int process_socket(int fd) { + iovec[n_iovec].iov_len = (size_t) n; + + cmsg_close_all(&mh); +- map_context_fields(iovec + n_iovec, context); ++ map_context_fields(iovec + n_iovec, &context); + n_iovec++; + } + +@@ -960,24 +964,24 @@ static int process_socket(int fd) { + } + + /* Make sure we got all data we really need */ +- assert(context[CONTEXT_PID]); +- assert(context[CONTEXT_UID]); +- assert(context[CONTEXT_GID]); +- assert(context[CONTEXT_SIGNAL]); +- assert(context[CONTEXT_TIMESTAMP]); +- assert(context[CONTEXT_RLIMIT]); +- assert(context[CONTEXT_HOSTNAME]); +- assert(context[CONTEXT_COMM]); ++ assert(context.meta[CONTEXT_PID]); ++ assert(context.meta[CONTEXT_UID]); ++ assert(context.meta[CONTEXT_GID]); ++ assert(context.meta[CONTEXT_SIGNAL]); ++ assert(context.meta[CONTEXT_TIMESTAMP]); ++ assert(context.meta[CONTEXT_RLIMIT]); ++ assert(context.meta[CONTEXT_HOSTNAME]); ++ assert(context.meta[CONTEXT_COMM]); + assert(coredump_fd >= 0); + + /* Small quirk: the journal fields contain the timestamp padded with six zeroes, so that the kernel-supplied 1s + * granularity timestamps becomes 1µs granularity, i.e. the granularity systemd usually operates in. Since we + * are reconstructing the original kernel context, we chop this off again, here. */ +- k = strlen(context[CONTEXT_TIMESTAMP]); ++ k = strlen(context.meta[CONTEXT_TIMESTAMP]); + if (k > 6) +- context[CONTEXT_TIMESTAMP] = strndupa(context[CONTEXT_TIMESTAMP], k - 6); ++ context.meta[CONTEXT_TIMESTAMP] = strndupa(context.meta[CONTEXT_TIMESTAMP], k - 6); + +- r = submit_coredump(context, iovec, n_allocated, n_iovec, coredump_fd); ++ r = submit_coredump(&context, iovec, n_allocated, n_iovec, coredump_fd); + + finish: + for (i = 0; i < n_iovec; i++) +@@ -1062,7 +1066,7 @@ static char* set_iovec_field_free(struct iovec *iovec, size_t *n_iovec, const ch + } + + static int gather_pid_metadata( +- char* context[_CONTEXT_MAX], ++ Context *context, + char **comm_fallback, + struct iovec *iovec, size_t *n_iovec) { + +@@ -1077,65 +1081,69 @@ static int gather_pid_metadata( + const char *p; + int r, signo; + +- r = parse_pid(context[CONTEXT_PID], &pid); ++ r = parse_pid(context->meta[CONTEXT_PID], &pid); + if (r < 0) +- return log_error_errno(r, "Failed to parse PID \"%s\": %m", context[CONTEXT_PID]); ++ return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[CONTEXT_PID]); + +- r = get_process_comm(pid, &context[CONTEXT_COMM]); ++ r = get_process_comm(pid, &t); + if (r < 0) { + log_warning_errno(r, "Failed to get COMM, falling back to the command line: %m"); +- context[CONTEXT_COMM] = strv_join(comm_fallback, " "); +- if (!context[CONTEXT_COMM]) ++ context->meta[CONTEXT_COMM] = strv_join(comm_fallback, " "); ++ if (!context->meta[CONTEXT_COMM]) + return log_oom(); +- } ++ } else ++ context->meta[CONTEXT_COMM] = t; + +- r = get_process_exe(pid, &context[CONTEXT_EXE]); ++ r = get_process_exe(pid, &t); + if (r < 0) + log_warning_errno(r, "Failed to get EXE, ignoring: %m"); ++ else ++ context->meta[CONTEXT_EXE] = t; + +- if (cg_pid_get_unit(pid, &context[CONTEXT_UNIT]) >= 0) { +- if (!is_journald_crash((const char**) context)) { ++ if (cg_pid_get_unit(pid, &t) >= 0) { ++ if (!is_journald_crash(context)) { + /* OK, now we know it's not the journal, hence we can make use of it now. */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + } + + /* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */ +- if (is_pid1_crash((const char**) context)) { ++ if (is_pid1_crash(context)) { + log_notice("Due to PID 1 having crashed coredump collection will now be turned off."); + disable_coredumps(); + } + +- set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]); +- } ++ set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context->meta[CONTEXT_UNIT]); ++ } else ++ context->meta[CONTEXT_UNIT] = t; + + if (cg_pid_get_user_unit(pid, &t) >= 0) + set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t); + + /* The next few are mandatory */ +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context->meta[CONTEXT_PID])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context->meta[CONTEXT_UID])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context->meta[CONTEXT_GID])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context->meta[CONTEXT_SIGNAL])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context->meta[CONTEXT_RLIMIT])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context->meta[CONTEXT_HOSTNAME])) + return log_oom(); + +- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM])) ++ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context->meta[CONTEXT_COMM])) + return log_oom(); + +- if (context[CONTEXT_EXE] && +- !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE])) ++ if (context->meta[CONTEXT_EXE] && ++ !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context->meta[CONTEXT_EXE])) + return log_oom(); + + if (sd_pid_get_session(pid, &t) >= 0) +@@ -1198,11 +1206,11 @@ static int gather_pid_metadata( + if (get_process_environ(pid, &t) >= 0) + set_iovec_field_free(iovec, n_iovec, "COREDUMP_ENVIRON=", t); + +- t = strjoin("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000"); ++ t = strjoin("COREDUMP_TIMESTAMP=", context->meta[CONTEXT_TIMESTAMP], "000000"); + if (t) + iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(t); + +- if (safe_atoi(context[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo)) ++ if (safe_atoi(context->meta[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo)) + set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo)); + + return 0; /* we successfully acquired all metadata */ +@@ -1210,7 +1218,7 @@ static int gather_pid_metadata( + + static int process_kernel(int argc, char* argv[]) { + +- char* context[_CONTEXT_MAX] = {}; ++ Context context = {}; + struct iovec iovec[29 + SUBMIT_COREDUMP_FIELDS]; + size_t i, n_iovec, n_to_free = 0; + int r; +@@ -1222,15 +1230,15 @@ static int process_kernel(int argc, char* argv[]) { + return -EINVAL; + } + +- context[CONTEXT_PID] = argv[1 + CONTEXT_PID]; +- context[CONTEXT_UID] = argv[1 + CONTEXT_UID]; +- context[CONTEXT_GID] = argv[1 + CONTEXT_GID]; +- context[CONTEXT_SIGNAL] = argv[1 + CONTEXT_SIGNAL]; +- context[CONTEXT_TIMESTAMP] = argv[1 + CONTEXT_TIMESTAMP]; +- context[CONTEXT_RLIMIT] = argv[1 + CONTEXT_RLIMIT]; +- context[CONTEXT_HOSTNAME] = argv[1 + CONTEXT_HOSTNAME]; ++ context.meta[CONTEXT_PID] = argv[1 + CONTEXT_PID]; ++ context.meta[CONTEXT_UID] = argv[1 + CONTEXT_UID]; ++ context.meta[CONTEXT_GID] = argv[1 + CONTEXT_GID]; ++ context.meta[CONTEXT_SIGNAL] = argv[1 + CONTEXT_SIGNAL]; ++ context.meta[CONTEXT_TIMESTAMP] = argv[1 + CONTEXT_TIMESTAMP]; ++ context.meta[CONTEXT_RLIMIT] = argv[1 + CONTEXT_RLIMIT]; ++ context.meta[CONTEXT_HOSTNAME] = argv[1 + CONTEXT_HOSTNAME]; + +- r = gather_pid_metadata(context, argv + 1 + CONTEXT_COMM, iovec, &n_to_free); ++ r = gather_pid_metadata(&context, argv + 1 + CONTEXT_COMM, iovec, &n_to_free); + if (r < 0) + goto finish; + +@@ -1243,8 +1251,8 @@ static int process_kernel(int argc, char* argv[]) { + + assert(n_iovec <= ELEMENTSOF(iovec)); + +- if (is_journald_crash((const char**) context) || is_pid1_crash((const char**) context)) +- r = submit_coredump((const char**) context, ++ if (is_journald_crash(&context) || is_pid1_crash(&context)) ++ r = submit_coredump(&context, + iovec, ELEMENTSOF(iovec), n_iovec, + STDIN_FILENO); + else +@@ -1255,15 +1263,15 @@ static int process_kernel(int argc, char* argv[]) { + free(iovec[i].iov_base); + + /* Those fields are allocated by gather_pid_metadata */ +- free(context[CONTEXT_COMM]); +- free(context[CONTEXT_EXE]); +- free(context[CONTEXT_UNIT]); ++ free((char *) context.meta[CONTEXT_COMM]); ++ free((char *) context.meta[CONTEXT_EXE]); ++ free((char *) context.meta[CONTEXT_UNIT]); + + return r; + } + + static int process_backtrace(int argc, char *argv[]) { +- char *context[_CONTEXT_MAX] = {}; ++ Context context = {}; + _cleanup_free_ char *message = NULL; + _cleanup_free_ struct iovec *iovec = NULL; + size_t n_iovec, n_allocated, n_to_free = 0, i; +@@ -1279,13 +1287,13 @@ static int process_backtrace(int argc, char *argv[]) { + return -EINVAL; + } + +- context[CONTEXT_PID] = argv[2 + CONTEXT_PID]; +- context[CONTEXT_UID] = argv[2 + CONTEXT_UID]; +- context[CONTEXT_GID] = argv[2 + CONTEXT_GID]; +- context[CONTEXT_SIGNAL] = argv[2 + CONTEXT_SIGNAL]; +- context[CONTEXT_TIMESTAMP] = argv[2 + CONTEXT_TIMESTAMP]; +- context[CONTEXT_RLIMIT] = argv[2 + CONTEXT_RLIMIT]; +- context[CONTEXT_HOSTNAME] = argv[2 + CONTEXT_HOSTNAME]; ++ context.meta[CONTEXT_PID] = argv[2 + CONTEXT_PID]; ++ context.meta[CONTEXT_UID] = argv[2 + CONTEXT_UID]; ++ context.meta[CONTEXT_GID] = argv[2 + CONTEXT_GID]; ++ context.meta[CONTEXT_SIGNAL] = argv[2 + CONTEXT_SIGNAL]; ++ context.meta[CONTEXT_TIMESTAMP] = argv[2 + CONTEXT_TIMESTAMP]; ++ context.meta[CONTEXT_RLIMIT] = argv[2 + CONTEXT_RLIMIT]; ++ context.meta[CONTEXT_HOSTNAME] = argv[2 + CONTEXT_HOSTNAME]; + + n_allocated = 34 + COREDUMP_STORAGE_EXTERNAL; + /* 26 metadata, 2 static, +unknown input, 4 storage, rounded up */ +@@ -1293,7 +1301,7 @@ static int process_backtrace(int argc, char *argv[]) { + if (!iovec) + return log_oom(); + +- r = gather_pid_metadata(context, argv + 2 + CONTEXT_COMM, iovec, &n_to_free); ++ r = gather_pid_metadata(&context, argv + 2 + CONTEXT_COMM, iovec, &n_to_free); + if (r < 0) + goto finish; + if (r > 0) { +@@ -1320,10 +1328,10 @@ static int process_backtrace(int argc, char *argv[]) { + if (journal_importer_eof(&importer)) { + log_warning("Did not receive a full journal entry on stdin, ignoring message sent by reporter"); + +- message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], +- " (", context[CONTEXT_COMM], ")" +- " of user ", context[CONTEXT_UID], +- " failed with ", context[CONTEXT_SIGNAL]); ++ message = strjoin("MESSAGE=Process ", context.meta[CONTEXT_PID], ++ " (", context.meta[CONTEXT_COMM], ")" ++ " of user ", context.meta[CONTEXT_UID], ++ " failed with ", context.meta[CONTEXT_SIGNAL]); + if (!message) { + r = log_oom(); + goto finish; +@@ -1349,9 +1357,9 @@ static int process_backtrace(int argc, char *argv[]) { + free(iovec[i].iov_base); + + /* Those fields are allocated by gather_pid_metadata */ +- free(context[CONTEXT_COMM]); +- free(context[CONTEXT_EXE]); +- free(context[CONTEXT_UNIT]); ++ free((char *) context.meta[CONTEXT_COMM]); ++ free((char *) context.meta[CONTEXT_EXE]); ++ free((char *) context.meta[CONTEXT_UNIT]); + + return r; + } diff --git a/SOURCES/0862-coredump-do-not-allow-user-to-access-coredumps-with-.patch b/SOURCES/0862-coredump-do-not-allow-user-to-access-coredumps-with-.patch new file mode 100644 index 0000000..707bdda --- /dev/null +++ b/SOURCES/0862-coredump-do-not-allow-user-to-access-coredumps-with-.patch @@ -0,0 +1,354 @@ +From d178865d3d9940423f4d99360e3dc2fcaf0b2c96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 28 Nov 2022 12:12:55 +0100 +Subject: [PATCH] coredump: do not allow user to access coredumps with changed + uid/gid/capabilities + +When the user starts a program which elevates its permissions via setuid, +setgid, or capabilities set on the file, it may access additional information +which would then be visible in the coredump. We shouldn't make the the coredump +visible to the user in such cases. + +Reported-by: Matthias Gerstner + +This reads the /proc//auxv file and attaches it to the process metadata as +PROC_AUXV. Before the coredump is submitted, it is parsed and if either +at_secure was set (which the kernel will do for processes that are setuid, +setgid, or setcap), or if the effective uid/gid don't match uid/gid, the file +is not made accessible to the user. If we can't access this data, we assume the +file should not be made accessible either. In principle we could also access +the auxv data from a note in the core file, but that is much more complex and +it seems better to use the stand-alone file that is provided by the kernel. + +Attaching auxv is both convient for this patch (because this way it's passed +between the stages along with other fields), but I think it makes sense to save +it in general. + +We use the information early in the core file to figure out if the program was +32-bit or 64-bit and its endianness. This way we don't need heuristics to guess +whether the format of the auxv structure. This test might reject some cases on +fringe architecutes. But the impact would be limited: we just won't grant the +user permissions to view the coredump file. If people report that we're missing +some cases, we can always enhance this to support more architectures. + +I tested auxv parsing on amd64, 32-bit program on amd64, arm64, arm32, and +ppc64el, but not the whole coredump handling. + +(cherry picked from commit 3e4d0f6cf99f8677edd6a237382a65bfe758de03) + +Resolves: #2155520 +--- + src/coredump/coredump.c | 190 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 182 insertions(+), 8 deletions(-) + +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index ebc56d8342..d8acd2d3a7 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -88,11 +89,13 @@ enum { + CONTEXT_COMM, + CONTEXT_EXE, + CONTEXT_UNIT, ++ CONTEXT_PROC_AUXV, + _CONTEXT_MAX + }; + + typedef struct Context { + const char *meta[_CONTEXT_MAX]; ++ size_t meta_size[_CONTEXT_MAX]; + } Context; + + typedef enum CoredumpStorage { +@@ -148,8 +151,7 @@ static inline uint64_t storage_size_max(void) { + return 0; + } + +-static int fix_acl(int fd, uid_t uid) { +- ++static int fix_acl(int fd, uid_t uid, bool allow_user) { + #if HAVE_ACL + _cleanup_(acl_freep) acl_t acl = NULL; + acl_entry_t entry; +@@ -157,6 +159,11 @@ static int fix_acl(int fd, uid_t uid) { + int r; + + assert(fd >= 0); ++ assert(uid_is_valid(uid)); ++ ++ /* We don't allow users to read coredumps if the uid or capabilities were changed. */ ++ if (!allow_user) ++ return 0; + + if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY) + return 0; +@@ -235,7 +242,8 @@ static int fix_permissions( + const char *filename, + const char *target, + const Context *context, +- uid_t uid) { ++ uid_t uid, ++ bool allow_user) { + + int r; + +@@ -245,7 +253,7 @@ static int fix_permissions( + + /* Ignore errors on these */ + (void) fchmod(fd, 0640); +- (void) fix_acl(fd, uid); ++ (void) fix_acl(fd, uid, allow_user); + (void) fix_xattr(fd, context); + + if (fsync(fd) < 0) +@@ -316,6 +324,154 @@ static int make_filename(const Context *context, char **ret) { + return 0; + } + ++static int parse_auxv64( ++ const uint64_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ if (size_bytes % (2 * sizeof(uint64_t)) != 0) ++ return log_warning_errno(-EIO, "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ size_t words = size_bytes / sizeof(uint64_t); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(-ENODATA, ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int parse_auxv32( ++ const uint32_t *auxv, ++ size_t size_bytes, ++ int *at_secure, ++ uid_t *uid, ++ uid_t *euid, ++ gid_t *gid, ++ gid_t *egid) { ++ ++ assert(auxv || size_bytes == 0); ++ ++ size_t words = size_bytes / sizeof(uint32_t); ++ ++ if (size_bytes % (2 * sizeof(uint32_t)) != 0) ++ return log_warning_errno(-EIO, "Incomplete auxv structure (%zu bytes).", size_bytes); ++ ++ /* Note that we set output variables even on error. */ ++ ++ for (size_t i = 0; i + 1 < words; i += 2) ++ switch (auxv[i]) { ++ case AT_SECURE: ++ *at_secure = auxv[i + 1] != 0; ++ break; ++ case AT_UID: ++ *uid = auxv[i + 1]; ++ break; ++ case AT_EUID: ++ *euid = auxv[i + 1]; ++ break; ++ case AT_GID: ++ *gid = auxv[i + 1]; ++ break; ++ case AT_EGID: ++ *egid = auxv[i + 1]; ++ break; ++ case AT_NULL: ++ if (auxv[i + 1] != 0) ++ goto error; ++ return 0; ++ } ++ error: ++ return log_warning_errno(-ENODATA, ++ "AT_NULL terminator not found, cannot parse auxv structure."); ++} ++ ++static int grant_user_access(int core_fd, const Context *context) { ++ int at_secure = -1; ++ uid_t uid = UID_INVALID, euid = UID_INVALID; ++ uid_t gid = GID_INVALID, egid = GID_INVALID; ++ int r; ++ ++ assert(core_fd >= 0); ++ assert(context); ++ ++ if (!context->meta[CONTEXT_PROC_AUXV]) ++ return log_warning_errno(-ENODATA, "No auxv data, not adjusting permissions."); ++ ++ uint8_t elf[EI_NIDENT]; ++ errno = 0; ++ if (pread(core_fd, &elf, sizeof(elf), 0) != sizeof(elf)) ++ return log_warning_errno(errno > 0 ? -errno : -EIO, ++ "Failed to pread from coredump fd: %s", ++ errno > 0 ? STRERROR(errno) : "Unexpected EOF"); ++ ++ if (elf[EI_MAG0] != ELFMAG0 || ++ elf[EI_MAG1] != ELFMAG1 || ++ elf[EI_MAG2] != ELFMAG2 || ++ elf[EI_MAG3] != ELFMAG3 || ++ elf[EI_VERSION] != EV_CURRENT) ++ return log_info_errno(-EUCLEAN, ++ "Core file does not have ELF header, not adjusting permissions."); ++ if (!IN_SET(elf[EI_CLASS], ELFCLASS32, ELFCLASS64) || ++ !IN_SET(elf[EI_DATA], ELFDATA2LSB, ELFDATA2MSB)) ++ return log_info_errno(-EUCLEAN, ++ "Core file has strange ELF class, not adjusting permissions."); ++ ++ if ((elf[EI_DATA] == ELFDATA2LSB) != (__BYTE_ORDER == __LITTLE_ENDIAN)) ++ return log_info_errno(-EUCLEAN, ++ "Core file has non-native endianness, not adjusting permissions."); ++ ++ if (elf[EI_CLASS] == ELFCLASS64) ++ r = parse_auxv64((const uint64_t*) context->meta[CONTEXT_PROC_AUXV], ++ context->meta_size[CONTEXT_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ else ++ r = parse_auxv32((const uint32_t*) context->meta[CONTEXT_PROC_AUXV], ++ context->meta_size[CONTEXT_PROC_AUXV], ++ &at_secure, &uid, &euid, &gid, &egid); ++ if (r < 0) ++ return r; ++ ++ /* We allow access if we got all the data and at_secure is not set and ++ * the uid/gid matches euid/egid. */ ++ bool ret = ++ at_secure == 0 && ++ uid != UID_INVALID && euid != UID_INVALID && uid == euid && ++ gid != GID_INVALID && egid != GID_INVALID && gid == egid; ++ log_debug("Will %s access (uid="UID_FMT " euid="UID_FMT " gid="GID_FMT " egid="GID_FMT " at_secure=%s)", ++ ret ? "permit" : "restrict", ++ uid, euid, gid, egid, yes_no(at_secure)); ++ return ret; ++} ++ + static int save_external_coredump( + const Context *context, + int input_fd, +@@ -395,6 +551,8 @@ static int save_external_coredump( + goto fail; + } + ++ bool allow_user = grant_user_access(fd, context) > 0; ++ + #if HAVE_XZ || HAVE_LZ4 + /* If we will remove the coredump anyway, do not compress. */ + if (arg_compress && !maybe_remove_external_coredump(NULL, st.st_size)) { +@@ -420,7 +578,7 @@ static int save_external_coredump( + goto fail_compressed; + } + +- r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid); ++ r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid, allow_user); + if (r < 0) + goto fail_compressed; + +@@ -443,7 +601,7 @@ static int save_external_coredump( + uncompressed: + #endif + +- r = fix_permissions(fd, tmp, fn, context, uid); ++ r = fix_permissions(fd, tmp, fn, context, uid, allow_user); + if (r < 0) + goto fail; + +@@ -842,6 +1000,7 @@ static void map_context_fields(const struct iovec *iovec, Context *context) { + [CONTEXT_HOSTNAME] = "COREDUMP_HOSTNAME=", + [CONTEXT_COMM] = "COREDUMP_COMM=", + [CONTEXT_EXE] = "COREDUMP_EXE=", ++ [CONTEXT_PROC_AUXV] = "COREDUMP_PROC_AUXV=", + }; + + unsigned i; +@@ -862,6 +1021,7 @@ static void map_context_fields(const struct iovec *iovec, Context *context) { + /* Note that these strings are NUL terminated, because we made sure that a trailing NUL byte is in the + * buffer, though not included in the iov_len count. (see below) */ + context->meta[i] = p; ++ context->meta_size[i] = iovec->iov_len - strlen(context_field_names[i]); + break; + } + } +@@ -1070,7 +1230,7 @@ static int gather_pid_metadata( + char **comm_fallback, + struct iovec *iovec, size_t *n_iovec) { + +- /* We need 27 empty slots in iovec! ++ /* We need 28 empty slots in iovec! + * + * Note that if we fail on oom later on, we do not roll-back changes to the iovec structure. (It remains valid, + * with the first n_iovec fields initialized.) */ +@@ -1078,6 +1238,7 @@ static int gather_pid_metadata( + uid_t owner_uid; + pid_t pid; + char *t; ++ size_t size; + const char *p; + int r, signo; + +@@ -1187,6 +1348,19 @@ static int gather_pid_metadata( + if (read_full_file(p, &t, NULL) >=0) + set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_MOUNTINFO=", t); + ++ /* We attach /proc/auxv here. ELF coredumps also contain a note for this (NT_AUXV), see elf(5). */ ++ p = procfs_file_alloca(pid, "auxv"); ++ if (read_full_file(p, &t, &size) >= 0) { ++ char *buf = malloc(strlen("COREDUMP_PROC_AUXV=") + size + 1); ++ if (buf) { ++ /* Add a dummy terminator to make save_context() happy. */ ++ *((uint8_t*) mempcpy(stpcpy(buf, "COREDUMP_PROC_AUXV="), t, size)) = '\0'; ++ iovec[(*n_iovec)++] = IOVEC_MAKE(buf, size + strlen("COREDUMP_PROC_AUXV=")); ++ } ++ ++ free(t); ++ } ++ + if (get_process_cwd(pid, &t) >= 0) + set_iovec_field_free(iovec, n_iovec, "COREDUMP_CWD=", t); + +@@ -1219,7 +1393,7 @@ static int gather_pid_metadata( + static int process_kernel(int argc, char* argv[]) { + + Context context = {}; +- struct iovec iovec[29 + SUBMIT_COREDUMP_FIELDS]; ++ struct iovec iovec[30 + SUBMIT_COREDUMP_FIELDS]; + size_t i, n_iovec, n_to_free = 0; + int r; + diff --git a/SOURCES/0863-logind-remember-our-idle-state-and-use-it-to-detect-.patch b/SOURCES/0863-logind-remember-our-idle-state-and-use-it-to-detect-.patch new file mode 100644 index 0000000..583749a --- /dev/null +++ b/SOURCES/0863-logind-remember-our-idle-state-and-use-it-to-detect-.patch @@ -0,0 +1,70 @@ +From a55bdb007ca24900a704f72359305b04125d9e05 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 20 Apr 2022 10:13:43 +0200 +Subject: [PATCH] logind: remember our idle state and use it to detect idle + level transitions + +Fixes #16391 + +(cherry picked from commit 4e2cfb778b9ed7f22ee98f48f28cf8678d25ad32) + +Resolved: #1866955 +--- + src/login/logind.c | 23 +++++++++++++++++++---- + src/login/logind.h | 1 + + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/login/logind.c b/src/login/logind.c +index 6b576dad0d..bb1d3f3523 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -1027,18 +1027,33 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us + n = now(CLOCK_MONOTONIC); + + r = manager_get_idle_hint(m, &since); +- if (r <= 0) ++ if (r <= 0) { + /* Not idle. Let's check if after a timeout it might be idle then. */ + elapse = n + m->idle_action_usec; +- else { ++ m->was_idle = false; ++ } else { ++ + /* Idle! Let's see if it's time to do something, or if + * we shall sleep for longer. */ + + if (n >= since.monotonic + m->idle_action_usec && + (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) { +- log_info("System idle. Taking action."); ++ bool is_edge = false; ++ ++ /* We weren't idle previously or some activity happened while we were sleeping, and now we are ++ * idle. Let's remember that for the next time and make this an edge transition. */ ++ if (!m->was_idle || since.monotonic >= m->idle_action_not_before_usec) { ++ is_edge = true; ++ m->was_idle = true; ++ } ++ ++ if (m->idle_action == HANDLE_LOCK && !is_edge) ++ /* We are idle and we were before so we are actually not taking any action. */ ++ log_debug("System idle."); ++ else ++ log_info("System idle. Doing %s operation.", handle_action_to_string(m->idle_action)); + +- manager_handle_action(m, 0, m->idle_action, false, false); ++ manager_handle_action(m, 0, m->idle_action, false, is_edge); + m->idle_action_not_before_usec = n; + } + +diff --git a/src/login/logind.h b/src/login/logind.h +index 606adf4fe6..b9b4a5113f 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -101,6 +101,7 @@ struct Manager { + usec_t idle_action_usec; + usec_t idle_action_not_before_usec; + HandleAction idle_action; ++ bool was_idle; + + usec_t stop_idle_session_usec; + diff --git a/SOURCES/0864-test-import-logind-test-from-debian-ubuntu-test-suit.patch b/SOURCES/0864-test-import-logind-test-from-debian-ubuntu-test-suit.patch new file mode 100644 index 0000000..6c058f8 --- /dev/null +++ b/SOURCES/0864-test-import-logind-test-from-debian-ubuntu-test-suit.patch @@ -0,0 +1,103 @@ +From 1925845dc10330e4b48fec68333fac6ef2b7bf5c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 1 Jun 2022 08:56:08 +0900 +Subject: [PATCH] test: import logind test from debian/ubuntu test suite + +[dtardon: Picked just the scaffolding, not the tests themselves.] + +(cherry picked from commit 9c94ab0f6ff22da4278a6e9a93ddc480607c55ac) + +Related: #1866955 +--- + test/TEST-35-LOGIN/Makefile | 1 + + test/TEST-35-LOGIN/test.sh | 55 +++++++++++++++++++++++++++++++++ + test/TEST-35-LOGIN/testsuite.sh | 9 ++++++ + 3 files changed, 65 insertions(+) + create mode 120000 test/TEST-35-LOGIN/Makefile + create mode 100755 test/TEST-35-LOGIN/test.sh + create mode 100755 test/TEST-35-LOGIN/testsuite.sh + +diff --git a/test/TEST-35-LOGIN/Makefile b/test/TEST-35-LOGIN/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-35-LOGIN/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-35-LOGIN/test.sh b/test/TEST-35-LOGIN/test.sh +new file mode 100755 +index 0000000000..32410c8149 +--- /dev/null ++++ b/test/TEST-35-LOGIN/test.sh +@@ -0,0 +1,55 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -e ++ ++TEST_DESCRIPTION="LOGIN" ++ ++# shellcheck source=test/test-functions ++. "${TEST_BASE_DIR:?}/test-functions" ++ ++test_setup() { ++ create_empty_image ++ mkdir -p "$TESTDIR"/root ++ mount "${LOOPDEV}p1" "$TESTDIR"/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name="${LOOPDEV}p2") ++ ++ setup_basic_environment ++ ++ inst_binary pkill ++ inst_binary useradd ++ inst_binary userdel ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >"$initdir"/etc/systemd/system/testsuite.service </failed ++ ++touch /testok ++rm /failed diff --git a/SOURCES/0865-test-introduce-inst_recursive-helper-function.patch b/SOURCES/0865-test-introduce-inst_recursive-helper-function.patch new file mode 100644 index 0000000..cb98216 --- /dev/null +++ b/SOURCES/0865-test-introduce-inst_recursive-helper-function.patch @@ -0,0 +1,37 @@ +From 21c281585983fe2efc2b74d712d98ff7e6c013b1 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 14 Jun 2022 09:11:00 +0900 +Subject: [PATCH] test: introduce inst_recursive() helper function + +(cherry picked from commit da0465dc95388afc15598357452afef85035c639) + +Related: #1866955 +--- + test/test-functions | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/test/test-functions b/test/test-functions +index 19363be858..9606a1b085 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1224,6 +1224,20 @@ inst_any() { + return 1 + } + ++inst_recursive() { ++ local p item ++ ++ for p in "$@"; do ++ while read -r item; do ++ if [[ -d "$item" ]]; then ++ inst_dir "$item" ++ elif [[ -f "$item" ]]; then ++ inst_simple "$item" ++ fi ++ done < <(find "$p" 2>/dev/null) ++ done ++} ++ + # dracut_install [-o ] [ ... ] + # Install to the initramfs image + # -o optionally install the and don't fail, if it is not there diff --git a/SOURCES/0866-tests-verify-that-Lock-D-Bus-signal-is-sent-when-Idl.patch b/SOURCES/0866-tests-verify-that-Lock-D-Bus-signal-is-sent-when-Idl.patch new file mode 100644 index 0000000..f1fe13a --- /dev/null +++ b/SOURCES/0866-tests-verify-that-Lock-D-Bus-signal-is-sent-when-Idl.patch @@ -0,0 +1,148 @@ +From 638c2418e705410344e07e77f944530df0f4608f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 1 Jul 2022 12:59:57 +0200 +Subject: [PATCH] tests: verify that Lock D-Bus signal is sent when + IdleAction=lock + +(cherry picked from commit 181656fc0faa885d69bc34822b8e9b5de3fdf6bf) + +Related: #1866955 +--- + test/TEST-35-LOGIN/test.sh | 11 +++- + test/TEST-35-LOGIN/testsuite.sh | 93 +++++++++++++++++++++++++++++++++ + 2 files changed, 103 insertions(+), 1 deletion(-) + +diff --git a/test/TEST-35-LOGIN/test.sh b/test/TEST-35-LOGIN/test.sh +index 32410c8149..f83afcff49 100755 +--- a/test/TEST-35-LOGIN/test.sh ++++ b/test/TEST-35-LOGIN/test.sh +@@ -14,14 +14,23 @@ test_setup() { + + ( + LOG_LEVEL=5 +- eval $(udevadm info --export --query=env --name="${LOOPDEV}p2") ++ eval "$(udevadm info --export --query=env --name="${LOOPDEV}p2")" + + setup_basic_environment + ++ inst_binary awk + inst_binary pkill + inst_binary useradd + inst_binary userdel + ++ if command -v expect >/dev/null && command -v tclsh >/dev/null ; then ++ # shellcheck disable=SC2016 ++ version="$(tclsh <<< 'puts $tcl_version')" ++ ++ dracut_install expect ++ inst_recursive /usr/lib64/tcl"$version" /usr/share/tcl"$version" ++ fi ++ + # mask some services that we do not want to run in these tests + ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-hwdb-update.service + ln -fs /dev/null "$initdir"/etc/systemd/system/systemd-journal-catalog-update.service +diff --git a/test/TEST-35-LOGIN/testsuite.sh b/test/TEST-35-LOGIN/testsuite.sh +index 9855b4bc80..e4d72beb74 100755 +--- a/test/TEST-35-LOGIN/testsuite.sh ++++ b/test/TEST-35-LOGIN/testsuite.sh +@@ -3,7 +3,100 @@ + set -eux + set -o pipefail + ++setup_idle_action_lock() { ++ useradd testuser ||: ++ ++ mkdir -p /run/systemd/logind.conf.d/ ++ cat >/run/systemd/logind.conf.d/idle-action-lock.conf </run/systemd/systemd-logind.service.d/debug.conf </dev/null ; then ++ echo >&2 "expect not installed, skiping test ${FUNCNAME[0]}" ++ return 0 ++ fi ++ ++ setup_idle_action_lock ++ trap teardown_idle_action_lock RETURN ++ ++ if loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -q testuser ; then ++ echo >&2 "Session of the \'testuser\' is already present." ++ return 1 ++ fi ++ ++ # IdleActionSec is set 1s but the accuracy of associated timer is 30s so we ++ # need to sleep in worst case for 31s to make sure timer elapsed. We sleep ++ # here for 35s to accomodate for any possible scheudling delays. ++ cat > /tmp/test.exp < dbus.log & ++ ++ expect /tmp/test.exp & ++ ++ # Sleep a bit to give expect time to spawn systemd-run before we check for ++ # the presence of resulting session. ++ sleep 2 ++ if [ "$(loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -c testuser)" != 1 ] ; then ++ echo >&2 "\'testuser\' is expected to have exactly one session running." ++ return 1 ++ fi ++ ++ wait %2 ++ sleep 20 ++ kill %1 ++ ++ # We slept for 35s , in that interval all sessions should have become idle ++ # and "Lock" signal should have been sent out. Then we wrote to tty to make ++ # session active again and next we slept for another 35s so sessions have ++ # become idle again. 'Lock' signal is sent out for each session, we have at ++ # least one session, so minimum of 2 "Lock" signals must have been sent. ++ if [ "$(grep -c Member=Lock dbus.log)" -lt 2 ]; then ++ echo >&2 "Too few 'Lock' D-Bus signal sent, expected at least 2." ++ return 1 ++ fi ++ ++ journalctl -b -u systemd-logind.service --since="$ts" > logind.log ++ if [ "$(grep -c 'System idle. Doing lock operation.' logind.log)" -lt 2 ]; then ++ echo >&2 "System haven't entered idle state at least 2 times." ++ return 1 ++ fi ++ ++ rm -f dbus.log logind.log ++} ++ + : >/failed + ++test_lock_idle_action ++ + touch /testok + rm /failed diff --git a/SOURCES/0867-systemctl-simplify-halt_main.patch b/SOURCES/0867-systemctl-simplify-halt_main.patch new file mode 100644 index 0000000..bd1d085 --- /dev/null +++ b/SOURCES/0867-systemctl-simplify-halt_main.patch @@ -0,0 +1,86 @@ +From 797b00e6a6f33d2b74beba02f678bf4d12e2146b Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Tue, 14 Dec 2021 17:27:05 +0100 +Subject: [PATCH] systemctl: simplify halt_main() + +The code at this point is not able to tell whether it was called as +halt/poweroff/reboot or shutdown with time "now". +The code also takes a shortcut to skip logind if called as root. +That however means asking shutdown for immediate action won't trigger a +wall message. +As per https://github.com/systemd/systemd/issues/8424#issuecomment-374677315 +all commands should trigger a wall message. +That simplifies the code as we can try logind first always. + +(cherry picked from commit adefc8789b63225662e50ceaa282f9553b5c64eb) + +Resolves: #2053273 +--- + src/systemctl/systemctl.c | 44 ++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 26 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index b967550b97..4bedb52f2a 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -8658,34 +8658,23 @@ static int logind_schedule_shutdown(void) { + static int halt_main(void) { + int r; + +- r = logind_check_inhibitors(arg_action); +- if (r < 0) +- return r; +- ++ /* always try logind first */ + if (arg_when > 0) +- return logind_schedule_shutdown(); +- +- if (geteuid() != 0) { +- if (arg_dry_run || arg_force > 0) { +- (void) must_be_root(); +- return -EPERM; +- } ++ r = logind_schedule_shutdown(); ++ else { ++ r = logind_check_inhibitors(arg_action); ++ if (r < 0) ++ return r; + +- /* Try logind if we are a normal user and no special +- * mode applies. Maybe PolicyKit allows us to shutdown +- * the machine. */ +- if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) { +- r = logind_reboot(arg_action); +- if (r >= 0) +- return r; +- if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) +- /* requested operation is not +- * supported on the local system or +- * already in progress */ +- return r; +- /* on all other errors, try low-level operation */ +- } ++ r = logind_reboot(arg_action); + } ++ if (r >= 0) ++ return r; ++ if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) ++ /* Requested operation is not supported on the local system or already in ++ * progress */ ++ return r; ++ /* on all other errors, try low-level operation */ + + /* In order to minimize the difference between operation with and + * without logind, we explicitly enable non-blocking mode for this, +@@ -8695,7 +8684,10 @@ static int halt_main(void) { + if (!arg_dry_run && !arg_force) + return start_with_fallback(); + +- assert(geteuid() == 0); ++ if (geteuid() != 0) { ++ (void) must_be_root(); ++ return -EPERM; ++ } + + if (!arg_no_wtmp) { + if (sd_booted() > 0) diff --git a/SOURCES/0868-systemctl-shutdown-don-t-fallback-on-auth-fail.patch b/SOURCES/0868-systemctl-shutdown-don-t-fallback-on-auth-fail.patch new file mode 100644 index 0000000..dd7b2dd --- /dev/null +++ b/SOURCES/0868-systemctl-shutdown-don-t-fallback-on-auth-fail.patch @@ -0,0 +1,51 @@ +From 1d63577410cde215c04921d62f435259a6b258d7 Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Mon, 20 Dec 2021 18:05:50 +0100 +Subject: [PATCH] systemctl: shutdown don't fallback on auth fail + +For shutdowns don't fall back to starting the target directly if talking +to logind failed with auth failure. That would just lead to another +polkit auth attempt. + +(cherry picked from commit 38d55bf2641f345445cb4e6a5e5e808555591db2) + +Related: #2053273 +--- + src/systemctl/systemctl.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 4bedb52f2a..199f736f7f 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -3675,8 +3675,8 @@ static int start_special(int argc, char *argv[], void *userdata) { + r = logind_reboot(a); + if (r >= 0) + return r; +- if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) +- /* requested operation is not supported or already in progress */ ++ if (IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS)) ++ /* Requested operation requires auth, is not supported or already in progress */ + return r; + + /* On all other errors, try low-level operation. In order to minimize the difference between +@@ -8644,7 +8644,7 @@ static int logind_schedule_shutdown(void) { + action, + arg_when); + if (r < 0) +- return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r)); ++ return log_warning_errno(r, "Failed to schedule shutdown: %s", bus_error_message(&error, r)); + + if (!arg_quiet) + log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when)); +@@ -8670,8 +8670,8 @@ static int halt_main(void) { + } + if (r >= 0) + return r; +- if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) +- /* Requested operation is not supported on the local system or already in ++ if (IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS)) ++ /* Requested operation requires auth, is not supported on the local system or already in + * progress */ + return r; + /* on all other errors, try low-level operation */ diff --git a/SOURCES/0869-systemctl-reintroduce-the-original-halt_main.patch b/SOURCES/0869-systemctl-reintroduce-the-original-halt_main.patch new file mode 100644 index 0000000..dce7359 --- /dev/null +++ b/SOURCES/0869-systemctl-reintroduce-the-original-halt_main.patch @@ -0,0 +1,82 @@ +From d36295d7c1b110d150b7af6e3354c28af4c4884d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 30 Jan 2023 14:27:24 +0100 +Subject: [PATCH] systemctl: reintroduce the original halt_main() + +RHEL-only + +Related: #2053273 +--- + src/systemctl/systemctl.c | 59 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 199f736f7f..a26e4a913a 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -8655,6 +8655,65 @@ static int logind_schedule_shutdown(void) { + #endif + } + ++static int halt_main_old(void) { ++ int r; ++ ++ r = logind_check_inhibitors(arg_action); ++ if (r < 0) ++ return r; ++ ++ if (arg_when > 0) ++ return logind_schedule_shutdown(); ++ ++ if (geteuid() != 0) { ++ if (arg_dry_run || arg_force > 0) { ++ (void) must_be_root(); ++ return -EPERM; ++ } ++ ++ /* Try logind if we are a normal user and no special ++ * mode applies. Maybe PolicyKit allows us to shutdown ++ * the machine. */ ++ if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) { ++ r = logind_reboot(arg_action); ++ if (r >= 0) ++ return r; ++ if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) ++ /* requested operation is not ++ * supported on the local system or ++ * already in progress */ ++ return r; ++ /* on all other errors, try low-level operation */ ++ } ++ } ++ ++ /* In order to minimize the difference between operation with and ++ * without logind, we explicitly enable non-blocking mode for this, ++ * as logind's shutdown operations are always non-blocking. */ ++ arg_no_block = true; ++ ++ if (!arg_dry_run && !arg_force) ++ return start_with_fallback(); ++ ++ assert(geteuid() == 0); ++ ++ if (!arg_no_wtmp) { ++ if (sd_booted() > 0) ++ log_debug("Not writing utmp record, assuming that systemd-update-utmp is used."); ++ else { ++ r = utmp_put_shutdown(); ++ if (r < 0) ++ log_warning_errno(r, "Failed to write utmp record: %m"); ++ } ++ } ++ ++ if (arg_dry_run) ++ return 0; ++ ++ r = halt_now(arg_action); ++ return log_error_errno(r, "Failed to reboot: %m"); ++} ++ + static int halt_main(void) { + int r; + diff --git a/SOURCES/0870-systemctl-preserve-old-behavior-unless-requested.patch b/SOURCES/0870-systemctl-preserve-old-behavior-unless-requested.patch new file mode 100644 index 0000000..e652470 --- /dev/null +++ b/SOURCES/0870-systemctl-preserve-old-behavior-unless-requested.patch @@ -0,0 +1,44 @@ +From 74632586b46c7e88b09c57eec50f9c4aed254b98 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 30 Jan 2023 14:31:23 +0100 +Subject: [PATCH] systemctl: preserve old behavior unless requested + +Currently, the legacy shutdown commands ignore inhibitors and reboot +immediately if run by root. Let's preserve that behavior in RHEL-8 by +default. The new behavior can be turned on by those who want it by +exporting SYSTEMD_NEW_SHUTDOWN=1 . + +RHEL-only + +Related: #2053273 +--- + src/systemctl/systemctl.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index a26e4a913a..1546119ce5 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -8714,7 +8714,7 @@ static int halt_main_old(void) { + return log_error_errno(r, "Failed to reboot: %m"); + } + +-static int halt_main(void) { ++static int halt_main_new(void) { + int r; + + /* always try logind first */ +@@ -8765,6 +8765,13 @@ static int halt_main(void) { + return log_error_errno(r, "Failed to reboot: %m"); + } + ++static int halt_main(void) { ++ if (getenv_bool("SYSTEMD_NEW_SHUTDOWN") > 0) ++ return halt_main_new(); ++ else ++ return halt_main_old(); ++} ++ + static int runlevel_main(void) { + int r, runlevel, previous; + diff --git a/SOURCES/0871-pam_systemd-suppress-LOG_DEBUG-log-messages-if-debug.patch b/SOURCES/0871-pam_systemd-suppress-LOG_DEBUG-log-messages-if-debug.patch new file mode 100644 index 0000000..70e8f6f --- /dev/null +++ b/SOURCES/0871-pam_systemd-suppress-LOG_DEBUG-log-messages-if-debug.patch @@ -0,0 +1,43 @@ +From ea3910e561f043f5a131a846862955c77169da1b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 19 Nov 2018 11:39:45 +0100 +Subject: [PATCH] pam_systemd: suppress LOG_DEBUG log messages if debugging is + off + +In the PAM module we need to suppress LOG_DEBUG messages manually, if +debug logging is not on, as PAM won't do this for us. We did this +correctly for most log messages already, but two were missing. Let's fix +those too. + +Fixes: #10822 +(cherry picked from commit 2675747f3cdd6f1e6236bbb2f79abfa53fb307f1) + +Resolves: #2170084 +--- + src/login/pam_systemd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index 64e1b4d1bf..c87e980b18 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -476,7 +476,8 @@ _public_ PAM_EXTERN int pam_sm_open_session( + } + + if (seat && !streq(seat, "seat0") && vtnr != 0) { +- pam_syslog(handle, LOG_DEBUG, "Ignoring vtnr %"PRIu32" for %s which is not seat0", vtnr, seat); ++ if (debug) ++ pam_syslog(handle, LOG_DEBUG, "Ignoring vtnr %"PRIu32" for %s which is not seat0", vtnr, seat); + vtnr = 0; + } + +@@ -577,7 +578,8 @@ _public_ PAM_EXTERN int pam_sm_open_session( + r = sd_bus_call(bus, m, 0, &error, &reply); + if (r < 0) { + if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) { +- pam_syslog(handle, LOG_DEBUG, "Cannot create session: %s", bus_error_message(&error, r)); ++ if (debug) ++ pam_syslog(handle, LOG_DEBUG, "Cannot create session: %s", bus_error_message(&error, r)); + return PAM_SUCCESS; + } else { + pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r)); diff --git a/SOURCES/0872-udev-net_id-introduce-naming-scheme-for-RHEL-8.8.patch b/SOURCES/0872-udev-net_id-introduce-naming-scheme-for-RHEL-8.8.patch new file mode 100644 index 0000000..c83b140 --- /dev/null +++ b/SOURCES/0872-udev-net_id-introduce-naming-scheme-for-RHEL-8.8.patch @@ -0,0 +1,50 @@ +From 33351e103734188a4a30b88e7f2ea0613d628599 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 16 Feb 2023 15:56:52 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.8 + +RHEL-only + +Resolves: #2170499 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index a567483995..3cc7719e99 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -328,6 +328,12 @@ + for that, the limit is increased to now 65535. + + ++ ++ rhel-8.8 ++ ++ Same as naming scheme rhel-8.7. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index df84acf27c..ef2bb1b08e 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -141,6 +141,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_5 = NAMING_RHEL_8_4, + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, ++ NAMING_RHEL_8_8 = NAMING_RHEL_8_7, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -161,6 +162,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.5", NAMING_RHEL_8_5 }, + { "rhel-8.6", NAMING_RHEL_8_6 }, + { "rhel-8.7", NAMING_RHEL_8_7 }, ++ { "rhel-8.8", NAMING_RHEL_8_8 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0873-journald-add-API-to-move-logging-from-var-to-run-aga.patch b/SOURCES/0873-journald-add-API-to-move-logging-from-var-to-run-aga.patch new file mode 100644 index 0000000..f44f50b --- /dev/null +++ b/SOURCES/0873-journald-add-API-to-move-logging-from-var-to-run-aga.patch @@ -0,0 +1,176 @@ +From 8f0a91b5192b72eb8b0f06e04ef3515d0397fcb8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Apr 2019 18:20:25 +0200 +Subject: [PATCH] journald: add API to move logging from /var to /run again + +We now have this nice little Varlink API, let's beef it up a bit. + +[dtardon: This diverges from the upstream commit in two ways: One is +that the new action is bound to a signal, as varlink is not available. +The other is that this introduces a new "flag" file +/run/systemd/journal/relinquished, which is essentially the opposite of +/run/systemd/journal/flushed (hence at most one of them may exist at any +time).] + +(cherry picked from commit b4e26d1d8e582d78e67ed766177f10e8e194404c) + +Related: #1873540 +--- + src/journal/journald-server.c | 64 ++++++++++++++++++++++++++++------- + 1 file changed, 51 insertions(+), 13 deletions(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 7632e2d9d0..279a32768c 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -283,13 +283,14 @@ static bool flushed_flag_is_set(void) { + return access("/run/systemd/journal/flushed", F_OK) >= 0; + } + +-static int system_journal_open(Server *s, bool flush_requested) { ++static int system_journal_open(Server *s, bool flush_requested, bool relinquish_requested) { + const char *fn; + int r = 0; + + if (!s->system_journal && + IN_SET(s->storage, STORAGE_PERSISTENT, STORAGE_AUTO) && +- (flush_requested || flushed_flag_is_set())) { ++ (flush_requested || flushed_flag_is_set()) && ++ !relinquish_requested) { + + /* If in auto mode: first try to create the machine + * path, but not the prefix. +@@ -331,7 +332,7 @@ static int system_journal_open(Server *s, bool flush_requested) { + + fn = strjoina(s->runtime_storage.path, "/system.journal"); + +- if (s->system_journal) { ++ if (s->system_journal && !relinquish_requested) { + + /* Try to open the runtime journal, but only + * if it already exists, so that we can flush +@@ -386,7 +387,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { + * else that's left the journals as NULL). + * + * Fixes https://github.com/systemd/systemd/issues/3968 */ +- (void) system_journal_open(s, false); ++ (void) system_journal_open(s, false, false); + + /* We split up user logs only on /var, not on /run. If the + * runtime file is open, we write to it exclusively, in order +@@ -964,7 +965,7 @@ int server_flush_to_var(Server *s, bool require_flag_file) { + char ts[FORMAT_TIMESPAN_MAX]; + usec_t start; + unsigned n = 0; +- int r; ++ int r, k; + + assert(s); + +@@ -977,7 +978,7 @@ int server_flush_to_var(Server *s, bool require_flag_file) { + if (require_flag_file && !flushed_flag_is_set()) + return 0; + +- (void) system_journal_open(s, true); ++ (void) system_journal_open(s, true, false); + + if (!s->system_journal) + return 0; +@@ -1056,6 +1057,13 @@ finish: + n), + NULL); + ++ if (unlink("/run/systemd/journal/relinquished") < 0 && errno != ENOENT) ++ log_warning_errno(errno, "Failed to unlink /run/systemd/journal/relinquished, ignoring: %m"); ++ ++ k = touch("/run/systemd/journal/flushed"); ++ if (k < 0) ++ log_warning_errno(k, "Failed to touch /run/systemd/journal/flushed, ignoring: %m"); ++ + return r; + } + +@@ -1180,7 +1188,6 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + + static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { + Server *s = userdata; +- int r; + + assert(s); + +@@ -1190,10 +1197,6 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo * + server_sync(s); + server_vacuum(s, false); + +- r = touch("/run/systemd/journal/flushed"); +- if (r < 0) +- log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m"); +- + server_space_usage_message(s, NULL); + return 0; + } +@@ -1250,12 +1253,43 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo + return 0; + } + ++ ++static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { ++ Server *s = userdata; ++ int r; ++ ++ assert(s); ++ ++ if (s->storage == STORAGE_NONE) ++ return 0; ++ ++ if (s->runtime_journal && !s->system_journal) ++ return 0; ++ ++ log_debug("Received request to relinquish /var from PID " PID_FMT, si->ssi_pid); ++ ++ (void) system_journal_open(s, false, true); ++ ++ s->system_journal = journal_file_close(s->system_journal); ++ ordered_hashmap_clear_with_destructor(s->user_journals, journal_file_close); ++ set_clear_with_destructor(s->deferred_closes, journal_file_close); ++ ++ if (unlink("/run/systemd/journal/flushed") < 0 && errno != ENOENT) ++ log_warning_errno(errno, "Failed to unlink /run/systemd/journal/flushed, ignoring: %m") ; ++ ++ r = write_timestamp_file_atomic("/run/systemd/journal/relinquished", now(CLOCK_MONOTONIC)); ++ if (r < 0) ++ log_warning_errno(r, "Failed to write /run/systemd/journal/relinquished, ignoring: %m"); ++ ++ return 0; ++} ++ + static int setup_signals(Server *s) { + int r; + + assert(s); + +- assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0); ++ assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, SIGRTMIN+2, -1) >= 0); + + r = sd_event_add_signal(s->event, &s->sigusr1_event_source, SIGUSR1, dispatch_sigusr1, s); + if (r < 0) +@@ -1294,6 +1328,10 @@ static int setup_signals(Server *s) { + if (r < 0) + return r; + ++ r = sd_event_add_signal(s->event, &s->sigrtmin1_event_source, SIGRTMIN+2, dispatch_sigrtmin2, s); ++ if (r < 0) ++ return r; ++ + r = sd_event_source_set_priority(s->sigrtmin1_event_source, SD_EVENT_PRIORITY_NORMAL+15); + if (r < 0) + return r; +@@ -1876,7 +1914,7 @@ int server_init(Server *s) { + + (void) client_context_acquire_default(s); + +- return system_journal_open(s, false); ++ return system_journal_open(s, false, false); + } + + void server_maybe_append_tags(Server *s) { diff --git a/SOURCES/0874-journalctl-add-new-relinquish-and-smart-relinquish-o.patch b/SOURCES/0874-journalctl-add-new-relinquish-and-smart-relinquish-o.patch new file mode 100644 index 0000000..65b8ac3 --- /dev/null +++ b/SOURCES/0874-journalctl-add-new-relinquish-and-smart-relinquish-o.patch @@ -0,0 +1,242 @@ +From fa93a97bdf18906d9517f4183802456986490c89 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Apr 2019 18:21:02 +0200 +Subject: [PATCH] journalctl: add new --relinquish and --smart-relinquish + options + +The latter is identical to the former, but becomes a NOP if +/var/log/journal is on the same mount as /, and thus during shutdown +unmounting /var is not necessary and hence we can keep logging until the +very end. + +[dtardon: The only divergence from the upstream commit is the impl. of +relinquish_var().] + +(cherry picked from commit c0dfcb318c28d87e1176a8ad87ac7cc4ecc50305) + +Related: #1873540 +--- + src/journal/journalctl.c | 161 +++++++++++++++++++++++++-------------- + 1 file changed, 103 insertions(+), 58 deletions(-) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index 228cfe7e49..6928c79a06 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -47,6 +47,7 @@ + #include "log.h" + #include "logs-show.h" + #include "mkdir.h" ++#include "mount-util.h" + #include "pager.h" + #include "parse-util.h" + #include "path-util.h" +@@ -162,6 +163,7 @@ static enum { + ACTION_UPDATE_CATALOG, + ACTION_LIST_BOOTS, + ACTION_FLUSH, ++ ACTION_RELINQUISH_VAR, + ACTION_SYNC, + ACTION_ROTATE, + ACTION_VACUUM, +@@ -358,6 +360,8 @@ static void help(void) { + " --vacuum-time=TIME Remove journal files older than specified time\n" + " --verify Verify journal file consistency\n" + " --sync Synchronize unwritten journal messages to disk\n" ++ " --relinquish-var Stop logging to disk, log to temporary file system\n" ++ " --smart-relinquish-var Similar, but NOP if log directory is on root mount\n" + " --flush Flush all journal data from /run into /var\n" + " --rotate Request immediate rotation of the journal files\n" + " --header Show journal header information\n" +@@ -402,6 +406,8 @@ static int parse_argv(int argc, char *argv[]) { + ARG_UTC, + ARG_SYNC, + ARG_FLUSH, ++ ARG_RELINQUISH_VAR, ++ ARG_SMART_RELINQUISH_VAR, + ARG_ROTATE, + ARG_VACUUM_SIZE, + ARG_VACUUM_FILES, +@@ -411,64 +417,66 @@ static int parse_argv(int argc, char *argv[]) { + }; + + static const struct option options[] = { +- { "help", no_argument, NULL, 'h' }, +- { "version" , no_argument, NULL, ARG_VERSION }, +- { "no-pager", no_argument, NULL, ARG_NO_PAGER }, +- { "pager-end", no_argument, NULL, 'e' }, +- { "follow", no_argument, NULL, 'f' }, +- { "force", no_argument, NULL, ARG_FORCE }, +- { "output", required_argument, NULL, 'o' }, +- { "all", no_argument, NULL, 'a' }, +- { "full", no_argument, NULL, 'l' }, +- { "no-full", no_argument, NULL, ARG_NO_FULL }, +- { "lines", optional_argument, NULL, 'n' }, +- { "no-tail", no_argument, NULL, ARG_NO_TAIL }, +- { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, +- { "quiet", no_argument, NULL, 'q' }, +- { "merge", no_argument, NULL, 'm' }, +- { "this-boot", no_argument, NULL, ARG_THIS_BOOT }, /* deprecated */ +- { "boot", optional_argument, NULL, 'b' }, +- { "list-boots", no_argument, NULL, ARG_LIST_BOOTS }, +- { "dmesg", no_argument, NULL, 'k' }, +- { "system", no_argument, NULL, ARG_SYSTEM }, +- { "user", no_argument, NULL, ARG_USER }, +- { "directory", required_argument, NULL, 'D' }, +- { "file", required_argument, NULL, ARG_FILE }, +- { "root", required_argument, NULL, ARG_ROOT }, +- { "header", no_argument, NULL, ARG_HEADER }, +- { "identifier", required_argument, NULL, 't' }, +- { "priority", required_argument, NULL, 'p' }, +- { "grep", required_argument, NULL, 'g' }, +- { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE }, +- { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, +- { "interval", required_argument, NULL, ARG_INTERVAL }, +- { "verify", no_argument, NULL, ARG_VERIFY }, +- { "verify-key", required_argument, NULL, ARG_VERIFY_KEY }, +- { "disk-usage", no_argument, NULL, ARG_DISK_USAGE }, +- { "cursor", required_argument, NULL, 'c' }, +- { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR }, +- { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR }, +- { "since", required_argument, NULL, 'S' }, +- { "until", required_argument, NULL, 'U' }, +- { "unit", required_argument, NULL, 'u' }, +- { "user-unit", required_argument, NULL, ARG_USER_UNIT }, +- { "field", required_argument, NULL, 'F' }, +- { "fields", no_argument, NULL, 'N' }, +- { "catalog", no_argument, NULL, 'x' }, +- { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, +- { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, +- { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG }, +- { "reverse", no_argument, NULL, 'r' }, +- { "machine", required_argument, NULL, 'M' }, +- { "utc", no_argument, NULL, ARG_UTC }, +- { "flush", no_argument, NULL, ARG_FLUSH }, +- { "sync", no_argument, NULL, ARG_SYNC }, +- { "rotate", no_argument, NULL, ARG_ROTATE }, +- { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE }, +- { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES }, +- { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME }, +- { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME }, +- { "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS }, ++ { "help", no_argument, NULL, 'h' }, ++ { "version" , no_argument, NULL, ARG_VERSION }, ++ { "no-pager", no_argument, NULL, ARG_NO_PAGER }, ++ { "pager-end", no_argument, NULL, 'e' }, ++ { "follow", no_argument, NULL, 'f' }, ++ { "force", no_argument, NULL, ARG_FORCE }, ++ { "output", required_argument, NULL, 'o' }, ++ { "all", no_argument, NULL, 'a' }, ++ { "full", no_argument, NULL, 'l' }, ++ { "no-full", no_argument, NULL, ARG_NO_FULL }, ++ { "lines", optional_argument, NULL, 'n' }, ++ { "no-tail", no_argument, NULL, ARG_NO_TAIL }, ++ { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, /* deprecated */ ++ { "quiet", no_argument, NULL, 'q' }, ++ { "merge", no_argument, NULL, 'm' }, ++ { "this-boot", no_argument, NULL, ARG_THIS_BOOT }, /* deprecated */ ++ { "boot", optional_argument, NULL, 'b' }, ++ { "list-boots", no_argument, NULL, ARG_LIST_BOOTS }, ++ { "dmesg", no_argument, NULL, 'k' }, ++ { "system", no_argument, NULL, ARG_SYSTEM }, ++ { "user", no_argument, NULL, ARG_USER }, ++ { "directory", required_argument, NULL, 'D' }, ++ { "file", required_argument, NULL, ARG_FILE }, ++ { "root", required_argument, NULL, ARG_ROOT }, ++ { "header", no_argument, NULL, ARG_HEADER }, ++ { "identifier", required_argument, NULL, 't' }, ++ { "priority", required_argument, NULL, 'p' }, ++ { "grep", required_argument, NULL, 'g' }, ++ { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE }, ++ { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, ++ { "interval", required_argument, NULL, ARG_INTERVAL }, ++ { "verify", no_argument, NULL, ARG_VERIFY }, ++ { "verify-key", required_argument, NULL, ARG_VERIFY_KEY }, ++ { "disk-usage", no_argument, NULL, ARG_DISK_USAGE }, ++ { "cursor", required_argument, NULL, 'c' }, ++ { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR }, ++ { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR }, ++ { "since", required_argument, NULL, 'S' }, ++ { "until", required_argument, NULL, 'U' }, ++ { "unit", required_argument, NULL, 'u' }, ++ { "user-unit", required_argument, NULL, ARG_USER_UNIT }, ++ { "field", required_argument, NULL, 'F' }, ++ { "fields", no_argument, NULL, 'N' }, ++ { "catalog", no_argument, NULL, 'x' }, ++ { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, ++ { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, ++ { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG }, ++ { "reverse", no_argument, NULL, 'r' }, ++ { "machine", required_argument, NULL, 'M' }, ++ { "utc", no_argument, NULL, ARG_UTC }, ++ { "flush", no_argument, NULL, ARG_FLUSH }, ++ { "relinquish-var", no_argument, NULL, ARG_RELINQUISH_VAR }, ++ { "smart-relinquish-var", no_argument, NULL, ARG_SMART_RELINQUISH_VAR }, ++ { "sync", no_argument, NULL, ARG_SYNC }, ++ { "rotate", no_argument, NULL, ARG_ROTATE }, ++ { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE }, ++ { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES }, ++ { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME }, ++ { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME }, ++ { "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS }, + {} + }; + +@@ -893,6 +901,35 @@ static int parse_argv(int argc, char *argv[]) { + arg_action = ACTION_FLUSH; + break; + ++ case ARG_SMART_RELINQUISH_VAR: { ++ int root_mnt_id, log_mnt_id; ++ ++ /* Try to be smart about relinquishing access to /var/log/journal/ during shutdown: ++ * if it's on the same mount as the root file system there's no point in ++ * relinquishing access and we can leave journald write to it until the very last ++ * moment. */ ++ ++ r = path_get_mnt_id("/", &root_mnt_id); ++ if (r < 0) ++ log_debug_errno(r, "Failed to get root mount ID, ignoring: %m"); ++ else { ++ r = path_get_mnt_id("/var/log/journal/", &log_mnt_id); ++ if (r < 0) ++ log_debug_errno(r, "Failed to get journal directory mount ID, ignoring: %m"); ++ else if (root_mnt_id == log_mnt_id) { ++ log_debug("/var/log/journal/ is on root file system, not relinquishing access to /var."); ++ return 0; ++ } else ++ log_debug("/var/log/journal/ is not on the root file system, relinquishing access to it."); ++ } ++ ++ _fallthrough_; ++ } ++ ++ case ARG_RELINQUISH_VAR: ++ arg_action = ACTION_RELINQUISH_VAR; ++ break; ++ + case ARG_ROTATE: + arg_action = ACTION_ROTATE; + break; +@@ -2056,6 +2093,10 @@ static int send_signal_and_wait(int sig, const char *watch_path) { + return 0; + } + ++static int relinquish_var(void) { ++ return send_signal_and_wait(SIGRTMIN+2, "/run/systemd/journal/relinquished"); ++} ++ + static int rotate(void) { + return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated"); + } +@@ -2171,6 +2212,10 @@ int main(int argc, char *argv[]) { + r = flush_to_var(); + goto finish; + ++ case ACTION_RELINQUISH_VAR: ++ r = relinquish_var(); ++ goto finish; ++ + case ACTION_SYNC: + r = sync_journal(); + goto finish; diff --git a/SOURCES/0875-units-automatically-revert-to-run-logging-on-shutdow.patch b/SOURCES/0875-units-automatically-revert-to-run-logging-on-shutdow.patch new file mode 100644 index 0000000..e5b3898 --- /dev/null +++ b/SOURCES/0875-units-automatically-revert-to-run-logging-on-shutdow.patch @@ -0,0 +1,26 @@ +From ce6531045b337c3f793d1d74f1e5641e658805bb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Apr 2019 18:22:31 +0200 +Subject: [PATCH] units: automatically revert to /run logging on shutdown if + necessary + +Fixes: #867 +(cherry picked from commit 1e187d2dd52cbb4f0bb30e4d96acf7f72a145b91) + +Resolves: #1873540 +--- + units/systemd-journal-flush.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in +index 439f5f3f76..653dcebe0e 100644 +--- a/units/systemd-journal-flush.service.in ++++ b/units/systemd-journal-flush.service.in +@@ -19,6 +19,7 @@ RequiresMountsFor=/var/log/journal + + [Service] + ExecStart=@rootbindir@/journalctl --flush ++ExecStop=@rootbindir@/journalctl --smart-relinquish-var + Type=oneshot + RemainAfterExit=yes + TimeoutSec=90s diff --git a/SOURCES/0876-pstore-Tool-to-archive-contents-of-pstore.patch b/SOURCES/0876-pstore-Tool-to-archive-contents-of-pstore.patch new file mode 100644 index 0000000..be1c25a --- /dev/null +++ b/SOURCES/0876-pstore-Tool-to-archive-contents-of-pstore.patch @@ -0,0 +1,929 @@ +From 2f75df5cd6dcd56775fec9e89fc79672e702d826 Mon Sep 17 00:00:00 2001 +From: Eric DeVolder +Date: Thu, 16 May 2019 08:59:01 -0500 +Subject: [PATCH] pstore: Tool to archive contents of pstore +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduces the systemd pstore service which will archive the +contents of the Linux persistent storage filesystem, pstore, to other storage, +thus preserving the existing information contained in the pstore, and clearing +pstore storage for future error events. + +Linux provides a persistent storage file system, pstore[1], that can store +error records when the kernel dies (or reboots or powers-off). These records in +turn can be referenced to debug kernel problems (currently the kernel stuffs +the tail of the dmesg, which also contains a stack backtrace, into pstore). + +The pstore file system supports a variety of backends that map onto persistent +storage, such as the ACPI ERST[2, Section 18.5 Error Serialization] and UEFI +variables[3 Appendix N Common Platform Error Record]. The pstore backends +typically offer a relatively small amount of persistent storage, e.g. 64KiB, +which can quickly fill up and thus prevent subsequent kernel crashes from +recording errors. Thus there is a need to monitor and extract the pstore +contents so that future kernel problems can also record information in the +pstore. + +The pstore service is independent of the kdump service. In cloud environments +specifically, host and guest filesystems are on remote filesystems (eg. iSCSI +or NFS), thus kdump relies [implicitly and/or explicitly] upon proper operation +of networking software *and* hardware *and* infrastructure. Thus it may not be +possible to capture a kernel coredump to a file since writes over the network +may not be possible. + +The pstore backend, on the other hand, is completely local and provides a path +to store error records which will survive a reboot and aid in post-mortem +debugging. + +Usage Notes: +This tool moves files from /sys/fs/pstore into /var/lib/systemd/pstore. + +To enable kernel recording of error records into pstore, one must either pass +crash_kexec_post_notifiers[4] to the kernel command line or enable via 'echo Y + > /sys/module/kernel/parameters/crash_kexec_post_notifiers'. This option +invokes the recording of errors into pstore *before* an attempt to kexec/kdump +on a kernel crash. + +Optionally, to record reboots and shutdowns in the pstore, one can either pass +the printk.always_kmsg_dump[4] to the kernel command line or enable via 'echo Y > +/sys/module/printk/parameters/always_kmsg_dump'. This option enables code on the +shutdown path to record information via pstore. + +This pstore service is a oneshot service. When run, the service invokes +systemd-pstore which is a tool that performs the following: + - reads the pstore.conf configuration file + - collects the lists of files in the pstore (eg. /sys/fs/pstore) + - for certain file types (eg. dmesg) a handler is invoked + - for all other files, the file is moved from pstore + + - In the case of dmesg handler, final processing occurs as such: + - files processed in reverse lexigraphical order to faciliate + reconstruction of original dmesg + - the filename is examined to determine which dmesg it is a part + - the file is appended to the reconstructed dmesg + +For example, the following pstore contents: + + root@vm356:~# ls -al /sys/fs/pstore + total 0 + drwxr-x--- 2 root root 0 May 9 09:50 . + drwxr-xr-x 7 root root 0 May 9 09:50 .. + -r--r--r-- 1 root root 1610 May 9 09:49 dmesg-efi-155741337601001 + -r--r--r-- 1 root root 1778 May 9 09:49 dmesg-efi-155741337602001 + -r--r--r-- 1 root root 1726 May 9 09:49 dmesg-efi-155741337603001 + -r--r--r-- 1 root root 1746 May 9 09:49 dmesg-efi-155741337604001 + -r--r--r-- 1 root root 1686 May 9 09:49 dmesg-efi-155741337605001 + -r--r--r-- 1 root root 1690 May 9 09:49 dmesg-efi-155741337606001 + -r--r--r-- 1 root root 1775 May 9 09:49 dmesg-efi-155741337607001 + -r--r--r-- 1 root root 1811 May 9 09:49 dmesg-efi-155741337608001 + -r--r--r-- 1 root root 1817 May 9 09:49 dmesg-efi-155741337609001 + -r--r--r-- 1 root root 1795 May 9 09:49 dmesg-efi-155741337710001 + -r--r--r-- 1 root root 1770 May 9 09:49 dmesg-efi-155741337711001 + -r--r--r-- 1 root root 1796 May 9 09:49 dmesg-efi-155741337712001 + -r--r--r-- 1 root root 1787 May 9 09:49 dmesg-efi-155741337713001 + -r--r--r-- 1 root root 1808 May 9 09:49 dmesg-efi-155741337714001 + -r--r--r-- 1 root root 1754 May 9 09:49 dmesg-efi-155741337715001 + +results in the following: + + root@vm356:~# ls -al /var/lib/systemd/pstore/155741337/ + total 92 + drwxr-xr-x 2 root root 4096 May 9 09:50 . + drwxr-xr-x 4 root root 40 May 9 09:50 .. + -rw-r--r-- 1 root root 1610 May 9 09:50 dmesg-efi-155741337601001 + -rw-r--r-- 1 root root 1778 May 9 09:50 dmesg-efi-155741337602001 + -rw-r--r-- 1 root root 1726 May 9 09:50 dmesg-efi-155741337603001 + -rw-r--r-- 1 root root 1746 May 9 09:50 dmesg-efi-155741337604001 + -rw-r--r-- 1 root root 1686 May 9 09:50 dmesg-efi-155741337605001 + -rw-r--r-- 1 root root 1690 May 9 09:50 dmesg-efi-155741337606001 + -rw-r--r-- 1 root root 1775 May 9 09:50 dmesg-efi-155741337607001 + -rw-r--r-- 1 root root 1811 May 9 09:50 dmesg-efi-155741337608001 + -rw-r--r-- 1 root root 1817 May 9 09:50 dmesg-efi-155741337609001 + -rw-r--r-- 1 root root 1795 May 9 09:50 dmesg-efi-155741337710001 + -rw-r--r-- 1 root root 1770 May 9 09:50 dmesg-efi-155741337711001 + -rw-r--r-- 1 root root 1796 May 9 09:50 dmesg-efi-155741337712001 + -rw-r--r-- 1 root root 1787 May 9 09:50 dmesg-efi-155741337713001 + -rw-r--r-- 1 root root 1808 May 9 09:50 dmesg-efi-155741337714001 + -rw-r--r-- 1 root root 1754 May 9 09:50 dmesg-efi-155741337715001 + -rw-r--r-- 1 root root 26754 May 9 09:50 dmesg.txt + +where dmesg.txt is reconstructed from the group of related +dmesg-efi-155741337* files. + +Configuration file: +The pstore.conf configuration file has four settings, described below. + - Storage : one of "none", "external", or "journal". With "none", this + tool leaves the contents of pstore untouched. With "external", the + contents of the pstore are moved into the /var/lib/systemd/pstore, + as well as logged into the journal. With "journal", the contents of + the pstore are recorded only in the systemd journal. The default is + "external". + - Unlink : is a boolean. When "true", the default, then files in the + pstore are removed once processed. When "false", processing of the + pstore occurs normally, but the pstore files remain. + +References: +[1] "Persistent storage for a kernel's dying breath", + March 23, 2011. + https://lwn.net/Articles/434821/ + +[2] "Advanced Configuration and Power Interface Specification", + version 6.2, May 2017. + https://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf + +[3] "Unified Extensible Firmware Interface Specification", + version 2.8, March 2019. + https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf + +[4] "The kernel’s command-line parameters", + https://static.lwn.net/kerneldoc/admin-guide/kernel-parameters.html + +(cherry picked from commit 9b4abc69b201e5d7295e1b0762883659f053e747) + +Resolves: #2158832 +--- + man/pstore.conf.xml | 89 +++++++ + man/rules/meson.build | 2 + + man/systemd-pstore.xml | 99 ++++++++ + meson.build | 20 ++ + meson_options.txt | 2 + + src/pstore/meson.build | 10 + + src/pstore/pstore.c | 395 ++++++++++++++++++++++++++++++++ + src/pstore/pstore.conf | 16 ++ + units/meson.build | 1 + + units/systemd-pstore.service.in | 24 ++ + 10 files changed, 658 insertions(+) + create mode 100644 man/pstore.conf.xml + create mode 100644 man/systemd-pstore.xml + create mode 100644 src/pstore/meson.build + create mode 100644 src/pstore/pstore.c + create mode 100644 src/pstore/pstore.conf + create mode 100644 units/systemd-pstore.service.in + +diff --git a/man/pstore.conf.xml b/man/pstore.conf.xml +new file mode 100644 +index 0000000000..b5cda47d02 +--- /dev/null ++++ b/man/pstore.conf.xml +@@ -0,0 +1,89 @@ ++ ++ ++ ++ ++ ++ ++ pstore.conf ++ systemd ++ ++ ++ ++ pstore.conf ++ 5 ++ ++ ++ ++ pstore.conf ++ pstore.conf.d ++ PStore configuration file ++ ++ ++ ++ ++ /etc/systemd/pstore.conf ++ /etc/systemd/pstore.conf.d/* ++ ++ ++ ++ ++ Description ++ ++ This file configures the behavior of ++ systemd-pstore8, ++ a tool for archiving the contents of the persistent storage filesystem, ++ pstore. ++ ++ ++ ++ ++ ++ ++ Options ++ ++ All options are configured in the ++ [PStore] section: ++ ++ ++ ++ ++ Storage= ++ ++ Controls where to archive (i.e. copy) files from the pstore filesystem. One of none, ++ external, and journal. When ++ none, the tool exits without processing files in the pstore filesystem. ++ When external (the default), files are archived into /var/lib/systemd/pstore/, ++ and logged into the journal. ++ When journal, pstore file contents are logged only in the journal. ++ ++ ++ ++ ++ ++ Unlink= ++ ++ Controls whether or not files are removed from pstore after processing. ++ Takes a boolean value. When true, a pstore file is removed from the pstore once it has been ++ archived (either to disk or into the journal). When false, processing of pstore files occurs ++ normally, but the files remain in the pstore. ++ The default is true in order to maintain the pstore in a nearly empty state, so that the pstore ++ has storage available for the next kernel error event. ++ ++ ++ ++ ++ The defaults for all values are listed as comments in the ++ template /etc/systemd/pstore.conf file that ++ is installed by default. ++ ++ ++ ++ See Also ++ ++ systemd-journald.service8, ++ ++ ++ ++ +diff --git a/man/rules/meson.build b/man/rules/meson.build +index e6c0a99bbd..6295330c5e 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -44,6 +44,7 @@ manpages = [ + ['os-release', '5', [], ''], + ['pam_systemd', '8', [], 'HAVE_PAM'], + ['portablectl', '1', [], 'ENABLE_PORTABLED'], ++ ['pstore.conf', '5', ['pstore.conf.d'], 'ENABLE_PSTORE'], + ['resolvectl', '1', ['resolvconf'], 'ENABLE_RESOLVE'], + ['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVE'], + ['runlevel', '8', [], 'ENABLE_UTMP'], +@@ -633,6 +634,7 @@ manpages = [ + ['systemd-nspawn', '1', [], ''], + ['systemd-path', '1', [], ''], + ['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'], ++ ['systemd-pstore', '8', ['systemd-pstore.service'], 'ENABLE_PSTORE'], + ['systemd-quotacheck.service', + '8', + ['systemd-quotacheck'], +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.xml +new file mode 100644 +index 0000000000..dd1aa5e83b +--- /dev/null ++++ b/man/systemd-pstore.xml +@@ -0,0 +1,99 @@ ++ ++ ++ ++ ++ ++ ++ ++ systemd-pstore ++ systemd ++ ++ ++ ++ systemd-pstore ++ 8 ++ ++ ++ ++ systemd-pstore ++ systemd-pstore.service ++ Tool to archive contents of the persistent storage filesytem ++ ++ ++ ++ /usr/lib/systemd/systemd-pstore ++ systemd-pstore.service ++ ++ ++ ++ Description ++ systemd-pstore.service is a system service that archives the ++ contents of the Linux persistent storage filesystem, pstore, to other storage, ++ thus preserving the existing information contained in the pstore, and clearing ++ pstore storage for future error events. ++ ++ Linux provides a persistent storage file system, pstore, that can store ++ error records when the kernel dies (or reboots or powers-off). These records in ++ turn can be referenced to debug kernel problems (currently the kernel stuffs ++ the tail of the dmesg, which also contains a stack backtrace, into pstore). ++ ++ The pstore file system supports a variety of backends that map onto persistent ++ storage, such as the ACPI ERST and UEFI variables. The pstore backends ++ typically offer a relatively small amount of persistent storage, e.g. 64KiB, ++ which can quickly fill up and thus prevent subsequent kernel crashes from ++ recording errors. Thus there is a need to monitor and extract the pstore ++ contents so that future kernel problems can also record information in the ++ pstore. ++ ++ The pstore service is independent of the kdump service. In cloud environments ++ specifically, host and guest filesystems are on remote filesystems (eg. iSCSI ++ or NFS), thus kdump relies [implicitly and/or explicitly] upon proper operation ++ of networking software *and* hardware *and* infrastructure. Thus it may not be ++ possible to capture a kernel coredump to a file since writes over the network ++ may not be possible. ++ ++ The pstore backend, on the other hand, is completely local and provides a path ++ to store error records which will survive a reboot and aid in post-mortem ++ debugging. ++ ++ The systemd-pstore executable does the actual work. Upon starting, ++ the pstore.conf is read to obtain options, then the /sys/fs/pstore ++ directory contents are processed according to the options. Pstore files are written to the ++ journal, and optionally saved into /var/lib/systemd/pstore. ++ ++ ++ ++ Configuration ++ ++ The behavior of systemd-pstore is configured through the configuration file ++ /etc/systemd/pstore.conf and corresponding snippets ++ /etc/systemd/pstore.conf.d/*.conf, see ++ pstore.conf5. ++ ++ ++ ++ Disabling pstore processing ++ ++ To disable pstore processing by systemd-pstore, ++ set Storage=none in ++ pstore.conf5. ++ ++ ++ ++ ++ ++ Usage ++ Data stored in the journal can be viewed with ++ journalctl1 ++ as usual. ++ ++ ++ ++ See Also ++ ++ pstore.conf5 ++ ++ ++ +diff --git a/meson.build b/meson.build +index af4cf331da..972a8fb6f7 100644 +--- a/meson.build ++++ b/meson.build +@@ -1224,6 +1224,7 @@ foreach term : ['utmp', + 'environment-d', + 'binfmt', + 'coredump', ++ 'pstore', + 'resolve', + 'logind', + 'hostnamed', +@@ -1439,6 +1440,7 @@ subdir('src/network') + subdir('src/analyze') + subdir('src/journal-remote') + subdir('src/coredump') ++subdir('src/pstore') + subdir('src/hostname') + subdir('src/import') + subdir('src/kernel-install') +@@ -2151,6 +2153,23 @@ if conf.get('ENABLE_COREDUMP') == 1 + public_programs += [exe] + endif + ++if conf.get('ENABLE_PSTORE') == 1 ++ executable('systemd-pstore', ++ systemd_pstore_sources, ++ include_directories : includes, ++ link_with : [libshared], ++ dependencies : [threads, ++ libacl, ++ libdw, ++ libxz, ++ liblz4], ++ install_rpath : rootlibexecdir, ++ install : true, ++ install_dir : rootlibexecdir) ++ ++ public_programs += exe ++endif ++ + if conf.get('ENABLE_BINFMT') == 1 + exe = executable('systemd-binfmt', + 'src/binfmt/binfmt.c', +@@ -3014,6 +3033,7 @@ foreach tuple : [ + ['resolve'], + ['DNS-over-TLS'], + ['coredump'], ++ ['pstore'], + ['polkit'], + ['legacy pkla', install_polkit_pkla], + ['efi'], +diff --git a/meson_options.txt b/meson_options.txt +index 213079ac15..5624304bf4 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -76,6 +76,8 @@ option('binfmt', type : 'boolean', + description : 'support for custom binary formats') + option('coredump', type : 'boolean', + description : 'install the coredump handler') ++option('pstore', type : 'boolean', ++ description : 'install the pstore archival tool') + option('logind', type : 'boolean', + description : 'install the systemd-logind stack') + option('hostnamed', type : 'boolean', +diff --git a/src/pstore/meson.build b/src/pstore/meson.build +new file mode 100644 +index 0000000000..adbac24b54 +--- /dev/null ++++ b/src/pstore/meson.build +@@ -0,0 +1,10 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++ ++systemd_pstore_sources = files(''' ++ pstore.c ++'''.split()) ++ ++if conf.get('ENABLE_PSTORE') == 1 ++ install_data('pstore.conf', ++ install_dir : pkgsysconfdir) ++endif +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +new file mode 100644 +index 0000000000..f95e016eb6 +--- /dev/null ++++ b/src/pstore/pstore.c +@@ -0,0 +1,395 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++/* Copyright © 2019 Oracle and/or its affiliates. */ ++ ++/* Generally speaking, the pstore contains a small number of files ++ * that in turn contain a small amount of data. */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sd-daemon.h" ++#include "sd-journal.h" ++#include "sd-login.h" ++#include "sd-messages.h" ++ ++#include "acl-util.h" ++#include "alloc-util.h" ++#include "capability-util.h" ++#include "cgroup-util.h" ++#include "compress.h" ++#include "conf-parser.h" ++#include "copy.h" ++#include "dirent-util.h" ++#include "escape.h" ++#include "fd-util.h" ++#include "fileio.h" ++#include "fs-util.h" ++#include "io-util.h" ++#include "journal-importer.h" ++#include "log.h" ++#include "macro.h" ++#include "missing.h" ++#include "mkdir.h" ++#include "parse-util.h" ++#include "process-util.h" ++#include "signal-util.h" ++#include "socket-util.h" ++#include "special.h" ++#include "string-table.h" ++#include "string-util.h" ++#include "strv.h" ++#include "user-util.h" ++#include "util.h" ++ ++/* Command line argument handling */ ++typedef enum PStoreStorage { ++ PSTORE_STORAGE_NONE, ++ PSTORE_STORAGE_EXTERNAL, ++ PSTORE_STORAGE_JOURNAL, ++ _PSTORE_STORAGE_MAX, ++ _PSTORE_STORAGE_INVALID = -1 ++} PStoreStorage; ++ ++static const char* const pstore_storage_table[_PSTORE_STORAGE_MAX] = { ++ [PSTORE_STORAGE_NONE] = "none", ++ [PSTORE_STORAGE_EXTERNAL] = "external", ++ [PSTORE_STORAGE_JOURNAL] = "journal", ++}; ++ ++DEFINE_PRIVATE_STRING_TABLE_LOOKUP(pstore_storage, PStoreStorage); ++static DEFINE_CONFIG_PARSE_ENUM(config_parse_pstore_storage, pstore_storage, PStoreStorage, "Failed to parse storage setting"); ++ ++static PStoreStorage arg_storage = PSTORE_STORAGE_EXTERNAL; ++ ++static bool arg_unlink = true; ++static const char *arg_sourcedir = "/sys/fs/pstore"; ++static const char *arg_archivedir = "/var/lib/systemd/pstore"; ++ ++static int parse_config(void) { ++ static const ConfigTableItem items[] = { ++ { "PStore", "Unlink", config_parse_bool, 0, &arg_unlink }, ++ { "PStore", "Storage", config_parse_pstore_storage, 0, &arg_storage }, ++ {} ++ }; ++ ++ return config_parse_many_nulstr(PKGSYSCONFDIR "/pstore.conf", ++ CONF_PATHS_NULSTR("systemd/pstore.conf.d"), ++ "PStore\0", ++ config_item_table_lookup, items, ++ CONFIG_PARSE_WARN, NULL); ++} ++ ++/* File list handling - PStoreEntry is the struct and ++ * and PStoreEntry is the type that contains all info ++ * about a pstore entry. */ ++typedef struct PStoreEntry { ++ struct dirent dirent; ++ bool is_binary; ++ bool handled; ++ char *content; ++ size_t content_size; ++} PStoreEntry; ++ ++typedef struct PStoreList { ++ PStoreEntry *entries; ++ size_t n_entries; ++ size_t n_entries_allocated; ++} PStoreList; ++ ++static void pstore_entries_reset(PStoreList *list) { ++ for (size_t i = 0; i < list->n_entries; i++) ++ free(list->entries[i].content); ++ free(list->entries); ++ list->n_entries = 0; ++} ++ ++static int compare_pstore_entries(const void *_a, const void *_b) { ++ PStoreEntry *a = (PStoreEntry *)_a, *b = (PStoreEntry *)_b; ++ return strcmp(a->dirent.d_name, b->dirent.d_name); ++} ++ ++static int move_file(PStoreEntry *pe, const char *subdir) { ++ _cleanup_free_ char *ifd_path = NULL; ++ _cleanup_free_ char *ofd_path = NULL; ++ int r = 0; ++ struct iovec iovec[2] = {}; ++ int n_iovec = 0; ++ _cleanup_free_ void *field = NULL; ++ const char *suffix = NULL; ++ size_t field_size; ++ ++ if (pe->handled) ++ return 0; ++ ++ ifd_path = path_join(NULL, arg_sourcedir, pe->dirent.d_name); ++ if (!ifd_path) ++ return log_oom(); ++ ++ ofd_path = path_join(arg_archivedir, subdir, pe->dirent.d_name); ++ if (!ofd_path) ++ return log_oom(); ++ ++ /* Always log to the journal */ ++ suffix = arg_storage == PSTORE_STORAGE_EXTERNAL ? strjoina(" moved to ", ofd_path) : (char *)"."; ++ field = strjoina("MESSAGE=PStore ", pe->dirent.d_name, suffix); ++ iovec[n_iovec++] = IOVEC_MAKE_STRING(field); ++ ++ field_size = strlen("FILE=") + pe->content_size; ++ field = malloc(field_size); ++ if (!field) ++ return log_oom(); ++ memcpy(stpcpy(field, "FILE="), pe->content, pe->content_size); ++ iovec[n_iovec++] = IOVEC_MAKE(field, field_size); ++ ++ r = sd_journal_sendv(iovec, n_iovec); ++ if (r < 0) ++ return log_error_errno(r, "Failed to log pstore entry: %m"); ++ ++ if (arg_storage == PSTORE_STORAGE_EXTERNAL) { ++ /* Move file from pstore to external storage */ ++ r = mkdir_parents(ofd_path, 0755); ++ if (r < 0) ++ return log_error_errno(r, "Failed to create directoy %s: %m", ofd_path); ++ r = copy_file_atomic(ifd_path, ofd_path, 0600, 0, COPY_REPLACE); ++ if (r < 0) ++ return log_error_errno(r, "Failed to copy_file_atomic: %s to %s", ifd_path, ofd_path); ++ } ++ ++ /* If file copied properly, remove it from pstore */ ++ if (arg_unlink) ++ (void) unlink(ifd_path); ++ ++ pe->handled = true; ++ ++ return 0; ++} ++ ++static int write_dmesg(const char *dmesg, size_t size, const char *id) { ++ _cleanup_(unlink_and_freep) char *ofd_path = NULL; ++ _cleanup_free_ char *tmp_path = NULL; ++ _cleanup_close_ int ofd = -1; ++ ssize_t wr; ++ int r; ++ ++ if (isempty(dmesg) || size == 0) ++ return 0; ++ ++ /* log_info("Record ID %s", id); */ ++ ++ ofd_path = path_join(arg_archivedir, id, "dmesg.txt"); ++ if (!ofd_path) ++ return log_oom(); ++ ++ ofd = open_tmpfile_linkable(ofd_path, O_CLOEXEC|O_CREAT|O_TRUNC|O_WRONLY, &tmp_path); ++ if (ofd < 0) ++ return log_error_errno(ofd, "Failed to open temporary file %s: %m", ofd_path); ++ wr = write(ofd, dmesg, size); ++ if (wr < 0) ++ return log_error_errno(errno, "Failed to store dmesg to %s: %m", ofd_path); ++ if (wr != (ssize_t)size) ++ return log_error_errno(-EIO, "Failed to store dmesg to %s. %zu bytes are lost.", ofd_path, size - wr); ++ r = link_tmpfile(ofd, tmp_path, ofd_path); ++ if (r < 0) ++ return log_error_errno(r, "Failed to write temporary file %s: %m", ofd_path); ++ ofd_path = mfree(ofd_path); ++ ++ return 0; ++} ++ ++static void process_dmesg_files(PStoreList *list) { ++ /* Move files, reconstruct dmesg.txt */ ++ PStoreEntry *pe; ++ _cleanup_free_ char *dmesg = NULL; ++ size_t dmesg_size = 0; ++ _cleanup_free_ char *dmesg_id = NULL; ++ ++ /* Handle each dmesg file: files processed in reverse ++ * order so as to properly reconstruct original dmesg */ ++ for (size_t n = list->n_entries; n > 0; n--) { ++ bool move_file_and_continue = false; ++ _cleanup_free_ char *pe_id = NULL; ++ char *p; ++ size_t plen; ++ ++ pe = &list->entries[n-1]; ++ ++ if (pe->handled) ++ continue; ++ if (!startswith(pe->dirent.d_name, "dmesg-")) ++ continue; ++ ++ if (endswith(pe->dirent.d_name, ".enc.z")) /* indicates a problem */ ++ move_file_and_continue = true; ++ p = strrchr(pe->dirent.d_name, '-'); ++ if (!p) ++ move_file_and_continue = true; ++ ++ if (move_file_and_continue) { ++ /* A dmesg file on which we do NO additional processing */ ++ (void) move_file(pe, NULL); ++ continue; ++ } ++ ++ /* See if this file is one of a related group of files ++ * in order to reconstruct dmesg */ ++ ++ /* When dmesg is written into pstore, it is done so in ++ * small chunks, whatever the exchange buffer size is ++ * with the underlying pstore backend (ie. EFI may be ++ * ~2KiB), which means an example pstore with approximately ++ * 64KB of storage may have up to roughly 32 dmesg files ++ * that could be related, depending upon the size of the ++ * original dmesg. ++ * ++ * Here we look at the dmesg filename and try to discern ++ * if files are part of a related group, meaning the same ++ * original dmesg. ++ * ++ * The two known pstore backends are EFI and ERST. These ++ * backends store data in the Common Platform Error ++ * Record, CPER, format. The dmesg- filename contains the ++ * CPER record id, a 64bit number (in decimal notation). ++ * In Linux, the record id is encoded with two digits for ++ * the dmesg part (chunk) number and 3 digits for the ++ * count number. So allowing an additional digit to ++ * compensate for advancing time, this code ignores the ++ * last six digits of the filename in determining the ++ * record id. ++ * ++ * For the EFI backend, the record id encodes an id in the ++ * upper 32 bits, and a timestamp in the lower 32-bits. ++ * So ignoring the least significant 6 digits has proven ++ * to generally identify related dmesg entries. */ ++#define PSTORE_FILENAME_IGNORE 6 ++ ++ /* determine common portion of record id */ ++ ++p; /* move beyond dmesg- */ ++ plen = strlen(p); ++ if (plen > PSTORE_FILENAME_IGNORE) { ++ pe_id = memdup_suffix0(p, plen - PSTORE_FILENAME_IGNORE); ++ if (!pe_id) { ++ log_oom(); ++ return; ++ } ++ } else ++ pe_id = mfree(pe_id); ++ ++ /* Now move file from pstore to archive storage */ ++ move_file(pe, pe_id); ++ ++ /* If the current record id is NOT the same as the ++ * previous record id, then start a new dmesg.txt file */ ++ if (!pe_id || !dmesg_id || !streq(pe_id, dmesg_id)) { ++ /* Encountered a new dmesg group, close out old one, open new one */ ++ if (dmesg) { ++ (void) write_dmesg(dmesg, dmesg_size, dmesg_id); ++ dmesg = mfree(dmesg); ++ dmesg_size = 0; ++ } ++ ++ /* now point dmesg_id to storage of pe_id */ ++ free_and_replace(dmesg_id, pe_id); ++ } ++ ++ /* Reconstruction of dmesg is done as a useful courtesy, do not log errors */ ++ dmesg = realloc(dmesg, dmesg_size + strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1); ++ if (dmesg) { ++ dmesg_size += sprintf(&dmesg[dmesg_size], "%s:\n", pe->dirent.d_name); ++ if (pe->content) { ++ memcpy(&dmesg[dmesg_size], pe->content, pe->content_size); ++ dmesg_size += pe->content_size; ++ } ++ } ++ ++ pe_id = mfree(pe_id); ++ } ++ if (dmesg) ++ (void) write_dmesg(dmesg, dmesg_size, dmesg_id); ++} ++ ++static int list_files(PStoreList *list, const char *sourcepath) { ++ _cleanup_(closedirp) DIR *dirp = NULL; ++ struct dirent *de; ++ int r = 0; ++ ++ dirp = opendir(sourcepath); ++ if (!dirp) ++ return log_error_errno(errno, "Failed to opendir %s: %m", sourcepath); ++ ++ FOREACH_DIRENT(de, dirp, return log_error_errno(errno, "Failed to iterate through %s: %m", sourcepath)) { ++ _cleanup_free_ char *ifd_path = NULL; ++ ++ ifd_path = path_join(NULL, sourcepath, de->d_name); ++ if (!ifd_path) ++ return log_oom(); ++ ++ _cleanup_free_ char *buf = NULL; ++ size_t buf_size; ++ ++ /* Now read contents of pstore file */ ++ r = read_full_file(ifd_path, &buf, &buf_size); ++ if (r < 0) { ++ log_warning_errno(r, "Failed to read file %s: %m", ifd_path); ++ continue; ++ } ++ ++ if (!GREEDY_REALLOC(list->entries, list->n_entries_allocated, list->n_entries + 1)) ++ return log_oom(); ++ ++ list->entries[list->n_entries++] = (PStoreEntry) { ++ .dirent = *de, ++ .content = TAKE_PTR(buf), ++ .content_size = buf_size, ++ .is_binary = true, ++ .handled = false, ++ }; ++ } ++ ++ return r; ++} ++ ++static int run(int argc, char *argv[]) { ++ _cleanup_(pstore_entries_reset) PStoreList list = {}; ++ int r; ++ ++ log_open(); ++ ++ /* Ignore all parse errors */ ++ (void) parse_config(); ++ ++ log_debug("Selected storage '%s'.", pstore_storage_to_string(arg_storage)); ++ log_debug("Selected Unlink '%d'.", arg_unlink); ++ ++ if (arg_storage == PSTORE_STORAGE_NONE) ++ /* Do nothing, intentionally, leaving pstore untouched */ ++ return 0; ++ ++ /* Obtain list of files in pstore */ ++ r = list_files(&list, arg_sourcedir); ++ if (r < 0) ++ return r; ++ ++ /* Handle each pstore file */ ++ /* Sort files lexigraphically ascending, generally needed by all */ ++ qsort_safe(list.entries, list.n_entries, sizeof(PStoreEntry), compare_pstore_entries); ++ ++ /* Process known file types */ ++ process_dmesg_files(&list); ++ ++ /* Move left over files out of pstore */ ++ for (size_t n = 0; n < list.n_entries; n++) ++ move_file(&list.entries[n], NULL); ++ ++ return 0; ++} ++ ++int main(int argc, char *argv[]) { ++ int r; ++ ++ r = run(argc, argv); ++ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; ++} +diff --git a/src/pstore/pstore.conf b/src/pstore/pstore.conf +new file mode 100644 +index 0000000000..93a8b6707c +--- /dev/null ++++ b/src/pstore/pstore.conf +@@ -0,0 +1,16 @@ ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++# ++# Entries in this file show the compile time defaults. ++# You can change settings by editing this file. ++# Defaults can be restored by simply deleting this file. ++# ++# See pstore.conf(5) for details. ++ ++[PStore] ++#Storage=external ++#Unlink=yes +diff --git a/units/meson.build b/units/meson.build +index a74fa95195..e8e64eb30a 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -136,6 +136,7 @@ in_units = [ + ['systemd-binfmt.service', 'ENABLE_BINFMT', + 'sysinit.target.wants/'], + ['systemd-coredump@.service', 'ENABLE_COREDUMP'], ++ ['systemd-pstore.service', 'ENABLE_PSTORE'], + ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT', + 'sysinit.target.wants/'], + ['systemd-fsck-root.service', ''], +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +new file mode 100644 +index 0000000000..fec2b1aebf +--- /dev/null ++++ b/units/systemd-pstore.service.in +@@ -0,0 +1,24 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# This file is part of systemd. ++# ++# systemd is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or ++# (at your option) any later version. ++ ++[Unit] ++Description=Platform Persistent Storage Archival ++Documentation=man:systemd-pstore(8) ++DefaultDependencies=no ++Wants=systemd-remount-fs.service ++After=systemd-remount-fs.service ++ ++[Service] ++Type=oneshot ++ExecStart=@rootlibexecdir@/systemd-pstore ++RemainAfterExit=yes ++StateDirectory=systemd/pstore ++ ++[Install] ++WantedBy=systemd-remount-fs.service diff --git a/SOURCES/0877-meson-drop-redundant-line.patch b/SOURCES/0877-meson-drop-redundant-line.patch new file mode 100644 index 0000000..ed13771 --- /dev/null +++ b/SOURCES/0877-meson-drop-redundant-line.patch @@ -0,0 +1,27 @@ +From c95ba53ab720dfbd7f692e0a87d7f5d4f89ea36b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 10:46:53 +0900 +Subject: [PATCH] meson: drop redundant line + +Found by @mattiasb. + +(cherry picked from commit 3f708e7f6909faad307bdb60ed0f8d68e84f6584) + +Related: #2158832 +--- + meson.build | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/meson.build b/meson.build +index 972a8fb6f7..673800a1a7 100644 +--- a/meson.build ++++ b/meson.build +@@ -2166,8 +2166,6 @@ if conf.get('ENABLE_PSTORE') == 1 + install_rpath : rootlibexecdir, + install : true, + install_dir : rootlibexecdir) +- +- public_programs += exe + endif + + if conf.get('ENABLE_BINFMT') == 1 diff --git a/SOURCES/0878-pstore-drop-unnecessary-initializations.patch b/SOURCES/0878-pstore-drop-unnecessary-initializations.patch new file mode 100644 index 0000000..6bc6613 --- /dev/null +++ b/SOURCES/0878-pstore-drop-unnecessary-initializations.patch @@ -0,0 +1,48 @@ +From 7e4b7cc35af0e3b3afbf32fa0fd9961cd01ad9a9 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 10:52:12 +0900 +Subject: [PATCH] pstore: drop unnecessary initializations + +(cherry picked from commit 2e4effd129343d22bfed34e94810d3f87c8f0e85) + +Related: #2158832 +--- + src/pstore/pstore.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index f95e016eb6..e6a342fc50 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -113,14 +113,12 @@ static int compare_pstore_entries(const void *_a, const void *_b) { + } + + static int move_file(PStoreEntry *pe, const char *subdir) { +- _cleanup_free_ char *ifd_path = NULL; +- _cleanup_free_ char *ofd_path = NULL; +- int r = 0; +- struct iovec iovec[2] = {}; +- int n_iovec = 0; ++ _cleanup_free_ char *ifd_path = NULL, *ofd_path = NULL; + _cleanup_free_ void *field = NULL; +- const char *suffix = NULL; ++ struct iovec iovec[2]; ++ const char *suffix; + size_t field_size; ++ int n_iovec = 0, r; + + if (pe->handled) + return 0; +@@ -202,10 +200,9 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) { + + static void process_dmesg_files(PStoreList *list) { + /* Move files, reconstruct dmesg.txt */ +- PStoreEntry *pe; +- _cleanup_free_ char *dmesg = NULL; ++ _cleanup_free_ char *dmesg = NULL, *dmesg_id = NULL; + size_t dmesg_size = 0; +- _cleanup_free_ char *dmesg_id = NULL; ++ PStoreEntry *pe; + + /* Handle each dmesg file: files processed in reverse + * order so as to properly reconstruct original dmesg */ diff --git a/SOURCES/0879-pstopre-fix-return-value-of-list_files.patch b/SOURCES/0879-pstopre-fix-return-value-of-list_files.patch new file mode 100644 index 0000000..72e8698 --- /dev/null +++ b/SOURCES/0879-pstopre-fix-return-value-of-list_files.patch @@ -0,0 +1,46 @@ +From a0485b96118d3d2ac439f510e404ffb3db03e23f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 10:55:10 +0900 +Subject: [PATCH] pstopre: fix return value of list_files() + +Previously, the return value of the last read_full_file() is returned. +This makes the error in read_full_file() is always ignored. + +(cherry picked from commit 337874a45fff46a80e4974c681a5e651f3a0fac9) + +Related: #2158832 +--- + src/pstore/pstore.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index e6a342fc50..2fbef48543 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -311,7 +311,7 @@ static void process_dmesg_files(PStoreList *list) { + static int list_files(PStoreList *list, const char *sourcepath) { + _cleanup_(closedirp) DIR *dirp = NULL; + struct dirent *de; +- int r = 0; ++ int r; + + dirp = opendir(sourcepath); + if (!dirp) +@@ -330,7 +330,7 @@ static int list_files(PStoreList *list, const char *sourcepath) { + /* Now read contents of pstore file */ + r = read_full_file(ifd_path, &buf, &buf_size); + if (r < 0) { +- log_warning_errno(r, "Failed to read file %s: %m", ifd_path); ++ log_warning_errno(r, "Failed to read file %s, skipping: %m", ifd_path); + continue; + } + +@@ -346,7 +346,7 @@ static int list_files(PStoreList *list, const char *sourcepath) { + }; + } + +- return r; ++ return 0; + } + + static int run(int argc, char *argv[]) { diff --git a/SOURCES/0880-pstore-remove-temporary-file-on-failure.patch b/SOURCES/0880-pstore-remove-temporary-file-on-failure.patch new file mode 100644 index 0000000..33bf5a0 --- /dev/null +++ b/SOURCES/0880-pstore-remove-temporary-file-on-failure.patch @@ -0,0 +1,36 @@ +From 58000dc7dd93ff6e8357de64154b0849d3c17c5d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 11:01:43 +0900 +Subject: [PATCH] pstore: remove temporary file on failure + +(cherry picked from commit 03c5f6cc02648eeff3179b2b762d46b9e1889bb1) + +Related: #2158832 +--- + src/pstore/pstore.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 2fbef48543..ce8080ceed 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -167,8 +167,8 @@ static int move_file(PStoreEntry *pe, const char *subdir) { + } + + static int write_dmesg(const char *dmesg, size_t size, const char *id) { +- _cleanup_(unlink_and_freep) char *ofd_path = NULL; +- _cleanup_free_ char *tmp_path = NULL; ++ _cleanup_(unlink_and_freep) char *tmp_path = NULL; ++ _cleanup_free_ char *ofd_path = NULL; + _cleanup_close_ int ofd = -1; + ssize_t wr; + int r; +@@ -193,7 +193,7 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) { + r = link_tmpfile(ofd, tmp_path, ofd_path); + if (r < 0) + return log_error_errno(r, "Failed to write temporary file %s: %m", ofd_path); +- ofd_path = mfree(ofd_path); ++ tmp_path = mfree(tmp_path); + + return 0; + } diff --git a/SOURCES/0881-pstore-do-not-add-FILE-journal-entry-if-content_size.patch b/SOURCES/0881-pstore-do-not-add-FILE-journal-entry-if-content_size.patch new file mode 100644 index 0000000..400dae5 --- /dev/null +++ b/SOURCES/0881-pstore-do-not-add-FILE-journal-entry-if-content_size.patch @@ -0,0 +1,57 @@ +From 5006e4bd9aecea40ca3d907adc692c4c8001a6c1 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 11:08:06 +0900 +Subject: [PATCH] pstore: do not add FILE= journal entry if content_size == 0 + +(cherry picked from commit 6bf18debddbe1b231f783617e054cc194bb36d1e) + +Related: #2158832 +--- + src/pstore/pstore.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index ce8080ceed..eb251d61c8 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -114,10 +114,8 @@ static int compare_pstore_entries(const void *_a, const void *_b) { + + static int move_file(PStoreEntry *pe, const char *subdir) { + _cleanup_free_ char *ifd_path = NULL, *ofd_path = NULL; +- _cleanup_free_ void *field = NULL; ++ const char *suffix, *message; + struct iovec iovec[2]; +- const char *suffix; +- size_t field_size; + int n_iovec = 0, r; + + if (pe->handled) +@@ -133,15 +131,20 @@ static int move_file(PStoreEntry *pe, const char *subdir) { + + /* Always log to the journal */ + suffix = arg_storage == PSTORE_STORAGE_EXTERNAL ? strjoina(" moved to ", ofd_path) : (char *)"."; +- field = strjoina("MESSAGE=PStore ", pe->dirent.d_name, suffix); +- iovec[n_iovec++] = IOVEC_MAKE_STRING(field); ++ message = strjoina("MESSAGE=PStore ", pe->dirent.d_name, suffix); ++ iovec[n_iovec++] = IOVEC_MAKE_STRING(message); + +- field_size = strlen("FILE=") + pe->content_size; +- field = malloc(field_size); +- if (!field) +- return log_oom(); +- memcpy(stpcpy(field, "FILE="), pe->content, pe->content_size); +- iovec[n_iovec++] = IOVEC_MAKE(field, field_size); ++ if (pe->content_size > 0) { ++ _cleanup_free_ void *field = NULL; ++ size_t field_size; ++ ++ field_size = strlen("FILE=") + pe->content_size; ++ field = malloc(field_size); ++ if (!field) ++ return log_oom(); ++ memcpy(stpcpy(field, "FILE="), pe->content, pe->content_size); ++ iovec[n_iovec++] = IOVEC_MAKE(field, field_size); ++ } + + r = sd_journal_sendv(iovec, n_iovec); + if (r < 0) diff --git a/SOURCES/0882-pstore-run-only-when-sys-fs-pstore-is-not-empty.patch b/SOURCES/0882-pstore-run-only-when-sys-fs-pstore-is-not-empty.patch new file mode 100644 index 0000000..ea535a5 --- /dev/null +++ b/SOURCES/0882-pstore-run-only-when-sys-fs-pstore-is-not-empty.patch @@ -0,0 +1,24 @@ +From a7247899f156761934bcb4b380861b3d3ec5449f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 22 Jul 2019 14:09:12 +0900 +Subject: [PATCH] pstore: run only when /sys/fs/pstore is not empty + +(cherry picked from commit 6d4f213b1f6afb2901f0d97cec0e28e20809b713) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index fec2b1aebf..dde21bc33e 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -10,6 +10,7 @@ + [Unit] + Description=Platform Persistent Storage Archival + Documentation=man:systemd-pstore(8) ++ConditionDirectoryNotEmpty=/sys/fs/pstore + DefaultDependencies=no + Wants=systemd-remount-fs.service + After=systemd-remount-fs.service diff --git a/SOURCES/0883-pstore-fix-use-after-free.patch b/SOURCES/0883-pstore-fix-use-after-free.patch new file mode 100644 index 0000000..3546fb3 --- /dev/null +++ b/SOURCES/0883-pstore-fix-use-after-free.patch @@ -0,0 +1,34 @@ +From 7f5bfbd5485e1cb779d7568cabb5783651fd9da3 Mon Sep 17 00:00:00 2001 +From: Michael Olbrich +Date: Fri, 6 Sep 2019 15:04:01 +0200 +Subject: [PATCH] pstore: fix use after free + +The memory is still needed in the sd_journal_sendv() after the 'if' block. + +(cherry picked from commit 1e19f5ac0d680a63eccae7ef1fc6ce225dca0bbf) + +Related: #2158832 +--- + src/pstore/pstore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index eb251d61c8..cafb1804c6 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -114,6 +114,7 @@ static int compare_pstore_entries(const void *_a, const void *_b) { + + static int move_file(PStoreEntry *pe, const char *subdir) { + _cleanup_free_ char *ifd_path = NULL, *ofd_path = NULL; ++ _cleanup_free_ void *field = NULL; + const char *suffix, *message; + struct iovec iovec[2]; + int n_iovec = 0, r; +@@ -135,7 +136,6 @@ static int move_file(PStoreEntry *pe, const char *subdir) { + iovec[n_iovec++] = IOVEC_MAKE_STRING(message); + + if (pe->content_size > 0) { +- _cleanup_free_ void *field = NULL; + size_t field_size; + + field_size = strlen("FILE=") + pe->content_size; diff --git a/SOURCES/0884-pstore-refuse-to-run-if-arguments-are-specified.patch b/SOURCES/0884-pstore-refuse-to-run-if-arguments-are-specified.patch new file mode 100644 index 0000000..de27c4c --- /dev/null +++ b/SOURCES/0884-pstore-refuse-to-run-if-arguments-are-specified.patch @@ -0,0 +1,29 @@ +From a35a90322f8587f650aeb72bfbe1ebcc93e503aa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 22 Jul 2019 10:43:19 +0200 +Subject: [PATCH] pstore: refuse to run if arguments are specified + +(This is why the --help chech passed.) + +(cherry picked from commit 22d6bea8820612e6a1483d8b6cfd820f1417ae6b) + +Related: #2158832 +--- + src/pstore/pstore.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index cafb1804c6..b0b21dedd4 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -358,6 +358,10 @@ static int run(int argc, char *argv[]) { + + log_open(); + ++ if (argc > 1) ++ return log_error_errno(-EINVAL, ++ "This program takes no arguments."); ++ + /* Ignore all parse errors */ + (void) parse_config(); + diff --git a/SOURCES/0885-pstore-allow-specifying-src-and-dst-dirs-are-argumen.patch b/SOURCES/0885-pstore-allow-specifying-src-and-dst-dirs-are-argumen.patch new file mode 100644 index 0000000..00779b3 --- /dev/null +++ b/SOURCES/0885-pstore-allow-specifying-src-and-dst-dirs-are-argumen.patch @@ -0,0 +1,44 @@ +From 76fe0974f62f0a2beb2d3d8e224e80a57c0ebd09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 4 Oct 2019 16:14:47 +0200 +Subject: [PATCH] pstore: allow specifying src and dst dirs are arguments + +This makes it much easier to debug the program as a normal user, since we +don't need to set up fake input under /sys/fs/pstore/. + +Also, let's make the debug output a bit nicer. + +(cherry picked from commit e05a72d7587ff916a983588f8393af624d330dd0) + +Related: #2158832 +--- + src/pstore/pstore.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index b0b21dedd4..7353e83a81 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -358,15 +358,18 @@ static int run(int argc, char *argv[]) { + + log_open(); + +- if (argc > 1) ++ if (argc == 3) { ++ arg_sourcedir = argv[1]; ++ arg_archivedir = argv[2]; ++ } else if (argc > 1) + return log_error_errno(-EINVAL, +- "This program takes no arguments."); ++ "This program takes zero or two arguments."); + + /* Ignore all parse errors */ + (void) parse_config(); + +- log_debug("Selected storage '%s'.", pstore_storage_to_string(arg_storage)); +- log_debug("Selected Unlink '%d'.", arg_unlink); ++ log_debug("Selected storage: %s.", pstore_storage_to_string(arg_storage)); ++ log_debug("Selected unlink: %s.", yes_no(arg_unlink)); + + if (arg_storage == PSTORE_STORAGE_NONE) + /* Do nothing, intentionally, leaving pstore untouched */ diff --git a/SOURCES/0886-pstore-rework-memory-handling-for-dmesg.patch b/SOURCES/0886-pstore-rework-memory-handling-for-dmesg.patch new file mode 100644 index 0000000..8c0adda --- /dev/null +++ b/SOURCES/0886-pstore-rework-memory-handling-for-dmesg.patch @@ -0,0 +1,133 @@ +From a2ba34a79de3748f51d57541c54dbe22e1d03a9e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 4 Oct 2019 16:17:27 +0200 +Subject: [PATCH] pstore: rework memory handling for dmesg + +Semmle Security Reports report: +> The problem occurs on the way realloc is being used. When a size +> bigger than the chunk that wants to be reallocated is passed, realloc +> try to malloc a bigger size, however in the case that malloc fails +> (for example, by forcing a big allocation) realloc will return NULL. +> +> According to the man page: +> "The realloc() function returns a pointer to the newly allocated +> memory, which is suitably aligned for any built-in type and may be +> different from ptr, or NULL if the request fails. If size was +> equal to 0, either NULL or a pointer suitable to be passed to free() +> is returned. If realloc() fails, the original block is left +> untouched; it is not freed or moved." +> +> The problem occurs when the memory ptr passed to the first argument of +> realloc is the same as the one used for the result, for example in +> this case: +> +> dmesg = realloc(dmesg, dmesg_size + strlen(pe->dirent.d_name) + +> strlen(":\n") + pe->content_size + 1); +> +> https://lgtm.com/projects/g/systemd/systemd/snapshot/f8bcb81955f9e93a4787627e28f43fffb2a84836/files/src/pstore/pstore.c?sort=name&dir=A +> SC&mode=heatmap#L300 +> +> If the malloc inside that realloc fails, then the original memory +> chunk will never be free but since realloc will return NULL, the +> pointer to that memory chunk will be lost and a memory leak will +> occur. +> +> In case you are curious, this is the query we used to find this problem: +> https://lgtm.com/query/8650323308193591473/ + +Let's use a more standard pattern: allocate memory using greedy_realloc, and +instead of freeing it when we wrote out a chunk, let's just move the cursor +back to the beginning and reuse the memory we allocated previously. + +If we fail to allocate the memory for dmesg contents, don't write the dmesg +entry, but let's still process the files to move them out of pstore. + +(cherry picked from commit 8198c3e42b0614b6bd1db6f38813b842c8577304) + +Related: #2158832 +--- + src/pstore/pstore.c | 43 ++++++++++++++++++++++++++----------------- + 1 file changed, 26 insertions(+), 17 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 7353e83a81..d70e142b4d 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -176,9 +176,11 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) { + ssize_t wr; + int r; + +- if (isempty(dmesg) || size == 0) ++ if (size == 0) + return 0; + ++ assert(dmesg); ++ + /* log_info("Record ID %s", id); */ + + ofd_path = path_join(arg_archivedir, id, "dmesg.txt"); +@@ -204,7 +206,8 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) { + static void process_dmesg_files(PStoreList *list) { + /* Move files, reconstruct dmesg.txt */ + _cleanup_free_ char *dmesg = NULL, *dmesg_id = NULL; +- size_t dmesg_size = 0; ++ size_t dmesg_size = 0, dmesg_allocated = 0; ++ bool dmesg_bad = false; + PStoreEntry *pe; + + /* Handle each dmesg file: files processed in reverse +@@ -281,33 +284,39 @@ static void process_dmesg_files(PStoreList *list) { + /* Now move file from pstore to archive storage */ + move_file(pe, pe_id); + ++ if (dmesg_bad) ++ continue; ++ + /* If the current record id is NOT the same as the + * previous record id, then start a new dmesg.txt file */ +- if (!pe_id || !dmesg_id || !streq(pe_id, dmesg_id)) { ++ if (!streq_ptr(pe_id, dmesg_id)) { + /* Encountered a new dmesg group, close out old one, open new one */ +- if (dmesg) { +- (void) write_dmesg(dmesg, dmesg_size, dmesg_id); +- dmesg = mfree(dmesg); +- dmesg_size = 0; +- } ++ (void) write_dmesg(dmesg, dmesg_size, dmesg_id); ++ dmesg_size = 0; + + /* now point dmesg_id to storage of pe_id */ + free_and_replace(dmesg_id, pe_id); + } + +- /* Reconstruction of dmesg is done as a useful courtesy, do not log errors */ +- dmesg = realloc(dmesg, dmesg_size + strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1); +- if (dmesg) { +- dmesg_size += sprintf(&dmesg[dmesg_size], "%s:\n", pe->dirent.d_name); +- if (pe->content) { +- memcpy(&dmesg[dmesg_size], pe->content, pe->content_size); +- dmesg_size += pe->content_size; +- } ++ /* Reconstruction of dmesg is done as a useful courtesy: do not fail, but don't write garbled ++ * output either. */ ++ size_t needed = strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1; ++ if (!GREEDY_REALLOC(dmesg, dmesg_allocated, dmesg_size + needed)) { ++ log_warning_errno(ENOMEM, "Failed to write dmesg file: %m"); ++ dmesg_bad = true; ++ continue; ++ } ++ ++ dmesg_size += sprintf(dmesg + dmesg_size, "%s:\n", pe->dirent.d_name); ++ if (pe->content) { ++ memcpy(dmesg + dmesg_size, pe->content, pe->content_size); ++ dmesg_size += pe->content_size; + } + + pe_id = mfree(pe_id); + } +- if (dmesg) ++ ++ if (!dmesg_bad) + (void) write_dmesg(dmesg, dmesg_size, dmesg_id); + } + diff --git a/SOURCES/0887-pstore-fixes-for-dmesg.txt-reconstruction.patch b/SOURCES/0887-pstore-fixes-for-dmesg.txt-reconstruction.patch new file mode 100644 index 0000000..cbfb074 --- /dev/null +++ b/SOURCES/0887-pstore-fixes-for-dmesg.txt-reconstruction.patch @@ -0,0 +1,504 @@ +From 5ac15c7dc49476e7cd7cc3a4b507282c9f78d528 Mon Sep 17 00:00:00 2001 +From: Eric DeVolder +Date: Mon, 21 Nov 2022 11:27:27 -0500 +Subject: [PATCH] pstore: fixes for dmesg.txt reconstruction + +This patch fixes problems with the re-assembly of the dmesg +from the records stored in pstore. + +The current code simply ignores the last 6 characters of the +file name to form a base record id, which then groups any +pstore files with this base id into the reconstructed dmesg.txt. +This approach fails when the following oops generated the +following in pstore: + + -rw-------. 1 root root 1808 Oct 27 22:07 dmesg-efi-166692286101001 + -rw-------. 1 root root 1341 Oct 27 22:07 dmesg-efi-166692286101002 + -rw-------. 1 root root 1812 Oct 27 22:07 dmesg-efi-166692286102001 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286102002 + -rw-------. 1 root root 1807 Oct 27 22:07 dmesg-efi-166692286103001 + -rw-------. 1 root root 1791 Oct 27 22:07 dmesg-efi-166692286103002 + -rw-------. 1 root root 1773 Oct 27 22:07 dmesg-efi-166692286104001 + -rw-------. 1 root root 1801 Oct 27 22:07 dmesg-efi-166692286104002 + -rw-------. 1 root root 1821 Oct 27 22:07 dmesg-efi-166692286105001 + -rw-------. 1 root root 1809 Oct 27 22:07 dmesg-efi-166692286105002 + -rw-------. 1 root root 1804 Oct 27 22:07 dmesg-efi-166692286106001 + -rw-------. 1 root root 1817 Oct 27 22:07 dmesg-efi-166692286106002 + -rw-------. 1 root root 1792 Oct 27 22:07 dmesg-efi-166692286107001 + -rw-------. 1 root root 1810 Oct 27 22:07 dmesg-efi-166692286107002 + -rw-------. 1 root root 1717 Oct 27 22:07 dmesg-efi-166692286108001 + -rw-------. 1 root root 1808 Oct 27 22:07 dmesg-efi-166692286108002 + -rw-------. 1 root root 1764 Oct 27 22:07 dmesg-efi-166692286109001 + -rw-------. 1 root root 1765 Oct 27 22:07 dmesg-efi-166692286109002 + -rw-------. 1 root root 1796 Oct 27 22:07 dmesg-efi-166692286110001 + -rw-------. 1 root root 1816 Oct 27 22:07 dmesg-efi-166692286110002 + -rw-------. 1 root root 1793 Oct 27 22:07 dmesg-efi-166692286111001 + -rw-------. 1 root root 1751 Oct 27 22:07 dmesg-efi-166692286111002 + -rw-------. 1 root root 1813 Oct 27 22:07 dmesg-efi-166692286112001 + -rw-------. 1 root root 1786 Oct 27 22:07 dmesg-efi-166692286112002 + -rw-------. 1 root root 1754 Oct 27 22:07 dmesg-efi-166692286113001 + -rw-------. 1 root root 1752 Oct 27 22:07 dmesg-efi-166692286113002 + -rw-------. 1 root root 1803 Oct 27 22:07 dmesg-efi-166692286114001 + -rw-------. 1 root root 1759 Oct 27 22:07 dmesg-efi-166692286114002 + -rw-------. 1 root root 1805 Oct 27 22:07 dmesg-efi-166692286115001 + -rw-------. 1 root root 1787 Oct 27 22:07 dmesg-efi-166692286115002 + -rw-------. 1 root root 1815 Oct 27 22:07 dmesg-efi-166692286116001 + -rw-------. 1 root root 1771 Oct 27 22:07 dmesg-efi-166692286116002 + -rw-------. 1 root root 1816 Oct 27 22:07 dmesg-efi-166692286117002 + -rw-------. 1 root root 1388 Oct 27 22:07 dmesg-efi-166692286701003 + -rw-------. 1 root root 1824 Oct 27 22:07 dmesg-efi-166692286702003 + -rw-------. 1 root root 1795 Oct 27 22:07 dmesg-efi-166692286703003 + -rw-------. 1 root root 1805 Oct 27 22:07 dmesg-efi-166692286704003 + -rw-------. 1 root root 1813 Oct 27 22:07 dmesg-efi-166692286705003 + -rw-------. 1 root root 1821 Oct 27 22:07 dmesg-efi-166692286706003 + -rw-------. 1 root root 1814 Oct 27 22:07 dmesg-efi-166692286707003 + -rw-------. 1 root root 1812 Oct 27 22:07 dmesg-efi-166692286708003 + -rw-------. 1 root root 1769 Oct 27 22:07 dmesg-efi-166692286709003 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286710003 + -rw-------. 1 root root 1755 Oct 27 22:07 dmesg-efi-166692286711003 + -rw-------. 1 root root 1790 Oct 27 22:07 dmesg-efi-166692286712003 + -rw-------. 1 root root 1756 Oct 27 22:07 dmesg-efi-166692286713003 + -rw-------. 1 root root 1763 Oct 27 22:07 dmesg-efi-166692286714003 + -rw-------. 1 root root 1791 Oct 27 22:07 dmesg-efi-166692286715003 + -rw-------. 1 root root 1775 Oct 27 22:07 dmesg-efi-166692286716003 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286717003 + +The "reconstructed" dmesg.txt that resulted from the above contained +the following (ignoring actual contents, just providing the Part info): + + Emergency#3 Part17 + Emergency#3 Part16 + Emergency#3 Part15 + Emergency#3 Part14 + Emergency#3 Part13 + Emergency#3 Part12 + Emergency#3 Part11 + Emergency#3 Part10 + Emergency#3 Part9 + Emergency#3 Part8 + Emergency#3 Part7 + Emergency#3 Part6 + Emergency#3 Part5 + Emergency#3 Part4 + Emergency#3 Part3 + Emergency#3 Part2 + Emergency#3 Part1 + Panic#2 Part17 + Panic#2 Part16 + Oops#1 Part16 + Panic#2 Part15 + Oops#1 Part15 + Panic#2 Part14 + Oops#1 Part14 + Panic#2 Part13 + Oops#1 Part13 + Panic#2 Part12 + Oops#1 Part12 + Panic#2 Part11 + Oops#1 Part11 + Panic#2 Part10 + Oops#1 Part10 + Panic#2 Part9 + Oops#1 Part9 + Panic#2 Part8 + Oops#1 Part8 + Panic#2 Part7 + Oops#1 Part7 + Panic#2 Part6 + Oops#1 Part6 + Panic#2 Part5 + Oops#1 Part5 + Panic#2 Part4 + Oops#1 Part4 + Panic#2 Part3 + Oops#1 Part3 + Panic#2 Part2 + Oops#1 Part2 + Panic#2 Part1 + Oops#1 Part1 + +The above is a interleaved mess of three dmesg dumps. + +This patch fixes the above problems, and simplifies the dmesg +reconstruction process. The code now distinguishes between +records on EFI vs ERST, which have differently formatted +record identifiers. Using knowledge of the format of the +record ids allows vastly improved reconstruction process. + +With this change in place, the above pstore records now +result in the following: + + # ls -alR /var/lib/systemd/pstore + 1666922861: + total 8 + drwxr-xr-x. 4 root root 28 Nov 18 14:58 . + drwxr-xr-x. 7 root root 144 Nov 18 14:58 .. + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 001 + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 002 + + 1666922861/001: + total 100 + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 . + drwxr-xr-x. 4 root root 28 Nov 18 14:58 .. + -rw-------. 1 root root 1808 Oct 27 22:07 dmesg-efi-166692286101001 + -rw-------. 1 root root 1812 Oct 27 22:07 dmesg-efi-166692286102001 + -rw-------. 1 root root 1807 Oct 27 22:07 dmesg-efi-166692286103001 + -rw-------. 1 root root 1773 Oct 27 22:07 dmesg-efi-166692286104001 + -rw-------. 1 root root 1821 Oct 27 22:07 dmesg-efi-166692286105001 + -rw-------. 1 root root 1804 Oct 27 22:07 dmesg-efi-166692286106001 + -rw-------. 1 root root 1792 Oct 27 22:07 dmesg-efi-166692286107001 + -rw-------. 1 root root 1717 Oct 27 22:07 dmesg-efi-166692286108001 + -rw-------. 1 root root 1764 Oct 27 22:07 dmesg-efi-166692286109001 + -rw-------. 1 root root 1796 Oct 27 22:07 dmesg-efi-166692286110001 + -rw-------. 1 root root 1793 Oct 27 22:07 dmesg-efi-166692286111001 + -rw-------. 1 root root 1813 Oct 27 22:07 dmesg-efi-166692286112001 + -rw-------. 1 root root 1754 Oct 27 22:07 dmesg-efi-166692286113001 + -rw-------. 1 root root 1803 Oct 27 22:07 dmesg-efi-166692286114001 + -rw-------. 1 root root 1805 Oct 27 22:07 dmesg-efi-166692286115001 + -rw-------. 1 root root 1815 Oct 27 22:07 dmesg-efi-166692286116001 + -rw-r-----. 1 root root 28677 Nov 18 14:58 dmesg.txt + + 1666922861/002: + total 104 + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 . + drwxr-xr-x. 4 root root 28 Nov 18 14:58 .. + -rw-------. 1 root root 1341 Oct 27 22:07 dmesg-efi-166692286101002 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286102002 + -rw-------. 1 root root 1791 Oct 27 22:07 dmesg-efi-166692286103002 + -rw-------. 1 root root 1801 Oct 27 22:07 dmesg-efi-166692286104002 + -rw-------. 1 root root 1809 Oct 27 22:07 dmesg-efi-166692286105002 + -rw-------. 1 root root 1817 Oct 27 22:07 dmesg-efi-166692286106002 + -rw-------. 1 root root 1810 Oct 27 22:07 dmesg-efi-166692286107002 + -rw-------. 1 root root 1808 Oct 27 22:07 dmesg-efi-166692286108002 + -rw-------. 1 root root 1765 Oct 27 22:07 dmesg-efi-166692286109002 + -rw-------. 1 root root 1816 Oct 27 22:07 dmesg-efi-166692286110002 + -rw-------. 1 root root 1751 Oct 27 22:07 dmesg-efi-166692286111002 + -rw-------. 1 root root 1786 Oct 27 22:07 dmesg-efi-166692286112002 + -rw-------. 1 root root 1752 Oct 27 22:07 dmesg-efi-166692286113002 + -rw-------. 1 root root 1759 Oct 27 22:07 dmesg-efi-166692286114002 + -rw-------. 1 root root 1787 Oct 27 22:07 dmesg-efi-166692286115002 + -rw-------. 1 root root 1771 Oct 27 22:07 dmesg-efi-166692286116002 + -rw-------. 1 root root 1816 Oct 27 22:07 dmesg-efi-166692286117002 + -rw-r-----. 1 root root 30000 Nov 18 14:58 dmesg.txt + + 1666922867: + total 4 + drwxr-xr-x. 3 root root 17 Nov 18 14:58 . + drwxr-xr-x. 7 root root 144 Nov 18 14:58 .. + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 003 + + 1666922867/003: + total 104 + drwxr-xr-x. 2 root root 4096 Nov 18 14:58 . + drwxr-xr-x. 3 root root 17 Nov 18 14:58 .. + -rw-------. 1 root root 1388 Oct 27 22:07 dmesg-efi-166692286701003 + -rw-------. 1 root root 1824 Oct 27 22:07 dmesg-efi-166692286702003 + -rw-------. 1 root root 1795 Oct 27 22:07 dmesg-efi-166692286703003 + -rw-------. 1 root root 1805 Oct 27 22:07 dmesg-efi-166692286704003 + -rw-------. 1 root root 1813 Oct 27 22:07 dmesg-efi-166692286705003 + -rw-------. 1 root root 1821 Oct 27 22:07 dmesg-efi-166692286706003 + -rw-------. 1 root root 1814 Oct 27 22:07 dmesg-efi-166692286707003 + -rw-------. 1 root root 1812 Oct 27 22:07 dmesg-efi-166692286708003 + -rw-------. 1 root root 1769 Oct 27 22:07 dmesg-efi-166692286709003 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286710003 + -rw-------. 1 root root 1755 Oct 27 22:07 dmesg-efi-166692286711003 + -rw-------. 1 root root 1790 Oct 27 22:07 dmesg-efi-166692286712003 + -rw-------. 1 root root 1756 Oct 27 22:07 dmesg-efi-166692286713003 + -rw-------. 1 root root 1763 Oct 27 22:07 dmesg-efi-166692286714003 + -rw-------. 1 root root 1791 Oct 27 22:07 dmesg-efi-166692286715003 + -rw-------. 1 root root 1775 Oct 27 22:07 dmesg-efi-166692286716003 + -rw-------. 1 root root 1820 Oct 27 22:07 dmesg-efi-166692286717003 + -rw-r-----. 1 root root 30111 Nov 18 14:58 dmesg.txt + +Furthemore, pstore records on ERST are now able to accurately +identify the change in timestamp sequence in order to start a +new dmesg.txt, as needed. + +(cherry picked from commit 5fbaa757077bde2db8d33b1c358518c41b990339) + +Related: #2158832 +--- + src/pstore/pstore.c | 216 +++++++++++++++++++------------------------- + 1 file changed, 92 insertions(+), 124 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index d70e142b4d..9f61e8f7f8 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -112,8 +112,8 @@ static int compare_pstore_entries(const void *_a, const void *_b) { + return strcmp(a->dirent.d_name, b->dirent.d_name); + } + +-static int move_file(PStoreEntry *pe, const char *subdir) { +- _cleanup_free_ char *ifd_path = NULL, *ofd_path = NULL; ++static int move_file(PStoreEntry *pe, const char *subdir1, const char *subdir2) { ++ _cleanup_free_ char *ifd_path = NULL, *ofd_path = NULL, *ofd_path_base = NULL; + _cleanup_free_ void *field = NULL; + const char *suffix, *message; + struct iovec iovec[2]; +@@ -126,7 +126,11 @@ static int move_file(PStoreEntry *pe, const char *subdir) { + if (!ifd_path) + return log_oom(); + +- ofd_path = path_join(arg_archivedir, subdir, pe->dirent.d_name); ++ ofd_path_base = path_join(arg_archivedir, subdir1, subdir2); ++ if (!ofd_path_base) ++ return log_oom(); ++ ++ ofd_path = path_join(NULL, ofd_path_base, pe->dirent.d_name); + if (!ofd_path) + return log_oom(); + +@@ -169,155 +173,119 @@ static int move_file(PStoreEntry *pe, const char *subdir) { + return 0; + } + +-static int write_dmesg(const char *dmesg, size_t size, const char *id) { +- _cleanup_(unlink_and_freep) char *tmp_path = NULL; +- _cleanup_free_ char *ofd_path = NULL; ++static int append_dmesg(PStoreEntry *pe, const char *subdir1, const char *subdir2) { ++ /* Append dmesg chunk to end, create if needed */ ++ _cleanup_free_ char *ofd_path = NULL, *ofd_path_base = NULL; + _cleanup_close_ int ofd = -1; + ssize_t wr; +- int r; + +- if (size == 0) +- return 0; ++ assert(pe); + +- assert(dmesg); ++ if (pe->content_size == 0) ++ return 0; + +- /* log_info("Record ID %s", id); */ ++ ofd_path_base = path_join(arg_archivedir, subdir1, subdir2); ++ if (!ofd_path_base) ++ return log_oom(); + +- ofd_path = path_join(arg_archivedir, id, "dmesg.txt"); ++ ofd_path = path_join(NULL, ofd_path_base, "dmesg.txt"); + if (!ofd_path) + return log_oom(); + +- ofd = open_tmpfile_linkable(ofd_path, O_CLOEXEC|O_CREAT|O_TRUNC|O_WRONLY, &tmp_path); ++ ofd = open(ofd_path, O_CREAT|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC|O_APPEND|O_WRONLY, 0640); + if (ofd < 0) +- return log_error_errno(ofd, "Failed to open temporary file %s: %m", ofd_path); +- wr = write(ofd, dmesg, size); ++ return log_error_errno(ofd, "Failed to open file %s: %m", ofd_path); ++ wr = write(ofd, pe->content, pe->content_size); + if (wr < 0) + return log_error_errno(errno, "Failed to store dmesg to %s: %m", ofd_path); +- if (wr != (ssize_t)size) +- return log_error_errno(-EIO, "Failed to store dmesg to %s. %zu bytes are lost.", ofd_path, size - wr); +- r = link_tmpfile(ofd, tmp_path, ofd_path); +- if (r < 0) +- return log_error_errno(r, "Failed to write temporary file %s: %m", ofd_path); +- tmp_path = mfree(tmp_path); ++ if ((size_t)wr != pe->content_size) ++ return log_error_errno(-EIO, "Failed to store dmesg to %s. %zu bytes are lost.", ofd_path, pe->content_size - wr); + + return 0; + } + +-static void process_dmesg_files(PStoreList *list) { ++static int process_dmesg_files(PStoreList *list) { + /* Move files, reconstruct dmesg.txt */ +- _cleanup_free_ char *dmesg = NULL, *dmesg_id = NULL; +- size_t dmesg_size = 0, dmesg_allocated = 0; +- bool dmesg_bad = false; +- PStoreEntry *pe; ++ _cleanup_free_ char *erst_subdir = NULL; ++ uint64_t last_record_id = 0; ++ ++ /* When dmesg is written into pstore, it is done so in small chunks, whatever the exchange buffer ++ * size is with the underlying pstore backend (ie. EFI may be ~2KiB), which means an example ++ * pstore with approximately 64KB of storage may have up to roughly 32 dmesg files, some likely ++ * related. ++ * ++ * Here we look at the dmesg filename and try to discern if files are part of a related group, ++ * meaning the same original dmesg. ++ * ++ * The dmesg- filename contains the backend-type and the Common Platform Error Record, CPER, ++ * record id, a 64-bit number. ++ * ++ * Files are processed in reverse lexigraphical order so as to properly reconstruct original dmesg.*/ + +- /* Handle each dmesg file: files processed in reverse +- * order so as to properly reconstruct original dmesg */ + for (size_t n = list->n_entries; n > 0; n--) { +- bool move_file_and_continue = false; +- _cleanup_free_ char *pe_id = NULL; ++ PStoreEntry *pe; + char *p; +- size_t plen; + + pe = &list->entries[n-1]; + + if (pe->handled) + continue; +- if (!startswith(pe->dirent.d_name, "dmesg-")) +- continue; +- + if (endswith(pe->dirent.d_name, ".enc.z")) /* indicates a problem */ +- move_file_and_continue = true; +- p = strrchr(pe->dirent.d_name, '-'); +- if (!p) +- move_file_and_continue = true; +- +- if (move_file_and_continue) { +- /* A dmesg file on which we do NO additional processing */ +- (void) move_file(pe, NULL); + continue; +- } +- +- /* See if this file is one of a related group of files +- * in order to reconstruct dmesg */ +- +- /* When dmesg is written into pstore, it is done so in +- * small chunks, whatever the exchange buffer size is +- * with the underlying pstore backend (ie. EFI may be +- * ~2KiB), which means an example pstore with approximately +- * 64KB of storage may have up to roughly 32 dmesg files +- * that could be related, depending upon the size of the +- * original dmesg. +- * +- * Here we look at the dmesg filename and try to discern +- * if files are part of a related group, meaning the same +- * original dmesg. +- * +- * The two known pstore backends are EFI and ERST. These +- * backends store data in the Common Platform Error +- * Record, CPER, format. The dmesg- filename contains the +- * CPER record id, a 64bit number (in decimal notation). +- * In Linux, the record id is encoded with two digits for +- * the dmesg part (chunk) number and 3 digits for the +- * count number. So allowing an additional digit to +- * compensate for advancing time, this code ignores the +- * last six digits of the filename in determining the +- * record id. +- * +- * For the EFI backend, the record id encodes an id in the +- * upper 32 bits, and a timestamp in the lower 32-bits. +- * So ignoring the least significant 6 digits has proven +- * to generally identify related dmesg entries. */ +-#define PSTORE_FILENAME_IGNORE 6 +- +- /* determine common portion of record id */ +- ++p; /* move beyond dmesg- */ +- plen = strlen(p); +- if (plen > PSTORE_FILENAME_IGNORE) { +- pe_id = memdup_suffix0(p, plen - PSTORE_FILENAME_IGNORE); +- if (!pe_id) { +- log_oom(); +- return; +- } +- } else +- pe_id = mfree(pe_id); +- +- /* Now move file from pstore to archive storage */ +- move_file(pe, pe_id); +- +- if (dmesg_bad) ++ if (!startswith(pe->dirent.d_name, "dmesg-")) + continue; + +- /* If the current record id is NOT the same as the +- * previous record id, then start a new dmesg.txt file */ +- if (!streq_ptr(pe_id, dmesg_id)) { +- /* Encountered a new dmesg group, close out old one, open new one */ +- (void) write_dmesg(dmesg, dmesg_size, dmesg_id); +- dmesg_size = 0; +- +- /* now point dmesg_id to storage of pe_id */ +- free_and_replace(dmesg_id, pe_id); +- } +- +- /* Reconstruction of dmesg is done as a useful courtesy: do not fail, but don't write garbled +- * output either. */ +- size_t needed = strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1; +- if (!GREEDY_REALLOC(dmesg, dmesg_allocated, dmesg_size + needed)) { +- log_warning_errno(ENOMEM, "Failed to write dmesg file: %m"); +- dmesg_bad = true; +- continue; +- } +- +- dmesg_size += sprintf(dmesg + dmesg_size, "%s:\n", pe->dirent.d_name); +- if (pe->content) { +- memcpy(dmesg + dmesg_size, pe->content, pe->content_size); +- dmesg_size += pe->content_size; +- } +- +- pe_id = mfree(pe_id); ++ if ((p = startswith(pe->dirent.d_name, "dmesg-efi-"))) { ++ /* For the EFI backend, the 3 least significant digits of record id encodes a ++ * "count" number, the next 2 least significant digits for the dmesg part ++ * (chunk) number, and the remaining digits as the timestamp. See ++ * linux/drivers/firmware/efi/efi-pstore.c in efi_pstore_write(). */ ++ _cleanup_free_ char *subdir1 = NULL, *subdir2 = NULL; ++ size_t plen = strlen(p); ++ ++ if (plen < 6) ++ continue; ++ ++ /* Extract base record id */ ++ subdir1 = strndup(p, plen - 5); ++ if (!subdir1) ++ return log_oom(); ++ /* Extract "count" field */ ++ subdir2 = strndup(p + plen - 3, 3); ++ if (!subdir2) ++ return log_oom(); ++ ++ /* Now move file from pstore to archive storage */ ++ (void) move_file(pe, subdir1, subdir2); ++ ++ /* Append to the dmesg */ ++ (void) append_dmesg(pe, subdir1, subdir2); ++ } else if ((p = startswith(pe->dirent.d_name, "dmesg-erst-"))) { ++ /* For the ERST backend, the record is a monotonically increasing number, seeded as ++ * a timestamp. See linux/drivers/acpi/apei/erst.c in erst_writer(). */ ++ uint64_t record_id; ++ ++ if (safe_atou64(p, &record_id) < 0) ++ continue; ++ if (last_record_id - 1 != record_id) ++ /* A discontinuity in the number has been detected, this current record id ++ * will become the directory name for all pieces of the dmesg in this ++ * series. */ ++ if (free_and_strdup(&erst_subdir, p) < 0) ++ return log_oom(); ++ ++ /* Now move file from pstore to archive storage */ ++ (void) move_file(pe, erst_subdir, NULL); ++ ++ /* Append to the dmesg */ ++ (void) append_dmesg(pe, erst_subdir, NULL); ++ ++ /* Update, but keep erst_subdir for next file */ ++ last_record_id = record_id; ++ } else ++ log_debug("Unknown backend, ignoring \"%s\".", pe->dirent.d_name); + } +- +- if (!dmesg_bad) +- (void) write_dmesg(dmesg, dmesg_size, dmesg_id); ++ return 0; + } + + static int list_files(PStoreList *list, const char *sourcepath) { +@@ -394,11 +362,11 @@ static int run(int argc, char *argv[]) { + qsort_safe(list.entries, list.n_entries, sizeof(PStoreEntry), compare_pstore_entries); + + /* Process known file types */ +- process_dmesg_files(&list); ++ (void) process_dmesg_files(&list); + + /* Move left over files out of pstore */ + for (size_t n = 0; n < list.n_entries; n++) +- move_file(&list.entries[n], NULL); ++ (void) move_file(&list.entries[n], NULL, NULL); + + return 0; + } diff --git a/SOURCES/0888-pstore-Don-t-start-systemd-pstore.service-in-contain.patch b/SOURCES/0888-pstore-Don-t-start-systemd-pstore.service-in-contain.patch new file mode 100644 index 0000000..10bb2fc --- /dev/null +++ b/SOURCES/0888-pstore-Don-t-start-systemd-pstore.service-in-contain.patch @@ -0,0 +1,27 @@ +From 653a635086cfeaf0af12da3a722b0ebe2029b927 Mon Sep 17 00:00:00 2001 +From: Balint Reczey +Date: Mon, 16 Dec 2019 19:03:19 +0100 +Subject: [PATCH] pstore: Don't start systemd-pstore.service in containers + +Usually it is not useful and can also fail making +boot-and-services autopkgtest fail. + +(cherry picked from commit 287f506c32f3f4a48ba020408f964cb0f964d752) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index dde21bc33e..89f34afe34 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -11,6 +11,7 @@ + Description=Platform Persistent Storage Archival + Documentation=man:systemd-pstore(8) + ConditionDirectoryNotEmpty=/sys/fs/pstore ++ConditionVirtualization=!container + DefaultDependencies=no + Wants=systemd-remount-fs.service + After=systemd-remount-fs.service diff --git a/SOURCES/0889-units-pull-in-systemd-pstore.service-from-sysinit.ta.patch b/SOURCES/0889-units-pull-in-systemd-pstore.service-from-sysinit.ta.patch new file mode 100644 index 0000000..3682e6f --- /dev/null +++ b/SOURCES/0889-units-pull-in-systemd-pstore.service-from-sysinit.ta.patch @@ -0,0 +1,36 @@ +From c7e65774a4ccc8a431f63c5a12ab776b24ee1190 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Apr 2020 16:12:00 +0200 +Subject: [PATCH] units: pull in systemd-pstore.service from sysinit.target + +sysinit.target is the target our early boot services are generally +pulled in from, make systemd-pstore.service not an exception of that. + +Effectively this doesn't mean much, either way our unit is part of the +initial transaction. + +(cherry picked from commit 167241912f51fbc0d7d0869b9af34c15b5ecc4b6) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index 89f34afe34..37fcf878f0 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -15,6 +15,7 @@ ConditionVirtualization=!container + DefaultDependencies=no + Wants=systemd-remount-fs.service + After=systemd-remount-fs.service ++Before=sysinit.target + + [Service] + Type=oneshot +@@ -23,4 +24,4 @@ RemainAfterExit=yes + StateDirectory=systemd/pstore + + [Install] +-WantedBy=systemd-remount-fs.service ++WantedBy=sysinit.target diff --git a/SOURCES/0890-units-drop-dependency-on-systemd-remount-fs.service-.patch b/SOURCES/0890-units-drop-dependency-on-systemd-remount-fs.service-.patch new file mode 100644 index 0000000..cb60e2b --- /dev/null +++ b/SOURCES/0890-units-drop-dependency-on-systemd-remount-fs.service-.patch @@ -0,0 +1,36 @@ +From bc6f273a0475a1fa7ab56bc1e498ee62c96aa660 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Apr 2020 16:10:38 +0200 +Subject: [PATCH] units: drop dependency on systemd-remount-fs.service from + systemd-pstore.service + +This dependency is now generated automatically given we use +StateDirectory=. Moreover the combination of Wants= and After= was too +strong anway, as whether remount-fs is pulled in or not should not be up +to systemd-pstore.service, and in fact is part of the initial +transaction anyway. + +[dtardon: This only removes Wants=, not After=, because I haven't +backported the auto-generation code the description talks about. The +code is simple, but it's just an optimisation allowing for slightly +shorter unit files, hence I don't think we really need it.] + +(cherry picked from commit 0c978faa16fa9ecf92f0bbb5c7cc709dc472d115) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index 37fcf878f0..9a86f3145c 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -13,7 +13,6 @@ Documentation=man:systemd-pstore(8) + ConditionDirectoryNotEmpty=/sys/fs/pstore + ConditionVirtualization=!container + DefaultDependencies=no +-Wants=systemd-remount-fs.service + After=systemd-remount-fs.service + Before=sysinit.target + diff --git a/SOURCES/0891-units-make-sure-systemd-pstore-stops-at-shutdown.patch b/SOURCES/0891-units-make-sure-systemd-pstore-stops-at-shutdown.patch new file mode 100644 index 0000000..6fdbf34 --- /dev/null +++ b/SOURCES/0891-units-make-sure-systemd-pstore-stops-at-shutdown.patch @@ -0,0 +1,29 @@ +From 818ddd1efd751ef50f9960920284465befe9d704 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 8 Apr 2020 16:25:03 +0200 +Subject: [PATCH] units: make sure systemd-pstore stops at shutdown + +This doesn't matter too much given that the service doesn't do anything +on shutdown, but let's still stop it to make things cleaner. + +(cherry picked from commit b0c1a07654c80d3cbbbcc52f860d4206707c0b08) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index 9a86f3145c..8cbf264a99 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -14,7 +14,8 @@ ConditionDirectoryNotEmpty=/sys/fs/pstore + ConditionVirtualization=!container + DefaultDependencies=no + After=systemd-remount-fs.service +-Before=sysinit.target ++Conflicts=shutdown.target ++Before=sysinit.target shutdown.target + + [Service] + Type=oneshot diff --git a/SOURCES/0892-pstore-Run-after-modules-are-loaded.patch b/SOURCES/0892-pstore-Run-after-modules-are-loaded.patch new file mode 100644 index 0000000..491e363 --- /dev/null +++ b/SOURCES/0892-pstore-Run-after-modules-are-loaded.patch @@ -0,0 +1,45 @@ +From 9cc6ee46e0083bc36b53d19e14fb637f7a1542dd Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Thu, 9 Jun 2022 16:20:43 +0200 +Subject: [PATCH] pstore: Run after modules are loaded + +The systemd-pstore service takes pstore files on boot and transfers them +to disk. It only does it once on boot and only if it finds any. The typical +location of the pstore on modern systems is the UEFI variable store. + +Most distributions ship with CONFIG_EFI_VARS_PSTORE=m. That means, the +UEFI variable store is only available on boot after the respective module +is loaded. + +In most situations, the pstore service gets loaded before the UEFI pstore, +so we don't get to transfer logs. Instead, they accumulate, filling up the +pstore over time, potentially breaking the UEFI variable store. + +Let's add a service dependency on any kernel module that can provide a +pstore to ensure we only scan for pstate after we can actually see pstate. + +I have seen live occurences of systems breaking because we did not erase +the pstates and ran out of UEFI nvram space. + +Fixes https://github.com/systemd/systemd/issues/18540 + +(cherry picked from commit 70e74a5997ae2ce7ba72a74ac949c3b2dad1a1d6) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index 8cbf264a99..1983a9738f 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -16,6 +16,8 @@ DefaultDependencies=no + After=systemd-remount-fs.service + Conflicts=shutdown.target + Before=sysinit.target shutdown.target ++After=modprobe@efi_pstore.service modprobe@mtdpstore.service modprobe@chromeos_pstore.service modprobe@ramoops.service modprobe@pstore_zone.service modprobe@pstore_blk.service ++Wants=modprobe@efi_pstore.service modprobe@mtdpstore.service modprobe@chromeos_pstore.service modprobe@ramoops.service modprobe@pstore_zone.service modprobe@pstore_blk.service + + [Service] + Type=oneshot diff --git a/SOURCES/0893-pstore-do-not-try-to-load-all-known-pstore-modules.patch b/SOURCES/0893-pstore-do-not-try-to-load-all-known-pstore-modules.patch new file mode 100644 index 0000000..2108fd0 --- /dev/null +++ b/SOURCES/0893-pstore-do-not-try-to-load-all-known-pstore-modules.patch @@ -0,0 +1,48 @@ +From 6a6f108b59e47581d93cbc6bdc604ee84f1bb791 Mon Sep 17 00:00:00 2001 +From: Nick Rosbrook +Date: Wed, 7 Sep 2022 13:25:13 -0400 +Subject: [PATCH] pstore: do not try to load all known pstore modules + +Commit 70e74a5997 ("pstore: Run after modules are loaded") added After= +and Wants= entries for all known kernel modules providing a pstore. + +While adding these dependencies on systems where one of the modules is +not present, or not configured, should not have a real affect on the +system, it can produce annoying error messages in the kernel log. E.g. +"mtd device must be supplied (device name is empty)" when the mtdpstore +module is not configured correctly. + +Since dependencies cannot be removed with drop-ins, if a distro wants to +remove some of these modules from systemd-pstore.service, they need to +patch units/systemd-pstore.service.in. On the other hand, if they want +to append to the dependencies this can be done by shipping a drop-in. + +Since the original intent of the previous commit was to fix [1], which +only requires the efi_pstore module, remove all other kernel module +dependencies from systemd-pstore.service, and let distros ship drop-ins +to add dependencies if needed. + +[1] https://github.com/systemd/systemd/issues/18540 + +(cherry picked from commit 8b8bd621e1d16808678fc3afed257df1fa03a281) + +Related: #2158832 +--- + units/systemd-pstore.service.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/units/systemd-pstore.service.in b/units/systemd-pstore.service.in +index 1983a9738f..19ffa8d4e8 100644 +--- a/units/systemd-pstore.service.in ++++ b/units/systemd-pstore.service.in +@@ -16,8 +16,8 @@ DefaultDependencies=no + After=systemd-remount-fs.service + Conflicts=shutdown.target + Before=sysinit.target shutdown.target +-After=modprobe@efi_pstore.service modprobe@mtdpstore.service modprobe@chromeos_pstore.service modprobe@ramoops.service modprobe@pstore_zone.service modprobe@pstore_blk.service +-Wants=modprobe@efi_pstore.service modprobe@mtdpstore.service modprobe@chromeos_pstore.service modprobe@ramoops.service modprobe@pstore_zone.service modprobe@pstore_blk.service ++After=modprobe@efi_pstore.service ++Wants=modprobe@efi_pstore.service + + [Service] + Type=oneshot diff --git a/SOURCES/0894-logind-session-make-stopping-of-idle-session-visible.patch b/SOURCES/0894-logind-session-make-stopping-of-idle-session-visible.patch new file mode 100644 index 0000000..df27c3b --- /dev/null +++ b/SOURCES/0894-logind-session-make-stopping-of-idle-session-visible.patch @@ -0,0 +1,26 @@ +From b18e19f2262e7ed95c25d53268d12427fe77102d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 21 Feb 2023 10:41:47 +0100 +Subject: [PATCH] logind-session: make stopping of idle session visible to + admins + +(cherry picked from commit 6269ffe7ee8a659df7336a2582054ecd9eecf4b1) + +Resolves: #2156780 +--- + src/login/logind-session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 18a07efcdb..916202a65a 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -673,7 +673,7 @@ static int session_dispatch_stop_on_idle(sd_event_source *source, uint64_t t, vo + + idle = session_get_idle_hint(s, &ts); + if (idle) { +- log_debug("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->name); ++ log_info("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->name); + + return session_stop(s, /* force */ true); + } diff --git a/SOURCES/0895-journald-Increase-stdout-buffer-size-sooner-when-alm.patch b/SOURCES/0895-journald-Increase-stdout-buffer-size-sooner-when-alm.patch new file mode 100644 index 0000000..f03ea88 --- /dev/null +++ b/SOURCES/0895-journald-Increase-stdout-buffer-size-sooner-when-alm.patch @@ -0,0 +1,32 @@ +From a0b52398692f3e4bda18520db9e2397f7b2c80dd Mon Sep 17 00:00:00 2001 +From: Benjamin Robin +Date: Sun, 3 May 2020 18:37:21 +0200 +Subject: [PATCH] journald: Increase stdout buffer size sooner, when almost + full + +If the previous received buffer length is almost equal to the allocated +buffer size, before this change the next read can only receive a couple +of bytes (in the worst case only 1 byte), which is not efficient. + +(cherry picked from commit 034e9719ac1ba88a36b05da38c7aa98761d42c77) + +Related: #2029426 +--- + src/journal/journald-stream.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 302a82d3d7..c8de984335 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -507,8 +507,8 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + goto terminate; + } + +- /* If the buffer is full already (discounting the extra NUL we need), add room for another 1K */ +- if (s->length + 1 >= s->allocated) { ++ /* If the buffer is almost full, add room for another 1K */ ++ if (s->length + 512 >= s->allocated) { + if (!GREEDY_REALLOC(s->buffer, s->allocated, s->length + 1 + 1024)) { + log_oom(); + goto terminate; diff --git a/SOURCES/0896-journald-rework-end-of-line-marker-handling-to-use-a.patch b/SOURCES/0896-journald-rework-end-of-line-marker-handling-to-use-a.patch new file mode 100644 index 0000000..a655502 --- /dev/null +++ b/SOURCES/0896-journald-rework-end-of-line-marker-handling-to-use-a.patch @@ -0,0 +1,77 @@ +From d8fabe7a6839eeb0d5d0504471f2d18b07545238 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 12 May 2020 18:53:35 +0200 +Subject: [PATCH] journald: rework end of line marker handling to use a field + table + +(cherry picked from commit 549b7379ba404c33fd448d2bca46a57f6529b00b) + +Related: #2029426 +--- + src/journal/journald-stream.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index c8de984335..58752a5a24 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -54,6 +54,8 @@ typedef enum LineBreak { + LINE_BREAK_NUL, + LINE_BREAK_LINE_MAX, + LINE_BREAK_EOF, ++ _LINE_BREAK_MAX, ++ _LINE_BREAK_INVALID = -1, + } LineBreak; + + struct StdoutStream { +@@ -233,7 +235,11 @@ fail: + return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file); + } + +-static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) { ++static int stdout_stream_log( ++ StdoutStream *s, ++ const char *p, ++ LineBreak line_break) { ++ + struct iovec *iovec; + int priority; + char syslog_priority[] = "PRIORITY=\0"; +@@ -245,6 +251,9 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea + assert(s); + assert(p); + ++ assert(line_break >= 0); ++ assert(line_break < _LINE_BREAK_MAX); ++ + if (s->context) + (void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY); + else if (pid_is_valid(s->ucred.pid)) { +@@ -296,17 +305,19 @@ static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_brea + iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier); + } + +- if (line_break != LINE_BREAK_NEWLINE) { +- const char *c; ++ static const char * const line_break_field_table[_LINE_BREAK_MAX] = { ++ [LINE_BREAK_NEWLINE] = NULL, /* Do not add field if traditional newline */ ++ [LINE_BREAK_NUL] = "_LINE_BREAK=nul", ++ [LINE_BREAK_LINE_MAX] = "_LINE_BREAK=line-max", ++ [LINE_BREAK_EOF] = "_LINE_BREAK=eof", ++ }; + +- /* If this log message was generated due to an uncommon line break then mention this in the log +- * entry */ ++ const char *c = line_break_field_table[line_break]; + +- c = line_break == LINE_BREAK_NUL ? "_LINE_BREAK=nul" : +- line_break == LINE_BREAK_LINE_MAX ? "_LINE_BREAK=line-max" : +- "_LINE_BREAK=eof"; ++ /* If this log message was generated due to an uncommon line break then mention this in the log ++ * entry */ ++ if (c) + iovec[n++] = IOVEC_MAKE_STRING(c); +- } + + message = strappend("MESSAGE=", p); + if (message) diff --git a/SOURCES/0897-journald-use-the-fact-that-client_context_release-re.patch b/SOURCES/0897-journald-use-the-fact-that-client_context_release-re.patch new file mode 100644 index 0000000..7d4ab74 --- /dev/null +++ b/SOURCES/0897-journald-use-the-fact-that-client_context_release-re.patch @@ -0,0 +1,27 @@ +From cd85a657c932725ac7c1b506dc6dd4270d1dc068 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 12 May 2020 19:15:38 +0200 +Subject: [PATCH] journald: use the fact that client_context_release() returns + NULL + +(cherry picked from commit 020b4a023c2c6dda83afb9a82a62e640569c40c1) + +Related: #2029426 +--- + src/journal/journald-stream.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 58752a5a24..ab1a855943 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -570,8 +570,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + goto terminate; + + s->ucred = *ucred; +- client_context_release(s->server, s->context); +- s->context = NULL; ++ s->context = client_context_release(s->server, s->context); + } + + s->length += l; diff --git a/SOURCES/0898-journald-rework-pid-change-handling.patch b/SOURCES/0898-journald-rework-pid-change-handling.patch new file mode 100644 index 0000000..09fb251 --- /dev/null +++ b/SOURCES/0898-journald-rework-pid-change-handling.patch @@ -0,0 +1,219 @@ +From 538bd9b42dabf1145cf7ab77f32347d516b01e88 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 12 May 2020 18:56:34 +0200 +Subject: [PATCH] journald: rework pid change handling + +Let's introduce an explicit line ending marker for line endings due to +pid change. + +Let's also make sure we don't get confused with buffer management. + +Fixes: #15654 +(cherry picked from commit 45ba1ea5e9264d385fa565328fe957ef1d78caa1) + +Resolves: #2029426 +--- + src/journal/journald-stream.c | 99 +++++++++++++++++++++++------------ + 1 file changed, 66 insertions(+), 33 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index ab1a855943..5be5b0939c 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -54,6 +54,7 @@ typedef enum LineBreak { + LINE_BREAK_NUL, + LINE_BREAK_LINE_MAX, + LINE_BREAK_EOF, ++ LINE_BREAK_PID_CHANGE, + _LINE_BREAK_MAX, + _LINE_BREAK_INVALID = -1, + } LineBreak; +@@ -310,6 +311,7 @@ static int stdout_stream_log( + [LINE_BREAK_NUL] = "_LINE_BREAK=nul", + [LINE_BREAK_LINE_MAX] = "_LINE_BREAK=line-max", + [LINE_BREAK_EOF] = "_LINE_BREAK=eof", ++ [LINE_BREAK_PID_CHANGE] = "_LINE_BREAK=pid-change", + }; + + const char *c = line_break_field_table[line_break]; +@@ -431,21 +433,43 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) { + assert_not_reached("Unknown stream state"); + } + +-static int stdout_stream_scan(StdoutStream *s, bool force_flush) { +- char *p; +- size_t remaining; ++static int stdout_stream_found( ++ StdoutStream *s, ++ char *p, ++ size_t l, ++ LineBreak line_break) { ++ ++ char saved; + int r; + + assert(s); ++ assert(p); ++ ++ /* Let's NUL terminate the specified buffer for this call, and revert back afterwards */ ++ saved = p[l]; ++ p[l] = 0; ++ r = stdout_stream_line(s, p, line_break); ++ p[l] = saved; + +- p = s->buffer; +- remaining = s->length; ++ return r; ++} ++ ++static int stdout_stream_scan( ++ StdoutStream *s, ++ char *p, ++ size_t remaining, ++ LineBreak force_flush, ++ size_t *ret_consumed) { + +- /* XXX: This function does nothing if (s->length == 0) */ ++ size_t consumed = 0; ++ int r; ++ ++ assert(s); ++ assert(p); + + for (;;) { + LineBreak line_break; +- size_t skip; ++ size_t skip, found; + char *end1, *end2; + + end1 = memchr(p, '\n', remaining); +@@ -453,43 +477,40 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + + if (end2) { + /* We found a NUL terminator */ +- skip = end2 - p + 1; ++ found = end2 - p; ++ skip = found + 1; + line_break = LINE_BREAK_NUL; + } else if (end1) { + /* We found a \n terminator */ +- *end1 = 0; +- skip = end1 - p + 1; ++ found = end1 - p; ++ skip = found + 1; + line_break = LINE_BREAK_NEWLINE; + } else if (remaining >= s->server->line_max) { + /* Force a line break after the maximum line length */ +- *(p + s->server->line_max) = 0; +- skip = remaining; ++ found = skip = s->server->line_max; + line_break = LINE_BREAK_LINE_MAX; + } else + break; + +- r = stdout_stream_line(s, p, line_break); ++ r = stdout_stream_found(s, p, found, line_break); + if (r < 0) + return r; + +- remaining -= skip; + p += skip; ++ consumed += skip; ++ remaining -= skip; + } + +- if (force_flush && remaining > 0) { +- p[remaining] = 0; +- r = stdout_stream_line(s, p, LINE_BREAK_EOF); ++ if (force_flush >= 0 && remaining > 0) { ++ r = stdout_stream_found(s, p, remaining, force_flush); + if (r < 0) + return r; + +- p += remaining; +- remaining = 0; ++ consumed += remaining; + } + +- if (p > s->buffer) { +- memmove(s->buffer, p, remaining); +- s->length = remaining; +- } ++ if (ret_consumed) ++ *ret_consumed = consumed; + + return 0; + } +@@ -497,11 +518,12 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + StdoutStream *s = userdata; ++ size_t limit, consumed; + struct ucred *ucred = NULL; + struct cmsghdr *cmsg; + struct iovec iovec; +- size_t limit; + ssize_t l; ++ char *p; + int r; + + struct msghdr msghdr = { +@@ -529,7 +551,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also, + * always leave room for a terminating NUL we might need to add. */ + limit = MIN(s->allocated - 1, s->server->line_max); +- ++ assert(s->length <= limit); + iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length); + + l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); +@@ -543,7 +565,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + cmsg_close_all(&msghdr); + + if (l == 0) { +- stdout_stream_scan(s, true); ++ (void) stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_EOF, NULL); + goto terminate; + } + +@@ -562,22 +584,33 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + * in the meantime. + */ + if (ucred && ucred->pid != s->ucred.pid) { +- /* force out any previously half-written lines from a +- * different process, before we switch to the new ucred +- * structure for everything we just added */ +- r = stdout_stream_scan(s, true); ++ /* Force out any previously half-written lines from a different process, before we switch to ++ * the new ucred structure for everything we just added */ ++ r = stdout_stream_scan(s, s->buffer, s->length, /* force_flush = */ LINE_BREAK_PID_CHANGE, NULL); + if (r < 0) + goto terminate; + +- s->ucred = *ucred; + s->context = client_context_release(s->server, s->context); ++ ++ p = s->buffer + s->length; ++ } else { ++ p = s->buffer; ++ l += s->length; + } + +- s->length += l; +- r = stdout_stream_scan(s, false); ++ /* Always copy in the new credentials */ ++ if (ucred) ++ s->ucred = *ucred; ++ ++ r = stdout_stream_scan(s, p, l, _LINE_BREAK_INVALID, &consumed); + if (r < 0) + goto terminate; + ++ /* Move what wasn't consumed to the front of the buffer */ ++ assert(consumed <= (size_t) l); ++ s->length = l - consumed; ++ memmove(s->buffer, p + consumed, s->length); ++ + return 1; + + terminate: diff --git a/SOURCES/0899-test-Add-a-test-case-for-15654.patch b/SOURCES/0899-test-Add-a-test-case-for-15654.patch new file mode 100644 index 0000000..24d7ee7 --- /dev/null +++ b/SOURCES/0899-test-Add-a-test-case-for-15654.patch @@ -0,0 +1,34 @@ +From e019afeefb396ea42d03f4c3f9713e262aff6450 Mon Sep 17 00:00:00 2001 +From: Benjamin Robin +Date: Wed, 6 May 2020 23:28:02 +0200 +Subject: [PATCH] test: Add a test case for #15654 + +(cherry picked from commit c11d8fd1dab3bc3f0abbc861ba5eb34518cec1da) + +Related: #2029426 +--- + test/TEST-04-JOURNAL/test-journal.sh | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh +index a3db1a7472..bdf137cd69 100755 +--- a/test/TEST-04-JOURNAL/test-journal.sh ++++ b/test/TEST-04-JOURNAL/test-journal.sh +@@ -76,6 +76,17 @@ journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output + grep -q "^_PID=$PID" /output + grep -vq "^_PID=$PID" /output + ++# https://github.com/systemd/systemd/issues/15654 ++ID=$(journalctl --new-id128 | sed -n 2p) ++printf "This will\nusually fail\nand be truncated\n">/expected ++systemd-cat -t "$ID" /bin/sh -c 'env echo -n "This will";echo;env echo -n "usually fail";echo;env echo -n "and be truncated";echo;' ++journalctl --sync ++journalctl -b -o cat -t "$ID" >/output ++cmp /expected /output ++ ++# Add new tests before here, the journald restarts below ++# may make tests flappy. ++ + # Don't lose streams on restart + systemctl start forever-print-hola + sleep 3 diff --git a/SOURCES/0900-test-Stricter-test-case-for-15654-Add-more-checks.patch b/SOURCES/0900-test-Stricter-test-case-for-15654-Add-more-checks.patch new file mode 100644 index 0000000..8ebaec2 --- /dev/null +++ b/SOURCES/0900-test-Stricter-test-case-for-15654-Add-more-checks.patch @@ -0,0 +1,32 @@ +From afcfb65ce7514bf32e59e0b9d212ae18d023a4b5 Mon Sep 17 00:00:00 2001 +From: Benjamin Robin +Date: Sat, 9 May 2020 12:01:07 +0200 +Subject: [PATCH] test: Stricter test case for #15654 (Add more checks) + +Check: + - There is only 3 messages logged with type stdout + - Check all messages logged does not have new line: LINE_BREAK=eof + - Check that the 3 messages are logged from a different PID + - Check the 3 MESSAGE= content +(cherry picked from commit d38b3b74dbde2d65b23e5963354c3db96acd3420) + +Related: #2029426 +--- + test/TEST-04-JOURNAL/test-journal.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh +index bdf137cd69..641259ce24 100755 +--- a/test/TEST-04-JOURNAL/test-journal.sh ++++ b/test/TEST-04-JOURNAL/test-journal.sh +@@ -83,6 +83,10 @@ systemd-cat -t "$ID" /bin/sh -c 'env echo -n "This will";echo;env echo -n "usual + journalctl --sync + journalctl -b -o cat -t "$ID" >/output + cmp /expected /output ++[[ $(journalctl -b -o export -t "$ID" --output-fields=_TRANSPORT | grep -Pc "^_TRANSPORT=stdout$") -eq 3 ]] ++[[ $(journalctl -b -o export -t "$ID" --output-fields=_LINE_BREAK | grep -Pc "^_LINE_BREAK=pid-change$") -eq 3 ]] ++[[ $(journalctl -b -o export -t "$ID" --output-fields=_PID | sort -u | grep -c "^_PID=.*$") -eq 3 ]] ++[[ $(journalctl -b -o export -t "$ID" --output-fields=MESSAGE | grep -Pc "^MESSAGE=(This will|usually fail|and be truncated)$") -eq 3 ]] + + # Add new tests before here, the journald restarts below + # may make tests flappy. diff --git a/SOURCES/0901-man-document-the-new-_LINE_BREAK-type.patch b/SOURCES/0901-man-document-the-new-_LINE_BREAK-type.patch new file mode 100644 index 0000000..75c0e85 --- /dev/null +++ b/SOURCES/0901-man-document-the-new-_LINE_BREAK-type.patch @@ -0,0 +1,42 @@ +From 2f55aeadef3dcdf65c61f24a41178148c3544ac3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 13 May 2020 00:09:43 +0200 +Subject: [PATCH] man: document the new _LINE_BREAK= type + +(cherry picked from commit a3d9aee14fa2f7df429dc401582877176206b7fd) + +Related: #2029426 +--- + man/systemd.journal-fields.xml | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml +index 0c95c4cd95..ad2b94dbd5 100644 +--- a/man/systemd.journal-fields.xml ++++ b/man/systemd.journal-fields.xml +@@ -326,15 +326,16 @@ + + _LINE_BREAK= + +- Only applies to _TRANSPORT=stdout records: indicates that the log message in the +- standard output/error stream was not terminated with a normal newline character (\n, +- i.e. ASCII 10). Specifically, when set this field is one of (in case the line was +- terminated by a NUL byte), (in case the maximum log line length was reached, as +- configured with LineMax= in +- journald.conf5) or +- (if this was the last log record of a stream and the stream ended without a final +- newline character). Note that this record is not generated when a normal newline character was used for +- marking the log line end. ++ Only applies to _TRANSPORT=stdout records: indicates that the log message ++ in the standard output/error stream was not terminated with a normal newline character ++ (\n, i.e. ASCII 10). Specifically, when set this field is one of ++ (in case the line was terminated by a NUL byte), (in ++ case the maximum log line length was reached, as configured with LineMax= in ++ journald.conf5), ++ (if this was the last log record of a stream and the stream ended without a ++ final newline character), or (if the process which generated the log ++ output changed in the middle of a line). Note that this record is not generated when a normal ++ newline character was used for marking the log line end. + + + diff --git a/SOURCES/0902-journald-server-always-create-state-file-in-signal-h.patch b/SOURCES/0902-journald-server-always-create-state-file-in-signal-h.patch new file mode 100644 index 0000000..ed9308c --- /dev/null +++ b/SOURCES/0902-journald-server-always-create-state-file-in-signal-h.patch @@ -0,0 +1,38 @@ +From 0491902d0eff9f4480ce873decc5dd29e5e189d7 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 13 Mar 2023 14:22:28 +0100 +Subject: [PATCH] journald-server: always create state file in signal handler + +`journalctl --flush` waits on that file, so we must create if even if +nothing has really happened. + +RHEL-only + +Resolves: #2176892 +--- + src/journal/journald-server.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 279a32768c..c72cb68095 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1188,6 +1188,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + + static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { + Server *s = userdata; ++ int r; + + assert(s); + +@@ -1197,6 +1198,10 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo * + server_sync(s); + server_vacuum(s, false); + ++ r = touch("/run/systemd/journal/flushed"); ++ if (r < 0) ++ log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m"); ++ + server_space_usage_message(s, NULL); + return 0; + } diff --git a/SOURCES/0903-journald-server-move-relinquish-code-into-function.patch b/SOURCES/0903-journald-server-move-relinquish-code-into-function.patch new file mode 100644 index 0000000..8536ff8 --- /dev/null +++ b/SOURCES/0903-journald-server-move-relinquish-code-into-function.patch @@ -0,0 +1,62 @@ +From 62c8e07498c9dd13aa79371fc169bb51652ef3a9 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 13 Mar 2023 14:31:38 +0100 +Subject: [PATCH] journald-server: move relinquish code into function + +No functional change, just refactoring. + +RHEL-only + +Related: #2176892 +--- + src/journal/journald-server.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index c72cb68095..aa70db95cc 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1258,20 +1258,16 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo + return 0; + } + +- +-static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { +- Server *s = userdata; ++static void relinquish_var(Server *s) { + int r; + + assert(s); + + if (s->storage == STORAGE_NONE) +- return 0; ++ return; + + if (s->runtime_journal && !s->system_journal) +- return 0; +- +- log_debug("Received request to relinquish /var from PID " PID_FMT, si->ssi_pid); ++ return; + + (void) system_journal_open(s, false, true); + +@@ -1286,6 +1282,19 @@ static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo + if (r < 0) + log_warning_errno(r, "Failed to write /run/systemd/journal/relinquished, ignoring: %m"); + ++ return; ++} ++ ++static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { ++ Server *s = userdata; ++ ++ assert(s); ++ assert(si); ++ ++ log_debug("Received request to relinquish /var from PID " PID_FMT, si->ssi_pid); ++ ++ relinquish_var(s); ++ + return 0; + } + diff --git a/SOURCES/0904-journald-server-always-touch-state-file-in-signal-ha.patch b/SOURCES/0904-journald-server-always-touch-state-file-in-signal-ha.patch new file mode 100644 index 0000000..b6b9436 --- /dev/null +++ b/SOURCES/0904-journald-server-always-touch-state-file-in-signal-ha.patch @@ -0,0 +1,58 @@ +From 05a06e34ac8a38c1cff2a08ba071386141e0b78d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 13 Mar 2023 14:32:20 +0100 +Subject: [PATCH] journald-server: always touch state file in signal handler + +`journalctl --relinquish-var` waits on that file, so we must create if +even if nothing has really happened. + +RHEL-only + +Related: #2176892 +--- + src/journal/journald-server.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index aa70db95cc..4788ff78bb 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1259,8 +1259,6 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo + } + + static void relinquish_var(Server *s) { +- int r; +- + assert(s); + + if (s->storage == STORAGE_NONE) +@@ -1278,15 +1276,15 @@ static void relinquish_var(Server *s) { + if (unlink("/run/systemd/journal/flushed") < 0 && errno != ENOENT) + log_warning_errno(errno, "Failed to unlink /run/systemd/journal/flushed, ignoring: %m") ; + +- r = write_timestamp_file_atomic("/run/systemd/journal/relinquished", now(CLOCK_MONOTONIC)); +- if (r < 0) +- log_warning_errno(r, "Failed to write /run/systemd/journal/relinquished, ignoring: %m"); ++ /* NOTE: We don't create our own state file here, because dispatch_sigrtmin2() has to do it anyway. ++ * But if this function is ever called from another place, the creation must be done here too. */ + + return; + } + + static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { + Server *s = userdata; ++ int r; + + assert(s); + assert(si); +@@ -1295,6 +1293,10 @@ static int dispatch_sigrtmin2(sd_event_source *es, const struct signalfd_siginfo + + relinquish_var(s); + ++ r = write_timestamp_file_atomic("/run/systemd/journal/relinquished", now(CLOCK_MONOTONIC)); ++ if (r < 0) ++ log_warning_errno(r, "Failed to write /run/systemd/journal/relinquished, ignoring: %m"); ++ + return 0; + } + diff --git a/SOURCES/0905-test-make-TEST-35-LOGIN-stable-again.patch b/SOURCES/0905-test-make-TEST-35-LOGIN-stable-again.patch new file mode 100644 index 0000000..45fa87d --- /dev/null +++ b/SOURCES/0905-test-make-TEST-35-LOGIN-stable-again.patch @@ -0,0 +1,299 @@ +From 96e69cb655c703d5312c4aa44912e6ce90b4f76f Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 29 Mar 2023 22:38:55 +0200 +Subject: [PATCH] test: make TEST-35-LOGIN stable again + +The expect stuff was anything but expected, so let's just backport +the upstream test case and tweak it a bit to account for the missing +parts in our downstream testing infrastructure. + +Follow-up to 638c2418e7. +Related: #2179309 +rhel-only +--- + test/TEST-35-LOGIN/testsuite.sh | 225 ++++++++++++++++++++++++-------- + test/test-functions | 2 +- + 2 files changed, 175 insertions(+), 52 deletions(-) + +diff --git a/test/TEST-35-LOGIN/testsuite.sh b/test/TEST-35-LOGIN/testsuite.sh +index e4d72beb74..149b2354a1 100755 +--- a/test/TEST-35-LOGIN/testsuite.sh ++++ b/test/TEST-35-LOGIN/testsuite.sh +@@ -3,6 +3,141 @@ + set -eux + set -o pipefail + ++cleanup_test_user() ( ++ set +ex ++ ++ pkill -u "$(id -u logind-test-user)" ++ sleep 1 ++ pkill -KILL -u "$(id -u logind-test-user)" ++ userdel -r logind-test-user ++ ++ return 0 ++) ++ ++setup_test_user() { ++ mkdir -p /var/spool/cron /var/spool/mail /var/run/console ++ useradd -m -s /bin/bash logind-test-user ++ trap cleanup_test_user EXIT ++} ++ ++test_enable_debug() { ++ mkdir -p /run/systemd/system/systemd-logind.service.d ++ cat >/run/systemd/system/systemd-logind.service.d/debug.conf <&2 ++ return 1 ++ fi ++ ++ seat=$(loginctl --no-legend | grep 'logind-test-user *seat' | awk '{ print $4 }') ++ if [[ -z "$seat" ]]; then ++ echo "no seat found for user logind-test-user" >&2 ++ return 1 ++ fi ++ ++ session=$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }') ++ if [[ -z "$session" ]]; then ++ echo "no session found for user logind-test-user" >&2 ++ return 1 ++ fi ++ ++ if ! loginctl session-status "$session" | grep -q "Unit: session-${session}\.scope"; then ++ echo "cannot find scope unit for session $session" >&2 ++ return 1 ++ fi ++ ++ leader_pid=$(loginctl session-status "$session" | awk '$1 == "Leader:" { print $2 }') ++ if [[ -z "$leader_pid" ]]; then ++ echo "cannot found leader process for session $session" >&2 ++ return 1 ++ fi ++ ++ # cgroup v1: "1:name=systemd:/user.slice/..."; unified hierarchy: "0::/user.slice" ++ if ! grep -q -E '(name=systemd|^0:):.*session.*scope' /proc/"$leader_pid"/cgroup; then ++ echo "FAIL: process $leader_pid is not in the session cgroup" >&2 ++ cat /proc/self/cgroup ++ return 1 ++ fi ++) ++ ++create_session() { ++ # login with the test user to start a session ++ mkdir -p /run/systemd/system/getty@tty2.service.d ++ cat >/run/systemd/system/getty@tty2.service.d/override.conf </dev/null ; then +- echo >&2 "expect not installed, skiping test ${FUNCNAME[0]}" +- return 0 +- fi ++ cleanup_session + +- setup_idle_action_lock +- trap teardown_idle_action_lock RETURN ++ return 0 ++) + +- if loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -q testuser ; then +- echo >&2 "Session of the \'testuser\' is already present." +- return 1 ++test_lock_idle_action() { ++ local ts ++ ++ if [[ ! -c /dev/tty2 ]]; then ++ echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}." ++ return + fi + +- # IdleActionSec is set 1s but the accuracy of associated timer is 30s so we +- # need to sleep in worst case for 31s to make sure timer elapsed. We sleep +- # here for 35s to accomodate for any possible scheudling delays. +- cat > /tmp/test.exp <&2 "Session of the \'logind-test-user\' is already present." ++ exit 1 ++ fi + +- ts="$(date '+%H:%M:%S')" +- busctl --match "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='Lock'" monitor > dbus.log & ++ trap teardown_lock_idle_action RETURN + +- expect /tmp/test.exp & ++ create_session + +- # Sleep a bit to give expect time to spawn systemd-run before we check for +- # the presence of resulting session. +- sleep 2 +- if [ "$(loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -c testuser)" != 1 ] ; then +- echo >&2 "\'testuser\' is expected to have exactly one session running." +- return 1 +- fi ++ ts="$(date '+%H:%M:%S')" + +- wait %2 +- sleep 20 +- kill %1 ++ mkdir -p /run/systemd/logind.conf.d ++ cat >/run/systemd/logind.conf.d/idle-action-lock.conf <&2 "Too few 'Lock' D-Bus signal sent, expected at least 2." +- return 1 +- fi ++ timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 1 ]]; do sleep 1; done" ++ ++ # Wakeup ++ touch /dev/tty2 ++ ++ # Wait again ++ timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 2 ]]; do sleep 1; done" + +- journalctl -b -u systemd-logind.service --since="$ts" > logind.log +- if [ "$(grep -c 'System idle. Doing lock operation.' logind.log)" -lt 2 ]; then ++ if [[ "$(journalctl -b -u systemd-logind.service --since="$ts" | grep -c 'System idle. Doing lock operation.')" -lt 2 ]]; then + echo >&2 "System haven't entered idle state at least 2 times." +- return 1 ++ exit 1 + fi +- +- rm -f dbus.log logind.log + } + + : >/failed + ++setup_test_user ++test_enable_debug + test_lock_idle_action + + touch /testok +diff --git a/test/test-functions b/test/test-functions +index 9606a1b085..e5d4d28a5f 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch b/SOURCES/0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch new file mode 100644 index 0000000..ddb15e1 --- /dev/null +++ b/SOURCES/0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch @@ -0,0 +1,113 @@ +From c971d99ffc43df89ca4e15cd81f9e44f4139ba91 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 31 Aug 2020 19:37:13 +0200 +Subject: [PATCH] pager: set $LESSSECURE whenver we invoke a pager + +Some extra safety when invoked via "sudo". With this we address a +genuine design flaw of sudo, and we shouldn't need to deal with this. +But it's still a good idea to disable this surface given how exotic it +is. + +Prompted by #5666 + +(cherry picked from commit 612ebf6c913dd0e4197c44909cb3157f5c51a2f0) + +Related: #2175624 +--- + man/less-variables.xml | 8 ++++++++ + man/systemctl.xml | 1 + + man/systemd.xml | 2 ++ + src/basic/pager.c | 23 +++++++++++++++++++++-- + 4 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index a3faa38997..9dad4247da 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -36,5 +36,13 @@ + the invoking terminal is determined to be UTF-8 compatible). + + ++ ++ $SYSTEMD_LESSSECURE ++ ++ Takes a boolean argument. Overrides the $LESSSECURE environment ++ variable when invoking the pager, which controls the "secure" mode of less (which disables commands ++ such as | which allow to easily shell out to external command lines). By default ++ less secure mode is enabled, with this setting it may be disabled. ++ + + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index a71e6c7c4f..abc386e6fb 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2010,6 +2010,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + ++ + + + +diff --git a/man/systemd.xml b/man/systemd.xml +index 17ab59beb5..66ae4d841d 100644 +--- a/man/systemd.xml ++++ b/man/systemd.xml +@@ -862,6 +862,8 @@ + + + ++ ++ + + $LISTEN_PID + $LISTEN_FDS +diff --git a/src/basic/pager.c b/src/basic/pager.c +index f241261119..4efb01c483 100644 +--- a/src/basic/pager.c ++++ b/src/basic/pager.c +@@ -11,6 +11,7 @@ + #include + + #include "copy.h" ++#include "env-util.h" + #include "fd-util.h" + #include "locale-util.h" + #include "log.h" +@@ -94,8 +95,7 @@ int pager_open(bool no_pager, bool jump_to_end) { + if (setenv("LESS", less_opts, 1) < 0) + _exit(EXIT_FAILURE); + +- /* Initialize a good charset for less. This is +- * particularly important if we output UTF-8 ++ /* Initialize a good charset for less. This is particularly important if we output UTF-8 + * characters. */ + less_charset = getenv("SYSTEMD_LESSCHARSET"); + if (!less_charset && is_locale_utf8()) +@@ -104,6 +104,25 @@ int pager_open(bool no_pager, bool jump_to_end) { + setenv("LESSCHARSET", less_charset, 1) < 0) + _exit(EXIT_FAILURE); + ++ /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out ++ * privileged stuff. */ ++ r = getenv_bool("SYSTEMD_LESSSECURE"); ++ if (r == 0) { /* Remove env var if off */ ++ if (unsetenv("LESSSECURE") < 0) { ++ log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); ++ } ++ } else { ++ /* Set env var otherwise */ ++ if (r < 0) ++ log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m"); ++ ++ if (setenv("LESSSECURE", "1", 1) < 0) { ++ log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); ++ } ++ } ++ + if (pager) { + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); diff --git a/SOURCES/0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch b/SOURCES/0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch new file mode 100644 index 0000000..c68d02d --- /dev/null +++ b/SOURCES/0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch @@ -0,0 +1,264 @@ +From a45636228c7000aef000e45d9853585e51bfb9ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 12 Oct 2020 18:57:32 +0200 +Subject: [PATCH] test-login: always test sd_pid_get_owner_uid(), modernize + +A long time some function only worked when in a session, and the test +didn't execute them when sd_pid_get_session() failed. Let's always call +them to increase coverage. + +While at it, let's test for ==0 not >=0 where we don't expect the function +to return anything except 0 or error. + +(cherry picked from commit 1b5b507cd2d1d7a2b053151abb548475ad9c5c3b) + +Related: #2175624 +--- + src/libsystemd/sd-login/test-login.c | 132 ++++++++++++++------------- + 1 file changed, 71 insertions(+), 61 deletions(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index ccb1905a46..60ef889ec0 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -8,20 +8,22 @@ + #include "sd-login.h" + + #include "alloc-util.h" ++#include "errno-list.h" + #include "fd-util.h" + #include "format-util.h" + #include "log.h" + #include "string-util.h" + #include "strv.h" +-#include "util.h" ++#include "time-util.h" ++#include "user-util.h" + + static char* format_uids(char **buf, uid_t* uids, int count) { +- int pos = 0, k, inc; ++ int pos = 0, inc; + size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1; + + assert_se(*buf = malloc(size)); + +- for (k = 0; k < count; k++) { ++ for (int k = 0; k < count; k++) { + sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc); + pos += inc; + } +@@ -32,6 +34,10 @@ static char* format_uids(char **buf, uid_t* uids, int count) { + return *buf; + } + ++static const char *e(int r) { ++ return r == 0 ? "OK" : errno_to_name(r); ++} ++ + static void test_login(void) { + _cleanup_close_pair_ int pair[2] = { -1, -1 }; + _cleanup_free_ char *pp = NULL, *qq = NULL, +@@ -41,65 +47,71 @@ static void test_login(void) { + *seat = NULL, *session = NULL, + *unit = NULL, *user_unit = NULL, *slice = NULL; + int r; +- uid_t u, u2; +- char *t, **seats, **sessions; ++ uid_t u, u2 = UID_INVALID; ++ char *t, **seats = NULL, **sessions = NULL; + + r = sd_pid_get_unit(0, &unit); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit)); ++ log_info("sd_pid_get_unit(0, …) → %s / \"%s\"", e(r), strnull(unit)); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_user_unit(0, &user_unit); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit)); ++ log_info("sd_pid_get_user_unit(0, …) → %s / \"%s\"", e(r), strnull(user_unit)); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_slice(0, &slice); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice)); ++ log_info("sd_pid_get_slice(0, …) → %s / \"%s\"", e(r), strnull(slice)); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ ++ r = sd_pid_get_owner_uid(0, &u2); ++ log_info("sd_pid_get_owner_uid(0, …) → %s / "UID_FMT, e(r), u2); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_session(0, &session); +- if (r < 0) { +- log_warning_errno(r, "sd_pid_get_session(0, …): %m"); +- if (r == -ENODATA) +- log_info("Seems we are not running in a session, skipping some tests."); +- } else { +- log_info("sd_pid_get_session(0, …) → \"%s\"", session); +- +- assert_se(sd_pid_get_owner_uid(0, &u2) == 0); +- log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2); +- +- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0); +- log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup); +- +- r = sd_uid_get_display(u2, &display_session); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"", +- u2, strnull(display_session)); +- +- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); +- sd_peer_get_session(pair[0], &pp); +- sd_peer_get_session(pair[1], &qq); +- assert_se(streq_ptr(pp, qq)); +- +- r = sd_uid_get_sessions(u2, false, &sessions); ++ log_info("sd_pid_get_session(0, …) → %s / \"%s\"", e(r), strnull(session)); ++ ++ r = sd_pid_get_cgroup(0, &cgroup); ++ log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup)); ++ assert_se(r == 0); ++ ++ r = sd_uid_get_display(u2, &display_session); ++ log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session)); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ ++ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); ++ sd_peer_get_session(pair[0], &pp); ++ sd_peer_get_session(pair[1], &qq); ++ assert_se(streq_ptr(pp, qq)); ++ ++ r = sd_uid_get_sessions(u2, false, &sessions); ++ assert_se(t = strv_join(sessions, " ")); ++ log_info("sd_uid_get_sessions("UID_FMT", …) → %s \"%s\"", u2, e(r), t); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else { + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); +- assert_se(t = strv_join(sessions, " ")); +- strv_free(sessions); +- log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t); +- free(t); ++ } ++ sessions = strv_free(sessions); ++ free(t); + +- assert_se(r == sd_uid_get_sessions(u2, false, NULL)); ++ assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + +- r = sd_uid_get_seats(u2, false, &seats); ++ r = sd_uid_get_seats(u2, false, &seats); ++ assert_se(t = strv_join(seats, " ")); ++ log_info("sd_uid_get_seats("UID_FMT", …) → %s \"%s\"", u2, e(r), t); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else { + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); +- assert_se(t = strv_join(seats, " ")); +- strv_free(seats); +- log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t); +- free(t); +- +- assert_se(r == sd_uid_get_seats(u2, false, NULL)); + } ++ seats = strv_free(seats); ++ free(t); ++ ++ assert_se(r == sd_uid_get_seats(u2, false, NULL)); + + if (session) { + r = sd_session_is_active(session); +@@ -111,7 +123,7 @@ static void test_login(void) { + log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); + + r = sd_session_get_state(session, &state); +- assert_se(r >= 0); ++ assert_se(r == 0); + log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); + + assert_se(sd_session_get_uid(session, &u) >= 0); +@@ -125,16 +137,16 @@ static void test_login(void) { + log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); + + r = sd_session_get_display(session, &display); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); + + r = sd_session_get_remote_user(session, &remote_user); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", + session, strna(remote_user)); + + r = sd_session_get_remote_host(session, &remote_host); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", + session, strna(remote_host)); + +@@ -160,7 +172,7 @@ static void test_login(void) { + assert_se(r == -ENODATA); + } + +- assert_se(sd_uid_get_state(u, &state2) >= 0); ++ assert_se(sd_uid_get_state(u, &state2) == 0); + log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); + } + +@@ -172,11 +184,11 @@ static void test_login(void) { + assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + + r = sd_seat_get_active(seat, &session2, &u2); +- assert_se(r >= 0); ++ assert_se(r == 0); + log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2); + + r = sd_uid_is_on_seat(u, 1, seat); +- assert_se(r >= 0); ++ assert_se(IN_SET(r, 0, 1)); + assert_se(!!r == streq(session, session2)); + + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); +@@ -184,8 +196,8 @@ static void test_login(void) { + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, " ")); + strv_free(sessions); +- log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}", +- seat, r, t, n, format_uids(&buf, uids, n)); ++ log_info("sd_seat_get_sessions(\"%s\", …) → %s, \"%s\", [%u] {%s}", ++ seat, e(r), t, n, format_uids(&buf, uids, n)); + free(t); + + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); +@@ -203,7 +215,7 @@ static void test_login(void) { + + r = sd_seat_get_active(NULL, &t, NULL); + assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t)); ++ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t)); + free(t); + + r = sd_get_sessions(&sessions); +@@ -243,13 +255,11 @@ static void test_login(void) { + + static void test_monitor(void) { + sd_login_monitor *m = NULL; +- unsigned n; + int r; + +- r = sd_login_monitor_new("session", &m); +- assert_se(r >= 0); ++ assert_se(sd_login_monitor_new("session", &m) == 0); + +- for (n = 0; n < 5; n++) { ++ for (unsigned n = 0; n < 5; n++) { + struct pollfd pollfd = {}; + usec_t timeout, nw; + diff --git a/SOURCES/0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch b/SOURCES/0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch new file mode 100644 index 0000000..101d8c4 --- /dev/null +++ b/SOURCES/0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch @@ -0,0 +1,198 @@ +From 7955f053c498a70616ac6c4d57c0fd47dfa8e5ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Oct 2020 11:15:05 +0200 +Subject: [PATCH] pager: make pager secure when under euid is changed or + explicitly requested + +The variable is renamed to SYSTEMD_PAGERSECURE (because it's not just about +less now), and we automatically enable secure mode in certain cases, but not +otherwise. + +This approach is more nuanced, but should provide a better experience for +users: + +- Previusly we would set LESSSECURE=1 and trust the pager to make use of + it. But this has an effect only on less. We need to not start pagers which + are insecure when in secure mode. In particular more is like that and is a + very popular pager. + +- We don't enable secure mode always, which means that those other pagers can + reasonably used. + +- We do the right thing by default, but the user has ultimate control by + setting SYSTEMD_PAGERSECURE. + +Fixes #5666. + +v2: +- also check $PKEXEC_UID + +v3: +- use 'sd_pid_get_owner_uid() != geteuid()' as the condition + +(cherry picked from commit 0a42426d797406b4b01a0d9c13bb759c2629d108) + +Resolves: #2175624 +--- + man/less-variables.xml | 28 ++++++++++++++--- + meson.build | 3 +- + src/basic/pager.c | 69 +++++++++++++++++++++++++++--------------- + 3 files changed, 69 insertions(+), 31 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index 9dad4247da..5f3a53c8dd 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -37,12 +37,30 @@ + + + +- $SYSTEMD_LESSSECURE ++ $SYSTEMD_PAGERSECURE + +- Takes a boolean argument. Overrides the $LESSSECURE environment +- variable when invoking the pager, which controls the "secure" mode of less (which disables commands +- such as | which allow to easily shell out to external command lines). By default +- less secure mode is enabled, with this setting it may be disabled. ++ Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if ++ false, disabled. If $SYSTEMD_PAGERSECURE is not set at all, secure mode is enabled ++ if the effective UID is not the same as the owner of the login session, see geteuid2 and ++ sd_pid_get_owner_uid3. ++ In secure mode, will be set when invoking the pager, and the pager shall ++ disable commands that open or create new files or start new subprocesses. When ++ $SYSTEMD_PAGERSECURE is not set at all, pagers which are not known to implement ++ secure mode will not be used. (Currently only ++ less1 implements ++ secure mode.) ++ ++ Note: when commands are invoked with elevated privileges, for example under sudo8 or ++ pkexec1, care ++ must be taken to ensure that unintended interactive features are not enabled. "Secure" mode for the ++ pager may be enabled automatically as describe above. Setting SYSTEMD_PAGERSECURE=0 ++ or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note ++ that if the $SYSTEMD_PAGER or $PAGER variables are to be ++ honoured, $SYSTEMD_PAGERSECURE must be set too. It might be reasonable to completly ++ disable the pager using instead. + + + +diff --git a/meson.build b/meson.build +index 673800a1a7..d986dd24ac 100644 +--- a/meson.build ++++ b/meson.build +@@ -1467,7 +1467,8 @@ test_dlopen = executable( + 'test-dlopen', + test_dlopen_c, + include_directories : includes, +- link_with : [libbasic], ++ link_with : [libsystemd_static, ++ libbasic], + dependencies : [libdl]) + + foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'], +diff --git a/src/basic/pager.c b/src/basic/pager.c +index 4efb01c483..c7e101235d 100644 +--- a/src/basic/pager.c ++++ b/src/basic/pager.c +@@ -10,6 +10,8 @@ + #include + #include + ++#include "sd-login.h" ++ + #include "copy.h" + #include "env-util.h" + #include "fd-util.h" +@@ -79,7 +81,7 @@ int pager_open(bool no_pager, bool jump_to_end) { + if (r < 0) + return r; + if (r == 0) { +- const char* less_opts, *less_charset; ++ const char* less_opts, *less_charset, *exe; + + /* In the child start the pager */ + +@@ -105,39 +107,56 @@ int pager_open(bool no_pager, bool jump_to_end) { + _exit(EXIT_FAILURE); + + /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out +- * privileged stuff. */ +- r = getenv_bool("SYSTEMD_LESSSECURE"); +- if (r == 0) { /* Remove env var if off */ +- if (unsetenv("LESSSECURE") < 0) { +- log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m"); +- _exit(EXIT_FAILURE); +- } +- } else { +- /* Set env var otherwise */ ++ * privileged stuff. If the user set $SYSTEMD_PAGERSECURE, trust their configuration of the ++ * pager. If they didn't, use secure mode when under euid is changed. If $SYSTEMD_PAGERSECURE ++ * wasn't explicitly set, and we autodetect the need for secure mode, only use the pager we ++ * know to be good. */ ++ int use_secure_mode = getenv_bool("SYSTEMD_PAGERSECURE"); ++ bool trust_pager = use_secure_mode >= 0; ++ if (use_secure_mode == -ENXIO) { ++ uid_t uid; ++ ++ r = sd_pid_get_owner_uid(0, &uid); + if (r < 0) +- log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m"); ++ log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); ++ ++ use_secure_mode = r < 0 || uid != geteuid(); ++ ++ } else if (use_secure_mode < 0) { ++ log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m"); ++ use_secure_mode = true; ++ } + +- if (setenv("LESSSECURE", "1", 1) < 0) { +- log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m"); +- _exit(EXIT_FAILURE); +- } ++ /* We generally always set variables used by less, even if we end up using a different pager. ++ * They shouldn't hurt in any case, and ideally other pagers would look at them too. */ ++ if (use_secure_mode) ++ r = setenv("LESSSECURE", "1", 1); ++ else ++ r = unsetenv("LESSSECURE"); ++ if (r < 0) { ++ log_error_errno(errno, "Failed to adjust environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); + } + +- if (pager) { ++ if (trust_pager && pager) { /* The pager config might be set globally, and we cannot ++ * know if the user adjusted it to be appropriate for the ++ * secure mode. Thus, start the pager specified through ++ * envvars only when $SYSTEMD_PAGERSECURE was explicitly set ++ * as well. */ + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); + } + +- /* Debian's alternatives command for pagers is +- * called 'pager'. Note that we do not call +- * sensible-pagers here, since that is just a +- * shell script that implements a logic that +- * is similar to this one anyway, but is +- * Debian-specific. */ +- execlp("pager", "pager", NULL); ++ /* Debian's alternatives command for pagers is called 'pager'. Note that we do not call ++ * sensible-pagers here, since that is just a shell script that implements a logic that is ++ * similar to this one anyway, but is Debian-specific. */ ++ FOREACH_STRING(exe, "pager", "less", "more") { ++ /* Only less implements secure mode right now. */ ++ if (use_secure_mode && !streq(exe, "less")) ++ continue; + +- execlp("less", "less", NULL); +- execlp("more", "more", NULL); ++ execlp(exe, exe, NULL); ++ } + + pager_fallback(); + /* not reached */ diff --git a/SOURCES/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch b/SOURCES/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch new file mode 100644 index 0000000..4845dee --- /dev/null +++ b/SOURCES/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch @@ -0,0 +1,49 @@ +From c4c9126b1d64fbe77ef1a74b464646711ced8f83 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 30 Mar 2023 17:16:44 +0200 +Subject: [PATCH] ci: trigger differential-shellcheck workflow on push + +Fixes: redhat-plumbers-in-action/differential-shellcheck#215 + +rhel-only + +Related: #2179309 +--- + .github/workflows/differential-shellcheck.yml | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml +index 4399f0bc64..19634c07b3 100644 +--- a/.github/workflows/differential-shellcheck.yml ++++ b/.github/workflows/differential-shellcheck.yml +@@ -3,9 +3,13 @@ + + name: Differential ShellCheck + on: ++ push: ++ branches: ++ - main ++ - rhel-8.*.0 + pull_request: + branches: +- - master ++ - main + - rhel-8.*.0 + + permissions: +@@ -18,7 +22,6 @@ jobs: + + permissions: + security-events: write +- pull-requests: write + + steps: + - name: Repository checkout +@@ -27,6 +30,6 @@ jobs: + fetch-depth: 0 + + - name: Differential ShellCheck +- uses: redhat-plumbers-in-action/differential-shellcheck@v3 ++ uses: redhat-plumbers-in-action/differential-shellcheck@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0910-ci-codeql-master-main.patch b/SOURCES/0910-ci-codeql-master-main.patch new file mode 100644 index 0000000..edd131e --- /dev/null +++ b/SOURCES/0910-ci-codeql-master-main.patch @@ -0,0 +1,34 @@ +From 5e5c1425db0982c9d5e5d51e164895aa780f76b2 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 30 Mar 2023 17:18:17 +0200 +Subject: [PATCH] ci: codeql `master` -> `main` + +rhel-only + +Related: #2179309 +--- + .github/workflows/codeql.yml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml +index c5426d5686..cc4fcf4754 100644 +--- a/.github/workflows/codeql.yml ++++ b/.github/workflows/codeql.yml +@@ -7,7 +7,7 @@ name: "CodeQL" + on: + pull_request: + branches: +- - master ++ - main + - rhel-* + paths: + - '**/meson.build' +@@ -17,7 +17,7 @@ on: + - 'tools/**' + push: + branches: +- - master ++ - main + - rhel-* + + permissions: diff --git a/SOURCES/0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch b/SOURCES/0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch new file mode 100644 index 0000000..6d35361 --- /dev/null +++ b/SOURCES/0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch @@ -0,0 +1,30 @@ +From d9e2735b88513e3b3af9ab468f4d2ba0f6bec64d Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Fri, 23 Oct 2020 15:50:28 -0400 +Subject: [PATCH] test: ignore ENOMEDIUM error from sd_pid_get_cgroup() + +Ubuntu builds on the Launchpad infrastructure run inside a chroot that does +not have the sysfs cgroup dirs mounted, so this call will return ENOMEDIUM +from cg_unified_cached() during the build-time testing, for example when +building the package in a Launchpad PPA. + +(cherry picked from commit 352ab9d74049b4ac694fdba1a6e67339f12ded93) + +Resolves: #2175622 +--- + src/libsystemd/sd-login/test-login.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index 60ef889ec0..d24a04ccc8 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -71,7 +71,7 @@ static void test_login(void) { + + r = sd_pid_get_cgroup(0, &cgroup); + log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup)); +- assert_se(r == 0); ++ assert_se(IN_SET(r, 0, -ENOMEDIUM)); + + r = sd_uid_get_display(u2, &display_session); + log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session)); diff --git a/SOURCES/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch b/SOURCES/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch new file mode 100644 index 0000000..e10ce1f --- /dev/null +++ b/SOURCES/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch @@ -0,0 +1,42 @@ +From d0e8ca2dcc1467a9e28c569e0dc608e5426bae79 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 24 Apr 2023 15:25:02 +0200 +Subject: [PATCH] ci(Mergify): drop requirements on linting workflows + +CodeQL and DifferentialShellCheck workflows aren't run for all PRs on all branches. +This results in Mergify incorrectly labeling PRs with `needs-ci` label. +Lets drop the requirements on these workflows. + +rhel-only + +Related: #2179309 +--- + .mergify.yml | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/.mergify.yml b/.mergify.yml +index a5eed6a82a..624eb7291d 100644 +--- a/.mergify.yml ++++ b/.mergify.yml +@@ -11,10 +11,6 @@ pull_request_rules: + - -check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - -check-success=CentOS CI (CentOS Stream 8) +- # CodeQL +- - -check-success=CodeQL +- # Other +- - -check-success=Differential ShellCheck + actions: + label: + add: +@@ -30,10 +26,6 @@ pull_request_rules: + - check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - check-success=CentOS CI (CentOS Stream 8) +- # CodeQL +- - check-success=CodeQL +- # Other +- - check-success=Differential ShellCheck + actions: + label: + remove: diff --git a/SOURCES/0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch b/SOURCES/0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch new file mode 100644 index 0000000..c1a27a7 --- /dev/null +++ b/SOURCES/0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch @@ -0,0 +1,51 @@ +From a81ace51e1efa2313fcad18f2ef5c6c6cd167240 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 24 Apr 2023 15:13:08 +0200 +Subject: [PATCH] ci: workflow for gathering metadata for source-git automation + +Workflow gathers metadata like pull request numbers and information about commits. +This metadata is used for commit validation and other actions. +This workflow also triggers for rest of the source-git automation workflows. + +rhel-only + +Related: #2179309 +--- + .github/workflows/gather-metadata.yml | 28 +++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + create mode 100644 .github/workflows/gather-metadata.yml + +diff --git a/.github/workflows/gather-metadata.yml b/.github/workflows/gather-metadata.yml +new file mode 100644 +index 0000000000..f432f41811 +--- /dev/null ++++ b/.github/workflows/gather-metadata.yml +@@ -0,0 +1,28 @@ ++name: Gather Pull Request Metadata ++on: ++ pull_request: ++ types: [ opened, reopened, synchronize ] ++ branches: ++ - main ++ - rhel-8.*.0 ++ ++permissions: ++ contents: read ++ ++jobs: ++ gather-metadata: ++ runs-on: ubuntu-latest ++ ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v3 ++ ++ - id: Metadata ++ name: Gather Pull Request Metadata ++ uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1 ++ ++ - name: Upload artifact with gathered metadata ++ uses: actions/upload-artifact@v3 ++ with: ++ name: pr-metadata ++ path: ${{ steps.Metadata.outputs.metadata-file }} diff --git a/SOURCES/0914-ci-first-part-of-the-source-git-automation-commit-li.patch b/SOURCES/0914-ci-first-part-of-the-source-git-automation-commit-li.patch new file mode 100644 index 0000000..4961ca3 --- /dev/null +++ b/SOURCES/0914-ci-first-part-of-the-source-git-automation-commit-li.patch @@ -0,0 +1,103 @@ +From 7e0eb456a99229d19b8e42491c1ddb7b8050903f Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 24 Apr 2023 15:15:00 +0200 +Subject: [PATCH] ci: first part of the source-git automation - commit linter + +Add a GitHub Workflow that is triggered on `workflow_run` events. +It uses metadata provided by `redhat-plumbers-in-action/gather-pull-request-metadata` +GitHub Action to get the PR number and the commit metadata. +The commit metadata is then used to check if the commit message contains +all required information (tracker and upstream reference). GitHub Action +responsible for commit verification `redhat-plumbers-in-action/advanced-commit-linter` +is configured via the `advanced-commit-linter.yml` file. + +rhel-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 23 +++++++++++ + .github/workflows/source-git-automation.yml | 45 +++++++++++++++++++++ + 2 files changed, 68 insertions(+) + create mode 100644 .github/advanced-commit-linter.yml + create mode 100644 .github/workflows/source-git-automation.yml + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +new file mode 100644 +index 0000000000..491836abbb +--- /dev/null ++++ b/.github/advanced-commit-linter.yml +@@ -0,0 +1,23 @@ ++policy: ++ cherry-pick: ++ upstream: ++ - github: systemd/systemd ++ - github: systemd/systemd-stable ++ exception: ++ note: ++ - rhel-only ++ tracker: ++ - keyword: ++ - 'Resolves: #?' ++ - 'Related: #?' ++ - 'Reverts: #?' ++ issue-format: ++ - '\d+$' ++ url: 'https://bugzilla.redhat.com/show_bug.cgi?id=' ++ - keyword: ++ - 'Resolves: ' ++ - 'Related: ' ++ - 'Reverts: ' ++ issue-format: ++ - 'RHEL-\d+$' ++ url: 'https://issues.redhat.com/browse/' +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +new file mode 100644 +index 0000000000..140f21b116 +--- /dev/null ++++ b/.github/workflows/source-git-automation.yml +@@ -0,0 +1,45 @@ ++name: Source git Automation ++on: ++ workflow_run: ++ workflows: [ Gather Pull Request Metadata ] ++ types: ++ - completed ++ ++permissions: ++ contents: read ++ ++jobs: ++ download-metadata: ++ if: > ++ github.event.workflow_run.event == 'pull_request' && ++ github.event.workflow_run.conclusion == 'success' ++ runs-on: ubuntu-latest ++ ++ outputs: ++ pr-metadata: ${{ steps.Artifact.outputs.pr-metadata-json }} ++ ++ steps: ++ - id: Artifact ++ name: Download Artifact ++ uses: redhat-plumbers-in-action/download-artifact@v1 ++ with: ++ name: pr-metadata ++ ++ commit-linter: ++ needs: [ download-metadata ] ++ runs-on: ubuntu-latest ++ ++ outputs: ++ validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} ++ ++ permissions: ++ statuses: write ++ pull-requests: write ++ ++ steps: ++ - id: commit-linter ++ name: Lint Commits ++ uses: redhat-plumbers-in-action/advanced-commit-linter@v1 ++ with: ++ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch b/SOURCES/0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch new file mode 100644 index 0000000..d978500 --- /dev/null +++ b/SOURCES/0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch @@ -0,0 +1,31 @@ +From f86a51500b5aa9288dbb2800e0a1f63ad863bd8f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 26 Apr 2023 20:07:10 +0200 +Subject: [PATCH] pstore: fix crash and forward dummy arguments instead of NULL + +[msekleta: in our version of systemd "const char path*" argument of +path_join() can't be NULL. Here we don't really want any subdirs paths +passed into move_file(), but we can't just pass NULL pointers because +they will be forwarded to path_join(). Hence, let's just pass "/" +instead.] + +rhel-only + +Related: #2190151 +--- + src/pstore/pstore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 9f61e8f7f8..5335c9f92d 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -366,7 +366,7 @@ static int run(int argc, char *argv[]) { + + /* Move left over files out of pstore */ + for (size_t n = 0; n < list.n_entries; n++) +- (void) move_file(&list.entries[n], NULL, NULL); ++ (void) move_file(&list.entries[n], "/", "/"); + + return 0; + } diff --git a/SOURCES/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch b/SOURCES/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch new file mode 100644 index 0000000..a2df2e4 --- /dev/null +++ b/SOURCES/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch @@ -0,0 +1,45 @@ +From 6fdc5f71ee28829bdedb159e7d138f7a1b447fb2 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Wed, 13 Nov 2019 10:46:08 -0800 +Subject: [PATCH] test: Disable LUKS devices from initramfs in QEMU tests + +We currently use the host's kernel and initramfs in our QEMU tests. + +If the host is running on an encrypted LUKS partition, then the initramfs +will have a crypttab setup looking for the particular root disk it needs to +encrypt before booting into the system. + +However, this disk obviously doesn't exist in our QEMU VM, so it turns out +our tests end up waiting for this device to become available, which will +never actually happen, and boot hangs for 90s until that service times out. + +[*** ] A start job is running for /dev/disk/by-uuid/01234567-abcd-1234-abcd-0123456789ab (20s / 1min 30s) + +In order to prevent this issue, let's pass "rd.luks=0" to disable LUKS in +the initramfs only as part of our default kernel command-line in our QEMU +tests. + +This is enough to disable this behavior and prevent the timeout, while at +the same time doesn't conflict with our tests that actually check for LUKS +behavior in the systemd running under test (such as TEST-02-CRYPTSETUP). + +Tested: `sudo make -C TEST-02-CRYPTSETUP/ clean setup run` +(cherry picked from commit 14e0259b499c188de09040f2e5857a0193094d5a) + +Related: #2190151 +--- + test/test-functions | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/test/test-functions b/test/test-functions +index e5d4d28a5f..a7b18991f4 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -154,6 +154,7 @@ fi + KERNEL_APPEND="$PARAMS \ + root=/dev/sda1 \ + raid=noautodetect \ ++rd.luks=0 \ + loglevel=2 \ + init=$PATH_TO_INIT \ + console=ttyS0 \ diff --git a/SOURCES/0917-pstore-explicitly-set-the-base-when-converting-recor.patch b/SOURCES/0917-pstore-explicitly-set-the-base-when-converting-recor.patch new file mode 100644 index 0000000..dd3941a --- /dev/null +++ b/SOURCES/0917-pstore-explicitly-set-the-base-when-converting-recor.patch @@ -0,0 +1,37 @@ +From 3aefa216bf5e8bcfaf5a628e9e06672e786ce9ea Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 28 Apr 2023 11:09:22 +0200 +Subject: [PATCH] pstore: explicitly set the base when converting record ID + +(cherry picked from commit a95d96a2430db171b40fc2e50589807236f8f746) + +Related: #2190151 +--- + src/pstore/pstore.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 5335c9f92d..073fedb7d2 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -207,7 +207,7 @@ static int append_dmesg(PStoreEntry *pe, const char *subdir1, const char *subdir + static int process_dmesg_files(PStoreList *list) { + /* Move files, reconstruct dmesg.txt */ + _cleanup_free_ char *erst_subdir = NULL; +- uint64_t last_record_id = 0; ++ unsigned long long last_record_id = 0; + + /* When dmesg is written into pstore, it is done so in small chunks, whatever the exchange buffer + * size is with the underlying pstore backend (ie. EFI may be ~2KiB), which means an example +@@ -263,9 +263,9 @@ static int process_dmesg_files(PStoreList *list) { + } else if ((p = startswith(pe->dirent.d_name, "dmesg-erst-"))) { + /* For the ERST backend, the record is a monotonically increasing number, seeded as + * a timestamp. See linux/drivers/acpi/apei/erst.c in erst_writer(). */ +- uint64_t record_id; ++ unsigned long long record_id; + +- if (safe_atou64(p, &record_id) < 0) ++ if (safe_atollu_full(p, 10, &record_id) < 0) + continue; + if (last_record_id - 1 != record_id) + /* A discontinuity in the number has been detected, this current record id diff --git a/SOURCES/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch b/SOURCES/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch new file mode 100644 index 0000000..a600799 --- /dev/null +++ b/SOURCES/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch @@ -0,0 +1,68 @@ +From 7a76b2a073b5df72e9afc39dc6c0cce388e0a733 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 28 Apr 2023 11:50:33 +0200 +Subject: [PATCH] pstore: avoid opening the dmesg.txt file if not requested + +Even with Storage=journal we would still attempt to open the final +dmesg.txt file which causes a lot of noise in the journal: + +``` +[ 5.764111] H testsuite-82.sh[658]: + systemctl start systemd-pstore +[ 5.806385] H systemd[1]: Starting modprobe@efi_pstore.service... +[ 5.808656] H systemd[1]: modprobe@efi_pstore.service: Deactivated successfully. +[ 5.808971] H systemd[1]: Finished modprobe@efi_pstore.service. +[ 5.818845] H kernel: audit: type=1130 audit(1682630623.637:114): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel msg='unit=modprobe@efi_pstore comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? termin> +[ 5.818865] H kernel: audit: type=1131 audit(1682630623.637:115): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel msg='unit=modprobe@efi_pstore comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? termin> +[ 5.816052] H systemd[1]: Starting systemd-pstore.service... +[ 5.840703] H systemd-pstore[806]: PStore dmesg-efi-168263062313014. +[ 5.841239] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841428] H systemd-pstore[806]: PStore dmesg-efi-168263062312014. +[ 5.841575] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841712] H systemd-pstore[806]: PStore dmesg-efi-168263062311014. +[ 5.841839] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841989] H systemd-pstore[806]: PStore dmesg-efi-168263062310014. +[ 5.842141] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842274] H systemd-pstore[806]: PStore dmesg-efi-168263062309014. +[ 5.842423] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842589] H systemd-pstore[806]: PStore dmesg-efi-168263062308014. +[ 5.842722] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842865] H systemd-pstore[806]: PStore dmesg-efi-168263062307014. +[ 5.843003] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843153] H systemd-pstore[806]: PStore dmesg-efi-168263062306014. +[ 5.843280] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843434] H systemd-pstore[806]: PStore dmesg-efi-168263062305014. +[ 5.843570] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843702] H systemd-pstore[806]: PStore dmesg-efi-168263062304014. +[ 5.843831] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843958] H systemd-pstore[806]: PStore dmesg-efi-168263062303014. +[ 5.844093] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844250] H systemd-pstore[806]: PStore dmesg-efi-168263062302014. +[ 5.844412] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844619] H systemd-pstore[806]: PStore dmesg-efi-168263062301014. +[ 5.844781] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844956] H systemd-pstore[806]: PStore dmesg-efi-168263062300014. +[ 5.845168] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.851101] H systemd[1]: Finished systemd-pstore.service. +``` + +(cherry picked from commit ad5980803adac8dc1cf980447a07cb18962c238b) + +Related: #2190151 +--- + src/pstore/pstore.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 073fedb7d2..9367071833 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -181,6 +181,9 @@ static int append_dmesg(PStoreEntry *pe, const char *subdir1, const char *subdir + + assert(pe); + ++ if (arg_storage != PSTORE_STORAGE_EXTERNAL) ++ return 0; ++ + if (pe->content_size == 0) + return 0; + diff --git a/SOURCES/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch b/SOURCES/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch new file mode 100644 index 0000000..029f380 --- /dev/null +++ b/SOURCES/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch @@ -0,0 +1,341 @@ +From 06b0704a8bb41fa9a496f5671e191dc7b6c7ed9b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 3 May 2023 15:25:18 +0200 +Subject: [PATCH] test: add a couple of tests for systemd-pstore + +Based on: + - 6858e32d730fd5574eaa3d7fbf4cb12aacaea336 + - edea0d6ac57610b7af603b833b19a846327e3638 + +Related: #2190151 +--- + test/TEST-74-AUX-UTILS/Makefile | 1 + + test/TEST-74-AUX-UTILS/test.sh | 48 +++++ + test/TEST-74-AUX-UTILS/testsuite.pstore.sh | 218 +++++++++++++++++++++ + test/TEST-74-AUX-UTILS/testsuite.sh | 14 ++ + test/test-functions | 2 +- + 5 files changed, 282 insertions(+), 1 deletion(-) + create mode 120000 test/TEST-74-AUX-UTILS/Makefile + create mode 100755 test/TEST-74-AUX-UTILS/test.sh + create mode 100755 test/TEST-74-AUX-UTILS/testsuite.pstore.sh + create mode 100755 test/TEST-74-AUX-UTILS/testsuite.sh + +diff --git a/test/TEST-74-AUX-UTILS/Makefile b/test/TEST-74-AUX-UTILS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-74-AUX-UTILS/test.sh b/test/TEST-74-AUX-UTILS/test.sh +new file mode 100755 +index 0000000000..fead257337 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/test.sh +@@ -0,0 +1,48 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Tests for auxiliary utilities" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service <"$DUMMY_DMESG_1" <<\EOF ++6,17159,5340096332127,-;usb 1-4: USB disconnect, device number 124 ++6,17160,5340109662397,-;input: WH-1000XM3 (AVRCP) as /devices/virtual/input/input293 ++6,17161,5343126458360,-;loop0: detected capacity change from 0 to 3145728 ++6,17162,5343126766065,-; loop0: p1 p2 ++6,17163,5343126815038,-;EXT4-fs (loop0p1): mounted filesystem with ordered data mode. Quota mode: none. ++6,17164,5343158037334,-;EXT4-fs (loop0p1): unmounting filesystem. ++6,17165,5343158072598,-;loop0: detected capacity change from 0 to 3145728 ++6,17166,5343158073563,-; loop0: p1 p2 ++6,17167,5343158074325,-; loop0: p1 p2 ++6,17168,5343158140859,-;EXT4-fs (loop0p1): mounted filesystem with ordered data mode. Quota mode: none. ++6,17169,5343158182977,-;EXT4-fs (loop0p1): unmounting filesystem. ++6,17170,5343158700241,-;loop0: detected capacity change from 0 to 3145728 ++6,17171,5343158700439,-; loop0: p1 p2 ++6,17172,5343158701120,-; loop0: p1 p2 ++EOF ++ ++DUMMY_DMESG_2="$(mktemp)" ++cat >"$DUMMY_DMESG_2" <<\EOF ++Nechť již hříšné saxofony ďáblů rozezvučí síň úděsnými tóny waltzu, tanga a quickstepu. ++Příliš žluťoučký kůň úpěl ďábelské ódy. ++Zvlášť zákeřný učeň s ďolíčky běží podél zóny úlů. ++Vyciď křišťálový nůž, ó učiň úděsné líbivým! ++Loď čeří kýlem tůň obzvlášť v Grónské úžině ++Ó, náhlý déšť již zvířil prach a čilá laň teď běží s houfcem gazel k úkrytům. ++Vypätá dcéra grófa Maxwella s IQ nižším ako kôň núti čeľaď hrýzť hŕbu jabĺk. ++Kŕdeľ šťastných ďatľov učí pri ústí Váhu mĺkveho koňa obhrýzať kôru a žrať čerstvé mäso. ++Stróż pchnął kość w quiz gędźb vel fax myjń. ++Portez ce vieux whisky au juge blond qui fume! ++EOF ++ ++file_count() { find "${1:?}" -type f | wc -l; } ++file_size() { wc -l <"${1:?}"; } ++random_efi_timestamp() { printf "%0.10d" "$((1000000000 + RANDOM))"; } ++ ++# The dmesg- filename contains the backend-type and the Common Platform Error Record, CPER, ++# record id, a 64-bit number. ++# ++# Files are processed in reverse lexigraphical order so as to properly reconstruct original dmesg. ++ ++prepare_efi_logs() { ++ local file="${1:?}" ++ local timestamp="${2:?}" ++ local chunk count filename ++ ++ # For the EFI backend, the 3 least significant digits of record id encodes a ++ # "count" number, the next 2 least significant digits for the dmesg part ++ # (chunk) number, and the remaining digits as the timestamp. See ++ # linux/drivers/firmware/efi/efi-pstore.c in efi_pstore_write(). ++ count="$(file_size "$file")" ++ chunk=0 ++ # The sed in the process substitution below just reverses the file ++ while read -r line; do ++ filename="$(printf "dmesg-efi-%0.10d%0.2d%0.3d" "$timestamp" "$chunk" "$count")" ++ echo "$line" >"/sys/fs/pstore/$filename" ++ chunk=$((chunk + 1)) ++ done < <(sed '1!G;h;$!d' "$file") ++ ++ if [[ "$chunk" -eq 0 ]]; then ++ echo >&2 "No dmesg-efi files were created" ++ exit 1 ++ fi ++} ++ ++prepare_erst_logs() { ++ local file="${1:?}" ++ local start_id="${2:?}" ++ local id filename ++ ++ # For the ERST backend, the record is a monotonically increasing number, seeded as ++ # a timestamp. See linux/drivers/acpi/apei/erst.c in erst_writer(). ++ id="$start_id" ++ # The sed in the process substitution below just reverses the file ++ while read -r line; do ++ filename="$(printf "dmesg-erst-%0.16d" "$id")" ++ echo "$line" >"/sys/fs/pstore/$filename" ++ id=$((id + 1)) ++ done < <(sed '1!G;h;$!d' "$file") ++ ++ if [[ "$id" -eq "$start_id" ]]; then ++ echo >&2 "No dmesg-erst files were created" ++ exit 1 ++ fi ++ ++ # ID of the last dmesg file will be the ID of the erst subfolder ++ echo "$((id - 1))" ++} ++ ++prepare_pstore_config() { ++ local storage="${1:?}" ++ local unlink="${2:?}" ++ ++ systemctl stop systemd-pstore ++ ++ rm -fr /sys/fs/pstore/* /var/lib/systemd/pstore/* ++ ++ mkdir -p /run/systemd/pstore.conf.d ++ cat >"/run/systemd/pstore.conf.d/99-test.conf" </sys/fs/pstore/foo.bar ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ filename_1="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_1" "$(file_size "$DUMMY_DMESG_1")")" ++ diff "$DUMMY_DMESG_1" "$filename_1" ++ filename_2="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_2" "$(file_size "$DUMMY_DMESG_2")")" ++ diff "$DUMMY_DMESG_2" "$filename_2" ++ grep "hello world" "/var/lib/systemd/pstore/foo.bar" ++ ++ : "Backend: EFI; Storage: journal; Unlink: $unlink" ++ timestamp="$(random_efi_timestamp)" ++ prepare_pstore_config "journal" "$unlink" ++ prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]] ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++ ++ : "Backend: ERST; Storage: external; Unlink: $unlink" ++ prepare_pstore_config "external" "$unlink" ++ last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ # We always log to journal ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++ filename="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id")" ++ diff "$DUMMY_DMESG_1" "$filename" ++ ++ : "Backend: ERST; Storage: external; Unlink: $unlink; multiple dmesg files" ++ prepare_pstore_config "external" "$unlink" ++ last_id_1="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ last_id_2="$(prepare_erst_logs "$DUMMY_DMESG_2" "$((last_id_1 + 10))")" ++ # Add one "random" (non-dmesg) file as well ++ echo "hello world" >/sys/fs/pstore/foo.bar ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ filename_1="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_1")" ++ diff "$DUMMY_DMESG_1" "$filename_1" ++ filename_2="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_2")" ++ diff "$DUMMY_DMESG_2" "$filename_2" ++ grep "hello world" "/var/lib/systemd/pstore/foo.bar" ++ ++ : "Backend: ERST; Storage: journal; Unlink: $unlink" ++ prepare_pstore_config "journal" "$unlink" ++ last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]] ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++done +diff --git a/test/TEST-74-AUX-UTILS/testsuite.sh b/test/TEST-74-AUX-UTILS/testsuite.sh +new file mode 100755 +index 0000000000..13c767e490 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/testsuite.sh +@@ -0,0 +1,14 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -eux ++set -o pipefail ++ ++: >/failed ++ ++for script in "${0%.sh}".*.sh; do ++ echo "Running $script" ++ "./$script" ++done ++ ++touch /testok ++rm /failed +diff --git a/test/test-functions b/test/test-functions +index a7b18991f4..f0cf6f8575 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0920-ci-update-permissions-for-source-git-automation-work.patch b/SOURCES/0920-ci-update-permissions-for-source-git-automation-work.patch new file mode 100644 index 0000000..2b123bb --- /dev/null +++ b/SOURCES/0920-ci-update-permissions-for-source-git-automation-work.patch @@ -0,0 +1,29 @@ +From ab5a221daca2783b73fd286f5410dbec905cabfa Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 19 May 2023 16:42:03 +0200 +Subject: [PATCH] ci: update permissions for source-git automation workflows + +The new version of `redhat-plumbers-in-action/advanced-commit-linter` requires new permission: `checks: write`. + +https://github.com/redhat-plumbers-in-action/advanced-commit-linter/commit/f1bb35fcdeff83d40eb67b5e7c58baad6be689b2 + +rhel-only + +Related: #2179309 +--- + .github/workflows/source-git-automation.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 140f21b116..e653e28a7f 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -33,7 +33,7 @@ jobs: + validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} + + permissions: +- statuses: write ++ checks: write + pull-requests: write + + steps: diff --git a/SOURCES/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch b/SOURCES/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch new file mode 100644 index 0000000..fa60f26 --- /dev/null +++ b/SOURCES/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch @@ -0,0 +1,130 @@ +From 30cbb55a8d9fedf07d5c9d792849b723b856cd62 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Sun, 12 Feb 2023 12:15:08 +0000 +Subject: [PATCH] sulogin: fix control lost of the current terminal when + default.target is rescue.target + +When default.target is rescue.target, exiting from the single-user shell +results in lost of the control of the current terminal. This is because the +operation performed to continue to boot is systemctl default but default.target +is now rescue.target and it is already active. Hence, no new process that +controls the current terminal is created. Users need to make hardware reset to +recover the situation. + +This sounds like a bit corner case issue and some might feel configuring +default.target as rescue.target is odd because there are several other ways to +transition to rescue.mode without configuring default.target to rescue.target +such as systemctl rescue or systemd.unit=rescue.target something like +that. However, users unfamiliar with systemd operations tend to come up with +systemctl set-default rescue.target. + +To fix this issue, let's transition to default.target only when default.target +is inactive. Otherwise, invoke the single-user shell again to keep control of +the current terminal for users. + +This new logic depends on whether D-Bus working well. Exiting without any check +of result of systemctl default could lead to again the control lost of the +current terminal. Hence, add checking results of each D-Bus operations +including systemctl default and invoke the single-user shell if they fail. + +(cherry picked from commit 937ca8330d11e406b8ef343bead6f4f6244e39c7) + +Resolves: #2169932 +--- + src/sulogin-shell/sulogin-shell.c | 60 +++++++++++++++++++++++++------ + 1 file changed, 50 insertions(+), 10 deletions(-) + +diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c +index a1ea2333de..8f14ee11bb 100644 +--- a/src/sulogin-shell/sulogin-shell.c ++++ b/src/sulogin-shell/sulogin-shell.c +@@ -14,6 +14,8 @@ + #include "process-util.h" + #include "sd-bus.h" + #include "signal-util.h" ++#include "special.h" ++#include "unit-def.h" + + static int reload_manager(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +@@ -43,6 +45,28 @@ static int reload_manager(sd_bus *bus) { + return 0; + } + ++static int default_target_is_inactive(sd_bus *bus) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_free_ char *path = NULL, *state = NULL; ++ int r; ++ ++ path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); ++ if (!path) ++ return log_oom(); ++ ++ r = sd_bus_get_property_string(bus, ++ "org.freedesktop.systemd1", ++ path, ++ "org.freedesktop.systemd1.Unit", ++ "ActiveState", ++ &error, ++ &state); ++ if (r < 0) ++ return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); ++ ++ return streq_ptr(state, "inactive"); ++} ++ + static int start_default_target(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; +@@ -95,7 +119,6 @@ int main(int argc, char *argv[]) { + NULL, /* --force */ + NULL + }; +- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); +@@ -108,17 +131,34 @@ int main(int argc, char *argv[]) { + /* allows passwordless logins if root account is locked. */ + sulogin_cmdline[1] = "--force"; + +- (void) fork_wait(sulogin_cmdline); ++ for (;;) { ++ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; ++ ++ (void) fork_wait(sulogin_cmdline); ++ ++ r = bus_connect_system_systemd(&bus); ++ if (r < 0) { ++ log_warning_errno(r, "Failed to get D-Bus connection: %m"); ++ goto fallback; ++ } + +- r = bus_connect_system_systemd(&bus); +- if (r < 0) { +- log_warning_errno(r, "Failed to get D-Bus connection: %m"); +- r = 0; +- } else { +- (void) reload_manager(bus); ++ if (reload_manager(bus) < 0) ++ goto fallback; + +- r = start_default_target(bus); ++ r = default_target_is_inactive(bus); ++ if (r < 0) ++ goto fallback; ++ if (!r) { ++ log_warning(SPECIAL_DEFAULT_TARGET" is not inactive. Please review the "SPECIAL_DEFAULT_TARGET" setting.\n"); ++ goto fallback; ++ } ++ ++ if (start_default_target(bus) >= 0) ++ break; ++ ++ fallback: ++ log_warning("Fallback to the single-user shell.\n"); + } + +- return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; ++ return 0; + } diff --git a/SOURCES/0922-parse-util-in-parse_permille-check-negative-earlier.patch b/SOURCES/0922-parse-util-in-parse_permille-check-negative-earlier.patch new file mode 100644 index 0000000..2e1065e --- /dev/null +++ b/SOURCES/0922-parse-util-in-parse_permille-check-negative-earlier.patch @@ -0,0 +1,49 @@ +From cb99c3e54af1ba7c6cf1cd99d61546f5aa9423cb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:50:25 +0200 +Subject: [PATCH] parse-util: in parse_permille() check negative earlier + +If 'v' is negative, it's wrong to add the decimal to it, as we'd +actually need to subtract it in this case. But given that we don't want +to allow negative vaues anyway, simply check earlier whether what we +have parsed so far was negative, and react to that before adding the +decimal to it. + +(cherry picked from commit 8cbc92d5975b603002c3141364a7709a9c66e23a) + +Related: #2178179 +--- + src/basic/parse-util.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 992ea3605b..2ab8e88451 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -728,6 +728,8 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + } else { + pc = endswith(p, "%"); + if (!pc) +@@ -748,15 +750,14 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + if (v > (INT_MAX - q) / 10) + return -ERANGE; + + v = v * 10 + q; + } + +- if (v < 0) +- return -ERANGE; +- + return v; + } + diff --git a/SOURCES/0923-tree-wide-increase-granularity-of-percent-specificat.patch b/SOURCES/0923-tree-wide-increase-granularity-of-percent-specificat.patch new file mode 100644 index 0000000..5e53d2a --- /dev/null +++ b/SOURCES/0923-tree-wide-increase-granularity-of-percent-specificat.patch @@ -0,0 +1,165 @@ +From 30343fc0ba66dd7a513de736c7708702ec5400be Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:52:42 +0200 +Subject: [PATCH] tree-wide: increase granularity of percent specifications all + over the place to permille + +We so far had various placed we'd parse percentages with +parse_percent(). Let's make them use parse_permille() instead, which is +downward compatible (as it also parses percent values), and increases +the granularity a bit. Given that on the wire we usually normalize +relative specifications to something like UINT32_MAX anyway changing +from base-100 to base-1000 calculations can be done easily without +breaking compat. + +This commit doesn't document this change in the man pages. While +allowing more precise specifcations permille is not as commonly +understood as perent I guess, hence let's keep this out of the docs for +now. + +(cherry picked from commit f806dfd34595dac8632ba777250323a4735568dc) + +Resolves: #2178179 +--- + src/core/load-fragment.c | 12 ++++++------ + src/login/logind-user.c | 6 +++--- + src/login/pam_systemd.c | 4 ++-- + src/shared/bus-unit-util.c | 22 ++++++++++++---------- + 4 files changed, 23 insertions(+), 21 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 53de7ff5e9..f6505cf83c 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -2991,13 +2991,13 @@ int config_parse_cpu_quota( + return 0; + } + +- r = parse_percent_unbounded(rvalue); ++ r = parse_permille_unbounded(rvalue); + if (r <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU quota '%s', ignoring.", rvalue); + return 0; + } + +- c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 100U; ++ c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 1000U; + return 0; + } + +@@ -3057,7 +3057,7 @@ int config_parse_memory_limit( + + if (!isempty(rvalue) && !streq(rvalue, "infinity")) { + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = parse_size(rvalue, 1024, &bytes); + if (r < 0) { +@@ -3065,7 +3065,7 @@ int config_parse_memory_limit( + return 0; + } + } else +- bytes = physical_memory_scale(r, 100U); ++ bytes = physical_memory_scale(r, 1000U); + + if (bytes >= UINT64_MAX || + (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { +@@ -3132,7 +3132,7 @@ int config_parse_tasks_max( + return 0; + } + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = safe_atou64(rvalue, &v); + if (r < 0) { +@@ -3140,7 +3140,7 @@ int config_parse_tasks_max( + return 0; + } + } else +- v = system_tasks_max_scale(r, 100U); ++ v = system_tasks_max_scale(r, 1000U); + + if (v <= 0 || v >= UINT64_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index bba3158d1a..00d25d5876 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -794,9 +794,9 @@ int config_parse_tmpfs_size( + assert(data); + + /* First, try to parse as percentage */ +- r = parse_percent(rvalue); +- if (r > 0 && r < 100) +- *sz = physical_memory_scale(r, 100U); ++ r = parse_permille(rvalue); ++ if (r > 0 && r < 1000) ++ *sz = physical_memory_scale(r, 1000U); + else { + uint64_t k; + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index c87e980b18..7a551a41bb 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -208,9 +208,9 @@ static int append_session_memory_max(pam_handle_t *handle, sd_bus_message *m, co + return r; + } + } else { +- r = parse_percent(limit); ++ r = parse_permille(limit); + if (r >= 0) { +- r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r)); + return r; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index c475bbafe0..aa4286ab6e 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -440,16 +440,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- r = parse_percent(eq); ++ r = parse_permille(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 MemoryLowScale property (and related +- * ones). This way the physical memory size can be determined server-side */ ++ /* When this is a percentage we'll convert this into a relative value in the range 0…UINT32_MAX ++ * and pass it in the MemoryLowScale property (and related ones). This way the physical memory ++ * size can be determined server-side. */ + + n = strjoina(field, "Scale"); +- r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) + return bus_log_create_error(r); + +@@ -467,13 +467,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); + else { +- r = parse_percent_unbounded(eq); +- if (r <= 0) { +- log_error_errno(r, "CPU quota '%s' invalid.", eq); +- return -EINVAL; ++ r = parse_permille_unbounded(eq); ++ if (r == 0) { ++ log_error("CPU quota too small."); ++ return -ERANGE; + } ++ if (r < 0) ++ return log_error_errno(r, "CPU quota '%s' invalid.", eq); + +- r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U); ++ r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (((uint64_t) r * USEC_PER_SEC) / 1000U)); + } + + if (r < 0) diff --git a/SOURCES/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch b/SOURCES/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..abed63e --- /dev/null +++ b/SOURCES/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,31 @@ +From 5a1d30b9a775a7bbac55752abdc10ed5383d209f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:39:35 +0900 +Subject: [PATCH] errno-util: introduce ERRNO_IS_TRANSIENT() + +(cherry picked from commit 7aad83580fccee926d903bdb1a2a6af2c40ef0fc) + +Related: #2172846 +--- + src/basic/util.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 195f02cf5f..48beb88bac 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -180,6 +180,14 @@ static inline int negative_errno(void) { + return -errno; + } + ++ ++/* For send()/recv() or read()/write(). */ ++static inline bool ERRNO_IS_TRANSIENT(int r) { ++ return IN_SET(abs(r), ++ EAGAIN, ++ EINTR); ++} ++ + /* Two different errors for access problems */ + static inline bool ERRNO_IS_PRIVILEGE(int r) { + return IN_SET(abs(r), diff --git a/SOURCES/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch b/SOURCES/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..2c0b3b1 --- /dev/null +++ b/SOURCES/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,545 @@ +From da79f303ec02fdb9a1c07e0fe48e0aaf4bd09e1b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 04:07:24 +0900 +Subject: [PATCH] tree-wide: use ERRNO_IS_TRANSIENT() + +(cherry picked from commit 8add30a03cb19e4a2722fa5a0fc08c277aaf67fd) + +Related: #2172846 +--- + src/basic/barrier.c | 7 ++++--- + src/basic/terminal-util.c | 2 +- + src/core/cgroup.c | 2 +- + src/core/manager.c | 17 ++++++++--------- + src/core/path.c | 2 +- + src/import/importd.c | 2 +- + src/journal/journald-kmsg.c | 2 +- + src/journal/journald-server.c | 2 +- + src/journal/journald-stream.c | 2 +- + src/journal/sd-journal.c | 2 +- + src/libsystemd-network/icmp6-util.c | 2 +- + src/libsystemd-network/sd-dhcp-client.c | 4 ++-- + src/libsystemd-network/sd-dhcp-server.c | 2 +- + src/libsystemd-network/sd-dhcp6-client.c | 2 +- + src/libsystemd-network/sd-ipv4acd.c | 2 +- + src/libsystemd-network/sd-lldp.c | 2 +- + src/libsystemd/sd-event/sd-event.c | 6 +++--- + src/libsystemd/sd-netlink/netlink-socket.c | 4 ++-- + src/libsystemd/sd-network/sd-network.c | 2 +- + src/nspawn/nspawn.c | 2 +- + src/resolve/resolved-dns-stream.c | 6 +++--- + src/resolve/resolved-dns-stub.c | 2 +- + src/resolve/resolved-manager.c | 2 +- + src/shared/ask-password-api.c | 6 +++--- + src/socket-proxy/socket-proxyd.c | 4 ++-- + src/time-wait-sync/time-wait-sync.c | 2 +- + .../tty-ask-password-agent.c | 2 +- + src/udev/udevd.c | 2 +- + 28 files changed, 47 insertions(+), 47 deletions(-) + +diff --git a/src/basic/barrier.c b/src/basic/barrier.c +index 587852aac8..d36c6c6f88 100644 +--- a/src/basic/barrier.c ++++ b/src/basic/barrier.c +@@ -13,6 +13,7 @@ + #include "barrier.h" + #include "fd-util.h" + #include "macro.h" ++#include "util.h" + + /** + * Barriers +@@ -181,7 +182,7 @@ static bool barrier_write(Barrier *b, uint64_t buf) { + assert(b->me >= 0); + do { + len = write(b->me, &buf, sizeof(buf)); +- } while (len < 0 && IN_SET(errno, EAGAIN, EINTR)); ++ } while (len < 0 && ERRNO_IS_TRANSIENT(errno)); + + if (len != sizeof(buf)) + goto error; +@@ -223,7 +224,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + int r; + + r = poll(pfd, 2, -1); +- if (r < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (r < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + else if (r < 0) + goto error; +@@ -233,7 +234,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + + /* events on @them signal new data for us */ + len = read(b->them, &buf, sizeof(buf)); +- if (len < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (len < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + + if (len != sizeof(buf)) +diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c +index e2bbe8187d..18176cfe17 100644 +--- a/src/basic/terminal-util.c ++++ b/src/basic/terminal-util.c +@@ -460,7 +460,7 @@ int acquire_terminal( + + l = read(notify, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f89bce3d61..0c8a66edd1 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2356,7 +2356,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read control group inotify events: %m"); +diff --git a/src/core/manager.c b/src/core/manager.c +index 4a9f9bfcf9..e09227d5ac 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2331,7 +2331,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t + + n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; /* Spurious wakeup, try again */ + + /* If this is any other, real error, then let's stop processing this socket. This of course means we +@@ -2573,19 +2573,18 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t + } + + n = read(m->signal_fd, &sfsi, sizeof(sfsi)); +- if (n != sizeof(sfsi)) { +- if (n >= 0) { +- log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); +- return 0; +- } +- +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (n < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + /* We return an error here, which will kill this handler, + * to avoid a busy loop on read error. */ + return log_error_errno(errno, "Reading from signal fd failed: %m"); + } ++ if (n != sizeof(sfsi)) { ++ log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); ++ return 0; ++ } + + log_received_signal(sfsi.ssi_signo == SIGCHLD || + (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) +@@ -4453,7 +4452,7 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re + + l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read from user lookup fd: %m"); +diff --git a/src/core/path.c b/src/core/path.c +index b899bde0de..dfa63d5102 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -152,7 +152,7 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) { + + l = read(s->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read inotify event: %m"); +diff --git a/src/import/importd.c b/src/import/importd.c +index 04563fb098..5463bd7146 100644 +--- a/src/import/importd.c ++++ b/src/import/importd.c +@@ -519,7 +519,7 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return -errno; +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 726c006ce1..a49cc5c4c5 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -321,7 +321,7 @@ static int server_read_dev_kmsg(Server *s) { + return 0; + } + +- if (IN_SET(errno, EAGAIN, EINTR, EPIPE)) ++ if (ERRNO_IS_TRANSIENT(errno) || errno == EPIPE) + return 0; + + return log_error_errno(errno, "Failed to read from kernel: %m"); +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 4788ff78bb..1e00e4b4bd 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1131,7 +1131,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_error_errno(errno, "recvmsg() failed: %m"); +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 5be5b0939c..470d2e2661 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -556,7 +556,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + + l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_warning_errno(errno, "Failed to read from stream: %m"); +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 4c502978de..ca083da161 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -2563,7 +2563,7 @@ _public_ int sd_journal_process(sd_journal *j) { + + l = read(j->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return got_something ? determine_change(j) : SD_JOURNAL_NOP; + + return -errno; +diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c +index 736df222f0..17d4d1faf2 100644 +--- a/src/libsystemd-network/icmp6-util.c ++++ b/src/libsystemd-network/icmp6-util.c +@@ -175,7 +175,7 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, + + len = recvmsg(fd, &msg, MSG_DONTWAIT); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c +index ff434f8ce7..8a8d806b3f 100644 +--- a/src/libsystemd-network/sd-dhcp-client.c ++++ b/src/libsystemd-network/sd-dhcp-client.c +@@ -1720,7 +1720,7 @@ static int client_receive_message_udp( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +@@ -1814,7 +1814,7 @@ static int client_receive_message_raw( + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c +index 5ca46b3502..c964b73da1 100644 +--- a/src/libsystemd-network/sd-dhcp-server.c ++++ b/src/libsystemd-network/sd-dhcp-server.c +@@ -962,7 +962,7 @@ static int server_receive_message(sd_event_source *s, int fd, + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c +index b3bc259280..67257f2e03 100644 +--- a/src/libsystemd-network/sd-dhcp6-client.c ++++ b/src/libsystemd-network/sd-dhcp6-client.c +@@ -1055,7 +1055,7 @@ static int client_receive_message( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m"); +diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c +index a40d40db90..f69810c6f5 100644 +--- a/src/libsystemd-network/sd-ipv4acd.c ++++ b/src/libsystemd-network/sd-ipv4acd.c +@@ -336,7 +336,7 @@ static int ipv4acd_on_packet( + + n = recv(fd, &packet, sizeof(struct ether_arp), 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m"); +diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c +index c75d6079e1..bf15029027 100644 +--- a/src/libsystemd-network/sd-lldp.c ++++ b/src/libsystemd-network/sd-lldp.c +@@ -200,7 +200,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v + + length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT); + if (length < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 2c9d331bf2..549103bc6f 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3007,7 +3007,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) { + + ss = read(fd, &x, sizeof(x)); + if (ss < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +@@ -3161,7 +3161,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { + + n = read(d->fd, &si, sizeof(si)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return read_one; + + return -errno; +@@ -3210,7 +3210,7 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t + + n = read(d->fd, &d->buffer, sizeof(d->buffer)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c +index f103cbedea..5fe91450a7 100644 +--- a/src/libsystemd/sd-netlink/netlink-socket.c ++++ b/src/libsystemd/sd-netlink/netlink-socket.c +@@ -265,7 +265,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + else if (errno == EAGAIN) + log_debug("rtnl: no data in socket"); + +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + if (sender.nl.nl_pid != 0) { +@@ -276,7 +276,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + /* drop the message */ + n = recvmsg(fd, &msg, 0); + if (n < 0) +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + return 0; +diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c +index 3b8ce935b0..09d3b86e14 100644 +--- a/src/libsystemd/sd-network/sd-network.c ++++ b/src/libsystemd/sd-network/sd-network.c +@@ -338,7 +338,7 @@ _public_ int sd_network_monitor_flush(sd_network_monitor *m) { + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 8cb7591f0e..025a513def 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -3252,7 +3252,7 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_warning_errno(errno, "Couldn't read notification socket: %m"); +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index ca0313d1d7..cebaba4207 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -380,7 +380,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_writev(s, iov, 2, 0); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else + s->n_written += ss; +@@ -402,7 +402,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_read(s, (uint8_t*) &s->read_size + s->n_read, sizeof(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +@@ -452,7 +452,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + (uint8_t*) DNS_PACKET_DATA(s->read_packet) + s->n_read - sizeof(s->read_size), + sizeof(s->read_size) + be16toh(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(errno, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(errno)) + return dns_stream_complete(s, errno); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c +index 5ddf13081e..1b80c42174 100644 +--- a/src/resolve/resolved-dns-stub.c ++++ b/src/resolve/resolved-dns-stub.c +@@ -458,7 +458,7 @@ static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (cfd < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 01372fc66b..2a23c387a6 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -755,7 +755,7 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + if (l == 0) + return 0; + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c +index 764ebd08e1..062db31bbd 100644 +--- a/src/shared/ask-password-api.c ++++ b/src/shared/ask-password-api.c +@@ -332,7 +332,7 @@ int ask_password_tty( + + n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -652,7 +652,7 @@ int ask_password_agent( + + n = recvmsg(socket_fd, &msghdr, 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -661,7 +661,7 @@ int ask_password_agent( + + cmsg_close_all(&msghdr); + +- if (n <= 0) { ++ if (n == 0) { + log_debug("Message too short"); + continue; + } +diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c +index 3d07483eb4..155631f1e7 100644 +--- a/src/socket-proxy/socket-proxyd.c ++++ b/src/socket-proxy/socket-proxyd.c +@@ -144,7 +144,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *from_source = sd_event_source_unref(*from_source); + *from = safe_close(*from); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + +@@ -156,7 +156,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *to_source = sd_event_source_unref(*to_source); + *to = safe_close(*to); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + } while (shoveled); +diff --git a/src/time-wait-sync/time-wait-sync.c b/src/time-wait-sync/time-wait-sync.c +index d268fb0c5a..2071cb2759 100644 +--- a/src/time-wait-sync/time-wait-sync.c ++++ b/src/time-wait-sync/time-wait-sync.c +@@ -94,7 +94,7 @@ static int inotify_handler(sd_event_source *s, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_warning_errno(errno, "Lost access to inotify: %m"); +diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c +index 40d594896b..3a20a381c9 100644 +--- a/src/tty-ask-password-agent/tty-ask-password-agent.c ++++ b/src/tty-ask-password-agent/tty-ask-password-agent.c +@@ -150,7 +150,7 @@ static int ask_password_plymouth( + + k = read(fd, buffer + p, sizeof(buffer) - p); + if (k < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 34f6a95503..172d21018e 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1119,7 +1119,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 1; + + return log_error_errno(errno, "Failed to read inotify fd: %m"); diff --git a/SOURCES/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch b/SOURCES/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch new file mode 100644 index 0000000..b24f961 --- /dev/null +++ b/SOURCES/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch @@ -0,0 +1,75 @@ +From 4cbf11180cc6c6792f541a861f3309c34c156f4b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:33:55 +0900 +Subject: [PATCH] libsystemd: ignore both EINTR and EAGAIN + +(cherry picked from commit b3d06b9226db96fddb6bb45a4708e2e8d413d91d) + +Related: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 8 ++++---- + src/libsystemd/sd-resolve/sd-resolve.c | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 8813dd5efd..c6e1a1624f 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -155,7 +155,7 @@ static int bus_socket_write_auth(sd_bus *b) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k); + return 1; +@@ -573,7 +573,7 @@ static int bus_socket_read_auth(sd_bus *b) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +@@ -1051,7 +1051,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + *idx += (size_t) k; + return 1; +@@ -1205,7 +1205,7 @@ int bus_socket_read_message(sd_bus *bus) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c +index a189f140f8..99ecb6a467 100644 +--- a/src/libsystemd/sd-resolve/sd-resolve.c ++++ b/src/libsystemd/sd-resolve/sd-resolve.c +@@ -402,7 +402,7 @@ static void* thread_worker(void *p) { + + length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0); + if (length < 0) { +- if (errno == EINTR) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + break; +@@ -850,7 +850,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) { + + l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0); + if (l < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; diff --git a/SOURCES/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch b/SOURCES/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch new file mode 100644 index 0000000..160c031 --- /dev/null +++ b/SOURCES/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch @@ -0,0 +1,90 @@ +From b1075e8b3ecb9e0770dd46331ce8517ea152e1ca Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Nov 2022 17:42:04 +0100 +Subject: [PATCH] sd-bus: handle -EINTR return from bus_poll() + +In sd_bus_wait(), let's convert EINTR to a return code of 0, thus asking +the caller do loop again and enter sd_bus_process() again (which will +not find any queued events). This way we'll not return an error on +something that isn't really an error. This should typically make sure +things are properly handled by the caller, magically, without eating up +the event entirely, and still giving the caller time to run some code if +they want. + +(cherry picked from commit 3022916b4d2483452c3ddbbac9ee7c4372b1cb46) + +Resolves: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 5 ++++- + src/libsystemd/sd-bus/sd-bus.c | 18 +++++++++++++++--- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index c6e1a1624f..a5c750fc69 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1266,8 +1266,11 @@ int bus_socket_process_opening(sd_bus *b) { + assert(b->state == BUS_OPENING); + + r = poll(&p, 1, 0); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) ++ return 0; + return -errno; ++ } + + if (!(p.revents & (POLLOUT|POLLERR|POLLHUP))) + return 0; +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 21e54591f7..5d934cbf73 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2209,8 +2209,11 @@ _public_ int sd_bus_call( + left = (uint64_t) -1; + + r = bus_poll(bus, true, left); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + goto fail; ++ } + if (r == 0) { + r = -ETIMEDOUT; + goto fail; +@@ -3069,6 +3072,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { + } + + _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { ++ int r; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); +@@ -3083,7 +3087,11 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { + if (bus->rqueue_size > 0) + return 0; + +- return bus_poll(bus, false, timeout_usec); ++ r = bus_poll(bus, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) ++ return 1; /* treat EINTR as success, but let's exit, so that the caller will call back into us soon. */ ++ ++ return r; + } + + _public_ int sd_bus_flush(sd_bus *bus) { +@@ -3125,8 +3133,12 @@ _public_ int sd_bus_flush(sd_bus *bus) { + return 0; + + r = bus_poll(bus, false, (uint64_t) -1); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; ++ + return r; ++ } + } + } + diff --git a/SOURCES/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch b/SOURCES/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch new file mode 100644 index 0000000..2bc16f7 --- /dev/null +++ b/SOURCES/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch @@ -0,0 +1,28 @@ +From 9ddb41dd9dc3bac57d6c3e05700485ee98df3e17 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:18:07 +0100 +Subject: [PATCH] stdio-bridge: don't be bothered with EINTR + +We handle signals via signal handlers, hence no need to be concerned +about EINTR. + +(cherry picked from commit 7c75f34131772781f690860de797d3e35fd0bed9) + +Related: #2172846 +--- + src/stdio-bridge/stdio-bridge.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c +index 519a92a094..493117ef95 100644 +--- a/src/stdio-bridge/stdio-bridge.c ++++ b/src/stdio-bridge/stdio-bridge.c +@@ -276,6 +276,8 @@ int main(int argc, char *argv[]) { + r = ppoll(p, ELEMENTSOF(p), ts, NULL); + } + if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) /* don't be bothered by signals, i.e. EINTR */ ++ continue; + log_error_errno(errno, "ppoll() failed: %m"); + goto finish; + } diff --git a/SOURCES/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch b/SOURCES/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch new file mode 100644 index 0000000..94f1ebb --- /dev/null +++ b/SOURCES/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch @@ -0,0 +1,36 @@ +From da367d5c87c039f4d1250c12097a5fb16f179a70 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 13:00:48 +0100 +Subject: [PATCH] sd-netlink: handle EINTR from poll() gracefully, as success + +(cherry picked from commit 69858785335afffc51bc03127beb53332c0fb983) + +Related: #2172846 +--- + src/libsystemd/sd-netlink/sd-netlink.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c +index a177f220ab..09900d577b 100644 +--- a/src/libsystemd/sd-netlink/sd-netlink.c ++++ b/src/libsystemd/sd-netlink/sd-netlink.c +@@ -488,13 +488,18 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) { + } + + int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) { ++ int r; ++ + assert_return(nl, -EINVAL); + assert_return(!rtnl_pid_changed(nl), -ECHILD); + + if (nl->rqueue_size > 0) + return 0; + +- return rtnl_poll(nl, false, timeout_usec); ++ r = rtnl_poll(nl, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) /* Convert EINTR to "something happened" and give user a chance to run some code before calling back into us */ ++ return 1; ++ return r; + } + + static int timeout_compare(const void *a, const void *b) { diff --git a/SOURCES/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch b/SOURCES/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch new file mode 100644 index 0000000..381f651 --- /dev/null +++ b/SOURCES/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch @@ -0,0 +1,79 @@ +From 1316ec49f209e31799d42d114bd7f35d5acbe097 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:28:19 +0100 +Subject: [PATCH] resolved: handle -EINTR returned from fd_wait_for_event() + better + +We might get signals for various reasons (for example, somebody asking +us to reload caches via a signal), hence let's handle this gracefully. + +(cherry picked from commit 6d66a221685c15798e796d9738f73fdb1fdccdb2) + +Related: #2172846 +--- + src/resolve/resolved-manager.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 2a23c387a6..5583d63527 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -842,11 +842,14 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + } + + static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(mh); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (sendmsg(fd, mh, flags) >= 0) + return 0; +@@ -857,20 +860,26 @@ static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } + } + + static int write_loop(int fd, void *message, size_t length) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(message); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (write(fd, message, length) >= 0) + return 0; +@@ -881,9 +890,12 @@ static int write_loop(int fd, void *message, size_t length) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } diff --git a/SOURCES/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch b/SOURCES/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch new file mode 100644 index 0000000..2d80680 --- /dev/null +++ b/SOURCES/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch @@ -0,0 +1,28 @@ +From c57daab191c6551ac757576fcf7df45fd9790b6b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:38 +0100 +Subject: [PATCH] utmp-wtmp: fix error in case isatty() fails + +(cherry picked from commit 80b780ba178a84b248ecee47eef82358480c9492) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index ef9427fa7b..743b784489 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -312,8 +312,10 @@ static int write_to_terminal(const char *tty, const char *message) { + assert(message); + + fd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); +- if (fd < 0 || !isatty(fd)) ++ if (fd < 0) + return -errno; ++ if (!isatty(fd)) ++ return -ENOTTY; + + p = message; + left = strlen(message); diff --git a/SOURCES/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch b/SOURCES/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch new file mode 100644 index 0000000..6cff781 --- /dev/null +++ b/SOURCES/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch @@ -0,0 +1,52 @@ +From 3590a9c5ce038bc56cdded426156cbd278903c86 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:55 +0100 +Subject: [PATCH] utmp-wtmp: handle EINTR gracefully when waiting to write to + tty + +(cherry picked from commit 22ecfa83123dbfa2322346ac4e25ad2193a3b10c) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index 743b784489..7358ece75d 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -320,7 +320,7 @@ static int write_to_terminal(const char *tty, const char *message) { + p = message; + left = strlen(message); + +- end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC; ++ end = usec_add(now(CLOCK_MONOTONIC), TIMEOUT_MSEC*USEC_PER_MSEC); + + while (left > 0) { + ssize_t n; +@@ -332,20 +332,22 @@ static int write_to_terminal(const char *tty, const char *message) { + int k; + + t = now(CLOCK_MONOTONIC); +- + if (t >= end) + return -ETIME; + + k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC); +- if (k < 0) ++ if (k < 0) { ++ if (ERRNO_IS_TRANSIENT(k)) ++ continue; + return -errno; + ++ } + if (k == 0) + return -ETIME; + + n = write(fd, p, left); + if (n < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; diff --git a/SOURCES/0933-journal-vacuum-count-size-of-all-journal-files.patch b/SOURCES/0933-journal-vacuum-count-size-of-all-journal-files.patch new file mode 100644 index 0000000..48c4403 --- /dev/null +++ b/SOURCES/0933-journal-vacuum-count-size-of-all-journal-files.patch @@ -0,0 +1,90 @@ +From 947296a00d17ef115f4097aa86a8c6f1bfc8bf58 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 22 Mar 2023 12:36:54 +0100 +Subject: [PATCH] journal-vacuum: count size of all journal files + +Currently, active journal files are excluded, which means that vacuuming +may not remove anything even if *MaxUse= has been exceeded. + +(cherry picked from commit 9ea46af4f2368b41d57705bac09774778126507f) + +Resolves: #2180380 +--- + src/journal/journal-vacuum.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c +index 8d3ae71440..dd21f40966 100644 +--- a/src/journal/journal-vacuum.c ++++ b/src/journal/journal-vacuum.c +@@ -179,6 +179,8 @@ int journal_directory_vacuum( + if (!S_ISREG(st.st_mode)) + continue; + ++ size = 512UL * (uint64_t) st.st_blocks; ++ + q = strlen(de->d_name); + + if (endswith(de->d_name, ".journal")) { +@@ -188,6 +190,7 @@ int journal_directory_vacuum( + + if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -195,6 +198,7 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] != '-' || + de->d_name[q-8-16-1-16-1-32-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -207,11 +211,13 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] = 0; + if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { + n_active_files++; ++ sum += size; + continue; + } + + if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -224,12 +230,14 @@ int journal_directory_vacuum( + + if (q < 1 + 16 + 1 + 16 + 8 + 1) { + n_active_files++; ++ sum += size; + continue; + } + + if (de->d_name[q-1-8-16-1] != '-' || + de->d_name[q-1-8-16-1-16-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -241,6 +249,7 @@ int journal_directory_vacuum( + + if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -251,8 +260,6 @@ int journal_directory_vacuum( + continue; + } + +- size = 512UL * (uint64_t) st.st_blocks; +- + r = journal_file_empty(dirfd(d), p); + if (r < 0) { + log_debug_errno(r, "Failed check if %s is empty, ignoring: %m", p); diff --git a/SOURCES/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch b/SOURCES/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch new file mode 100644 index 0000000..3a51892 --- /dev/null +++ b/SOURCES/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch @@ -0,0 +1,365 @@ +From fc8959efebc662f4050700cc1ed2798750b15b73 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 13:32:53 +0100 +Subject: [PATCH] resolved: instead of closing DNS UDP transaction fds + right-away, add them to a socket "graveyard" + +The "socket graveyard" shall contain sockets we have sent a question out +of, but not received a reply. If we'd close thus sockets immediately +when we are not interested anymore, we'd trigger ICMP port unreachable +messages once we after all *do* get a reply. Let's avoid that, by +leaving the fds open for a bit longer, until a timeout is reached or a +reply datagram received. + +Fixes: #17421 +(cherry picked from commit 80710ade03d971a8877fde8ce9d42eb2b07f4c47) + +Resolves: #2156751 +--- + src/resolve/meson.build | 2 + + src/resolve/resolved-dns-transaction.c | 44 ++++++-- + src/resolve/resolved-manager.c | 2 + + src/resolve/resolved-manager.h | 5 + + src/resolve/resolved-socket-graveyard.c | 133 ++++++++++++++++++++++++ + src/resolve/resolved-socket-graveyard.h | 18 ++++ + 6 files changed, 194 insertions(+), 10 deletions(-) + create mode 100644 src/resolve/resolved-socket-graveyard.c + create mode 100644 src/resolve/resolved-socket-graveyard.h + +diff --git a/src/resolve/meson.build b/src/resolve/meson.build +index 15f3835d55..a975e58242 100644 +--- a/src/resolve/meson.build ++++ b/src/resolve/meson.build +@@ -63,6 +63,8 @@ systemd_resolved_sources = files(''' + resolved-dns-stub.c + resolved-etc-hosts.h + resolved-etc-hosts.c ++ resolved-socket-graveyard.c ++ resolved-socket-graveyard.h + '''.split()) + + resolvectl_sources = files(''' +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index c60b8215a6..95aea21134 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -48,7 +48,14 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) { + } + } + +-static void dns_transaction_close_connection(DnsTransaction *t) { ++static void dns_transaction_close_connection( ++ DnsTransaction *t, ++ bool use_graveyard) { /* Set use_graveyard = false when you know the connection is already ++ * dead, for example because you got a connection error back from the ++ * kernel. In that case there's no point in keeping the fd around, ++ * hence don't. */ ++ int r; ++ + assert(t); + + if (t->stream) { +@@ -62,6 +69,20 @@ static void dns_transaction_close_connection(DnsTransaction *t) { + } + + t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source); ++ ++ /* If we have an UDP socket where we sent a packet, but never received one, then add it to the socket ++ * graveyard, instead of closing it right away. That way it will stick around for a moment longer, ++ * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP ++ * port unreachable error message. */ ++ ++ if (use_graveyard && t->dns_udp_fd >= 0 && t->sent && !t->received) { ++ r = manager_add_socket_to_graveyard(t->scope->manager, t->dns_udp_fd); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add UDP socket to graveyard, closing immediately: %m"); ++ else ++ TAKE_FD(t->dns_udp_fd); ++ } ++ + t->dns_udp_fd = safe_close(t->dns_udp_fd); + } + +@@ -81,7 +102,7 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) { + + log_debug("Freeing transaction %" PRIu16 ".", t->id); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + dns_packet_unref(t->sent); +@@ -341,7 +362,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { + + t->state = state; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + /* Notify all queries that are interested, but make sure the +@@ -455,7 +476,7 @@ static int dns_transaction_maybe_restart(DnsTransaction *t) { + static void on_transaction_stream_error(DnsTransaction *t, int error) { + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (ERRNO_IS_DISCONNECT(error)) { + if (t->scope->protocol == DNS_PROTOCOL_LLMNR) { +@@ -478,7 +499,7 @@ static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) { + assert(t); + assert(p); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (dns_packet_validate_reply(p) <= 0) { + log_debug("Invalid TCP reply packet."); +@@ -583,7 +604,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + switch (t->scope->protocol) { + +@@ -692,7 +713,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + r = dns_stream_write_packet(t->stream, t->sent); + if (r < 0) { +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, /* use_graveyard= */ false); + return r; + } + +@@ -1196,7 +1217,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { + if (r > 0) { + /* There are DNSSEC transactions pending now. Update the state accordingly. */ + t->state = DNS_TRANSACTION_VALIDATING; +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + return; + } +@@ -1277,7 +1298,10 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */ + int fd; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); ++ ++ /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */ ++ manager_socket_graveyard_process(t->scope->manager); + + fd = dns_scope_socket_udp(t->scope, t->server, 53); + if (fd < 0) +@@ -1297,7 +1321,7 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r < 0) + return r; + } else +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent); + if (r < 0) +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 5583d63527..5feb92a676 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -683,6 +683,8 @@ Manager *manager_free(Manager *m) { + manager_mdns_stop(m); + manager_dns_stub_stop(m); + ++ manager_socket_graveyard_clear(m); ++ + sd_bus_slot_unref(m->prepare_for_sleep_slot); + sd_bus_unref(m->bus); + +diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h +index d94b2888ab..80119bfcb3 100644 +--- a/src/resolve/resolved-manager.h ++++ b/src/resolve/resolved-manager.h +@@ -20,6 +20,7 @@ typedef struct Manager Manager; + #include "resolved-dns-stream.h" + #include "resolved-dns-trust-anchor.h" + #include "resolved-link.h" ++#include "resolved-socket-graveyard.h" + + #define MANAGER_SEARCH_DOMAINS_MAX 32 + #define MANAGER_DNS_SERVERS_MAX 32 +@@ -130,6 +131,10 @@ struct Manager { + sd_event_source *dns_stub_tcp_event_source; + + Hashmap *polkit_registry; ++ ++ LIST_HEAD(SocketGraveyard, socket_graveyard); ++ SocketGraveyard *socket_graveyard_oldest; ++ size_t n_socket_graveyard; + }; + + /* Manager */ +diff --git a/src/resolve/resolved-socket-graveyard.c b/src/resolve/resolved-socket-graveyard.c +new file mode 100644 +index 0000000000..067cb666d4 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.c +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "resolved-socket-graveyard.h" ++ ++#define SOCKET_GRAVEYARD_USEC (5 * USEC_PER_SEC) ++#define SOCKET_GRAVEYARD_MAX 100 ++ ++/* This implements a socket "graveyard" for UDP sockets. If a socket fd is added to the graveyard it is kept ++ * open for a couple of more seconds, expecting one reply. Once the reply is received the fd is closed ++ * immediately, or if none is received it is closed after the timeout. Why all this? So that if we contact a ++ * DNS server, and it doesn't reply instantly, and we lose interest in the response and thus close the fd, we ++ * don't end up sending back an ICMP error once the server responds but we aren't listening anymore. (See ++ * https://github.com/systemd/systemd/issues/17421 for further information.) ++ * ++ * Note that we don't allocate any timer event source to clear up the graveyard once the socket's timeout is ++ * reached. Instead we operate lazily: we close old entries when adding a new fd to the graveyard, or ++ * whenever any code runs manager_socket_graveyard_process() — which the DNS transaction code does right ++ * before allocating a new UDP socket. */ ++ ++static SocketGraveyard* socket_graveyard_free(SocketGraveyard *g) { ++ if (!g) ++ return NULL; ++ ++ if (g->manager) { ++ assert(g->manager->n_socket_graveyard > 0); ++ g->manager->n_socket_graveyard--; ++ ++ if (g->manager->socket_graveyard_oldest == g) ++ g->manager->socket_graveyard_oldest = g->graveyard_prev; ++ ++ LIST_REMOVE(graveyard, g->manager->socket_graveyard, g); ++ ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard); ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard_oldest); ++ } ++ ++ if (g->io_event_source) { ++ log_debug("Closing graveyard socket fd %i", sd_event_source_get_io_fd(g->io_event_source)); ++ sd_event_source_unref(g->io_event_source); ++ } ++ ++ return mfree(g); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(SocketGraveyard*, socket_graveyard_free); ++ ++void manager_socket_graveyard_process(Manager *m) { ++ usec_t n = USEC_INFINITY; ++ ++ assert(m); ++ ++ while (m->socket_graveyard_oldest) { ++ SocketGraveyard *g = m->socket_graveyard_oldest; ++ ++ if (n == USEC_INFINITY) ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &n) >= 0); ++ ++ if (g->deadline > n) ++ break; ++ ++ socket_graveyard_free(g); ++ } ++} ++ ++void manager_socket_graveyard_clear(Manager *m) { ++ assert(m); ++ ++ while (m->socket_graveyard) ++ socket_graveyard_free(m->socket_graveyard); ++} ++ ++static int on_io_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ SocketGraveyard *g = userdata; ++ ++ assert(g); ++ ++ /* An IO event happened on the graveyard fd. We don't actually care which event that is, and we don't ++ * read any incoming packet off the socket. We just close the fd, that's enough to not trigger the ++ * ICMP unreachable port event */ ++ ++ socket_graveyard_free(g); ++ return 0; ++} ++ ++static void manager_socket_graveyard_make_room(Manager *m) { ++ assert(m); ++ ++ while (m->n_socket_graveyard >= SOCKET_GRAVEYARD_MAX) ++ socket_graveyard_free(m->socket_graveyard_oldest); ++} ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd) { ++ _cleanup_(socket_graveyard_freep) SocketGraveyard *g = NULL; ++ int r; ++ ++ assert(m); ++ assert(fd >= 0); ++ ++ manager_socket_graveyard_process(m); ++ manager_socket_graveyard_make_room(m); ++ ++ g = new(SocketGraveyard, 1); ++ if (!g) ++ return log_oom(); ++ ++ *g = (SocketGraveyard) { ++ .manager = m, ++ }; ++ ++ LIST_PREPEND(graveyard, m->socket_graveyard, g); ++ if (!m->socket_graveyard_oldest) ++ m->socket_graveyard_oldest = g; ++ ++ m->n_socket_graveyard++; ++ ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &g->deadline) >= 0); ++ g->deadline += SOCKET_GRAVEYARD_USEC; ++ ++ r = sd_event_add_io(m->event, &g->io_event_source, fd, EPOLLIN, on_io_event, g); ++ if (r < 0) ++ return log_error_errno(r, "Failed to create graveyard IO source: %m"); ++ ++ r = sd_event_source_set_io_fd_own(g->io_event_source, true); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enable graveyard IO source fd ownership: %m"); ++ ++ (void) sd_event_source_set_description(g->io_event_source, "graveyard"); ++ ++ log_debug("Added socket %i to graveyard", fd); ++ ++ TAKE_PTR(g); ++ return 0; ++} +diff --git a/src/resolve/resolved-socket-graveyard.h b/src/resolve/resolved-socket-graveyard.h +new file mode 100644 +index 0000000000..9b13bb0482 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++typedef struct SocketGraveyard SocketGraveyard; ++ ++#include "resolved-manager.h" ++ ++struct SocketGraveyard { ++ Manager *manager; ++ usec_t deadline; ++ sd_event_source *io_event_source; ++ LIST_FIELDS(SocketGraveyard, graveyard); ++}; ++ ++void manager_socket_graveyard_process(Manager *m); ++void manager_socket_graveyard_clear(Manager *m); ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd); diff --git a/SOURCES/0935-resolved-close-UDP-socket-when-we-received-a-network.patch b/SOURCES/0935-resolved-close-UDP-socket-when-we-received-a-network.patch new file mode 100644 index 0000000..25c1692 --- /dev/null +++ b/SOURCES/0935-resolved-close-UDP-socket-when-we-received-a-network.patch @@ -0,0 +1,26 @@ +From 648fe0097229c7ae46a6b5911521cef27a726cbe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 14:31:56 +0100 +Subject: [PATCH] resolved: close UDP socket when we received a network error + on it + +(cherry picked from commit d68dbb37d7408c025e736181f294152e2a515bf1) + +Related: #2156751 +--- + src/resolve/resolved-dns-transaction.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index 95aea21134..c975215468 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -1250,6 +1250,8 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use + assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0); + dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level); + ++ dns_transaction_close_connection(t, /* use_graveyard = */ false); ++ + dns_transaction_retry(t, true); + return 0; + } diff --git a/SOURCES/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch b/SOURCES/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch new file mode 100644 index 0000000..342a153 --- /dev/null +++ b/SOURCES/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch @@ -0,0 +1,24 @@ +From 950cc2c5109f269561d3c0fdd020c6bf7cb561e1 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 10 Jul 2023 12:38:05 +0200 +Subject: [PATCH] ci: allow RHEL-only labels to mark downstream-only commits + +RHEL-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 491836abbb..327af0467a 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -6,6 +6,7 @@ policy: + exception: + note: + - rhel-only ++ - RHEL-only + tracker: + - keyword: + - 'Resolves: #?' diff --git a/SOURCES/0937-man-tweak-markup-in-systemd-pstore.service-8.patch b/SOURCES/0937-man-tweak-markup-in-systemd-pstore.service-8.patch new file mode 100644 index 0000000..eec7298 --- /dev/null +++ b/SOURCES/0937-man-tweak-markup-in-systemd-pstore.service-8.patch @@ -0,0 +1,39 @@ +From e3d4d6b36c111c5273ce5da124116f1c98b10d9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:48:44 +0100 +Subject: [PATCH] man: tweak markup in systemd-pstore.service(8) + +(cherry picked from commit e3b192626e24cbd3a4dc2c7d5fb9a3b3fd136e24) + +Related: #2217786 +--- + man/systemd-pstore.xml | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.xml +index dd1aa5e83b..8726071cf0 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.xml +@@ -49,8 +49,8 @@ + + The pstore service is independent of the kdump service. In cloud environments + specifically, host and guest filesystems are on remote filesystems (eg. iSCSI +- or NFS), thus kdump relies [implicitly and/or explicitly] upon proper operation +- of networking software *and* hardware *and* infrastructure. Thus it may not be ++ or NFS), thus kdump relies (implicitly and/or explicitly) upon proper operation ++ of networking software *and* hardware *and* infrastructure. Thus it may not be + possible to capture a kernel coredump to a file since writes over the network + may not be possible. + +@@ -59,9 +59,9 @@ + debugging. + + The systemd-pstore executable does the actual work. Upon starting, +- the pstore.conf is read to obtain options, then the /sys/fs/pstore ++ the pstore.conf file is read and the /sys/fs/pstore + directory contents are processed according to the options. Pstore files are written to the +- journal, and optionally saved into /var/lib/systemd/pstore. ++ journal, and optionally saved into /var/lib/systemd/pstore. + + + diff --git a/SOURCES/0938-man-add-.service-suffix-to-systemd-pstore-8.patch b/SOURCES/0938-man-add-.service-suffix-to-systemd-pstore-8.patch new file mode 100644 index 0000000..2a4f140 --- /dev/null +++ b/SOURCES/0938-man-add-.service-suffix-to-systemd-pstore-8.patch @@ -0,0 +1,61 @@ +From ff17baae0631f42f59be6e425943c7181c6c5c18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:57:06 +0100 +Subject: [PATCH] man: add .service suffix to systemd-pstore(8) + +That is the pattern that we always use with executables not in +$PATH. + +(cherry picked from commit aa07dc70932837bfeda982affe53f01d36ec6efe) + +Related: #2217786 +--- + man/rules/meson.build | 2 +- + man/{systemd-pstore.xml => systemd-pstore.service.xml} | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + rename man/{systemd-pstore.xml => systemd-pstore.service.xml} (95%) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 6295330c5e..05eb0a1604 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -634,7 +634,7 @@ manpages = [ + ['systemd-nspawn', '1', [], ''], + ['systemd-path', '1', [], ''], + ['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'], +- ['systemd-pstore', '8', ['systemd-pstore.service'], 'ENABLE_PSTORE'], ++ ['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'], + ['systemd-quotacheck.service', + '8', + ['systemd-quotacheck'], +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.service.xml +similarity index 95% +rename from man/systemd-pstore.xml +rename to man/systemd-pstore.service.xml +index 8726071cf0..47916da521 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.service.xml +@@ -7,19 +7,19 @@ + xmlns:xi="http://www.w3.org/2001/XInclude"> + + +- systemd-pstore ++ systemd-pstore.service + systemd + + + +- systemd-pstore ++ systemd-pstore.service + 8 + + + +- systemd-pstore + systemd-pstore.service +- Tool to archive contents of the persistent storage filesytem ++ systemd-pstore ++ A service to archive contents of pstore + + + diff --git a/SOURCES/0939-presets-enable-systemd-pstore.service-by-default.patch b/SOURCES/0939-presets-enable-systemd-pstore.service-by-default.patch new file mode 100644 index 0000000..0999eb3 --- /dev/null +++ b/SOURCES/0939-presets-enable-systemd-pstore.service-by-default.patch @@ -0,0 +1,26 @@ +From 36d9a1a50f80322b24ff5756b8fb89a07363dfd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 10:01:39 +0100 +Subject: [PATCH] presets: enable systemd-pstore.service by default + +It has no effect is the pstore is not used, and prevents the non-volatile +storage from filling up if is used by the kernel. + +https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=952767 +(cherry picked from commit 5926ea0a6860095eaa83403417cbbf345db864f6) + +Resolves: #2217786 +--- + presets/90-systemd.preset | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/presets/90-systemd.preset b/presets/90-systemd.preset +index 11960e5423..b8edc23d48 100644 +--- a/presets/90-systemd.preset ++++ b/presets/90-systemd.preset +@@ -34,3 +34,5 @@ disable syslog.socket + disable systemd-journal-gatewayd.* + disable systemd-journal-remote.* + disable systemd-journal-upload.* ++ ++enable systemd-pstore.service diff --git a/SOURCES/0940-logind-simplify-code.patch b/SOURCES/0940-logind-simplify-code.patch new file mode 100644 index 0000000..b1a4a25 --- /dev/null +++ b/SOURCES/0940-logind-simplify-code.patch @@ -0,0 +1,54 @@ +From bf5b87db9785b86fadbd2b5e97e4883cbe51797d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 23 Jun 2022 09:56:33 +0200 +Subject: [PATCH] logind: simplify code + +Follow-up for 4885d7490b23e08d8444e5a68927ce9ce8727e5a. + +(cherry picked from commit e5c09aad375551b9db499703ab7eb123d408ba16) + +Resolves: #2209328 +--- + src/login/logind-session.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 916202a65a..fabf680b61 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -349,12 +349,11 @@ fail: + } + + static int session_load_devices(Session *s, const char *devices) { +- const char *p; + int r = 0; + + assert(s); + +- for (p = devices;;) { ++ for (const char *p = devices;;) { + _cleanup_free_ char *word = NULL; + SessionDevice *sd; + dev_t dev; +@@ -531,7 +530,7 @@ int session_load(Session *s) { + s->class = c; + } + +- if (state && streq(state, "closing")) ++ if (streq_ptr(state, "closing")) + s->stopping = true; + + if (s->fifo_path) { +@@ -1073,11 +1072,8 @@ int session_set_display(Session *s, const char *display) { + assert(s); + assert(display); + +- if (streq(s->display, display)) +- return 0; +- + r = free_and_strdup(&s->display, display); +- if (r < 0) ++ if (r <= 0) /* 0 means the strings were equal */ + return r; + + session_save(s); diff --git a/SOURCES/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch b/SOURCES/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch new file mode 100644 index 0000000..5b62383 --- /dev/null +++ b/SOURCES/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch @@ -0,0 +1,89 @@ +From 2fb7d36caf560e4ce57265673da7a518d7a5348f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 16 Jul 2019 00:44:14 +0900 +Subject: [PATCH] format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE + +(cherry picked from commit c5bbb2b5be079852d92d16ebc0d0840929ed82e1) + +Related: #2156786 +--- + src/basic/format-table.c | 25 ++++++++++++++++++------- + src/basic/format-table.h | 2 ++ + 2 files changed, 20 insertions(+), 7 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index c541e92b3c..5f2e5e3d73 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -236,6 +236,8 @@ static size_t table_data_size(TableDataType type, const void *data) { + return sizeof(bool); + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + return sizeof(usec_t); + +@@ -700,6 +702,8 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { + break; + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + buffer.usec = va_arg(ap, usec_t); + data = &buffer.usec; +@@ -837,11 +841,9 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t + return 0; + + case TABLE_TIMESTAMP: +- if (a->timestamp < b->timestamp) +- return -1; +- if (a->timestamp > b->timestamp) +- return 1; +- return 0; ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: ++ return CMP(a->timestamp, b->timestamp); + + case TABLE_TIMESPAN: + if (a->timespan < b->timespan) +@@ -952,14 +954,23 @@ static const char *table_data_format(TableData *d) { + case TABLE_BOOLEAN: + return yes_no(d->boolean); + +- case TABLE_TIMESTAMP: { ++ case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: { + _cleanup_free_ char *p; ++ char *ret; + + p = new(char, FORMAT_TIMESTAMP_MAX); + if (!p) + return NULL; + +- if (!format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp)) ++ if (d->type == TABLE_TIMESTAMP) ++ ret = format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else if (d->type == TABLE_TIMESTAMP_UTC) ++ ret = format_timestamp_utc(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else ++ ret = format_timestamp_relative(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ if (!ret) + return "n/a"; + + d->formatted = TAKE_PTR(p); +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 5a076b5383..1c8ab5436d 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -12,6 +12,8 @@ typedef enum TableDataType { + TABLE_STRING, + TABLE_BOOLEAN, + TABLE_TIMESTAMP, ++ TABLE_TIMESTAMP_UTC, ++ TABLE_TIMESTAMP_RELATIVE, + TABLE_TIMESPAN, + TABLE_SIZE, + TABLE_UINT32, diff --git a/SOURCES/0942-loginctl-shorten-variable-name.patch b/SOURCES/0942-loginctl-shorten-variable-name.patch new file mode 100644 index 0000000..e959206 --- /dev/null +++ b/SOURCES/0942-loginctl-shorten-variable-name.patch @@ -0,0 +1,39 @@ +From c88514d4de20ceeeea2028917087e2710ea419b2 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 23 May 2023 10:48:15 +0200 +Subject: [PATCH] loginctl: shorten variable name + +(cherry picked from commit 86f128558d57586bd28c55eb63968eab3dc4b36e) + +Related: #2156786 +--- + src/login/loginctl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9b3fed928b..079c0e2b17 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -147,7 +147,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + (void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100); + + for (;;) { +- _cleanup_(sd_bus_error_free) sd_bus_error error_tty = SD_BUS_ERROR_NULL; ++ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; + const char *id, *user, *seat, *object, *tty = NULL; + uint32_t uid; +@@ -164,11 +164,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + object, + "org.freedesktop.login1.Session", + "TTY", +- &error_tty, ++ &e, + &reply_tty, + "s"); + if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&error_tty, r)); ++ log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); + else { + r = sd_bus_message_read(reply_tty, "s", &tty); + if (r < 0) diff --git a/SOURCES/0943-loginctl-use-bus_map_all_properties.patch b/SOURCES/0943-loginctl-use-bus_map_all_properties.patch new file mode 100644 index 0000000..3786b5c --- /dev/null +++ b/SOURCES/0943-loginctl-use-bus_map_all_properties.patch @@ -0,0 +1,137 @@ +From 5d2f49451c5e697d6e3548cfc9087ef3c16aa969 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 13:33:58 +0200 +Subject: [PATCH] loginctl: use bus_map_all_properties + +(cherry picked from commit 5b7d1536d0c2ccf0b7688490f31c92c1e766ea44) + +Related: #2156786 +--- + src/login/loginctl.c | 78 ++++++++++++++++++++++---------------------- + 1 file changed, 39 insertions(+), 39 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 079c0e2b17..9e4c710062 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -47,6 +47,27 @@ static bool arg_ask_password = true; + static unsigned arg_lines = 10; + static OutputMode arg_output = OUTPUT_SHORT; + ++typedef struct SessionStatusInfo { ++ const char *id; ++ uid_t uid; ++ const char *name; ++ struct dual_timestamp timestamp; ++ unsigned int vtnr; ++ const char *seat; ++ const char *tty; ++ const char *display; ++ bool remote; ++ const char *remote_host; ++ const char *remote_user; ++ const char *service; ++ pid_t leader; ++ const char *type; ++ const char *class; ++ const char *state; ++ const char *scope; ++ const char *desktop; ++} SessionStatusInfo; ++ + static OutputFlags get_output_flags(void) { + + return +@@ -112,6 +133,12 @@ static int show_table(Table *table, const char *word) { + } + + static int list_sessions(int argc, char *argv[], void *userdata) { ++ ++ static const struct bus_properties_map map[] = { ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ {}, ++ }; ++ + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(table_unrefp) Table *table = NULL; +@@ -148,9 +175,10 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + for (;;) { + _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; +- const char *id, *user, *seat, *object, *tty = NULL; ++ const char *id, *user, *seat, *object; + uint32_t uid; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; ++ SessionStatusInfo i = {}; + + r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object); + if (r < 0) +@@ -158,21 +186,14 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r == 0) + break; + +- r = sd_bus_get_property( +- bus, +- "org.freedesktop.login1", +- object, +- "org.freedesktop.login1.Session", +- "TTY", +- &e, +- &reply_tty, +- "s"); +- if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); +- else { +- r = sd_bus_message_read(reply_tty, "s", &tty); +- if (r < 0) +- return bus_log_parse_error(r); ++ r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); ++ if (r < 0) { ++ if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) ++ /* The session is already closed when we're querying the property */ ++ continue; ++ ++ log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); + } + + r = table_add_many(table, +@@ -180,7 +201,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(tty)); ++ TABLE_STRING, strna(i.tty)); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } +@@ -341,27 +362,6 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit + return 0; + } + +-typedef struct SessionStatusInfo { +- const char *id; +- uid_t uid; +- const char *name; +- struct dual_timestamp timestamp; +- unsigned int vtnr; +- const char *seat; +- const char *tty; +- const char *display; +- bool remote; +- const char *remote_host; +- const char *remote_user; +- const char *service; +- pid_t leader; +- const char *type; +- const char *class; +- const char *state; +- const char *scope; +- const char *desktop; +-} SessionStatusInfo; +- + typedef struct UserStatusInfo { + uid_t uid; + bool linger; diff --git a/SOURCES/0944-loginctl-show-session-idle-status-in-list-sessions.patch b/SOURCES/0944-loginctl-show-session-idle-status-in-list-sessions.patch new file mode 100644 index 0000000..1edd5e2 --- /dev/null +++ b/SOURCES/0944-loginctl-show-session-idle-status-in-list-sessions.patch @@ -0,0 +1,80 @@ +From 0d1082f3cf9d4028ac69c22e9dad2adb51ee910d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 14:03:09 +0200 +Subject: [PATCH] loginctl: show session idle status in list-sessions + +(cherry picked from commit 556723e738b96a5c2b2d45a96b87b7b80e0c5664) + +Resolves: #2156786 +--- + src/login/loginctl.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9e4c710062..65fe182195 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -66,6 +66,8 @@ typedef struct SessionStatusInfo { + const char *state; + const char *scope; + const char *desktop; ++ bool idle_hint; ++ dual_timestamp idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -135,7 +137,9 @@ static int show_table(Table *table, const char *word) { + static int list_sessions(int argc, char *argv[], void *userdata) { + + static const struct bus_properties_map map[] = { +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -165,7 +169,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r < 0) + return bus_log_parse_error(r); + +- table = table_new("SESSION", "UID", "USER", "SEAT", "TTY"); ++ table = table_new("SESSION", "UID", "USER", "SEAT", "TTY", "IDLE", "SINCE"); + if (!table) + return log_oom(); + +@@ -188,12 +192,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); + if (r < 0) { +- if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) +- /* The session is already closed when we're querying the property */ +- continue; +- +- log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", +- id, bus_error_message(&e, r)); ++ log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING, ++ r, ++ "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); ++ continue; + } + + r = table_add_many(table, +@@ -201,7 +204,15 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(i.tty)); ++ TABLE_STRING, strna(i.tty), ++ TABLE_BOOLEAN, i.idle_hint); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add row to table: %m"); ++ ++ if (i.idle_hint) ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ else ++ r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } diff --git a/SOURCES/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch b/SOURCES/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch new file mode 100644 index 0000000..93a96b5 --- /dev/null +++ b/SOURCES/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch @@ -0,0 +1,53 @@ +From ea3d85221a7ba83ff1d9612d29cc8ca3e054f2fa Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 25 May 2023 01:20:45 +0800 +Subject: [PATCH] loginctl: list-sessions: fix timestamp for idle hint + +Follow-up for 556723e738b96a5c2b2d45a96b87b7b80e0c5664 + +TABLE_TIMESTAMP_RELATIVE takes a realtime timestamp. + +(cherry picked from commit be88af3d9646c8bd1aaea3d4a00520e97ee8674d) + +Related: #2156786 +--- + src/login/loginctl.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 65fe182195..1131267015 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -67,7 +67,7 @@ typedef struct SessionStatusInfo { + const char *scope; + const char *desktop; + bool idle_hint; +- dual_timestamp idle_hint_timestamp; ++ usec_t idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -136,10 +136,10 @@ static int show_table(Table *table, const char *word) { + + static int list_sessions(int argc, char *argv[], void *userdata) { + +- static const struct bus_properties_map map[] = { +- { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, +- { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ static const struct bus_properties_map map[] = { ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -210,7 +210,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + return log_error_errno(r, "Failed to add row to table: %m"); + + if (i.idle_hint) +- r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp); + else + r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) diff --git a/SOURCES/0946-loginctl-also-show-idle-hint-in-session-status.patch b/SOURCES/0946-loginctl-also-show-idle-hint-in-session-status.patch new file mode 100644 index 0000000..f69b6fa --- /dev/null +++ b/SOURCES/0946-loginctl-also-show-idle-hint-in-session-status.patch @@ -0,0 +1,40 @@ +From 0d3f481f791d918380a1b5587529cb8642d3e407 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Tue, 23 May 2023 18:54:30 +0800 +Subject: [PATCH] loginctl: also show idle hint in session-status + +(cherry picked from commit 82449055af97cf92466dbe132a89c9d889440c3d) + +Related: #2156786 +--- + src/login/loginctl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 1131267015..80d0a302d3 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -473,6 +473,8 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) }, + { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) }, + { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, + { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) }, + { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) }, + {} +@@ -571,6 +573,14 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + if (i.state) + printf("\t State: %s\n", i.state); + ++ if (i.idle_hint && i.idle_hint_timestamp > 0) { ++ s1 = format_timestamp_relative(since1, sizeof(since1), i.idle_hint_timestamp); ++ s2 = format_timestamp(since2, sizeof(since2), i.idle_hint_timestamp); ++ ++ printf("\t Idle: %s since %s (%s)\n", yes_no(i.idle_hint), s2, s1); ++ } else ++ printf("\t Idle: %s\n", yes_no(i.idle_hint)); ++ + if (i.scope) { + printf("\t Unit: %s\n", i.scope); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader); diff --git a/SOURCES/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch b/SOURCES/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch new file mode 100644 index 0000000..cc9bb1a --- /dev/null +++ b/SOURCES/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch @@ -0,0 +1,46 @@ +From a741d3b8bc23b4be1b83e393ca864983558a730c Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 23 May 2023 16:24:47 +0200 +Subject: [PATCH] core/timer: Always use inactive_exit_timestamp if it is set + +If we're doing a daemon-reload, we'll be going from TIMER_DEAD => TIMER_WAITING, +so we won't use inactive_exit_timestamp because TIMER_DEAD != UNIT_ACTIVE, even +though inactive_exit_timestamp is serialized/deserialized and will be valid after +the daemon-reload. + +This issue can lead to timers never firing as we'll always calculate the next +elapse based on the current realtime on daemon-reload, so if daemon-reload happens +often enough, the elapse interval will be moved into the future every time, which +means the timer will never trigger. + +To fix the issue, let's always use inactive_exit_timestamp if it is set, and only +fall back to the current realtime if it is not set. + +(cherry picked from commit 6546045fa0bf84737bd8b2e1e8bf7dd3941d8352) + +Resolves: #1719364 +--- + src/core/timer.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 990f05fee4..b80f6d714c 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -368,12 +368,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + + if (t->last_trigger.realtime > 0) + b = t->last_trigger.realtime; +- else { +- if (state_translation_table[t->state] == UNIT_ACTIVE) +- b = UNIT(t)->inactive_exit_timestamp.realtime; +- else +- b = ts.realtime; +- } ++ else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) ++ b = UNIT(t)->inactive_exit_timestamp.realtime; ++ else ++ b = ts.realtime; + + r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse); + if (r < 0) diff --git a/SOURCES/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch b/SOURCES/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch new file mode 100644 index 0000000..e7518ab --- /dev/null +++ b/SOURCES/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch @@ -0,0 +1,25 @@ +From e7c06a10a106068e5bd9f092edbfcc937954a959 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 24 May 2023 11:41:37 +0200 +Subject: [PATCH] timer: Use dual_timestamp_is_set() in one more place + +(cherry picked from commit e21f75afcd95a46261a36a2614712eff6bc119f4) + +Related: #1719364 +--- + src/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index b80f6d714c..81468d4ca6 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -366,7 +366,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + * to that. If we don't, just start from + * the activation time. */ + +- if (t->last_trigger.realtime > 0) ++ if (dual_timestamp_is_set(&t->last_trigger)) + b = t->last_trigger.realtime; + else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) + b = UNIT(t)->inactive_exit_timestamp.realtime; diff --git a/SOURCES/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch b/SOURCES/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch new file mode 100644 index 0000000..0900c1b --- /dev/null +++ b/SOURCES/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch @@ -0,0 +1,28 @@ +From d55687b7489127b4b6be953c54719f3219e852f6 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 13 Jul 2023 14:23:51 +0200 +Subject: [PATCH] ci: drop systemd-stable from advanced-commit-linter config + +It's sufficient enough to check only the `systemd/systemd` repo. + +Related to https://github.com/redhat-plumbers-in-action/advanced-commit-linter/issues/62 + +rhel-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 327af0467a..0fb74a9dc8 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -2,7 +2,6 @@ policy: + cherry-pick: + upstream: + - github: systemd/systemd +- - github: systemd/systemd-stable + exception: + note: + - rhel-only diff --git a/SOURCES/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch b/SOURCES/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch new file mode 100644 index 0000000..c7d466c --- /dev/null +++ b/SOURCES/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch @@ -0,0 +1,108 @@ +From 048c335acdaaba173574305c9b03677b3fde999f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 11 May 2023 19:21:57 +0900 +Subject: [PATCH] core/mount: escape invalid UTF8 char in dbus reply + +When What= or Options= may contain invalid UTF8 chars. + +Replaces aaf7b0e41105d7b7cf30912cdac32820f011a219 (#27541). + +(cherry picked from commit 4804da58536ab7ad46178a03f4d2da49fd8e4ba2) + +Resolves: #2158724 +--- + src/core/dbus-mount.c | 69 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c +index 3f98d3ecf0..a089b37e04 100644 +--- a/src/core/dbus-mount.c ++++ b/src/core/dbus-mount.c +@@ -9,21 +9,68 @@ + #include "mount.h" + #include "string-util.h" + #include "unit.h" ++#include "utf8.h" ++ ++static int property_get_what( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); + +-static const char *mount_get_what(const Mount *m) { + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what) +- return m->parameters_proc_self_mountinfo.what; +- if (m->from_fragment && m->parameters_fragment.what) +- return m->parameters_fragment.what; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.what; ++ else if (m->from_fragment && m->parameters_fragment.what) ++ s = m->parameters_fragment.what; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + +-static const char *mount_get_options(const Mount *m) { ++static int property_get_options( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); ++ + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options) +- return m->parameters_proc_self_mountinfo.options; +- if (m->from_fragment && m->parameters_fragment.options) +- return m->parameters_fragment.options; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.options; ++ else if (m->from_fragment && m->parameters_fragment.options) ++ s = m->parameters_fragment.options; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + + static const char *mount_get_fstype(const Mount *m) { +@@ -34,8 +81,6 @@ static const char *mount_get_fstype(const Mount *m) { + return NULL; + } + +-static BUS_DEFINE_PROPERTY_GET(property_get_what, "s", Mount, mount_get_what); +-static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Mount, mount_get_options); + static BUS_DEFINE_PROPERTY_GET(property_get_type, "s", Mount, mount_get_fstype); + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult); + diff --git a/SOURCES/0951-login-add-a-missing-error-check-for-session_set_lead.patch b/SOURCES/0951-login-add-a-missing-error-check-for-session_set_lead.patch new file mode 100644 index 0000000..3004e81 --- /dev/null +++ b/SOURCES/0951-login-add-a-missing-error-check-for-session_set_lead.patch @@ -0,0 +1,32 @@ +From fd6e63d9c24845c0e9f97d0929d89dbe0c4a4434 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 14 Feb 2019 10:59:13 +0900 +Subject: [PATCH] login: add a missing error check for session_set_leader() + +session_set_leader() may fail. If it fails, then manager_start_scope() +will trigger assertion. + +This may be related to RHBZ#1663704. + +(cherry picked from commit fe3ab8458b9c0ead4b3e14ac25b342d8c34376fe) + +Related: #2158167 +--- + src/login/logind-dbus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 81aacb4eed..5edcf4e43f 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -784,7 +784,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + goto fail; + + session_set_user(session, user); +- session_set_leader(session, leader); ++ r = session_set_leader(session, leader); ++ if (r < 0) ++ goto fail; + + session->type = t; + session->class = c; diff --git a/SOURCES/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch b/SOURCES/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch new file mode 100644 index 0000000..fe3fdb9 --- /dev/null +++ b/SOURCES/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch @@ -0,0 +1,77 @@ +From ab53c4f5c39ab8d34a3cca652de67fe31dbb776d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 5 Jul 2023 15:27:38 +0200 +Subject: [PATCH] logind: reset session leader if we know for a fact that it is + gone + +rhel-only + +Related: #2158167 +--- + src/login/logind-dbus.c | 3 +++ + src/login/logind-session.c | 18 ++++++++++++++++++ + src/login/logind-session.h | 1 + + 3 files changed, 22 insertions(+) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 5edcf4e43f..dbac406035 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -3169,6 +3169,9 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err + session->scope_job = mfree(session->scope_job); + (void) session_jobs_reply(session, unit, result); + ++ /* Scope job is done so leader should be gone as well. */ ++ session_invalidate_leader(session); ++ + session_save(session); + user_save(session->user); + } +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index fabf680b61..4edc4b9b88 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -179,6 +179,23 @@ int session_set_leader(Session *s, pid_t pid) { + return 1; + } + ++int session_invalidate_leader(Session *s) { ++ assert(s); ++ ++ if (s->leader <= 0) ++ return 0; ++ ++ if (pid_is_alive(s->leader)) ++ return 0; ++ ++ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); ++ s->leader = 0; ++ ++ (void) session_save(s); ++ ++ return 1; ++} ++ + static void session_save_devices(Session *s, FILE *f) { + SessionDevice *sd; + Iterator i; +@@ -1092,6 +1109,7 @@ static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, + /* EOF on the FIFO means the session died abnormally. */ + + session_remove_fifo(s); ++ session_invalidate_leader(s); + session_stop(s, false); + + return 1; +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 6678441bb9..0557696761 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -127,6 +127,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free); + + void session_set_user(Session *s, User *u); + int session_set_leader(Session *s, pid_t pid); ++int session_invalidate_leader(Session *s); + bool session_may_gc(Session *s, bool drop_not_started); + void session_add_to_gc_queue(Session *s); + int session_activate(Session *s); diff --git a/SOURCES/0953-test-login-skip-consistency-checks-when-logind-is-no.patch b/SOURCES/0953-test-login-skip-consistency-checks-when-logind-is-no.patch new file mode 100644 index 0000000..b7c0b43 --- /dev/null +++ b/SOURCES/0953-test-login-skip-consistency-checks-when-logind-is-no.patch @@ -0,0 +1,170 @@ +From f80320d15ba6815f0b385e4b8f86f3293fed66ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 16 Dec 2020 15:56:44 +0100 +Subject: [PATCH] test-login: skip consistency checks when logind is not active +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are two ways in swich sd_login_* functions acquire data: +some are derived from the cgroup path, but others use the data serialized +by logind. + +When the tests are executed under Fedora's mock, without systemd-spawn +but instead in a traditional chroot, test-login gets confused: +the "outside" cgroup path is visible, so sd_pid_get_unit() and +sd_pid_get_session() work, but sd_session_is_active() and other functions +that need logind data fail. + +Such a buildroot setup is fairly bad, but it can be encountered in the wild, so +let's just skip the tests in that case. + +/* Information printed is from the live system */ +sd_pid_get_unit(0, …) → "session-237.scope" +sd_pid_get_user_unit(0, …) → "n/a" +sd_pid_get_slice(0, …) → "user-1000.slice" +sd_pid_get_session(0, …) → "237" +sd_pid_get_owner_uid(0, …) → 1000 +sd_pid_get_cgroup(0, …) → "/user.slice/user-1000.slice/session-237.scope" +sd_uid_get_display(1000, …) → "(null)" +sd_uid_get_sessions(1000, …) → [0] "" +sd_uid_get_seats(1000, …) → [0] "" +Assertion 'r >= 0' failed at src/libsystemd/sd-login/test-login.c:104, function test_login(). Aborting. + +(cherry picked from commit ac5644635dba54ce5eb0ff394fc0bc772a984849) + +Resolves: #2223582 +--- + src/libsystemd/sd-login/test-login.c | 98 +++++++++++++++------------- + 1 file changed, 52 insertions(+), 46 deletions(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index d24a04ccc8..5a64aef868 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -115,65 +115,71 @@ static void test_login(void) { + + if (session) { + r = sd_session_is_active(session); +- assert_se(r >= 0); +- log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); ++ if (r == -ENXIO) ++ log_notice("sd_session_is_active() failed with ENXIO, it seems logind is not running."); ++ else { ++ /* All those tests will fail with ENXIO, so let's skip them. */ + +- r = sd_session_is_remote(session); +- assert_se(r >= 0); +- log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); ++ assert_se(r >= 0); ++ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); + +- r = sd_session_get_state(session, &state); +- assert_se(r == 0); +- log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); ++ r = sd_session_is_remote(session); ++ assert_se(r >= 0); ++ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); + +- assert_se(sd_session_get_uid(session, &u) >= 0); +- log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); +- assert_se(u == u2); ++ r = sd_session_get_state(session, &state); ++ assert_se(r == 0); ++ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); + +- assert_se(sd_session_get_type(session, &type) >= 0); +- log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); ++ assert_se(sd_session_get_uid(session, &u) >= 0); ++ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); ++ assert_se(u == u2); + +- assert_se(sd_session_get_class(session, &class) >= 0); +- log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); ++ assert_se(sd_session_get_type(session, &type) >= 0); ++ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); + +- r = sd_session_get_display(session, &display); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); ++ assert_se(sd_session_get_class(session, &class) >= 0); ++ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); + +- r = sd_session_get_remote_user(session, &remote_user); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", +- session, strna(remote_user)); ++ r = sd_session_get_display(session, &display); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); + +- r = sd_session_get_remote_host(session, &remote_host); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", +- session, strna(remote_host)); ++ r = sd_session_get_remote_user(session, &remote_user); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", ++ session, strna(remote_user)); + +- r = sd_session_get_seat(session, &seat); +- if (r >= 0) { +- assert_se(seat); ++ r = sd_session_get_remote_host(session, &remote_host); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", ++ session, strna(remote_host)); + +- log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); ++ r = sd_session_get_seat(session, &seat); ++ if (r >= 0) { ++ assert_se(seat); + +- r = sd_seat_can_multi_session(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); ++ log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); + +- r = sd_seat_can_tty(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); ++ r = sd_seat_can_multi_session(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); + +- r = sd_seat_can_graphical(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); +- } else { +- log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); +- assert_se(r == -ENODATA); +- } ++ r = sd_seat_can_tty(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); + +- assert_se(sd_uid_get_state(u, &state2) == 0); +- log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ r = sd_seat_can_graphical(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); ++ } else { ++ log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); ++ assert_se(r == -ENODATA); ++ } ++ ++ assert_se(sd_uid_get_state(u, &state2) == 0); ++ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ } + } + + if (seat) { +@@ -214,7 +220,7 @@ static void test_login(void) { + assert_se(sd_get_seats(NULL) == r); + + r = sd_seat_get_active(NULL, &t, NULL); +- assert_se(IN_SET(r, 0, -ENODATA)); ++ assert_se(IN_SET(r, 0, -ENODATA, -ENXIO)); + log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t)); + free(t); + diff --git a/SOURCES/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch b/SOURCES/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch new file mode 100644 index 0000000..aabdbcd --- /dev/null +++ b/SOURCES/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch @@ -0,0 +1,91 @@ +From 7bbad13204b3c0870caa80e738d5d5ca39e956c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 25 Sep 2018 11:10:12 +0200 +Subject: [PATCH] sd-event: remove dead code and use _cleanup_ + +CID #1393250. + +(cherry picked from commit 8c75fe1765341b538ddded29be6f98e1619f1996) + +Related: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 30 +++++++++--------------------- + 1 file changed, 9 insertions(+), 21 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 549103bc6f..5e22190366 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1129,6 +1129,7 @@ static void source_free(sd_event_source *s) { + free(s->description); + free(s); + } ++DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free); + + static int source_set_pending(sd_event_source *s, bool b) { + int r; +@@ -1993,11 +1994,10 @@ _public_ int sd_event_add_inotify( + sd_event_inotify_handler_t callback, + void *userdata) { + +- bool rm_inotify = false, rm_inode = false; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; + _cleanup_close_ int fd = -1; +- sd_event_source *s; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + +@@ -2035,13 +2035,13 @@ _public_ int sd_event_add_inotify( + /* Allocate an inotify object for this priority, and an inode object within it */ + r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data); + if (r < 0) +- goto fail; +- rm_inotify = r > 0; ++ return r; + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); +- if (r < 0) +- goto fail; +- rm_inode = r > 0; ++ if (r < 0) { ++ event_free_inotify_data(e, inotify_data); ++ return r; ++ } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ +@@ -2054,30 +2054,18 @@ _public_ int sd_event_add_inotify( + LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s); + s->inotify.inode_data = inode_data; + +- rm_inode = rm_inotify = false; +- + /* Actually realize the watch now */ + r = inode_data_realize_watch(e, inode_data); + if (r < 0) +- goto fail; ++ return r; + + (void) sd_event_source_set_description(s, path); + + if (ret) + *ret = s; ++ TAKE_PTR(s); + + return 0; +- +-fail: +- source_free(s); +- +- if (rm_inode) +- event_free_inode_data(e, inode_data); +- +- if (rm_inotify) +- event_free_inotify_data(e, inotify_data); +- +- return r; + } + + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { diff --git a/SOURCES/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch b/SOURCES/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch new file mode 100644 index 0000000..6fb60e2 --- /dev/null +++ b/SOURCES/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch @@ -0,0 +1,100 @@ +From 4436c767d45c6568cbdb7aa73e5efba6d0f31f1f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:11:38 +0100 +Subject: [PATCH] sd-event: don't destroy inotify data structures from inotify + event handler + +This fixes a bad memory access when we destroy an inotify source handler +from the handler itself, and thus destroy the associated inotify_data +structures. + +Fixes: #20177 +(cherry picked from commit 53baf2efa420cab6c4b1904c9a0c46a0c4ec80a1) + +Resolves: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 45 +++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 5e22190366..01a97a4801 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -263,6 +263,11 @@ struct inotify_data { + * the events locally if they can't be coalesced). */ + unsigned n_pending; + ++ /* If this counter is non-zero, don't GC the inotify data object even if not used to watch any inode ++ * anymore. This is useful to pin the object for a bit longer, after the last event source needing it ++ * is gone. */ ++ unsigned n_busy; ++ + /* A linked list of all inotify objects with data already read, that still need processing. We keep this list + * to make it efficient to figure out what inotify objects to process data on next. */ + LIST_FIELDS(struct inotify_data, buffered); +@@ -1845,6 +1850,29 @@ static void event_free_inode_data( + free(d); + } + ++static void event_gc_inotify_data( ++ sd_event *e, ++ struct inotify_data *d) { ++ ++ assert(e); ++ ++ /* GCs the inotify data object if we don't need it anymore. That's the case if we don't want to watch ++ * any inode with it anymore, which in turn happens if no event source of this priority is interested ++ * in any inode any longer. That said, we maintain an extra busy counter: if non-zero we'll delay GC ++ * (under the expectation that the GC is called again once the counter is decremented). */ ++ ++ if (!d) ++ return; ++ ++ if (!hashmap_isempty(d->inodes)) ++ return; ++ ++ if (d->n_busy > 0) ++ return; ++ ++ event_free_inotify_data(e, d); ++} ++ + static void event_gc_inode_data( + sd_event *e, + struct inode_data *d) { +@@ -1862,8 +1890,7 @@ static void event_gc_inode_data( + inotify_data = d->inotify_data; + event_free_inode_data(e, d); + +- if (inotify_data && hashmap_isempty(inotify_data->inodes)) +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + } + + static int event_make_inode_data( +@@ -3447,13 +3474,23 @@ static int source_dispatch(sd_event_source *s) { + sz = offsetof(struct inotify_event, name) + d->buffer.ev.len; + assert(d->buffer_filled >= sz); + ++ /* If the inotify callback destroys the event source then this likely means we don't need to ++ * watch the inode anymore, and thus also won't need the inotify object anymore. But if we'd ++ * free it immediately, then we couldn't drop the event from the inotify event queue without ++ * memory corruption anymore, as below. Hence, let's not free it immediately, but mark it ++ * "busy" with a counter (which will ensure it's not GC'ed away prematurely). Let's then ++ * explicitly GC it after we are done dropping the inotify event from the buffer. */ ++ d->n_busy++; + r = s->inotify.callback(s, &d->buffer.ev, s->userdata); ++ d->n_busy--; + +- /* When no event is pending anymore on this inotify object, then let's drop the event from the +- * buffer. */ ++ /* When no event is pending anymore on this inotify object, then let's drop the event from ++ * the inotify event queue buffer. */ + if (d->n_pending == 0) + event_inotify_data_drop(e, d, sz); + ++ /* Now we don't want to access 'd' anymore, it's OK to GC now. */ ++ event_gc_inotify_data(e, d); + break; + } + diff --git a/SOURCES/0956-sd-event-add-sd_event_add_inotify_fd-call.patch b/SOURCES/0956-sd-event-add-sd_event_add_inotify_fd-call.patch new file mode 100644 index 0000000..726c029 --- /dev/null +++ b/SOURCES/0956-sd-event-add-sd_event_add_inotify_fd-call.patch @@ -0,0 +1,232 @@ +From a78186fbbc05637ef9678b20c630597f2e5d6270 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:10:58 +0100 +Subject: [PATCH] sd-event: add sd_event_add_inotify_fd() call + +sd_event_add_inotify_fd() is like sd_event_add_inotify(), but takes an +fd to an inode instead of a path, and is hence a ton nicer. + +(cherry picked from commit e67d738a8771c220a2e1ee81d5499a90589dd15d) + +Related: #2211358 +--- + man/rules/meson.build | 4 +- + man/sd_event_add_inotify.xml | 16 +++++++ + src/libsystemd/libsystemd.sym | 1 + + src/libsystemd/sd-event/sd-event.c | 76 +++++++++++++++++++++++------- + src/systemd/sd-event.h | 1 + + 5 files changed, 81 insertions(+), 17 deletions(-) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 05eb0a1604..431a1cf269 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -272,7 +272,9 @@ manpages = [ + ''], + ['sd_event_add_inotify', + '3', +- ['sd_event_inotify_handler_t', 'sd_event_source_get_inotify_mask'], ++ ['sd_event_add_inotify_fd', ++ 'sd_event_inotify_handler_t', ++ 'sd_event_source_get_inotify_mask'], + ''], + ['sd_event_add_io', + '3', +diff --git a/man/sd_event_add_inotify.xml b/man/sd_event_add_inotify.xml +index 605863c356..17415bbc17 100644 +--- a/man/sd_event_add_inotify.xml ++++ b/man/sd_event_add_inotify.xml +@@ -18,6 +18,7 @@ + + + sd_event_add_inotify ++ sd_event_add_inotify_fd + sd_event_source_get_inotify_mask + sd_event_inotify_handler_t + +@@ -47,6 +48,16 @@ + void *userdata + + ++ ++ int sd_event_add_inotify_fd ++ sd_event *event ++ sd_event_source **source ++ int fd ++ uint32_t mask ++ sd_event_inotify_handler_t handler ++ void *userdata ++ ++ + + int sd_event_source_get_inotify_mask + sd_event_source *source +@@ -72,6 +83,11 @@ + inotify7 for + further information. + ++ sd_event_add_inotify_fd() is identical to ++ sd_event_add_inotify(), except that it takes a file descriptor to an inode (possibly ++ an O_PATH one, but any other will do too) instead of a path in the file ++ system. ++ + If multiple event sources are installed for the same inode the backing inotify watch descriptor is + automatically shared. The mask parameter may contain any flag defined by the inotify API, with the exception of + IN_MASK_ADD. +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 449918093c..dc37472b18 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -593,5 +593,6 @@ global: + + LIBSYSTEMD_250 { + global: ++ sd_event_add_inotify_fd; + sd_event_source_set_ratelimit_expire_callback; + } LIBSYSTEMD_248; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 01a97a4801..9247087c41 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2013,25 +2013,25 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { + return 1; + } + +-_public_ int sd_event_add_inotify( ++static int event_add_inotify_fd_internal( + sd_event *e, + sd_event_source **ret, +- const char *path, ++ int fd, ++ bool donate, + uint32_t mask, + sd_event_inotify_handler_t callback, + void *userdata) { + ++ _cleanup_close_ int donated_fd = donate ? fd : -1; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; +- _cleanup_close_ int fd = -1; +- _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + + assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); +- assert_return(path, -EINVAL); +- assert_return(callback, -EINVAL); ++ assert_return(fd >= 0, -EBADF); + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(!event_pid_changed(e), -ECHILD); + +@@ -2041,12 +2041,6 @@ _public_ int sd_event_add_inotify( + if (mask & IN_MASK_ADD) + return -EINVAL; + +- fd = open(path, O_PATH|O_CLOEXEC| +- (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| +- (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); +- if (fd < 0) +- return -errno; +- + if (fstat(fd, &st) < 0) + return -errno; + +@@ -2066,14 +2060,24 @@ _public_ int sd_event_add_inotify( + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); + if (r < 0) { +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + return r; + } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ + if (inode_data->fd < 0) { +- inode_data->fd = TAKE_FD(fd); ++ if (donated_fd >= 0) ++ inode_data->fd = TAKE_FD(donated_fd); ++ else { ++ inode_data->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); ++ if (inode_data->fd < 0) { ++ r = -errno; ++ event_gc_inode_data(e, inode_data); ++ return r; ++ } ++ } ++ + LIST_PREPEND(to_close, e->inode_data_to_close, inode_data); + } + +@@ -2086,8 +2090,6 @@ _public_ int sd_event_add_inotify( + if (r < 0) + return r; + +- (void) sd_event_source_set_description(s, path); +- + if (ret) + *ret = s; + TAKE_PTR(s); +@@ -2095,6 +2097,48 @@ _public_ int sd_event_add_inotify( + return 0; + } + ++_public_ int sd_event_add_inotify_fd( ++ sd_event *e, ++ sd_event_source **ret, ++ int fd, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ return event_add_inotify_fd_internal(e, ret, fd, /* donate= */ false, mask, callback, userdata); ++} ++ ++_public_ int sd_event_add_inotify( ++ sd_event *e, ++ sd_event_source **ret, ++ const char *path, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ sd_event_source *s; ++ int fd, r; ++ ++ assert_return(path, -EINVAL); ++ ++ fd = open(path, O_PATH|O_CLOEXEC| ++ (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| ++ (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); ++ if (fd < 0) ++ return -errno; ++ ++ r = event_add_inotify_fd_internal(e, &s, fd, /* donate= */ true, mask, callback, userdata); ++ if (r < 0) ++ return r; ++ ++ (void) sd_event_source_set_description(s, path); ++ ++ if (ret) ++ *ret = s; ++ ++ return r; ++} ++ + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { + + if (!s) +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index 960bea1ac4..48b053c127 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -91,6 +91,7 @@ int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock + int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); + int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); + int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); ++int sd_event_add_inotify_fd(sd_event *e, sd_event_source **s, int fd, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); + int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); diff --git a/SOURCES/0957-test-add-test-case-for-self-destroy-inotify-handler.patch b/SOURCES/0957-test-add-test-case-for-self-destroy-inotify-handler.patch new file mode 100644 index 0000000..c2e2cb3 --- /dev/null +++ b/SOURCES/0957-test-add-test-case-for-self-destroy-inotify-handler.patch @@ -0,0 +1,65 @@ +From 2fcb71007e5137e1be4a16fb24783ff329313ebf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:15:43 +0100 +Subject: [PATCH] test: add test case for self-destroy inotify handler + +(cherry picked from commit 035daf73fbfa05e5abf049bd9385fc0994ab5672) + +Related: #2211358 +--- + src/libsystemd/sd-event/test-event.c | 36 ++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index 9135b22839..df3de1bfb0 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -588,6 +588,40 @@ static void test_ratelimit(void) { + assert_se(expired == 0); + } + ++static int inotify_self_destroy_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) { ++ sd_event_source **p = userdata; ++ ++ assert_se(ev); ++ assert_se(p); ++ assert_se(*p == s); ++ ++ assert_se(FLAGS_SET(ev->mask, IN_ATTRIB)); ++ ++ assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0); ++ ++ *p = sd_event_source_unref(*p); /* here's what we actually intend to test: we destroy the event ++ * source from inside the event source handler */ ++ return 1; ++} ++ ++static void test_inotify_self_destroy(void) { ++ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; ++ _cleanup_(sd_event_unrefp) sd_event *e = NULL; ++ char path[] = "/tmp/inotifyXXXXXX"; ++ _cleanup_close_ int fd = -1; ++ ++ /* Tests that destroying an inotify event source from its own handler is safe */ ++ ++ assert_se(sd_event_default(&e) >= 0); ++ ++ fd = mkostemp_safe(path); ++ assert_se(fd >= 0); ++ assert_se(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s) >= 0); ++ fd = safe_close(fd); ++ assert_se(unlink(path) >= 0); /* This will trigger IN_ATTRIB because link count goes to zero */ ++ assert_se(sd_event_loop(e) >= 0); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -602,5 +636,7 @@ int main(int argc, char *argv[]) { + + test_ratelimit(); + ++ test_inotify_self_destroy(); ++ + return 0; + } diff --git a/SOURCES/0958-doc-add-downstream-CONTRIBUTING-document.patch b/SOURCES/0958-doc-add-downstream-CONTRIBUTING-document.patch new file mode 100644 index 0000000..c221180 --- /dev/null +++ b/SOURCES/0958-doc-add-downstream-CONTRIBUTING-document.patch @@ -0,0 +1,86 @@ +From 322ef6cb5fe3c293c6b9a37fe2e58491e9a5100b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 4 Aug 2023 13:09:46 +0200 +Subject: [PATCH] doc: add downstream CONTRIBUTING document + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) + create mode 100644 CONTRIBUTING.md + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +new file mode 100644 +index 0000000000..361366d899 +--- /dev/null ++++ b/CONTRIBUTING.md +@@ -0,0 +1,67 @@ ++# Contributing ++ ++Welcome to systemd source-git for CentOS Stream and RHEL. When contributing, please follow the guide below. ++ ++## Workflow ++ ++```mermaid ++flowchart LR ++ A(Issue) --> B{is fixed\nupstream} ++ B -->|YES| C(backport\nupstream patch) ++ B -->|NO| D(upstream\nsubmit issue or PR) ++ D --> E{accepted\nand fixed} ++ E -->|YES| C ++ E -->|NO| F(rhel-only patch) --> G ++ C --> G(submit PR) ++``` ++ ++## Filing issues ++ ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++ ++GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). ++ ++## Posting Pull Requests ++ ++Every Pull Request has to comply with the following rules: ++ ++- Each commit has to reference [upstream](https://github.com/systemd/systemd) commit. ++- Each commit has to reference the approved issue/tracker. ++- Pull requests have to pass mandatory CI validation and testing ++- Pull requests have to be approved by at least one systemd downstream maintainer ++ ++### Upstream reference ++ ++When doing a back-port of an upstream commit, always use `cherry-pick -x `. Consider proposing a change upstream first when an upstream commit doesn't exist. ++If the change isn't upstream relevant or accepted by upstream, mark the commit with the `rhel-only` string. ++ ++```md ++doc: Fix TYPO ++ ++rhel-only ++ ++Resolves: RHEL-678 ++``` ++ ++### Issue reference ++ ++Each commit has to reference the relevant approved systemd issue (see: [Filling issues section](#filing-issues)). For referencing issues, we use the following keywords: ++ ++- **Resolves** for commits that directly resolve issues described in a referenced tracker ++- **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. ++- **Reverts** for commits that reverts previously merged commit ++ ++When referencing issues, use following structure: `: `. See the example below: ++ ++```md ++doc: Fix TYPO ++ ++(cherry picked from commit c5afbac31bb33e7b1f4d59b253425af991a630a4) ++ ++Resolves: RHEL-678 ++``` ++ ++### Validation and testing ++ ++Each Pull Request has to pass all enabled tests that are automatically run using GitHub Actions, CentOS Stream CI, and others. ++If CI failure is unrelated to the change introduced in Pull Request, the downstream maintainer will set the `ci-waived` label and explain why CI was waived. diff --git a/SOURCES/0959-doc-use-link-with-prefilled-Jira-issue.patch b/SOURCES/0959-doc-use-link-with-prefilled-Jira-issue.patch new file mode 100644 index 0000000..d93e59e --- /dev/null +++ b/SOURCES/0959-doc-use-link-with-prefilled-Jira-issue.patch @@ -0,0 +1,25 @@ +From b50b19af7889a2d44e904fcb327b09130c9c96e7 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 8 Aug 2023 13:12:03 +0200 +Subject: [PATCH] doc: use link with prefilled Jira issue + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 361366d899..1de2b88995 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + diff --git a/SOURCES/0960-docs-link-downstream-CONTRIBUTING-in-README.patch b/SOURCES/0960-docs-link-downstream-CONTRIBUTING-in-README.patch new file mode 100644 index 0000000..0d5de6b --- /dev/null +++ b/SOURCES/0960-docs-link-downstream-CONTRIBUTING-in-README.patch @@ -0,0 +1,52 @@ +From 380f7af4fb00d692132b38999813fd9023e14c81 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 10 Aug 2023 15:25:22 +0200 +Subject: [PATCH] docs: link downstream CONTRIBUTING in README + +This should increase the visibility of the downstream CONTRIBUTING. + +Also fix some wording and update links. + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 4 ++-- + README.md | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 1de2b88995..bd17067be2 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). ++When you find an issue with systemd used in **CentOS Stream** or **RHEL**, please file an issue in Red Hat [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515&priority=10300). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + +@@ -51,7 +51,7 @@ Each commit has to reference the relevant approved systemd issue (see: [Filling + - **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. + - **Reverts** for commits that reverts previously merged commit + +-When referencing issues, use following structure: `: `. See the example below: ++When referencing issues, use the following structure: `: `. See the example below: + + ```md + doc: Fix TYPO +diff --git a/README.md b/README.md +index a57566834c..2e02350299 100644 +--- a/README.md ++++ b/README.md +@@ -17,7 +17,7 @@ Consult our [NEWS file](../master/NEWS) for information about what's new in the + + Please see the [HACKING file](../master/doc/HACKING) for information how to hack on systemd and test your modifications. + +-Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. ++Please see our [Contribution Guidelines](CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. + + When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/doc/CODING_STYLE). + diff --git a/SOURCES/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch b/SOURCES/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch new file mode 100644 index 0000000..a346838 --- /dev/null +++ b/SOURCES/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch @@ -0,0 +1,47 @@ +From e257d900b45df7db779fd34f01b251d4054f3685 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:49:51 +0000 +Subject: [PATCH] unit drop-in: Fix ordering of special type.d drop-ins + +(cherry picked from commit e6627f2392cde12e21c40a7cfa96578c648c1f33) + +Related: #2156620 +--- + src/shared/dropin.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index 11ed4c7184..927107c508 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -242,6 +242,10 @@ int unit_file_find_dropin_paths( + + assert(ret); + ++ SET_FOREACH(name, names, i) ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); ++ + /* All the names in the unit are of the same type so just grab one. */ + name = (char*) set_first(names); + if (name) { +@@ -253,7 +257,7 @@ int unit_file_find_dropin_paths( + "Failed to to derive unit type from unit name: %s", + name); + +- /* Special top level drop in for ".". Add this first as it's the most generic ++ /* Special top level drop in for ".". Add this last as it's the most generic + * and should be able to be overridden by more specific drop-ins. */ + STRV_FOREACH(p, lookup_path) + (void) unit_file_find_dirs(original_root, +@@ -264,10 +268,6 @@ int unit_file_find_dropin_paths( + &dirs); + } + +- SET_FOREACH(name, names, i) +- STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); +- + if (strv_isempty(dirs)) { + *ret = NULL; + return 0; diff --git a/SOURCES/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch b/SOURCES/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch new file mode 100644 index 0000000..1fbf0c3 --- /dev/null +++ b/SOURCES/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch @@ -0,0 +1,57 @@ +From 471f790115b2b0a56328cbf14a6e0f51c1176b62 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:36:49 +0000 +Subject: [PATCH] Add failing test to show service.d global drop-in does not + get overridden by more specific dropins + +(cherry picked from commit f5dd6e50a781b83bc6b1d8e018783661142aabd0) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5419169f7b..a9d1ef0a10 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -118,6 +118,31 @@ EOF + clear_services a b c + } + ++test_hierarchical_dropins () { ++ echo "Testing hierarchical dropins..." ++ echo "*** test service.d/ top level drop-in" ++ create_services a-b-c ++ check_ko a-b-c ExecCondition "/bin/echo service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Service] ++ExecCondition=/bin/echo $dropin ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ done ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ rm -rf /usr/lib/systemd/system/$dropin ++ done ++ ++ clear_services a-b-c ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -303,6 +328,7 @@ test_invalid_dropins () { + } + + test_basic_dropins ++test_hierarchical_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/SOURCES/0963-test-set-indentation-to-4-spaces.patch b/SOURCES/0963-test-set-indentation-to-4-spaces.patch new file mode 100644 index 0000000..30a5591 --- /dev/null +++ b/SOURCES/0963-test-set-indentation-to-4-spaces.patch @@ -0,0 +1,522 @@ +From 3681938e3aa5d3580038011b4579ac39612df23e Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 13 Apr 2023 14:48:00 +0200 +Subject: [PATCH] test: set indentation to 4 spaces + +This is what upstream commit cc5549ca12616376a4e4ef04fd4e2fb53d6d098c +has done, but just for a single shell file. + +RHEL-only + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 448 ++++++++++++++--------------- + 1 file changed, 224 insertions(+), 224 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a9d1ef0a10..64d8a98fc7 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,103 +4,103 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ systemctl stop $1.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} + } + + clear_services () { +- for u in $*; do +- _clear_service $u +- done +- systemctl daemon-reload ++ for u in $*; do ++ _clear_service $u ++ done ++ systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ clear_services $1 + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/$1.service</usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/wants-b.conf</usr/lib/systemd/system/a.service.d/wants-b.conf< +Date: Sat, 21 Mar 2020 16:30:27 +0100 +Subject: [PATCH] test/TEST-15: remove all created unit files + +We would miss anything created under a template instance. + +(cherry picked from commit 4e2ac45a83e5495a5c1d3ecac62a054e0cef7746) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 64d8a98fc7..30f1e84954 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -8,6 +8,12 @@ _clear_service () { + rm -f /{etc,run,usr/lib}/systemd/system/$1.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ if [[ $1 == *@ ]]; then ++ systemctl stop $1*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ fi + } + + clear_services () { diff --git a/SOURCES/0965-test-use-quotes-where-necessary.patch b/SOURCES/0965-test-use-quotes-where-necessary.patch new file mode 100644 index 0000000..03bf462 --- /dev/null +++ b/SOURCES/0965-test-use-quotes-where-necessary.patch @@ -0,0 +1,95 @@ +From 209b8c92f0c44644d0476349b4a65f4b9ad942de Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 9 Apr 2021 19:49:32 +0200 +Subject: [PATCH] test: use quotes where necessary + +to avoid possible word splitting. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit 38825267983a439f2cf8375463b1edc9ca2d3323) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 30f1e84954..a197989f72 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,51 +4,53 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} +- if [[ $1 == *@ ]]; then +- systemctl stop $1*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} ++ if [[ $SERVICE_NAME == *@ ]]; then ++ systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} + fi + } + + clear_services () { +- for u in $*; do +- _clear_service $u ++ for u in "$@"; do ++ _clear_service "$u" + done + systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ local SERVICE_NAME="${1:?create_service: missing argument}" ++ clear_services "$SERVICE_NAME" + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/"$SERVICE_NAME".service < +Date: Wed, 4 May 2022 08:24:06 +0200 +Subject: [PATCH] tree-wide: drop manually-crafted message for missing + variables + +Bash will generate a very nice message for us: +/tmp/ff.sh: line 1: SOMEVAR: parameter null or not set + +Let's save some keystrokes by not replacing this with our own inferior +messages. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit d7ff52403902900b61f644f87b5222822fd4a69b) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a197989f72..c2c96d9797 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,7 +4,7 @@ set -e + set -x + + _clear_service () { +- local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service + rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +@@ -25,7 +25,7 @@ clear_services () { + } + + create_service () { +- local SERVICE_NAME="${1:?create_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + clear_services "$SERVICE_NAME" + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Fri, 14 Oct 2022 14:40:24 +0200 +Subject: [PATCH] manager: reformat boolean expression in unit_is_pristine() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not not IN_SET(…) is just too much for my poor brain. Let's invert +the expression to make it easier to undertand. + +(cherry picked from commit b146a7345b69de16e88347acadb3783ffeeaad9d) + +Related: #2156620 +--- + src/core/unit.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 9be2a0c326..78666e73bf 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4848,12 +4848,12 @@ bool unit_is_pristine(Unit *u) { + * are marked UNIT_LOADED even though nothing was actually + * loaded, as those unit types don't require a file on disk. */ + +- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) || +- u->fragment_path || +- u->source_path || +- !strv_isempty(u->dropin_paths) || +- u->job || +- u->merged_into); ++ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && ++ !u->fragment_path && ++ !u->source_path && ++ strv_isempty(u->dropin_paths) && ++ !u->job && ++ !u->merged_into; + } + + pid_t unit_control_pid(Unit *u) { diff --git a/SOURCES/0968-manager-allow-transient-units-to-have-drop-ins.patch b/SOURCES/0968-manager-allow-transient-units-to-have-drop-ins.patch new file mode 100644 index 0000000..c6826d1 --- /dev/null +++ b/SOURCES/0968-manager-allow-transient-units-to-have-drop-ins.patch @@ -0,0 +1,88 @@ +From fa8ed66b5ff48e0d8e02cfae28e90e65c70e52e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Oct 2022 15:02:20 +0200 +Subject: [PATCH] manager: allow transient units to have drop-ins + +In https://github.com/containers/podman/issues/16107, starting of a transient +slice unit fails because there's a "global" drop-in +/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by +systemd-oomd-defaults package to install some default oomd policy). This means +that the unit_is_pristine() check fails and starting of the unit is forbidden. + +It seems pretty clear to me that dropins at any other level then the unit +should be ignored in this check: we now have multiple layers of drop-ins +(for each level of the cgroup path, and also "global" ones for a specific +unit type). If we install a "global" drop-in, we wouldn't be able to start +any transient units of that type, which seems undesired. + +In principle we could reject dropins at the unit level, but I don't think that +is useful. The whole reason for drop-ins is that they are "add ons", and there +isn't any particular reason to disallow them for transient units. It would also +make things harder to implement and describe: one place for drop-ins is good, +but another is bad. (And as a corner case: for instanciated units, a drop-in +in the template would be acceptable, but a instance-specific drop-in bad?) + +Thus, $subject. + +While at it, adjust the message. All the conditions in unit_is_pristine() +essentially mean that it wasn't loaded (e.g. it might be in an error state), +and that it doesn't have a fragment path (now that drop-ins are acceptable). +If there's a job for it, it necessarilly must have been loaded. If it is +merged into another unit, it also was loaded and found to be an alias. +Based on the discussion in the bugs, it seems that the current message +is far from obvious ;) + +Fixes https://github.com/containers/podman/issues/16107, +https://bugzilla.redhat.com/show_bug.cgi?id=2133792. + +(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb) + +Resolves: #2156620 +--- + src/core/dbus-manager.c | 3 ++- + src/core/unit.c | 14 ++++++++------ + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 8a41eda4a6..ea2f3e7f59 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -892,7 +892,8 @@ static int transient_unit_from_message( + return r; + + if (!unit_is_pristine(u)) +- return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, ++ "Unit %s was already loaded or has a fragment file.", name); + + /* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +diff --git a/src/core/unit.c b/src/core/unit.c +index 78666e73bf..76fb9f8075 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4842,16 +4842,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) { + bool unit_is_pristine(Unit *u) { + assert(u); + +- /* Check if the unit already exists or is already around, +- * in a number of different ways. Note that to cater for unit +- * types such as slice, we are generally fine with units that +- * are marked UNIT_LOADED even though nothing was actually +- * loaded, as those unit types don't require a file on disk. */ ++ /* Check if the unit already exists or is already around, in a number of different ways. Note that to ++ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED ++ * even though nothing was actually loaded, as those unit types don't require a file on disk. ++ * ++ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units ++ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service: ++ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf. ++ */ + + return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && + !u->fragment_path && + !u->source_path && +- strv_isempty(u->dropin_paths) && + !u->job && + !u->merged_into; + } diff --git a/SOURCES/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch b/SOURCES/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch new file mode 100644 index 0000000..79f29d0 --- /dev/null +++ b/SOURCES/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch @@ -0,0 +1,135 @@ +From 8a85dd4af8e4948299b4c84df65c789999024d5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 12:42:35 +0200 +Subject: [PATCH] TEST-15: allow helper functions to accept other unit types + +clear_services() is renamed to clear_units() and now takes a full +unit name including the suffix as an argument. + +_clear_service() is renamed to clear_unit() and changed likewise. +create_service() didn't have the same underscore prefix, and I don't think +it's useful or needed for a local function, so it is removed. + +No functional change. + +(cherry picked from commit 5731e1378ad6256e34f3da33ee993343f025c075) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index c2c96d9797..bcd351360d 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -3,30 +3,32 @@ + set -e + set -x + +-_clear_service () { +- local SERVICE_NAME="${1:?}" +- systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} +- if [[ $SERVICE_NAME == *@ ]]; then +- systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} ++clear_unit () { ++ local UNIT_NAME="${1:?}" ++ systemctl stop "$UNIT_NAME" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".{wants,requires} ++ if [[ $UNIT_NAME == *@ ]]; then ++ local base="${UNIT_NAME%@*}" ++ local suffix="${UNIT_NAME##*.}" ++ systemctl stop "$base@"*."$suffix" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".{wants,requires} + fi + } + +-clear_services () { ++clear_units () { + for u in "$@"; do +- _clear_service "$u" ++ clear_unit "$u" + done + systemctl daemon-reload + } + + create_service () { + local SERVICE_NAME="${1:?}" +- clear_services "$SERVICE_NAME" ++ clear_units "${SERVICE_NAME}".service + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Sun, 16 Oct 2022 12:54:34 +0200 +Subject: [PATCH] TEST-15: also test hierarchical drop-ins for slices + +Slices are worth testing too, because they don't need a fragment path so they +behave slightly differently than service units. I'm making this a separate +patch from the actual tests that I wanted to add later because it's complex +enough on its own. + +(cherry picked from commit f80c874af376052b6b81f47cbbc43d7fecd98cd6) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 37 +++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index bcd351360d..d46946fd77 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -128,8 +128,8 @@ EOF + clear_units {a,b,c}.service + } + +-test_hierarchical_dropins () { +- echo "Testing hierarchical dropins..." ++test_hierarchical_service_dropins () { ++ echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c + check_ko a-b-c ExecCondition "/bin/echo service.d" +@@ -153,6 +153,36 @@ ExecCondition=/bin/echo $dropin + clear_units a-b-c.service + } + ++test_hierarchical_slice_dropins () { ++ echo "Testing hierarchical slice dropins..." ++ echo "*** test slice.d/ top level drop-in" ++ # Slice units don't even need a fragment, so we test the defaults here ++ check_ok a-b-c.slice Description "a-b-c.slice" ++ check_ok a-b-c.slice MemoryMax "infinity" ++ ++ # Test drop-ins ++ for dropin in slice.d a-.slice.d a-b-.slice.d a-b-c.slice.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Slice] ++MemoryMax=1000000000 ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ rm /usr/lib/systemd/system/$dropin/override.conf ++ done ++ ++ # Test unit with a fragment ++ echo " ++[Slice] ++MemoryMax=1000000001 ++ " >/usr/lib/systemd/system/a-b-c.slice ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000001" ++ ++ clear_units a-b-c.slice ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -338,7 +368,8 @@ test_invalid_dropins () { + } + + test_basic_dropins +-test_hierarchical_dropins ++test_hierarchical_service_dropins ++test_hierarchical_slice_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/SOURCES/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch b/SOURCES/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch new file mode 100644 index 0000000..4d892e4 --- /dev/null +++ b/SOURCES/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch @@ -0,0 +1,109 @@ +From c4db01d0c3e1ff05286261971ba39839cc91c21a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 14:02:45 +0200 +Subject: [PATCH] TEST-15: add test for transient units with drop-ins + +We want to test four things: +- that the transient units are successfully started when drop-ins exist +- that the transient setings override the defaults +- the drop-ins override the transient settings (the same as for a normal unit) +- that things are the same before and after a reload + +To make things more fun, we start and stop units in two different ways: via +systemctl and via a direct busctl invocation. This gives us a bit more coverage +of different code paths. + +(cherry picked from commit 6854434cfb5dda10c07d95835c38b75e5e71c2b5) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 62 +++++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index d46946fd77..5f061d3629 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -132,19 +132,40 @@ test_hierarchical_service_dropins () { + echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c +- check_ko a-b-c ExecCondition "/bin/echo service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ check_ko a-b-c ExecCondition "echo service.d" ++ check_ko a-b-c ExecCondition "echo a-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-c.service.d" + + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + mkdir -p /usr/lib/systemd/system/$dropin + echo " + [Service] +-ExecCondition=/bin/echo $dropin ++ExecCondition=echo $dropin + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload +- check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ check_ok a-b-c ExecCondition "echo $dropin" ++ ++ # Check that we can start a transient service in presence of the drop-ins ++ systemd-run --unit a-b-c2.service -p Description='sleepy' sleep infinity ++ ++ # The transient setting replaces the default ++ check_ok a-b-c2.service Description "sleepy" ++ ++ # The override takes precedence for ExecCondition ++ # (except the last iteration when it only applies to the other service) ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c2.service Description "sleepy" ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ systemctl stop a-b-c2.service + done + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + rm -rf /usr/lib/systemd/system/$dropin +@@ -169,6 +190,35 @@ MemoryMax=1000000000 + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload + check_ok a-b-c.slice MemoryMax "1000000000" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StartTransientUnit 'ssa(sv)a(sa(sv))' \ ++ 'a-b-c.slice' 'replace' \ ++ 2 \ ++ 'Description' s 'slice too' \ ++ 'MemoryMax' t 1000000002 \ ++ 0 ++ ++ # The override takes precedence for MemoryMax ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ # The transient setting replaces the default ++ check_ok a-b-c.slice Description "slice too" ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ check_ok a-b-c.slice Description "slice too" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StopUnit 'ss' \ ++ 'a-b-c.slice' 'replace' ++ + rm /usr/lib/systemd/system/$dropin/override.conf + done + diff --git a/SOURCES/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch b/SOURCES/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch new file mode 100644 index 0000000..d27d06d --- /dev/null +++ b/SOURCES/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch @@ -0,0 +1,66 @@ +From 832ceb778409cac37c3b64294dc64312e86eedc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 21:52:43 +0200 +Subject: [PATCH] TEST-15: add one more test for drop-in precedence + +(cherry picked from commit c3fa408dcc03bb6dbd11f180540fb9e684893c39) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 36 ++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5f061d3629..f6b3844630 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -233,6 +233,41 @@ MemoryMax=1000000001 + clear_units a-b-c.slice + } + ++test_transient_service_dropins () { ++ echo "Testing dropins for a transient service..." ++ echo "*** test transient service drop-ins" ++ ++ mkdir -p /etc/systemd/system/service.d ++ mkdir -p /etc/systemd/system/a-.service.d ++ mkdir -p /etc/systemd/system/a-b-.service.d ++ mkdir -p /etc/systemd/system/a-b-c.service.d ++ ++ echo -e '[Service]\nStandardInputText=aaa' >/etc/systemd/system/service.d/drop1.conf ++ echo -e '[Service]\nStandardInputText=bbb' >/etc/systemd/system/a-.service.d/drop2.conf ++ echo -e '[Service]\nStandardInputText=ccc' >/etc/systemd/system/a-b-.service.d/drop3.conf ++ echo -e '[Service]\nStandardInputText=ddd' >/etc/systemd/system/a-b-c.service.d/drop4.conf ++ ++ # There's no fragment yet, so this fails ++ systemctl cat a-b-c.service && exit 1 ++ ++ # xxx → eHh4Cg== ++ systemd-run --unit a-b-c.service -p StandardInputData=eHh4Cg== sleep infinity ++ ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ # xxx\naaa\n\bbb\nccc\nddd\n → eHh4… ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ # Do a reload and check again ++ systemctl daemon-reload ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ clear_units a-b-c.service ++ rm /etc/systemd/system/service.d/drop1.conf \ ++ /etc/systemd/system/a-.service.d/drop2.conf \ ++ /etc/systemd/system/a-b-.service.d/drop3.conf ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -420,6 +455,7 @@ test_invalid_dropins () { + test_basic_dropins + test_hierarchical_service_dropins + test_hierarchical_slice_dropins ++test_transient_service_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/SOURCES/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch b/SOURCES/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch new file mode 100644 index 0000000..a5e1176 --- /dev/null +++ b/SOURCES/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch @@ -0,0 +1,50 @@ +From 79e852a6c50ab2eae16761f128c52ef286c2956b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 14 Aug 2023 15:58:02 +0200 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.9 + +rhel-only + +Resolves: #2231846 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index 3cc7719e99..ddd41646ae 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -334,6 +334,12 @@ + Same as naming scheme rhel-8.7. + + ++ ++ rhel-8.9 ++ ++ Same as naming scheme rhel-8.7. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ef2bb1b08e..0f42c1c007 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -142,6 +142,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, + NAMING_RHEL_8_8 = NAMING_RHEL_8_7, ++ NAMING_RHEL_8_9 = NAMING_RHEL_8_7, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -163,6 +164,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.6", NAMING_RHEL_8_6 }, + { "rhel-8.7", NAMING_RHEL_8_7 }, + { "rhel-8.8", NAMING_RHEL_8_8 }, ++ { "rhel-8.9", NAMING_RHEL_8_9 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/0974-meson-remove-libdw-dependency-from-pstore.patch b/SOURCES/0974-meson-remove-libdw-dependency-from-pstore.patch new file mode 100644 index 0000000..87c5315 --- /dev/null +++ b/SOURCES/0974-meson-remove-libdw-dependency-from-pstore.patch @@ -0,0 +1,27 @@ +From e89c5274a75907bf24689859cdcdf8335df382cd Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 24 Nov 2021 20:23:02 +0000 +Subject: [PATCH] meson: remove libdw dependency from pstore + +systemd-pstore does not use any symbol from libdw, and never did, +but the dependency was listed since the beginning + +(cherry picked from commit 5361f62d6d5b25c6545059f7d2513324be8d7a49) + +Related: #2211416 +--- + meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/meson.build b/meson.build +index d986dd24ac..d00d250444 100644 +--- a/meson.build ++++ b/meson.build +@@ -2161,7 +2161,6 @@ if conf.get('ENABLE_PSTORE') == 1 + link_with : [libshared], + dependencies : [threads, + libacl, +- libdw, + libxz, + liblz4], + install_rpath : rootlibexecdir, diff --git a/SOURCES/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch b/SOURCES/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch new file mode 100644 index 0000000..473087c --- /dev/null +++ b/SOURCES/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch @@ -0,0 +1,113 @@ +From e7f656192ea399043947640a664bd94129e9549b Mon Sep 17 00:00:00 2001 +From: Eric DeVolder +Date: Mon, 13 Apr 2020 16:22:04 -0500 +Subject: [PATCH] pstore: introduce tmpfiles.d/systemd-pstore.conf + +The systemd pstore service archives the contents of /sys/fs/pstore +upon boot so that there is room for a subsequent dump. The issue is +that while the service is present, the kernel still needs to be +configured to write data into the pstore. The kernel has two +parameters, crash_kexec_post_notifiers and printk.always_kmsg_dump, +that control writes into pstore. + +The crash_kexec_post_notifiers parameter enables the kernel to write +dmesg (including stack trace) into pstore upon a panic, and +printk.always_kmsg_dump parameter enables the kernel to write dmesg +upon a shutdown (shutdown, reboot, halt). + +As it stands today, these parameters are not managed/manipulated by +the systemd pstore service, and are solely reliant upon the user [to +have the foresight] to set them on the kernel command line at boot, or +post boot via sysfs. Furthermore, the user would need to set these +parameters in a persistent fashion so that that they are enabled on +subsequent reboots. + +This patch introduces the setting of these two kernel parameters via +the systemd tmpfiles technique. + +(cherry picked from commit f00c36641a253f4ea659ec3def5d87ba1336eb3b) + +Resolves: #2211416 +--- + man/systemd-pstore.service.xml | 18 ++++++++++++++++++ + tmpfiles.d/meson.build | 1 + + tmpfiles.d/systemd-pstore.conf | 29 +++++++++++++++++++++++++++++ + 3 files changed, 48 insertions(+) + create mode 100644 tmpfiles.d/systemd-pstore.conf + +diff --git a/man/systemd-pstore.service.xml b/man/systemd-pstore.service.xml +index 47916da521..335a3b3d18 100644 +--- a/man/systemd-pstore.service.xml ++++ b/man/systemd-pstore.service.xml +@@ -81,6 +81,24 @@ + pstore.conf5. + + ++ ++ ++ Controlling kernel parameters ++ ++ The kernel has two parameters, ++ /sys/module/kernel/parameters/crash_kexec_post_notifiers and ++ /sys/module/printk/parameters/always_kmsg_dump, ++ that control writes into pstore. ++ The crash_kexec_post_notifiers parameter enables the kernel to write ++ dmesg (including stack trace) into pstore upon a panic or crash, and ++ printk.always_kmsg_dump parameter enables the kernel to write dmesg ++ upon a normal shutdown (shutdown, reboot, halt). These kernel ++ parameters are managed via the ++ tmpfiles.d5 ++ mechanism, specifically the file /usr/lib/tmpfiles/systemd-pstore.conf. ++ ++ ++ + + + +diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build +index 35eea2be5c..5ebb8f432a 100644 +--- a/tmpfiles.d/meson.build ++++ b/tmpfiles.d/meson.build +@@ -7,6 +7,7 @@ tmpfiles = [['home.conf', ''], + ['systemd-nologin.conf', ''], + ['systemd-nspawn.conf', 'ENABLE_MACHINED'], + ['portables.conf', 'ENABLE_PORTABLED'], ++ ['systemd-pstore.conf', 'ENABLE_PSTORE'], + ['tmp.conf', ''], + ['x11.conf', ''], + ['legacy.conf', 'HAVE_SYSV_COMPAT'], +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +new file mode 100644 +index 0000000000..cb600ec1ee +--- /dev/null ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -0,0 +1,29 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# The systemd-pstore.service(1) archives the contents of /sys/fs/pstore ++# upon boot so that there is room for a subsequent dump. This service ++# is enabled with: ++# systemctl enable systemd-pstore ++# ++# With the service enabled, the kernel still needs to be configured ++# to write data into the pstore. The kernel has two parameters, ++# crash_kexec_post_notifiers and printk.always_kmsg_dump, that ++# control writes into pstore. ++# ++# The crash_kexec_post_notifiers parameter enables the kernel to write ++# dmesg (including stack trace) into pstore upon a panic, and ++# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# upon a normal shutdown (shutdown, reboot, halt). ++# ++# To configure the kernel parameters, uncomment the appropriate ++# line(s) below. The value written is either 'Y' to enable the ++# kernel parameter, or 'N' to disable the kernel parameter. ++# ++# After making a change to this file, do: ++# systemd-tmpfiles --create path/to/tmpfiles.d/systemd-pstore.conf ++# ++# These changes are automatically applied on future re-boots. ++ ++d /var/lib/systemd/pstore 0755 root root 14d ++#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/SOURCES/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch b/SOURCES/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch new file mode 100644 index 0000000..4dec077 --- /dev/null +++ b/SOURCES/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch @@ -0,0 +1,25 @@ +From fec31cf3f20aa97b7dc8b381e64f30eea4d4c2d2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 May 2020 16:11:51 +0200 +Subject: [PATCH] tmpfiles: don't complain if we can't enable pstore in + containers + +(cherry picked from commit 203c07c95b91b4ae3b0c1ae3c92accdb71fd5e13) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index cb600ec1ee..8b6a1dafc3 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -25,5 +25,5 @@ + # These changes are automatically applied on future re-boots. + + d /var/lib/systemd/pstore 0755 root root 14d +-#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/SOURCES/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch b/SOURCES/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch new file mode 100644 index 0000000..1824a74 --- /dev/null +++ b/SOURCES/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch @@ -0,0 +1,66 @@ +From 21e0afbe2764476c98d7809af6634773835723d4 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Tue, 4 Aug 2020 17:30:51 +0800 +Subject: [PATCH] pstore: don't enable crash_kexec_post_notifiers by default + +commit f00c36641a253f4ea659ec3def5d87ba1336eb3b enabled +crash_kexec_post_notifiers by default regardless of whether pstore +is enabled or not. + +The original intention to enabled this option by default is that +it only affects kernel post-panic behavior, so should have no harm. +But this is not true if the user wants a reliable kdump. + +crash_kexec_post_notifiers is known to cause problem with kdump, +and it's documented in kernel. It's not easy to fix the problem +because of how kdump works. Kdump expects the crashed kernel to +jump to an pre-loaded crash kernel, so doing any extra job before +the jump will increase the risk. + +It depends on the user to choose between having a reliable kdump or +some other post-panic debug mechanic. + +So it's better to keep this config untouched by default, or it may put +kdump at higher risk of failing silently. User should enable it by +uncommenting the config line manually if pstore is always needed. + +Also add a inline comment inform user about the potential issue. + +Thanks to Dave Young for finding out this issue. + +Fixes #16661 + +Signed-off-by: Kairui Song +(cherry picked from commit edb8c98446e7dae54bcda90806bf6c068e1c6385) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index 8b6a1dafc3..e8e9ed48ae 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -11,8 +11,13 @@ + # control writes into pstore. + # + # The crash_kexec_post_notifiers parameter enables the kernel to write +-# dmesg (including stack trace) into pstore upon a panic, and +-# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# dmesg (including stack trace) into pstore upon a panic even if kdump ++# is loaded, only needed if you want to use pstore with kdump. Without ++# this parameter, kdump could block writing to pstore for stability ++# reason. Note this increases the risk of kdump failure even if pstore ++# is not available. ++# ++# The printk.always_kmsg_dump parameter enables the kernel to write dmesg + # upon a normal shutdown (shutdown, reboot, halt). + # + # To configure the kernel parameters, uncomment the appropriate +@@ -26,4 +31,4 @@ + + d /var/lib/systemd/pstore 0755 root root 14d + #w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/SOURCES/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch b/SOURCES/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch new file mode 100644 index 0000000..cf88994 --- /dev/null +++ b/SOURCES/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch @@ -0,0 +1,217 @@ +From 44d19e4beb486969b25c07f7efdee2e8b8bcf986 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:19:07 +0100 +Subject: [PATCH] core: when Delegate=yes is set for a unit, run ExecStartPre= + and friends in a subcgroup of the unit + +Otherwise we might conflict with the "no-processes-in-inner-cgroup" rule +of cgroupsv2. Consider nspawn starting up and initializing its cgroup +hierarchy with "supervisor/" and "payload/" as subcgroup, with itself +moved into the former and the payload into the latter. Now, if an +ExecStartPre= is run right after it cannot be placed in the main cgroup, +because that is now in inner cgroup with populated children. + +Hence, let's run these helpers in another sub-cgroup .control/ below it. + +This is somewhat ugly since it weakens the clear separation of +ownership, but given that this is an explicit contract, and double opt-in should be acceptable. + +Fixes: #10482 +(cherry picked from commit 78f93209fc7f61f15b12d7a5f74d712bd020b249) + +Resolves: #2215925 +--- + src/core/execute.c | 67 +++++++++++++++++++++++++++++++++++++++------- + src/core/execute.h | 9 ++++--- + src/core/service.c | 13 ++++----- + 3 files changed, 70 insertions(+), 19 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index b1d8dceb32..7e186c948c 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2834,6 +2834,37 @@ bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) { + return c->cpu_affinity_from_numa; + } + ++static int exec_parameters_get_cgroup_path(const ExecParameters *params, char **ret) { ++ bool using_subcgroup; ++ char *p; ++ ++ assert(params); ++ assert(ret); ++ ++ if (!params->cgroup_path) ++ return -EINVAL; ++ ++ /* If we are called for a unit where cgroup delegation is on, and the payload created its own populated ++ * subcgroup (which we expect it to do, after all it asked for delegation), then we cannot place the control ++ * processes started after the main unit's process in the unit's main cgroup because it is now an inner one, ++ * and inner cgroups may not contain processes. Hence, if delegation is on, and this is a control process, ++ * let's use ".control" as subcgroup instead. Note that we do so only for ExecStartPost=, ExecReload=, ++ * ExecStop=, ExecStopPost=, i.e. for the commands where the main process is already forked. For ExecStartPre= ++ * this is not necessary, the cgroup is still empty. We distinguish these cases with the EXEC_CONTROL_CGROUP ++ * flag, which is only passed for the former statements, not for the latter. */ ++ ++ using_subcgroup = FLAGS_SET(params->flags, EXEC_CONTROL_CGROUP|EXEC_CGROUP_DELEGATE|EXEC_IS_CONTROL); ++ if (using_subcgroup) ++ p = strjoin(params->cgroup_path, "/.control"); ++ else ++ p = strdup(params->cgroup_path); ++ if (!p) ++ return -ENOMEM; ++ ++ *ret = p; ++ return using_subcgroup; ++} ++ + static int exec_child( + Unit *unit, + const ExecCommand *command, +@@ -3055,10 +3086,18 @@ static int exec_child( + } + + if (params->cgroup_path) { +- r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL); ++ _cleanup_free_ char *p = NULL; ++ ++ r = exec_parameters_get_cgroup_path(params, &p); + if (r < 0) { + *exit_status = EXIT_CGROUP; +- return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", params->cgroup_path); ++ return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m"); ++ } ++ ++ r = cg_attach_everywhere(params->cgroup_supported, p, 0, NULL, NULL); ++ if (r < 0) { ++ *exit_status = EXIT_CGROUP; ++ return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", p); + } + } + +@@ -3659,6 +3698,7 @@ int exec_spawn(Unit *unit, + DynamicCreds *dcreds, + pid_t *ret) { + ++ _cleanup_free_ char *subcgroup_path = NULL; + _cleanup_strv_free_ char **files_env = NULL; + int *fds = NULL; + size_t n_storage_fds = 0, n_socket_fds = 0; +@@ -3716,6 +3756,17 @@ int exec_spawn(Unit *unit, + LOG_UNIT_ID(unit), + LOG_UNIT_INVOCATION_ID(unit)); + ++ if (params->cgroup_path) { ++ r = exec_parameters_get_cgroup_path(params, &subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to acquire subcgroup path: %m"); ++ if (r > 0) { /* We are using a child cgroup */ ++ r = cg_create(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to create control group '%s': %m", subcgroup_path); ++ } ++ } ++ + pid = fork(); + if (pid < 0) + return log_unit_error_errno(unit, errno, "Failed to fork: %m"); +@@ -3754,13 +3805,11 @@ int exec_spawn(Unit *unit, + + log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid); + +- /* We add the new process to the cgroup both in the child (so +- * that we can be sure that no user code is ever executed +- * outside of the cgroup) and in the parent (so that we can be +- * sure that when we kill the cgroup the process will be +- * killed too). */ +- if (params->cgroup_path) +- (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid); ++ /* We add the new process to the cgroup both in the child (so that we can be sure that no user code is ever ++ * executed outside of the cgroup) and in the parent (so that we can be sure that when we kill the cgroup the ++ * process will be killed too). */ ++ if (subcgroup_path) ++ (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path, pid); + + exec_status_start(&command->exec_status, pid); + +diff --git a/src/core/execute.h b/src/core/execute.h +index 62c6229621..f5bc180ece 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -289,12 +289,13 @@ typedef enum ExecFlags { + EXEC_CHOWN_DIRECTORIES = 1 << 5, /* chown() the runtime/state/cache/log directories to the user we run as, under all conditions */ + EXEC_NSS_BYPASS_BUS = 1 << 6, /* Set the SYSTEMD_NSS_BYPASS_BUS environment variable, to disable nss-systemd for dbus */ + EXEC_CGROUP_DELEGATE = 1 << 7, ++ EXEC_IS_CONTROL = 1 << 8, ++ EXEC_CONTROL_CGROUP = 1 << 9, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */ + + /* The following are not used by execute.c, but by consumers internally */ +- EXEC_PASS_FDS = 1 << 8, +- EXEC_IS_CONTROL = 1 << 9, +- EXEC_SETENV_RESULT = 1 << 10, +- EXEC_SET_WATCHDOG = 1 << 11, ++ EXEC_PASS_FDS = 1 << 10, ++ EXEC_SETENV_RESULT = 1 << 11, ++ EXEC_SET_WATCHDOG = 1 << 12, + } ExecFlags; + + struct ExecParameters { +diff --git a/src/core/service.c b/src/core/service.c +index e05d0e0514..0423f2c73e 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1429,7 +1429,7 @@ static int service_spawn( + assert(c); + assert(_pid); + +- r = unit_prepare_exec(UNIT(s)); ++ r = unit_prepare_exec(UNIT(s)); /* This realizes the cgroup, among other things */ + if (r < 0) + return r; + +@@ -1798,7 +1798,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1913,7 +1913,7 @@ static void service_enter_stop(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1991,7 +1991,7 @@ static void service_enter_start_post(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2269,7 +2269,7 @@ static void service_enter_reload(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2309,7 +2309,8 @@ static void service_run_next_control(Service *s) { + timeout, + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL| + (IN_SET(s->control_command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)| +- (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0), ++ (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0)| ++ (IN_SET(s->control_command_id, SERVICE_EXEC_START_POST, SERVICE_EXEC_RELOAD, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_CONTROL_CGROUP : 0), + &s->control_pid); + if (r < 0) + goto fail; diff --git a/SOURCES/0979-man-link-Delegate-documentation-up-with-the-markdown.patch b/SOURCES/0979-man-link-Delegate-documentation-up-with-the-markdown.patch new file mode 100644 index 0000000..a28e88d --- /dev/null +++ b/SOURCES/0979-man-link-Delegate-documentation-up-with-the-markdown.patch @@ -0,0 +1,26 @@ +From 0c1f96220f2a42c256a1e22e5f16d2ff8f4144df Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:29:02 +0100 +Subject: [PATCH] man: link Delegate= documentation up with the markdown docs + +(cherry picked from commit 077c40bc5271dfc8d9cee179fbed27a27e741973) + +Related: #2215925 +--- + man/systemd.resource-control.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index d3bff29169..36a622ebf0 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -808,6 +808,9 @@ + specific to the unified hierarchy while others are specific to the legacy hierarchy. Also note that the + kernel might support further controllers, which aren't covered here yet as delegation is either not supported + at all for them or not defined cleanly. ++ ++ For further details on the delegation model consult Control Group APIs and Delegation. + + + diff --git a/SOURCES/0980-ci-Extend-source-git-automation.patch b/SOURCES/0980-ci-Extend-source-git-automation.patch new file mode 100644 index 0000000..6c969e7 --- /dev/null +++ b/SOURCES/0980-ci-Extend-source-git-automation.patch @@ -0,0 +1,196 @@ +From 1628f48a0ecd13db92b79b7689e74b0ed4cb31a0 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 14 Sep 2023 13:54:12 +0200 +Subject: [PATCH] ci: Extend source-git-automation + +* on schedule and on demand workflows +* Added Tracker validation for Bugzilla and Jira + +rhel-only + +Resolves: RHEL-1087 +--- + .github/tracker-validator.yml | 13 +++ + .../source-git-automation-on-demand.yml | 99 +++++++++++++++++++ + .github/workflows/source-git-automation.yml | 29 +++++- + 3 files changed, 139 insertions(+), 2 deletions(-) + create mode 100644 .github/tracker-validator.yml + create mode 100644 .github/workflows/source-git-automation-on-demand.yml + +diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml +new file mode 100644 +index 0000000000..10ead63eaa +--- /dev/null ++++ b/.github/tracker-validator.yml +@@ -0,0 +1,13 @@ ++labels: ++ missing-tracker: tracker/missing ++ invalid-product: tracker/invalid-product ++ invalid-component: tracker/invalid-component ++ unapproved: tracker/unapproved ++products: ++ - CentOS Stream 8 ++ - rhel-8.2.0 ++ - rhel-8.4.0 ++ - rhel-8.6.0 ++ - rhel-8.8.0 ++ - rhel-8.9.0 ++ - rhel-8.10.0 +diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml +new file mode 100644 +index 0000000000..92a65c8cc7 +--- /dev/null ++++ b/.github/workflows/source-git-automation-on-demand.yml +@@ -0,0 +1,99 @@ ++--- ++ ++name: Source git Automation Scheduled/On Demand ++on: ++ schedule: ++ # Workflow runs every 15 minutes ++ - cron: '*/15 * * * *' ++ workflow_dispatch: ++ inputs: ++ pr-number: ++ description: 'Pull Request number/s ; when not provided, the workflow will run for all open PRs' ++ required: true ++ default: '0' ++ ++permissions: ++ contents: read ++ ++jobs: ++ # Get all open PRs ++ gather-pull-requests: ++ if: github.repository == 'redhat-plumbers/systemd-rhel8' ++ runs-on: ubuntu-latest ++ ++ outputs: ++ pr-numbers: ${{ steps.get-pr-numbers.outputs.result }} ++ pr-numbers-manual: ${{ steps.parse-manual-input.outputs.result }} ++ ++ steps: ++ - id: get-pr-numbers ++ if: inputs.pr-number == '0' ++ name: Get all open PRs ++ uses: actions/github-script@v6 ++ with: ++ # !FIXME: this is not working if there is more than 100 PRs opened ++ script: | ++ const { data: pullRequests } = await github.rest.pulls.list({ ++ owner: context.repo.owner, ++ repo: context.repo.repo, ++ state: 'open', ++ per_page: 100 ++ }); ++ return pullRequests.map(pr => pr.number); ++ ++ - id: parse-manual-input ++ if: inputs.pr-number != '0' ++ name: Parse manual input ++ run: | ++ echo "result="[ ${{ inputs.pr-number }} ]"" >> $GITHUB_OUTPUT ++ shell: bash ++ ++ validate-pr: ++ name: 'Validation of Pull Request #${{ matrix.pr-number }}' ++ needs: [ gather-pull-requests ] ++ runs-on: ubuntu-latest ++ ++ strategy: ++ fail-fast: false ++ matrix: ++ pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }} ++ ++ permissions: ++ statuses: write ++ checks: write ++ pull-requests: write ++ ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v3 ++ ++ - id: metadata ++ name: Gather Pull Request Metadata ++ uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1 ++ with: ++ pr-number: ${{ matrix.pr-number }} ++ ++ - id: commit-linter ++ name: Lint Commits ++ uses: redhat-plumbers-in-action/advanced-commit-linter@v2 ++ with: ++ pr-metadata: ${{ steps.metadata.outputs.metadata }} ++ token: ${{ secrets.GITHUB_TOKEN }} ++ ++ # Validates tracker, changes tracker status, updates PR title ++ - id: tracker-validator ++ name: Validate Tracker ++ uses: redhat-plumbers-in-action/tracker-validator@v1 ++ with: ++ pr-metadata: ${{ steps.metadata.outputs.metadata }} ++ component: systemd ++ tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} ++ tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} ++ bugzilla-instance: https://bugzilla.redhat.com ++ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} ++ jira-instance: https://issues.redhat.com ++ jira-api-token: ${{ secrets.JIRA_API_TOKEN }} ++ token: ${{ secrets.GITHUB_TOKEN }} ++ ++ # TODO: merge PR if all checks passed ++ # TODO: add comment to Tracker that PR was merged ... +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index e653e28a7f..16c6f83d77 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -12,7 +12,8 @@ jobs: + download-metadata: + if: > + github.event.workflow_run.event == 'pull_request' && +- github.event.workflow_run.conclusion == 'success' ++ github.event.workflow_run.conclusion == 'success' && ++ github.repository == 'redhat-plumbers/systemd-rhel8' + runs-on: ubuntu-latest + + outputs: +@@ -33,13 +34,37 @@ jobs: + validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} + + permissions: ++ statuses: write + checks: write + pull-requests: write + + steps: + - id: commit-linter + name: Lint Commits +- uses: redhat-plumbers-in-action/advanced-commit-linter@v1 ++ uses: redhat-plumbers-in-action/advanced-commit-linter@v2 + with: + pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} + token: ${{ secrets.GITHUB_TOKEN }} ++ ++ # Validates tracker, changes tracker status, updates PR title ++ tracker-validation: ++ needs: [ download-metadata, commit-linter ] ++ runs-on: ubuntu-latest ++ ++ permissions: ++ checks: write ++ pull-requests: write ++ ++ steps: ++ - name: Validate Tracker ++ uses: redhat-plumbers-in-action/tracker-validator@v1 ++ with: ++ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} ++ component: systemd ++ tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} ++ tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} ++ bugzilla-instance: https://bugzilla.redhat.com ++ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} ++ jira-instance: https://issues.redhat.com ++ jira-api-token: ${{ secrets.JIRA_API_TOKEN }} ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0981-ci-add-missing-configuration-for-commit-linter.patch b/SOURCES/0981-ci-add-missing-configuration-for-commit-linter.patch new file mode 100644 index 0000000..6a30f07 --- /dev/null +++ b/SOURCES/0981-ci-add-missing-configuration-for-commit-linter.patch @@ -0,0 +1,32 @@ +From 21200fc506b1d15be6ed6d5b9ac70f1ec865f9bc Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 19 Sep 2023 09:53:35 +0200 +Subject: [PATCH] ci: add missing configuration for commit linter + +rhel-only + +Related: RHEL-1087 +--- + .github/advanced-commit-linter.yml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 0fb74a9dc8..86f0e911f2 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -11,6 +11,7 @@ policy: + - 'Resolves: #?' + - 'Related: #?' + - 'Reverts: #?' ++ type: bugzilla + issue-format: + - '\d+$' + url: 'https://bugzilla.redhat.com/show_bug.cgi?id=' +@@ -18,6 +19,7 @@ policy: + - 'Resolves: ' + - 'Related: ' + - 'Reverts: ' ++ type: jira + issue-format: + - 'RHEL-\d+$' + url: 'https://issues.redhat.com/browse/' diff --git a/SOURCES/0982-ci-add-Red-Hat-Enterprise-Linux-8-to-the-list-of-sup.patch b/SOURCES/0982-ci-add-Red-Hat-Enterprise-Linux-8-to-the-list-of-sup.patch new file mode 100644 index 0000000..8a3d248 --- /dev/null +++ b/SOURCES/0982-ci-add-Red-Hat-Enterprise-Linux-8-to-the-list-of-sup.patch @@ -0,0 +1,25 @@ +From ffd775b4b96ce0d772bcbb2fe2fbc62ed06bb4a4 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 19 Sep 2023 15:17:48 +0200 +Subject: [PATCH] ci: add `Red Hat Enterprise Linux 8` to the list of supported + products + +rhel-only + +Related: RHEL-1087 +--- + .github/tracker-validator.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml +index 10ead63eaa..500dce3d92 100644 +--- a/.github/tracker-validator.yml ++++ b/.github/tracker-validator.yml +@@ -4,6 +4,7 @@ labels: + invalid-component: tracker/invalid-component + unapproved: tracker/unapproved + products: ++ - Red Hat Enterprise Linux 8 + - CentOS Stream 8 + - rhel-8.2.0 + - rhel-8.4.0 diff --git a/SOURCES/0983-ci-enable-source-git-automation-to-validate-reviews-.patch b/SOURCES/0983-ci-enable-source-git-automation-to-validate-reviews-.patch new file mode 100644 index 0000000..336a464 --- /dev/null +++ b/SOURCES/0983-ci-enable-source-git-automation-to-validate-reviews-.patch @@ -0,0 +1,95 @@ +From bf728def0c6eebdf8d2b8912232ba7806e109293 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 20 Oct 2023 13:32:22 +0200 +Subject: [PATCH] ci: enable source-git automation to validate reviews and ci + results + +rhel-only + +Related: RHEL-1087 +--- + .github/pull-request-validator.yml | 4 ++++ + .../source-git-automation-on-demand.yml | 14 ++++++++++---- + .github/workflows/source-git-automation.yml | 18 +++++++++++++++++- + 3 files changed, 31 insertions(+), 5 deletions(-) + create mode 100644 .github/pull-request-validator.yml + +diff --git a/.github/pull-request-validator.yml b/.github/pull-request-validator.yml +new file mode 100644 +index 0000000000..4bb5bbec12 +--- /dev/null ++++ b/.github/pull-request-validator.yml +@@ -0,0 +1,4 @@ ++labels: ++ missing-review: pr/needs-review ++ changes-requested: pr/changes-requested ++ missing-failing-ci: pr/needs-ci +diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml +index 92a65c8cc7..e70ba4857a 100644 +--- a/.github/workflows/source-git-automation-on-demand.yml ++++ b/.github/workflows/source-git-automation-on-demand.yml +@@ -73,7 +73,8 @@ jobs: + with: + pr-number: ${{ matrix.pr-number }} + +- - id: commit-linter ++ - if: ${{ !cancelled() }} ++ id: commit-linter + name: Lint Commits + uses: redhat-plumbers-in-action/advanced-commit-linter@v2 + with: +@@ -81,7 +82,8 @@ jobs: + token: ${{ secrets.GITHUB_TOKEN }} + + # Validates tracker, changes tracker status, updates PR title +- - id: tracker-validator ++ - if: ${{ !cancelled() }} ++ id: tracker-validator + name: Validate Tracker + uses: redhat-plumbers-in-action/tracker-validator@v1 + with: +@@ -95,5 +97,9 @@ jobs: + jira-api-token: ${{ secrets.JIRA_API_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} + +- # TODO: merge PR if all checks passed +- # TODO: add comment to Tracker that PR was merged ... ++ - if: ${{ !cancelled() }} ++ name: Pull Request Validator ++ uses: redhat-plumbers-in-action/pull-request-validator@v1 ++ with: ++ pr-metadata: ${{ steps.metadata.outputs.metadata }} ++ token: ${{ secrets.GITHUB_TOKEN }} +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 16c6f83d77..9faaaca099 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -47,7 +47,8 @@ jobs: + token: ${{ secrets.GITHUB_TOKEN }} + + # Validates tracker, changes tracker status, updates PR title +- tracker-validation: ++ tracker-validator: ++ if: ${{ !cancelled() }} + needs: [ download-metadata, commit-linter ] + runs-on: ubuntu-latest + +@@ -68,3 +69,18 @@ jobs: + jira-instance: https://issues.redhat.com + jira-api-token: ${{ secrets.JIRA_API_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} ++ ++ pull-request-validator: ++ needs: [ download-metadata ] ++ runs-on: ubuntu-latest ++ ++ permissions: ++ checks: write ++ pull-requests: write ++ ++ steps: ++ - name: Pull Request Validator ++ uses: redhat-plumbers-in-action/pull-request-validator@v1 ++ with: ++ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0984-ci-remove-Mergify-config-replaced-by-Pull-Request-Va.patch b/SOURCES/0984-ci-remove-Mergify-config-replaced-by-Pull-Request-Va.patch new file mode 100644 index 0000000..6b8fbd0 --- /dev/null +++ b/SOURCES/0984-ci-remove-Mergify-config-replaced-by-Pull-Request-Va.patch @@ -0,0 +1,52 @@ +From 36266d377ee5e57e24cd3c45f6db2a29919798f3 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 20 Oct 2023 13:33:38 +0200 +Subject: [PATCH] ci: remove Mergify config - replaced by Pull Request + Validator + +rhel-only + +Related: RHEL-1087 +--- + .mergify.yml | 32 -------------------------------- + 1 file changed, 32 deletions(-) + delete mode 100644 .mergify.yml + +diff --git a/.mergify.yml b/.mergify.yml +deleted file mode 100644 +index 624eb7291d..0000000000 +--- a/.mergify.yml ++++ /dev/null +@@ -1,32 +0,0 @@ +-# doc: https://docs.mergify.com +---- +- +-pull_request_rules: +- - name: Add `needs-ci` label on CI fail +- conditions: +- - label!=ci-waived +- - or: +- # Unit tests +- - -check-success=build (stream8, GCC) +- - -check-success=build (stream8, GCC_ASAN) +- # CentOS Stream CI +- - -check-success=CentOS CI (CentOS Stream 8) +- actions: +- label: +- add: +- - needs-ci +- +- - name: Remove `needs-ci` label on CI success +- conditions: +- - or: +- - label=ci-waived +- - and: +- # Unit tests +- - check-success=build (stream8, GCC) +- - check-success=build (stream8, GCC_ASAN) +- # CentOS Stream CI +- - check-success=CentOS CI (CentOS Stream 8) +- actions: +- label: +- remove: +- - needs-ci diff --git a/SOURCES/0985-ci-enable-auto-merge-GH-Action.patch b/SOURCES/0985-ci-enable-auto-merge-GH-Action.patch new file mode 100644 index 0000000..6828fca --- /dev/null +++ b/SOURCES/0985-ci-enable-auto-merge-GH-Action.patch @@ -0,0 +1,84 @@ +From 73b327eeeb3e2f17cbc1abd19aa5b87c28fcf509 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 3 Nov 2023 14:07:04 +0100 +Subject: [PATCH] ci: enable auto-merge GH Action + +rhel-only + +Related: RHEL-1087 +--- + .github/auto-merge.yml | 4 ++++ + .../source-git-automation-on-demand.yml | 14 ++++++++++++ + .github/workflows/source-git-automation.yml | 22 +++++++++++++++++++ + 3 files changed, 40 insertions(+) + create mode 100644 .github/auto-merge.yml + +diff --git a/.github/auto-merge.yml b/.github/auto-merge.yml +new file mode 100644 +index 0000000000..35c2539295 +--- /dev/null ++++ b/.github/auto-merge.yml +@@ -0,0 +1,4 @@ ++labels: ++ dont-merge: dont-merge ++ manual-merge: pr/needs-manual-merge ++target-branch': ['main'] +diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml +index e70ba4857a..948708916d 100644 +--- a/.github/workflows/source-git-automation-on-demand.yml ++++ b/.github/workflows/source-git-automation-on-demand.yml +@@ -59,6 +59,7 @@ jobs: + pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }} + + permissions: ++ contents: write + statuses: write + checks: write + pull-requests: write +@@ -103,3 +104,16 @@ jobs: + with: + pr-metadata: ${{ steps.metadata.outputs.metadata }} + token: ${{ secrets.GITHUB_TOKEN }} ++ ++ - id: auto-merge ++ name: Auto Merge ++ uses: redhat-plumbers-in-action/auto-merge@v1 ++ with: ++ pr-metadata: ${{ steps.metadata.outputs.metadata }} ++ tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} ++ tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} ++ bugzilla-instance: https://bugzilla.redhat.com ++ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} ++ jira-instance: https://issues.redhat.com ++ jira-api-token: ${{ secrets.JIRA_API_TOKEN }} ++ token: ${{ secrets.GITHUB_TOKEN }} +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 9faaaca099..95819baa8b 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -84,3 +84,25 @@ jobs: + with: + pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} + token: ${{ secrets.GITHUB_TOKEN }} ++ ++ auto-merge: ++ needs: [ download-metadata, commit-linter, tracker-validator, pull-request-validator ] ++ runs-on: ubuntu-latest ++ ++ permissions: ++ contents: write ++ checks: write ++ pull-requests: write ++ ++ steps: ++ - name: Auto Merge ++ uses: redhat-plumbers-in-action/auto-merge@v1 ++ with: ++ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} ++ tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} ++ tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} ++ bugzilla-instance: https://bugzilla.redhat.com ++ bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} ++ jira-instance: https://issues.redhat.com ++ jira-api-token: ${{ secrets.JIRA_API_TOKEN }} ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0986-fstab-generator-allow-overriding-etc-fstab-with-SYST.patch b/SOURCES/0986-fstab-generator-allow-overriding-etc-fstab-with-SYST.patch new file mode 100644 index 0000000..4123a1d --- /dev/null +++ b/SOURCES/0986-fstab-generator-allow-overriding-etc-fstab-with-SYST.patch @@ -0,0 +1,179 @@ +From d0f59d4190a9f1e0e6db4b22b5e87bec2db4f7fb Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 27 Nov 2023 15:20:47 +0100 +Subject: [PATCH] fstab-generator: allow overriding /etc/fstab with + $SYSTEMD_FSTAB + +Based on: ed4ad4889723a9acdf75ed86f10cee0024bbbcbc +Related: RHEL-1087 + +rhel-only +--- + src/cryptsetup/cryptsetup.c | 3 ++- + src/fstab-generator/fstab-generator.c | 28 ++++++++++++++------------- + src/remount-fs/remount-fs.c | 5 +++-- + src/shared/fstab-util.c | 4 ++-- + src/shared/fstab-util.h | 4 ++++ + 5 files changed, 26 insertions(+), 18 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 11162eb722..de4bc9579c 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -13,6 +13,7 @@ + #include "device-util.h" + #include "escape.h" + #include "fileio.h" ++#include "fstab-util.h" + #include "log.h" + #include "mount-util.h" + #include "parse-util.h" +@@ -318,7 +319,7 @@ static char *disk_mount_point(const char *label) { + if (asprintf(&device, "/dev/mapper/%s", label) < 0) + return NULL; + +- f = setmntent("/etc/fstab", "re"); ++ f = setmntent(fstab_path(), "re"); + if (!f) + return NULL; + +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index f24c1d29da..105ddd2fd0 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -105,15 +105,17 @@ static int add_swap( + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + +- r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f); ++ r = generator_open_unit_file(arg_dest, fstab_path(), name, &f); + if (r < 0) + return r; + +- fputs("# Automatically generated by systemd-fstab-generator\n\n" +- "[Unit]\n" +- "SourcePath=/etc/fstab\n" +- "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n" +- "[Swap]\n", f); ++ fprintf(f, ++ "# Automatically generated by systemd-fstab-generator\n\n" ++ "[Unit]\n" ++ "SourcePath=%s\n" ++ "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n" ++ "[Swap]\n", ++ fstab_path()); + + r = write_what(f, what); + if (r < 0) +@@ -334,7 +336,7 @@ static int add_mount( + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + +- r = generator_open_unit_file(dest, "/etc/fstab", name, &f); ++ r = generator_open_unit_file(dest, fstab_path(), name, &f); + if (r < 0) + return r; + +@@ -451,7 +453,7 @@ static int add_mount( + + fclose(f); + +- r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f); ++ r = generator_open_unit_file(dest, fstab_path(), automount_name, &f); + if (r < 0) + return r; + +@@ -503,17 +505,17 @@ static int add_mount( + + static int parse_fstab(bool initrd) { + _cleanup_endmntent_ FILE *f = NULL; +- const char *fstab_path; ++ const char *fstab; + struct mntent *me; + int r = 0; + +- fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab"; +- f = setmntent(fstab_path, "re"); ++ fstab = initrd ? "/sysroot/etc/fstab" : fstab_path(); ++ f = setmntent(fstab, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + +- return log_error_errno(errno, "Failed to open %s: %m", fstab_path); ++ return log_error_errno(errno, "Failed to open %s: %m", fstab); + } + + while ((me = getmntent(f))) { +@@ -592,7 +594,7 @@ static int parse_fstab(bool initrd) { + me->mnt_passno, + makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT, + post, +- fstab_path); ++ fstab); + } + + if (r >= 0 && k < 0) +diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c +index 9220a00215..5bcee999cc 100644 +--- a/src/remount-fs/remount-fs.c ++++ b/src/remount-fs/remount-fs.c +@@ -9,6 +9,7 @@ + #include + + #include "exit-status.h" ++#include "fstab-util.h" + #include "log.h" + #include "mount-setup.h" + #include "mount-util.h" +@@ -39,14 +40,14 @@ int main(int argc, char *argv[]) { + + umask(0022); + +- f = setmntent("/etc/fstab", "re"); ++ f = setmntent(fstab_path(), "re"); + if (!f) { + if (errno == ENOENT) { + r = 0; + goto finish; + } + +- r = log_error_errno(errno, "Failed to open /etc/fstab: %m"); ++ r = log_error_errno(errno, "Failed to open %s: %m", fstab_path()); + goto finish; + } + +diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c +index 6fd9866c00..bc0c047509 100644 +--- a/src/shared/fstab-util.c ++++ b/src/shared/fstab-util.c +@@ -21,7 +21,7 @@ int fstab_has_fstype(const char *fstype) { + _cleanup_endmntent_ FILE *f = NULL; + struct mntent *m; + +- f = setmntent("/etc/fstab", "re"); ++ f = setmntent(fstab_path(), "re"); + if (!f) + return errno == ENOENT ? false : -errno; + +@@ -41,7 +41,7 @@ int fstab_is_mount_point(const char *mount) { + _cleanup_endmntent_ FILE *f = NULL; + struct mntent *m; + +- f = setmntent("/etc/fstab", "re"); ++ f = setmntent(fstab_path(), "re"); + if (!f) + return errno == ENOENT ? false : -errno; + +diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h +index 9820f78ca8..9ec6db068c 100644 +--- a/src/shared/fstab-util.h ++++ b/src/shared/fstab-util.h +@@ -33,3 +33,7 @@ static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no + } + + char *fstab_node_to_udev_node(const char *p); ++ ++static inline const char *fstab_path(void) { ++ return secure_getenv("SYSTEMD_FSTAB") ?: "/etc/fstab"; ++} diff --git a/SOURCES/0987-fstab-generator-allow-overriding-path-to-sysroot-etc.patch b/SOURCES/0987-fstab-generator-allow-overriding-path-to-sysroot-etc.patch new file mode 100644 index 0000000..6693c2d --- /dev/null +++ b/SOURCES/0987-fstab-generator-allow-overriding-path-to-sysroot-etc.patch @@ -0,0 +1,37 @@ +From f4a9bdf74c23a55ea96de696155ce9a5dfa43850 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 27 Nov 2023 16:16:40 +0100 +Subject: [PATCH] fstab-generator: allow overriding path to /sysroot/etc/fstab + too + +Based on: 99e3d4767932bce5febb45e8543162d729d17425 +Related: RHEL-1087 + +rhel-only +--- + src/fstab-generator/fstab-generator.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 105ddd2fd0..02f0bccd2f 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -503,13 +503,17 @@ static int add_mount( + return 0; + } + ++static const char *sysroot_fstab_path(void) { ++ return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab"; ++} ++ + static int parse_fstab(bool initrd) { + _cleanup_endmntent_ FILE *f = NULL; + const char *fstab; + struct mntent *me; + int r = 0; + +- fstab = initrd ? "/sysroot/etc/fstab" : fstab_path(); ++ fstab = initrd ? sysroot_fstab_path() : fstab_path(); + f = setmntent(fstab, "re"); + if (!f) { + if (errno == ENOENT) diff --git a/SOURCES/0988-test-backport-TEST-81-GENERATORS-fstab-generator-onl.patch b/SOURCES/0988-test-backport-TEST-81-GENERATORS-fstab-generator-onl.patch new file mode 100644 index 0000000..cf9269d --- /dev/null +++ b/SOURCES/0988-test-backport-TEST-81-GENERATORS-fstab-generator-onl.patch @@ -0,0 +1,611 @@ +From 52026032996f021963f5af8d625a5b9653d3f815 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 27 Nov 2023 14:54:15 +0100 +Subject: [PATCH] test: backport TEST-81-GENERATORS (fstab-generator only) + +Some fstab-generator features are not present on RHEL 8 or they behave +differently - in such case there's an inline comment explaining what's +different with a reference to an upstream commit that introduced the +changed behavior. + +Related: RHEL-1087 + +rhel-only +--- + test/TEST-81-GENERATORS/Makefile | 1 + + test/TEST-81-GENERATORS/generator-utils.sh | 78 ++++ + test/TEST-81-GENERATORS/test.sh | 50 +++ + .../testsuite.fstab-generator.sh | 397 ++++++++++++++++++ + test/TEST-81-GENERATORS/testsuite.sh | 14 + + test/test-functions | 2 +- + 6 files changed, 541 insertions(+), 1 deletion(-) + create mode 120000 test/TEST-81-GENERATORS/Makefile + create mode 100755 test/TEST-81-GENERATORS/generator-utils.sh + create mode 100755 test/TEST-81-GENERATORS/test.sh + create mode 100755 test/TEST-81-GENERATORS/testsuite.fstab-generator.sh + create mode 100755 test/TEST-81-GENERATORS/testsuite.sh + +diff --git a/test/TEST-81-GENERATORS/Makefile b/test/TEST-81-GENERATORS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-81-GENERATORS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-81-GENERATORS/generator-utils.sh b/test/TEST-81-GENERATORS/generator-utils.sh +new file mode 100755 +index 0000000000..fb62747fa1 +--- /dev/null ++++ b/test/TEST-81-GENERATORS/generator-utils.sh +@@ -0,0 +1,78 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++ ++link_endswith() { ++ [[ -h "${1:?}" && "$(readlink "${1:?}")" =~ ${2:?}$ ]] ++} ++ ++link_eq() { ++ [[ -h "${1:?}" && "$(readlink "${1:?}")" == "${2:?}" ]] ++} ++ ++# Get the value from a 'key=value' assignment ++opt_get_arg() { ++ local arg ++ ++ IFS="=" read -r _ arg <<< "${1:?}" ++ test -n "$arg" ++ echo "$arg" ++} ++ ++in_initrd() { ++ [[ "${SYSTEMD_IN_INITRD:-0}" -ne 0 ]] ++} ++ ++# Check if we're parsing host's fstab in initrd ++in_initrd_host() { ++ in_initrd && [[ "${SYSTEMD_SYSROOT_FSTAB:-/dev/null}" != /dev/null ]] ++} ++ ++in_container() { ++ systemd-detect-virt -qc ++} ++ ++opt_filter() ( ++ set +x ++ local opt split_options filtered_options ++ ++ IFS="," read -ra split_options <<< "${1:?}" ++ for opt in "${split_options[@]}"; do ++ if [[ "$opt" =~ ${2:?} ]]; then ++ continue ++ fi ++ ++ filtered_options+=("$opt") ++ done ++ ++ IFS=","; printf "%s" "${filtered_options[*]}" ++) ++ ++# Run the given generator $1 with target directory $2 - clean the target ++# directory beforehand ++run_and_list() { ++ local generator="${1:?}" ++ local out_dir="${2:?}" ++ local environ ++ ++ # If $PID1_ENVIRON is set temporarily overmount /proc/1/environ with ++ # a temporary file that contains contents of $PID1_ENVIRON. This is ++ # necessary in cases where the generator reads the environment through ++ # getenv_for_pid(1, ...) or similar like getty-generator does. ++ # ++ # Note: $PID1_ENVIRON should be a NUL separated list of env assignments ++ if [[ -n "${PID1_ENVIRON:-}" ]]; then ++ environ="$(mktemp)" ++ echo -ne "${PID1_ENVIRON}\0" >"${environ:?}" ++ mount -v --bind "$environ" /proc/1/environ ++ fi ++ ++ rm -fr "${out_dir:?}"/* ++ mkdir -p "$out_dir"/{normal,early,late} ++ SYSTEMD_LOG_LEVEL="${SYSTEMD_LOG_LEVEL:-debug}" "$generator" "$out_dir/normal" "$out_dir/early" "$out_dir/late" ++ ls -lR "$out_dir" ++ ++ if [[ -n "${environ:-}" ]]; then ++ umount /proc/1/environ ++ rm -f "$environ" ++ fi ++} +diff --git a/test/TEST-81-GENERATORS/test.sh b/test/TEST-81-GENERATORS/test.sh +new file mode 100755 +index 0000000000..ec9c608c60 +--- /dev/null ++++ b/test/TEST-81-GENERATORS/test.sh +@@ -0,0 +1,50 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Test systemd generators" ++ ++# shellcheck source=test/test-functions ++. "$TEST_BASE_DIR/test-functions" ++ ++test_setup() { ++ create_empty_image ++ mkdir -p "${TESTDIR:?}/root" ++ mount "${LOOPDEV:?}p1" "$TESTDIR/root" ++ ++ ( ++ LOG_LEVEL=5 ++ # shellcheck disable=SC2046 ++ eval $(udevadm info --export --query=env --name="${LOOPDEV}p2") ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-hwdb-update.service" ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-journal-catalog-update.service" ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-networkd.service" ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-networkd.socket" ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-resolved.service" ++ ln -fs /dev/null "$initdir/etc/systemd/system/systemd-machined.service" ++ ++ # setup the testsuite service ++ cat >"$initdir/etc/systemd/system/testsuite.service" <&2 "Unhandled mount option: $opt" ++ exit 1 ++ fi ++ done ++ done ++} ++ ++: "fstab-generator: regular" ++printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB" ++cat "$FSTAB" ++SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR" ++ ++# Skip the rest when running in a container, as it makes little sense to check ++# initrd-related stuff there and fstab-generator might have a bit strange ++# behavior during certain tests, like https://github.com/systemd/systemd/issues/27156 ++if in_container; then ++ echo "Running in a container, skipping the rest of the fstab-generator tests..." ++ exit 0 ++fi ++ ++# In this mode we treat the entries as "regular" ones ++: "fstab-generator: initrd - initrd fstab" ++printf "%s\n" "${FSTAB_GENERAL[@]}" >"$FSTAB" ++cat "$FSTAB" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null check_fstab_mount_units FSTAB_GENERAL "$OUT_DIR" ++ ++# In this mode we prefix the mount target with /sysroot and ignore all mounts ++# that don't have the x-initrd.mount flag ++: "fstab-generator: initrd - host fstab" ++printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB" ++cat "$FSTAB" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR" ++ ++# Check the default stuff that we (almost) always create in initrd ++: "fstab-generator: initrd default" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++test -e "$OUT_DIR/normal/sysroot.mount" ++test -e "$OUT_DIR/normal/systemd-fsck-root.service" ++link_eq "$OUT_DIR/normal/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount" ++link_eq "$OUT_DIR/normal/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount" ++ ++# systemd-sysroot-fstab-check is not in RHEL 8 ++ ++: "fstab-generator: duplicate" ++printf "%s\n" "${FSTAB_DUPLICATE[@]}" >"$FSTAB" ++cat "$FSTAB" ++(! SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR") ++ ++: "fstab-generator: invalid" ++printf "%s\n" "${FSTAB_INVALID[@]}" >"$FSTAB" ++cat "$FSTAB" ++# Don't care about the exit code here ++SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR" || : ++# No mounts should get created here ++[[ "$(find "$OUT_DIR" -name "*.mount" | wc -l)" -eq 0 ]] ++ ++: "fstab-generator: kernel args - fstab=0" ++printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB" ++SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++(! SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR") ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR") ++ ++: "fstab-generator: kernel args - rd.fstab=0" ++printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB" ++SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR") ++ ++# systemd.swap kernel cmdline arguments is not supported on RHEL 8, see ++# 567a5307601728c618546c584f63307283fa8def ++ ++# Possible TODO ++# - combine the rootfs & usrfs arguments and mix them with fstab entries ++# - systemd.volatile= ++: "fstab-generator: kernel args - root= + rootfstype= + rootflags=" ++# shellcheck disable=SC2034 ++EXPECTED_FSTAB=( ++ "/dev/disk/by-label/rootfs / ext4 noexec,ro 0 1" ++) ++CMDLINE="root=LABEL=rootfs rootfstype=ext4 rootflags=noexec" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++# The /proc/cmdline here is a dummy value to tell the in_initrd_host() function ++# we're parsing host's fstab, but it's all on the kernel cmdline instead ++SYSTEMD_IN_INITRD=1 SYSTEMD_SYSROOT_FSTAB=/proc/cmdline check_fstab_mount_units EXPECTED_FSTAB "$OUT_DIR" ++ ++# This is a very basic sanity test that involves manual checks, since adding it ++# to the check_fstab_mount_units() function would make it way too complex ++# (yet another possible TODO) ++: "fstab-generator: kernel args - mount.usr= + mount.usrfstype= + mount.usrflags=" ++CMDLINE="mount.usr=UUID=be780f43-8803-4a76-9732-02ceda6e9808 mount.usrfstype=ext4 mount.usrflags=noexec,nodev" ++SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" ++cat "$OUT_DIR/normal/sysroot-usr.mount" ++# We don't do the /sysusr/usr/ -> /sysroot/usr/ dance on RHEL 8, see ++# 29a24ab28e9790680348b1ffab653a321fa49a67 ++grep -qE "^What=/dev/disk/by-uuid/be780f43-8803-4a76-9732-02ceda6e9808$" "$OUT_DIR/normal/sysroot-usr.mount" ++grep -qE "^Where=/sysroot/usr$" "$OUT_DIR/normal/sysroot-usr.mount" ++grep -qE "^Type=ext4$" "$OUT_DIR/normal/sysroot-usr.mount" ++grep -qE "^Options=noexec,nodev,ro$" "$OUT_DIR/normal/sysroot-usr.mount" ++link_eq "$OUT_DIR/normal/initrd-fs.target.requires/sysroot-usr.mount" "../sysroot-usr.mount" +diff --git a/test/TEST-81-GENERATORS/testsuite.sh b/test/TEST-81-GENERATORS/testsuite.sh +new file mode 100755 +index 0000000000..13c767e490 +--- /dev/null ++++ b/test/TEST-81-GENERATORS/testsuite.sh +@@ -0,0 +1,14 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -eux ++set -o pipefail ++ ++: >/failed ++ ++for script in "${0%.sh}".*.sh; do ++ echo "Running $script" ++ "./$script" ++done ++ ++touch /testok ++rm /failed +diff --git a/test/test-functions b/test/test-functions +index f0cf6f8575..2345ab6e8a 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff dirname readlink" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/SOURCES/0989-resolved-actually-check-authenticated-flag-of-SOA-tr.patch b/SOURCES/0989-resolved-actually-check-authenticated-flag-of-SOA-tr.patch new file mode 100644 index 0000000..6a702d4 --- /dev/null +++ b/SOURCES/0989-resolved-actually-check-authenticated-flag-of-SOA-tr.patch @@ -0,0 +1,37 @@ +From c3a86a3ab06713e865db694a80c0c5034ab902af Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 20 Dec 2023 16:44:14 +0100 +Subject: [PATCH] resolved: actually check authenticated flag of SOA + transaction + +Fixes #25676 + +(cherry picked from commit 3b4cc1437b51fcc0b08da8cc3f5d1175eed25eb1) + +Resolves: RHEL-6213 +--- + src/resolve/resolved-dns-transaction.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index c975215468..6f614d7493 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -2520,7 +2520,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * + if (r == 0) + continue; + +- return t->answer_authenticated; ++ return dt->answer_authenticated; + } + + return true; +@@ -2550,7 +2550,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * + * RR for us. This means we are not at a zone cut. In + * this case, we require authentication if the SOA + * lookup was authenticated too. */ +- return t->answer_authenticated; ++ return dt->answer_authenticated; + } + + return true; diff --git a/SOURCES/0990-fd-util-rework-how-we-determine-highest-possible-fd.patch b/SOURCES/0990-fd-util-rework-how-we-determine-highest-possible-fd.patch new file mode 100644 index 0000000..f976e78 --- /dev/null +++ b/SOURCES/0990-fd-util-rework-how-we-determine-highest-possible-fd.patch @@ -0,0 +1,70 @@ +From 1b547e500207a469a533d819db5b7c6c22516ec3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 17 Jan 2019 12:23:21 +0100 +Subject: [PATCH] fd-util: rework how we determine highest possible fd + +(cherry picked from commit 498e265df1c63212ec1a0991c135877a23f1ba4f) + +Related: RHEL-18302 +--- + src/basic/fd-util.c | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) + +diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c +index e085dc23b4..fea93d2039 100644 +--- a/src/basic/fd-util.c ++++ b/src/basic/fd-util.c +@@ -188,6 +188,27 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) { + return false; + } + ++static int get_max_fd(void) { ++ struct rlimit rl; ++ rlim_t m; ++ ++ /* Return the highest possible fd, based RLIMIT_NOFILE, but enforcing FD_SETSIZE-1 as lower boundary ++ * and INT_MAX as upper boundary. */ ++ ++ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) ++ return -errno; ++ ++ m = MAX(rl.rlim_cur, rl.rlim_max); ++ if (m < FD_SETSIZE) /* Let's always cover at least 1024 fds */ ++ return FD_SETSIZE-1; ++ ++ if (m == RLIM_INFINITY || m > INT_MAX) /* Saturate on overflow. After all fds are "int", hence can ++ * never be above INT_MAX */ ++ return INT_MAX; ++ ++ return (int) (m - 1); ++} ++ + int close_all_fds(const int except[], size_t n_except) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; +@@ -197,20 +218,14 @@ int close_all_fds(const int except[], size_t n_except) { + + d = opendir("/proc/self/fd"); + if (!d) { +- struct rlimit rl; + int fd, max_fd; + +- /* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd +- * table */ +- +- assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0); +- +- if (rl.rlim_max == 0) +- return -EINVAL; ++ /* When /proc isn't available (for example in chroots) the fallback is brute forcing through ++ * the fd table */ + +- /* Let's take special care if the resource limit is set to unlimited, or actually larger than the range +- * of 'int'. Let's avoid implicit overflows. */ +- max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1); ++ max_fd = get_max_fd(); ++ if (max_fd < 0) ++ return max_fd; + + for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) { + int q; diff --git a/SOURCES/0991-basic-fd-util-refuse-infinite-loop-in-close_all_fds.patch b/SOURCES/0991-basic-fd-util-refuse-infinite-loop-in-close_all_fds.patch new file mode 100644 index 0000000..e7d679e --- /dev/null +++ b/SOURCES/0991-basic-fd-util-refuse-infinite-loop-in-close_all_fds.patch @@ -0,0 +1,70 @@ +From 957edb063f3e9751bbdc05bd973bb2190ab0e917 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 15 Mar 2019 15:13:25 +0100 +Subject: [PATCH] basic/fd-util: refuse "infinite" loop in close_all_fds() + +I had a test machine with ulimit -n set to 1073741816 through pam +("session required pam_limits.so set_all", which copies the limits from PID 1, +left over from testing of #10921). + +test-execute would "hang" and then fail with a timeout when running +exec-inaccessiblepaths-proc.service. It turns out that the problem was in +close_all_fds(), which would go to the fallback path of doing close() +1073741813 times. Let's just fail if we hit this case. This only matters +for cases where both /proc is inaccessible, and the *soft* limit has been +raised. + + (gdb) bt + #0 0x00007f7e2e73fdc8 in close () from target:/lib64/libc.so.6 + #1 0x00007f7e2e42cdfd in close_nointr () + from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so + #2 0x00007f7e2e42d525 in close_all_fds () + from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so + #3 0x0000000000426e53 in exec_child () + #4 0x0000000000429578 in exec_spawn () + #5 0x00000000004ce1ab in service_spawn () + #6 0x00000000004cff77 in service_enter_start () + #7 0x00000000004d028f in service_enter_start_pre () + #8 0x00000000004d16f2 in service_start () + #9 0x00000000004568f4 in unit_start () + #10 0x0000000000416987 in test () + #11 0x0000000000417632 in test_exec_inaccessiblepaths () + #12 0x0000000000419362 in run_tests () + #13 0x0000000000419632 in main () + +(cherry picked from commit 6a461d1f59850ff27bd254a3b71fe9ade0523e76) + +Related: RHEL-18302 +--- + src/basic/fd-util.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c +index fea93d2039..5d0df11d7e 100644 +--- a/src/basic/fd-util.c ++++ b/src/basic/fd-util.c +@@ -24,6 +24,10 @@ + #include "stdio-util.h" + #include "util.h" + ++/* The maximum number of iterations in the loop to close descriptors in the fallback case ++ * when /proc/self/fd/ is inaccessible. */ ++#define MAX_FD_LOOP_LIMIT (1024*1024) ++ + int close_nointr(int fd) { + assert(fd >= 0); + +@@ -227,6 +231,13 @@ int close_all_fds(const int except[], size_t n_except) { + if (max_fd < 0) + return max_fd; + ++ /* Refuse to do the loop over more too many elements. It's better to fail immediately than to ++ * spin the CPU for a long time. */ ++ if (max_fd > MAX_FD_LOOP_LIMIT) ++ return log_debug_errno(EPERM, ++ "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.", ++ max_fd); ++ + for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) { + int q; + diff --git a/SOURCES/0992-fd-util-split-out-inner-fallback-loop-of-close_all_f.patch b/SOURCES/0992-fd-util-split-out-inner-fallback-loop-of-close_all_f.patch new file mode 100644 index 0000000..faa1977 --- /dev/null +++ b/SOURCES/0992-fd-util-split-out-inner-fallback-loop-of-close_all_f.patch @@ -0,0 +1,110 @@ +From c2665abd4cae74f262d9a522b94528841ad141d2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 12 Oct 2021 15:53:27 +0200 +Subject: [PATCH] fd-util: split out inner fallback loop of close_all_fds() as + close_all_fds_without_malloc() + +(cherry picked from commit 11966552a88039869972ca4b450f622664bd1c5e) + +Related: RHEL-18302 +--- + src/basic/fd-util.c | 63 +++++++++++++++++++++++++-------------------- + src/basic/fd-util.h | 1 + + 2 files changed, 36 insertions(+), 28 deletions(-) + +diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c +index 5d0df11d7e..7e4611dfda 100644 +--- a/src/basic/fd-util.c ++++ b/src/basic/fd-util.c +@@ -213,44 +213,51 @@ static int get_max_fd(void) { + return (int) (m - 1); + } + +-int close_all_fds(const int except[], size_t n_except) { +- _cleanup_closedir_ DIR *d = NULL; +- struct dirent *de; +- int r = 0; ++int close_all_fds_without_malloc(const int except[], size_t n_except) { ++ int max_fd, r = 0; + + assert(n_except == 0 || except); + +- d = opendir("/proc/self/fd"); +- if (!d) { +- int fd, max_fd; ++ /* This is the inner fallback core of close_all_fds(). This never calls malloc() or opendir() or so ++ * and hence is safe to be called in signal handler context. Most users should call close_all_fds(), ++ * but when we assume we are called from signal handler context, then use this simpler call ++ * instead. */ + +- /* When /proc isn't available (for example in chroots) the fallback is brute forcing through +- * the fd table */ ++ max_fd = get_max_fd(); ++ if (max_fd < 0) ++ return max_fd; + +- max_fd = get_max_fd(); +- if (max_fd < 0) +- return max_fd; ++ /* Refuse to do the loop over more too many elements. It's better to fail immediately than to ++ * spin the CPU for a long time. */ ++ if (max_fd > MAX_FD_LOOP_LIMIT) ++ return log_debug_errno(EPERM, ++ "Refusing to loop over %d potential fds.", ++ max_fd); + +- /* Refuse to do the loop over more too many elements. It's better to fail immediately than to +- * spin the CPU for a long time. */ +- if (max_fd > MAX_FD_LOOP_LIMIT) +- return log_debug_errno(EPERM, +- "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.", +- max_fd); ++ for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) { ++ int q; + +- for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) { +- int q; ++ if (fd_in_set(fd, except, n_except)) ++ continue; + +- if (fd_in_set(fd, except, n_except)) +- continue; ++ q = close_nointr(fd); ++ if (q < 0 && q != -EBADF && r >= 0) ++ r = q; ++ } + +- q = close_nointr(fd); +- if (q < 0 && q != -EBADF && r >= 0) +- r = q; +- } ++ return r; ++} + +- return r; +- } ++int close_all_fds(const int except[], size_t n_except) { ++ _cleanup_closedir_ DIR *d = NULL; ++ struct dirent *de; ++ int r = 0; ++ ++ assert(n_except == 0 || except); ++ ++ d = opendir("/proc/self/fd"); ++ if (!d) ++ return close_all_fds_without_malloc(except, n_except); /* ultimate fallback if /proc/ is not available */ + + FOREACH_DIRENT(de, d, return -errno) { + int fd = -1, q; +diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h +index 8adc959da8..b2837d3588 100644 +--- a/src/basic/fd-util.h ++++ b/src/basic/fd-util.h +@@ -54,6 +54,7 @@ int fd_nonblock(int fd, bool nonblock); + int fd_cloexec(int fd, bool cloexec); + + int close_all_fds(const int except[], size_t n_except); ++int close_all_fds_without_malloc(const int except[], size_t n_except); + + int same_fd(int a, int b); + diff --git a/SOURCES/0993-exec-util-use-close_all_fds_without_malloc-from-free.patch b/SOURCES/0993-exec-util-use-close_all_fds_without_malloc-from-free.patch new file mode 100644 index 0000000..f82bbdb --- /dev/null +++ b/SOURCES/0993-exec-util-use-close_all_fds_without_malloc-from-free.patch @@ -0,0 +1,29 @@ +From 140e598dcf6b86007b1daba42c31253521964b2e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 29 Jul 2021 16:50:44 +0200 +Subject: [PATCH] exec-util: use close_all_fds_without_malloc() from freeze() + +(cherry picked from commit ab27b2fe56c6c4bd0295b248448adb1c698e9284) + +Resolves: RHEL-18302 +--- + src/basic/process-util.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index 6016d83d41..9e2237375d 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -991,8 +991,10 @@ _noreturn_ void freeze(void) { + + log_close(); + +- /* Make sure nobody waits for us on a socket anymore */ +- close_all_fds(NULL, 0); ++ /* Make sure nobody waits for us (i.e. on one of our sockets) anymore. Note that we use ++ * close_all_fds_without_malloc() instead of plain close_all_fds() here, since we want this function ++ * to be compatible with being called from signal handlers. */ ++ (void) close_all_fds_without_malloc(NULL, 0); + + sync(); + diff --git a/SOURCES/0994-ci-use-source-git-automation-composite-Action.patch b/SOURCES/0994-ci-use-source-git-automation-composite-Action.patch new file mode 100644 index 0000000..1ca70f2 --- /dev/null +++ b/SOURCES/0994-ci-use-source-git-automation-composite-Action.patch @@ -0,0 +1,185 @@ +From 5d0fc67965b48e05c28d0993368a3982efd03b4b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 12 Jan 2024 16:01:43 +0100 +Subject: [PATCH] ci: use source-git-automation composite Action + +This will allow us maintain the source-git automation in separate repo +and reduce the duplication of the code and noise in the systemd repo. + +rhel-only + +Related: RHEL-1087 +--- + .../source-git-automation-on-demand.yml | 55 ++------------ + .github/workflows/source-git-automation.yml | 72 ++----------------- + 2 files changed, 9 insertions(+), 118 deletions(-) + +diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml +index 948708916d..0c72f9f210 100644 +--- a/.github/workflows/source-git-automation-on-demand.yml ++++ b/.github/workflows/source-git-automation-on-demand.yml +@@ -1,5 +1,3 @@ +---- +- + name: Source git Automation Scheduled/On Demand + on: + schedule: +@@ -59,61 +57,16 @@ jobs: + pr-number: ${{ inputs.pr-number == 0 && fromJSON(needs.gather-pull-requests.outputs.pr-numbers) || fromJSON(needs.gather-pull-requests.outputs.pr-numbers-manual) }} + + permissions: ++ # required for merging PRs + contents: write +- statuses: write +- checks: write ++ # required for PR comments and setting labels + pull-requests: write + + steps: +- - name: Repository checkout +- uses: actions/checkout@v3 +- +- - id: metadata +- name: Gather Pull Request Metadata +- uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1 ++ - name: Source-git Automation ++ uses: redhat-plumbers-in-action/source-git-automation@v1 + with: + pr-number: ${{ matrix.pr-number }} +- +- - if: ${{ !cancelled() }} +- id: commit-linter +- name: Lint Commits +- uses: redhat-plumbers-in-action/advanced-commit-linter@v2 +- with: +- pr-metadata: ${{ steps.metadata.outputs.metadata }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- # Validates tracker, changes tracker status, updates PR title +- - if: ${{ !cancelled() }} +- id: tracker-validator +- name: Validate Tracker +- uses: redhat-plumbers-in-action/tracker-validator@v1 +- with: +- pr-metadata: ${{ steps.metadata.outputs.metadata }} +- component: systemd +- tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} +- tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} +- bugzilla-instance: https://bugzilla.redhat.com +- bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} +- jira-instance: https://issues.redhat.com +- jira-api-token: ${{ secrets.JIRA_API_TOKEN }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- - if: ${{ !cancelled() }} +- name: Pull Request Validator +- uses: redhat-plumbers-in-action/pull-request-validator@v1 +- with: +- pr-metadata: ${{ steps.metadata.outputs.metadata }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- - id: auto-merge +- name: Auto Merge +- uses: redhat-plumbers-in-action/auto-merge@v1 +- with: +- pr-metadata: ${{ steps.metadata.outputs.metadata }} +- tracker: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} +- tracker-type: ${{ fromJSON(steps.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} +- bugzilla-instance: https://bugzilla.redhat.com + bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} +- jira-instance: https://issues.redhat.com + jira-api-token: ${{ secrets.JIRA_API_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 95819baa8b..b6cefa67b1 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -26,83 +26,21 @@ jobs: + with: + name: pr-metadata + +- commit-linter: ++ source-git-automation: + needs: [ download-metadata ] + runs-on: ubuntu-latest + +- outputs: +- validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} +- +- permissions: +- statuses: write +- checks: write +- pull-requests: write +- +- steps: +- - id: commit-linter +- name: Lint Commits +- uses: redhat-plumbers-in-action/advanced-commit-linter@v2 +- with: +- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- # Validates tracker, changes tracker status, updates PR title +- tracker-validator: +- if: ${{ !cancelled() }} +- needs: [ download-metadata, commit-linter ] +- runs-on: ubuntu-latest +- +- permissions: +- checks: write +- pull-requests: write +- +- steps: +- - name: Validate Tracker +- uses: redhat-plumbers-in-action/tracker-validator@v1 +- with: +- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} +- component: systemd +- tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} +- tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} +- bugzilla-instance: https://bugzilla.redhat.com +- bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} +- jira-instance: https://issues.redhat.com +- jira-api-token: ${{ secrets.JIRA_API_TOKEN }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- pull-request-validator: +- needs: [ download-metadata ] +- runs-on: ubuntu-latest +- +- permissions: +- checks: write +- pull-requests: write +- +- steps: +- - name: Pull Request Validator +- uses: redhat-plumbers-in-action/pull-request-validator@v1 +- with: +- pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} +- token: ${{ secrets.GITHUB_TOKEN }} +- +- auto-merge: +- needs: [ download-metadata, commit-linter, tracker-validator, pull-request-validator ] +- runs-on: ubuntu-latest +- + permissions: ++ # required for merging PRs + contents: write +- checks: write ++ # required for PR comments and setting labels + pull-requests: write + + steps: +- - name: Auto Merge +- uses: redhat-plumbers-in-action/auto-merge@v1 ++ - name: Source-git Automation ++ uses: redhat-plumbers-in-action/source-git-automation@v1 + with: + pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} +- tracker: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.id }} +- tracker-type: ${{ fromJSON(needs.commit-linter.outputs.validated-pr-metadata).validation.tracker.type }} +- bugzilla-instance: https://bugzilla.redhat.com + bugzilla-api-token: ${{ secrets.BUGZILLA_API_TOKEN }} +- jira-instance: https://issues.redhat.com + jira-api-token: ${{ secrets.JIRA_API_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SOURCES/0995-ci-increase-the-cron-interval-to-45-minutes.patch b/SOURCES/0995-ci-increase-the-cron-interval-to-45-minutes.patch new file mode 100644 index 0000000..439ff3e --- /dev/null +++ b/SOURCES/0995-ci-increase-the-cron-interval-to-45-minutes.patch @@ -0,0 +1,29 @@ +From fd21fb2e2e3bbbd937d120197b11c740d608fb19 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 12 Jan 2024 16:03:09 +0100 +Subject: [PATCH] ci: increase the cron interval to 45 minutes + +This should help us to avoid hitting the rate limit on the GitHub API. + +rhel-only + +Related: RHEL-1087 +--- + .github/workflows/source-git-automation-on-demand.yml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/source-git-automation-on-demand.yml b/.github/workflows/source-git-automation-on-demand.yml +index 0c72f9f210..6aeee51e6d 100644 +--- a/.github/workflows/source-git-automation-on-demand.yml ++++ b/.github/workflows/source-git-automation-on-demand.yml +@@ -1,8 +1,8 @@ + name: Source git Automation Scheduled/On Demand + on: + schedule: +- # Workflow runs every 15 minutes +- - cron: '*/15 * * * *' ++ # Workflow runs every 45 minutes ++ - cron: '*/45 * * * *' + workflow_dispatch: + inputs: + pr-number: diff --git a/SOURCES/0996-ci-add-all-Z-Stream-versions-to-array-of-allowed-ver.patch b/SOURCES/0996-ci-add-all-Z-Stream-versions-to-array-of-allowed-ver.patch new file mode 100644 index 0000000..673fc84 --- /dev/null +++ b/SOURCES/0996-ci-add-all-Z-Stream-versions-to-array-of-allowed-ver.patch @@ -0,0 +1,31 @@ +From 42e3739198e41c65b986f69a53bc6c93f7e112be Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 12 Jan 2024 16:04:22 +0100 +Subject: [PATCH] ci: add all Z-Stream versions to array of allowed versions + +rhel-only + +Related: RHEL-1087 +--- + .github/tracker-validator.yml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml +index 500dce3d92..b09f702dd9 100644 +--- a/.github/tracker-validator.yml ++++ b/.github/tracker-validator.yml +@@ -7,8 +7,14 @@ products: + - Red Hat Enterprise Linux 8 + - CentOS Stream 8 + - rhel-8.2.0 ++ - rhel-8.2.0.z + - rhel-8.4.0 ++ - rhel-8.4.0.z + - rhel-8.6.0 ++ - rhel-8.6.0.z + - rhel-8.8.0 ++ - rhel-8.8.0.z + - rhel-8.9.0 ++ - rhel-8.9.0.z + - rhel-8.10.0 ++ - rhel-8.10.0.z diff --git a/SOURCES/0997-tree-wide-always-declare-bitflag-enums-the-same-way.patch b/SOURCES/0997-tree-wide-always-declare-bitflag-enums-the-same-way.patch new file mode 100644 index 0000000..774b0fe --- /dev/null +++ b/SOURCES/0997-tree-wide-always-declare-bitflag-enums-the-same-way.patch @@ -0,0 +1,215 @@ +From dd3c13f364e03e843d838bf925a5fc85513343ed Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 7 Jan 2019 17:48:28 +0100 +Subject: [PATCH] tree-wide: always declare bitflag enums the same way + +let's always use the 1 << x syntax. No change of behaviour or even of +the compiled binary. + +(cherry picked from commit be0b7a1a66fd269b644124c4633088ab2224d1fb) + +Resolves: RHEL-2857 +--- + src/basic/btrfs-util.h | 16 ++++++++-------- + src/basic/cgroup-util.h | 6 +++--- + src/basic/extract-word.h | 12 ++++++------ + src/basic/unit-name.h | 10 +++++----- + src/libsystemd/sd-bus/bus-dump.h | 4 ++-- + src/libsystemd/sd-bus/bus-protocol.h | 12 ++++++------ + src/login/logind-inhibit.h | 18 +++++++++--------- + src/resolve/resolved-dns-answer.h | 10 +++++----- + 8 files changed, 44 insertions(+), 44 deletions(-) + +diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h +index a594387b5a..967627991f 100644 +--- a/src/basic/btrfs-util.h ++++ b/src/basic/btrfs-util.h +@@ -27,17 +27,17 @@ typedef struct BtrfsQuotaInfo { + } BtrfsQuotaInfo; + + typedef enum BtrfsSnapshotFlags { +- BTRFS_SNAPSHOT_FALLBACK_COPY = 1, /* If the source isn't a subvolume, reflink everything */ +- BTRFS_SNAPSHOT_READ_ONLY = 2, +- BTRFS_SNAPSHOT_RECURSIVE = 4, +- BTRFS_SNAPSHOT_QUOTA = 8, +- BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 16, /* If the destination doesn't support subvolumes, reflink/copy instead */ +- BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 32, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */ ++ BTRFS_SNAPSHOT_FALLBACK_COPY = 1 << 0, /* If the source isn't a subvolume, reflink everything */ ++ BTRFS_SNAPSHOT_READ_ONLY = 1 << 1, ++ BTRFS_SNAPSHOT_RECURSIVE = 1 << 2, ++ BTRFS_SNAPSHOT_QUOTA = 1 << 3, ++ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 1 << 4, /* If the destination doesn't support subvolumes, reflink/copy instead */ ++ BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 1 << 5, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */ + } BtrfsSnapshotFlags; + + typedef enum BtrfsRemoveFlags { +- BTRFS_REMOVE_RECURSIVE = 1, +- BTRFS_REMOVE_QUOTA = 2, ++ BTRFS_REMOVE_RECURSIVE = 1 << 0, ++ BTRFS_REMOVE_QUOTA = 1 << 1, + } BtrfsRemoveFlags; + + int btrfs_is_filesystem(int fd); +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index 1210b38a83..65d2dbd4b6 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -136,9 +136,9 @@ int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); + int cg_read_subgroup(DIR *d, char **fn); + + typedef enum CGroupFlags { +- CGROUP_SIGCONT = 1, +- CGROUP_IGNORE_SELF = 2, +- CGROUP_REMOVE = 4, ++ CGROUP_SIGCONT = 1 << 0, ++ CGROUP_IGNORE_SELF = 1 << 1, ++ CGROUP_REMOVE = 1 << 2, + } CGroupFlags; + + typedef void (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata); +diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h +index 8c63b7c306..705ebbe95b 100644 +--- a/src/basic/extract-word.h ++++ b/src/basic/extract-word.h +@@ -4,12 +4,12 @@ + #include "macro.h" + + typedef enum ExtractFlags { +- EXTRACT_RELAX = 1, +- EXTRACT_CUNESCAPE = 2, +- EXTRACT_CUNESCAPE_RELAX = 4, +- EXTRACT_QUOTES = 8, +- EXTRACT_DONT_COALESCE_SEPARATORS = 16, +- EXTRACT_RETAIN_ESCAPE = 32, ++ EXTRACT_RELAX = 1 << 0, ++ EXTRACT_CUNESCAPE = 1 << 1, ++ EXTRACT_CUNESCAPE_RELAX = 1 << 2, ++ EXTRACT_QUOTES = 1 << 3, ++ EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 4, ++ EXTRACT_RETAIN_ESCAPE = 1 << 5, + } ExtractFlags; + + int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); +diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h +index 602295af8f..7df532bbc8 100644 +--- a/src/basic/unit-name.h ++++ b/src/basic/unit-name.h +@@ -9,9 +9,9 @@ + #define UNIT_NAME_MAX 256 + + typedef enum UnitNameFlags { +- UNIT_NAME_PLAIN = 1, /* Allow foo.service */ +- UNIT_NAME_INSTANCE = 2, /* Allow foo@bar.service */ +- UNIT_NAME_TEMPLATE = 4, /* Allow foo@.service */ ++ UNIT_NAME_PLAIN = 1 << 0, /* Allow foo.service */ ++ UNIT_NAME_INSTANCE = 1 << 1, /* Allow foo@bar.service */ ++ UNIT_NAME_TEMPLATE = 1 << 2, /* Allow foo@.service */ + UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, + } UnitNameFlags; + +@@ -53,8 +53,8 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha + int unit_name_to_path(const char *name, char **ret); + + typedef enum UnitNameMangle { +- UNIT_NAME_MANGLE_GLOB = 1, +- UNIT_NAME_MANGLE_WARN = 2, ++ UNIT_NAME_MANGLE_GLOB = 1 << 0, ++ UNIT_NAME_MANGLE_WARN = 1 << 1, + } UnitNameMangle; + + int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret); +diff --git a/src/libsystemd/sd-bus/bus-dump.h b/src/libsystemd/sd-bus/bus-dump.h +index 8e47411a45..7c1f81edec 100644 +--- a/src/libsystemd/sd-bus/bus-dump.h ++++ b/src/libsystemd/sd-bus/bus-dump.h +@@ -10,8 +10,8 @@ + #include "sd-bus.h" + + enum { +- BUS_MESSAGE_DUMP_WITH_HEADER = 1, +- BUS_MESSAGE_DUMP_SUBTREE_ONLY = 2, ++ BUS_MESSAGE_DUMP_WITH_HEADER = 1 << 0, ++ BUS_MESSAGE_DUMP_SUBTREE_ONLY = 1 << 1, + }; + + int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags); +diff --git a/src/libsystemd/sd-bus/bus-protocol.h b/src/libsystemd/sd-bus/bus-protocol.h +index 20d19d4022..f96d4b39aa 100644 +--- a/src/libsystemd/sd-bus/bus-protocol.h ++++ b/src/libsystemd/sd-bus/bus-protocol.h +@@ -57,9 +57,9 @@ enum { + /* Flags */ + + enum { +- BUS_MESSAGE_NO_REPLY_EXPECTED = 1, +- BUS_MESSAGE_NO_AUTO_START = 2, +- BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION = 4, ++ BUS_MESSAGE_NO_REPLY_EXPECTED = 1 << 0, ++ BUS_MESSAGE_NO_AUTO_START = 1 << 1, ++ BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION = 1 << 2, + }; + + /* Header fields */ +@@ -81,9 +81,9 @@ enum { + /* RequestName parameters */ + + enum { +- BUS_NAME_ALLOW_REPLACEMENT = 1, +- BUS_NAME_REPLACE_EXISTING = 2, +- BUS_NAME_DO_NOT_QUEUE = 4 ++ BUS_NAME_ALLOW_REPLACEMENT = 1 << 0, ++ BUS_NAME_REPLACE_EXISTING = 1 << 1, ++ BUS_NAME_DO_NOT_QUEUE = 1 << 2, + }; + + /* RequestName returns */ +diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h +index d358a48559..650587106d 100644 +--- a/src/login/logind-inhibit.h ++++ b/src/login/logind-inhibit.h +@@ -4,15 +4,15 @@ + typedef struct Inhibitor Inhibitor; + + typedef enum InhibitWhat { +- INHIBIT_SHUTDOWN = 1, +- INHIBIT_SLEEP = 2, +- INHIBIT_IDLE = 4, +- INHIBIT_HANDLE_POWER_KEY = 8, +- INHIBIT_HANDLE_SUSPEND_KEY = 16, +- INHIBIT_HANDLE_HIBERNATE_KEY = 32, +- INHIBIT_HANDLE_LID_SWITCH = 64, +- _INHIBIT_WHAT_MAX = 128, +- _INHIBIT_WHAT_INVALID = -1 ++ INHIBIT_SHUTDOWN = 1 << 0, ++ INHIBIT_SLEEP = 1 << 1, ++ INHIBIT_IDLE = 1 << 2, ++ INHIBIT_HANDLE_POWER_KEY = 1 << 3, ++ INHIBIT_HANDLE_SUSPEND_KEY = 1 << 4, ++ INHIBIT_HANDLE_HIBERNATE_KEY = 1 << 5, ++ INHIBIT_HANDLE_LID_SWITCH = 1 << 6, ++ _INHIBIT_WHAT_MAX = 1 << 7, ++ _INHIBIT_WHAT_INVALID = -1 + } InhibitWhat; + + typedef enum InhibitMode { +diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h +index aff594a00e..cc90a82529 100644 +--- a/src/resolve/resolved-dns-answer.h ++++ b/src/resolve/resolved-dns-answer.h +@@ -15,11 +15,11 @@ typedef struct DnsAnswerItem DnsAnswerItem; + * Note that we usually encode the empty DnsAnswer object as a simple NULL. */ + + typedef enum DnsAnswerFlags { +- DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */ +- DNS_ANSWER_CACHEABLE = 2, /* Item is subject to caching */ +- DNS_ANSWER_SHARED_OWNER = 4, /* For mDNS: RRset may be owner by multiple peers */ +- DNS_ANSWER_CACHE_FLUSH = 8, /* For mDNS: sets cache-flush bit in the rrclass of response records */ +- DNS_ANSWER_GOODBYE = 16, /* For mDNS: item is subject to disappear */ ++ DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */ ++ DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */ ++ DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */ ++ DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */ ++ DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */ + } DnsAnswerFlags; + + struct DnsAnswerItem { diff --git a/SOURCES/0998-login-Add-KEY_RESTART-handling.patch b/SOURCES/0998-login-Add-KEY_RESTART-handling.patch new file mode 100644 index 0000000..46ac8b3 --- /dev/null +++ b/SOURCES/0998-login-Add-KEY_RESTART-handling.patch @@ -0,0 +1,343 @@ +From d3072cec8cec84c6cb6e5771a5084e64f78c7e80 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 14 Aug 2020 13:10:18 +0200 +Subject: [PATCH] login: Add KEY_RESTART handling + +KEY_RESTART is widely used in Linux to indicate device reboot. +So lets handle it in the same fashion as KEY_POWER. + +Signed-off-by: Robert Marko +(cherry picked from commit adbb2b6afed7858f64f5b940579f6efe79eee997) + +Resolves: RHEL-2857 +--- + man/logind.conf.xml | 26 +++++++++++++++---------- + src/login/logind-button.c | 25 +++++++++++++++++++----- + src/login/logind-core.c | 4 ++++ + src/login/logind-dbus.c | 1 + + src/login/logind-gperf.gperf | 2 ++ + src/login/logind-inhibit.c | 14 ++++++++++++- + src/login/logind-inhibit.h | 3 ++- + src/login/logind.conf.in | 2 ++ + src/login/logind.h | 2 ++ + src/login/org.freedesktop.login1.policy | 11 +++++++++++ + src/systemd/sd-messages.h | 2 ++ + 11 files changed, 75 insertions(+), 17 deletions(-) + +diff --git a/man/logind.conf.xml b/man/logind.conf.xml +index 00b5b1f2e8..56981c1837 100644 +--- a/man/logind.conf.xml ++++ b/man/logind.conf.xml +@@ -202,10 +202,11 @@ + HandleLidSwitch= + HandleLidSwitchExternalPower= + HandleLidSwitchDocked= ++ HandleRebootKey= + + Controls how logind shall handle the +- system power and sleep keys and the lid switch to trigger +- actions such as system power-off or suspend. Can be one of ++ system power, reboot and sleep keys and the lid switch to trigger ++ actions such as system power-off, reboot or suspend. Can be one of + ignore, + poweroff, + reboot, +@@ -222,7 +223,8 @@ + in the respective event. Only input devices with the + power-switch udev tag will be watched for + key/lid switch events. HandlePowerKey= +- defaults to poweroff. ++ defaults to poweroff, HandleRebootKey= ++ defaults to reboot. + HandleSuspendKey= and + HandleLidSwitch= default to + suspend. +@@ -243,7 +245,8 @@ + A different application may disable logind's handling of system power and + sleep keys and the lid switch by taking a low-level inhibitor lock + (handle-power-key, handle-suspend-key, +- handle-hibernate-key, handle-lid-switch). ++ handle-hibernate-key, handle-lid-switch, ++ handle-reboot-switch). + This is most commonly used by graphical desktop environments + to take over suspend and hibernation handling, and to use their own configuration + mechanisms. If a low-level inhibitor lock is taken, logind will not take any +@@ -256,20 +259,23 @@ + SuspendKeyIgnoreInhibited= + HibernateKeyIgnoreInhibited= + LidSwitchIgnoreInhibited= ++ RebootKeyIgnoreInhibited= + + Controls whether actions that systemd-logind +- takes when the power and sleep keys and the lid switch are triggered are subject +- to high-level inhibitor locks ("shutdown", "sleep", "idle"). Low level inhibitor ++ takes when the power, reboot and sleep keys and the lid switch are triggered are subject ++ to high-level inhibitor locks ("shutdown", "reboot", "sleep", "idle"). Low level inhibitor + locks (handle-power-key, handle-suspend-key, +- handle-hibernate-key, handle-lid-switch), ++ handle-hibernate-key, handle-lid-switch, ++ handle-reboot-key), + are always honored, irrespective of this setting. + + These settings take boolean arguments. If no, the + inhibitor locks taken by applications are respected. If yes, +- "shutdown", "sleep", and "idle" inhibitor locks are ignored. ++ "shutdown", "reboot" "sleep", and "idle" inhibitor locks are ignored. + PowerKeyIgnoreInhibited=, +- SuspendKeyIgnoreInhibited=, and +- HibernateKeyIgnoreInhibited= default to no. ++ SuspendKeyIgnoreInhibited=, ++ HibernateKeyIgnoreInhibited= and ++ RebootKeyIgnoreInhibited= default to no. + LidSwitchIgnoreInhibited= defaults to yes. + This means that when systemd-logind is handling events by + itself (no low level inhibitor locks are taken by another application), the lid +diff --git a/src/login/logind-button.c b/src/login/logind-button.c +index 9944eb2316..48fc004198 100644 +--- a/src/login/logind-button.c ++++ b/src/login/logind-button.c +@@ -15,7 +15,7 @@ + #include "string-util.h" + #include "util.h" + +-#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d)) ++#define CONST_MAX5(a, b, c, d, e) CONST_MAX(CONST_MAX(a, b), CONST_MAX(CONST_MAX(c, d), e)) + + #define ULONG_BITS (sizeof(unsigned long)*8) + +@@ -159,7 +159,20 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u + manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true); + break; + +- /* The kernel is a bit confused here: ++ /* The kernel naming is a bit confusing here: ++ KEY_RESTART was probably introduced for media playback purposes, but ++ is now being predominantly used to indicate device reboot. ++ */ ++ ++ case KEY_RESTART: ++ log_struct(LOG_INFO, ++ LOG_MESSAGE("Reboot key pressed."), ++ "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR); ++ ++ manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true); ++ break; ++ ++ /* The kernel naming is a bit confusing here: + + KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend" + KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate" +@@ -233,7 +246,7 @@ static int button_suitable(Button *b) { + return -errno; + + if (bitset_get(types, EV_KEY)) { +- unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1]; ++ unsigned long keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1]; + + if (ioctl(b->fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0) + return -errno; +@@ -241,7 +254,8 @@ static int button_suitable(Button *b) { + if (bitset_get(keys, KEY_POWER) || + bitset_get(keys, KEY_POWER2) || + bitset_get(keys, KEY_SLEEP) || +- bitset_get(keys, KEY_SUSPEND)) ++ bitset_get(keys, KEY_SUSPEND) || ++ bitset_get(keys, KEY_RESTART)) + return true; + } + +@@ -262,7 +276,7 @@ static int button_suitable(Button *b) { + static int button_set_mask(Button *b) { + unsigned long + types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {}, +- keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {}, ++ keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1] = {}, + switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {}; + struct input_mask mask; + +@@ -287,6 +301,7 @@ static int button_set_mask(Button *b) { + bitset_put(keys, KEY_POWER2); + bitset_put(keys, KEY_SLEEP); + bitset_put(keys, KEY_SUSPEND); ++ bitset_put(keys, KEY_RESTART); + + mask = (struct input_mask) { + .type = EV_KEY, +diff --git a/src/login/logind-core.c b/src/login/logind-core.c +index abe6eecffb..81ec4f2653 100644 +--- a/src/login/logind-core.c ++++ b/src/login/logind-core.c +@@ -39,10 +39,12 @@ void manager_reset_config(Manager *m) { + m->handle_lid_switch = HANDLE_SUSPEND; + m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID; + m->handle_lid_switch_docked = HANDLE_IGNORE; ++ m->handle_reboot_key = HANDLE_REBOOT; + m->power_key_ignore_inhibited = false; + m->suspend_key_ignore_inhibited = false; + m->hibernate_key_ignore_inhibited = false; + m->lid_switch_ignore_inhibited = true; ++ m->reboot_key_ignore_inhibited = false; + + m->holdoff_timeout_usec = 30 * USEC_PER_SEC; + +@@ -698,6 +700,8 @@ bool manager_all_buttons_ignored(Manager *m) { + return false; + if (m->handle_lid_switch_docked != HANDLE_IGNORE) + return false; ++ if (m->handle_reboot_key != HANDLE_IGNORE) ++ return false; + + return true; + } +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index dbac406035..61fd47999d 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -2616,6 +2616,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error + w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : + w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : + w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : ++ w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" : + w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : + "org.freedesktop.login1.inhibit-handle-lid-switch", + NULL, +diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf +index 214ac5c4a3..c49703698a 100644 +--- a/src/login/logind-gperf.gperf ++++ b/src/login/logind-gperf.gperf +@@ -30,10 +30,12 @@ Login.HandleHibernateKey, config_parse_handle_action, 0, offse + Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch) + Login.HandleLidSwitchExternalPower, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep) + Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked) ++Login.HandleRebootKey, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key) + Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited) + Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited) + Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited) + Login.LidSwitchIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, lid_switch_ignore_inhibited) ++Login.RebootKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, reboot_key_ignore_inhibited) + Login.HoldoffTimeoutSec, config_parse_sec, 0, offsetof(Manager, holdoff_timeout_usec) + Login.IdleAction, config_parse_handle_action, 0, offsetof(Manager, idle_action) + Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec) +diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c +index b1f45baaca..27b862e7c4 100644 +--- a/src/login/logind-inhibit.c ++++ b/src/login/logind-inhibit.c +@@ -405,7 +405,15 @@ bool manager_is_inhibited( + } + + const char *inhibit_what_to_string(InhibitWhat w) { +- static thread_local char buffer[97]; ++ static thread_local char buffer[STRLEN( ++ "shutdown:" ++ "sleep:" ++ "idle:" ++ "handle-power-key:" ++ "handle-suspend-key:" ++ "handle-hibernate-key:" ++ "handle-lid-switch:" ++ "handle-reboot-key")+1]; + char *p; + + if (w < 0 || w >= _INHIBIT_WHAT_MAX) +@@ -426,6 +434,8 @@ const char *inhibit_what_to_string(InhibitWhat w) { + p = stpcpy(p, "handle-hibernate-key:"); + if (w & INHIBIT_HANDLE_LID_SWITCH) + p = stpcpy(p, "handle-lid-switch:"); ++ if (w & INHIBIT_HANDLE_REBOOT_KEY) ++ p = stpcpy(p, "handle-reboot-key:"); + + if (p > buffer) + *(p-1) = 0; +@@ -455,6 +465,8 @@ InhibitWhat inhibit_what_from_string(const char *s) { + what |= INHIBIT_HANDLE_HIBERNATE_KEY; + else if (l == 17 && strneq(word, "handle-lid-switch", l)) + what |= INHIBIT_HANDLE_LID_SWITCH; ++ else if (l == 17 && strneq(word, "handle-reboot-key", l)) ++ what |= INHIBIT_HANDLE_REBOOT_KEY; + else + return _INHIBIT_WHAT_INVALID; + } +diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h +index 650587106d..51095a0bde 100644 +--- a/src/login/logind-inhibit.h ++++ b/src/login/logind-inhibit.h +@@ -11,7 +11,8 @@ typedef enum InhibitWhat { + INHIBIT_HANDLE_SUSPEND_KEY = 1 << 4, + INHIBIT_HANDLE_HIBERNATE_KEY = 1 << 5, + INHIBIT_HANDLE_LID_SWITCH = 1 << 6, +- _INHIBIT_WHAT_MAX = 1 << 7, ++ INHIBIT_HANDLE_REBOOT_KEY = 1 << 7, ++ _INHIBIT_WHAT_MAX = 1 << 8, + _INHIBIT_WHAT_INVALID = -1 + } InhibitWhat; + +diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in +index a62c2b0b57..95f2d48d02 100644 +--- a/src/login/logind.conf.in ++++ b/src/login/logind.conf.in +@@ -24,10 +24,12 @@ + #HandleLidSwitch=suspend + #HandleLidSwitchExternalPower=suspend + #HandleLidSwitchDocked=ignore ++#HandleRebootKey=reboot + #PowerKeyIgnoreInhibited=no + #SuspendKeyIgnoreInhibited=no + #HibernateKeyIgnoreInhibited=no + #LidSwitchIgnoreInhibited=yes ++#RebootKeyIgnoreInhibited=no + #HoldoffTimeoutSec=30s + #IdleAction=ignore + #IdleActionSec=30min +diff --git a/src/login/logind.h b/src/login/logind.h +index b9b4a5113f..395306ced3 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -111,11 +111,13 @@ struct Manager { + HandleAction handle_lid_switch; + HandleAction handle_lid_switch_ep; + HandleAction handle_lid_switch_docked; ++ HandleAction handle_reboot_key; + + bool power_key_ignore_inhibited; + bool suspend_key_ignore_inhibited; + bool hibernate_key_ignore_inhibited; + bool lid_switch_ignore_inhibited; ++ bool reboot_key_ignore_inhibited; + + bool remove_ipc; + +diff --git a/src/login/org.freedesktop.login1.policy b/src/login/org.freedesktop.login1.policy +index 83760e1580..882975849e 100644 +--- a/src/login/org.freedesktop.login1.policy ++++ b/src/login/org.freedesktop.login1.policy +@@ -113,6 +113,17 @@ + + + ++ ++ Allow applications to inhibit system handling of the reboot key ++ Authentication is required for an application to inhibit system handling of the reboot key. ++ ++ no ++ yes ++ yes ++ ++ org.freedesktop.login1.inhibit-handle-suspend-key org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch ++ ++ + + Allow non-logged-in user to run programs + Explicit request is required to run programs as a non-logged-in user. +diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h +index 847b698ba4..3e9584c0b2 100644 +--- a/src/systemd/sd-messages.h ++++ b/src/systemd/sd-messages.h +@@ -134,6 +134,8 @@ _SD_BEGIN_DECLARATIONS; + #define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) + #define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) + #define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) ++#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) ++#define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) + #define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) + #define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) + #define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) diff --git a/SOURCES/0999-analyze-security-fix-recursive-call-of-syscall_names.patch b/SOURCES/0999-analyze-security-fix-recursive-call-of-syscall_names.patch new file mode 100644 index 0000000..21a1e74 --- /dev/null +++ b/SOURCES/0999-analyze-security-fix-recursive-call-of-syscall_names.patch @@ -0,0 +1,62 @@ +From dd7a5f4144bde111334582eafbc0f358e63854ea Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 1 Feb 2019 11:49:24 +0100 +Subject: [PATCH] analyze security: fix recursive call of + syscall_names_in_filter() + +When `syscall_names_in_filter()` is called in itself, it is already +examined with `whitelist`. Or, in other words, `syscall_names_in_filter()` +returns bad or good in boolean. So, the returned value should not be +compared with `whitelist` again. + +This replaces #11302. + +(cherry picked from commit 95832a0f8c2941df83e72dfc9d37eab20da8b1fa) + +Related: RHEL-5991 +--- + src/analyze/analyze-security.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +index 969101c57b..5ef5d52e75 100644 +--- a/src/analyze/analyze-security.c ++++ b/src/analyze/analyze-security.c +@@ -480,26 +480,24 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS + const char *syscall; + + NULSTR_FOREACH(syscall, f->value) { +- bool b; ++ int id; + + if (syscall[0] == '@') { + const SyscallFilterSet *g; +- assert_se(g = syscall_filter_set_find(syscall)); +- b = syscall_names_in_filter(s, whitelist, g); +- } else { +-#if HAVE_SECCOMP +- int id; + +- /* Let's see if the system call actually exists on this platform, before complaining */ +- id = seccomp_syscall_resolve_name(syscall); +- if (id < 0) +- continue; +-#endif ++ assert_se(g = syscall_filter_set_find(syscall)); ++ if (syscall_names_in_filter(s, whitelist, g)) ++ return true; /* bad! */ + +- b = set_contains(s, syscall); ++ continue; + } + +- if (whitelist == b) { ++ /* Let's see if the system call actually exists on this platform, before complaining */ ++ id = seccomp_syscall_resolve_name(syscall); ++ if (id < 0) ++ continue; ++ ++ if (set_contains(s, syscall) == whitelist) { + log_debug("Offending syscall filter item: %s", syscall); + return true; /* bad! */ + } diff --git a/SOURCES/1000-analyze-security-do-not-assign-badness-to-filtered-o.patch b/SOURCES/1000-analyze-security-do-not-assign-badness-to-filtered-o.patch new file mode 100644 index 0000000..ba06451 --- /dev/null +++ b/SOURCES/1000-analyze-security-do-not-assign-badness-to-filtered-o.patch @@ -0,0 +1,28 @@ +From c8fe27ea2c560a213c3e3968fa76b5dd84e181f5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 1 Aug 2020 11:28:09 +0200 +Subject: [PATCH] analyze-security: do not assign badness to filtered-out + syscalls + +Fixes #16451, https://bugzilla.redhat.com/show_bug.cgi?id=1856273. + +(cherry picked from commit 01ecb3674ad3650bcbb14155b2dcbd4b9f4ed57e) + +Resolves: RHEL-5991 +--- + src/analyze/analyze-security.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +index 5ef5d52e75..7c937e3587 100644 +--- a/src/analyze/analyze-security.c ++++ b/src/analyze/analyze-security.c +@@ -549,7 +549,7 @@ static int assess_system_call_filter( + b = 10; + } else { + (void) asprintf(&d, "System call blacklist defined for service, and %s is included", f->name); +- b = 5; ++ b = 0; + } + } + } diff --git a/SOURCES/1001-analyze-security-include-an-actual-syscall-name-in-t.patch b/SOURCES/1001-analyze-security-include-an-actual-syscall-name-in-t.patch new file mode 100644 index 0000000..edc5dea --- /dev/null +++ b/SOURCES/1001-analyze-security-include-an-actual-syscall-name-in-t.patch @@ -0,0 +1,105 @@ +From 7aa12839166b5ae2c67d51946008543d016a7733 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 1 Aug 2020 11:41:57 +0200 +Subject: [PATCH] analyze-security: include an actual syscall name in the + message + +This information was already available in the debug output, but I think it +is good to include it in the message in the table. This makes it easier to wrap +one's head around the allowlist/denylist filtering. + +(cherry picked from commit a9134af2e3ab22eba96228ea6ba440e89213cef2) + +Related: RHEL-5991 +--- + src/analyze/analyze-security.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c +index 7c937e3587..d156aa607a 100644 +--- a/src/analyze/analyze-security.c ++++ b/src/analyze/analyze-security.c +@@ -476,7 +476,7 @@ static int assess_system_call_architectures( + return 0; + } + +-static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterSet *f) { ++static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterSet *f, const char **ret_offending_syscall) { + const char *syscall; + + NULSTR_FOREACH(syscall, f->value) { +@@ -486,7 +486,7 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS + const SyscallFilterSet *g; + + assert_se(g = syscall_filter_set_find(syscall)); +- if (syscall_names_in_filter(s, whitelist, g)) ++ if (syscall_names_in_filter(s, whitelist, g, ret_offending_syscall)) + return true; /* bad! */ + + continue; +@@ -499,10 +499,13 @@ static bool syscall_names_in_filter(Set *s, bool whitelist, const SyscallFilterS + + if (set_contains(s, syscall) == whitelist) { + log_debug("Offending syscall filter item: %s", syscall); ++ if (ret_offending_syscall) ++ *ret_offending_syscall = syscall; + return true; /* bad! */ + } + } + ++ *ret_offending_syscall = NULL; + return false; + } + +@@ -513,31 +516,33 @@ static int assess_system_call_filter( + uint64_t *ret_badness, + char **ret_description) { + +- const SyscallFilterSet *f; +- char *d = NULL; +- uint64_t b; +- + assert(a); + assert(info); + assert(ret_badness); + assert(ret_description); + + assert(a->parameter < _SYSCALL_FILTER_SET_MAX); +- f = syscall_filter_sets + a->parameter; ++ const SyscallFilterSet *f = syscall_filter_sets + a->parameter; ++ ++ char *d = NULL; ++ uint64_t b; + + if (!info->system_call_filter_whitelist && set_isempty(info->system_call_filter)) { + d = strdup("Service does not filter system calls"); + b = 10; + } else { + bool bad; ++ const char *offender = NULL; + + log_debug("Analyzing system call filter, checking against: %s", f->name); +- bad = syscall_names_in_filter(info->system_call_filter, info->system_call_filter_whitelist, f); ++ bad = syscall_names_in_filter(info->system_call_filter, info->system_call_filter_whitelist, f, &offender); + log_debug("Result: %s", bad ? "bad" : "good"); + + if (info->system_call_filter_whitelist) { + if (bad) { +- (void) asprintf(&d, "System call whitelist defined for service, and %s is included", f->name); ++ (void) asprintf(&d, "System call whitelist defined for service, and %s is included " ++ "(e.g. %s is allowed)", ++ f->name, offender); + b = 9; + } else { + (void) asprintf(&d, "System call whitelist defined for service, and %s is not included", f->name); +@@ -545,7 +550,9 @@ static int assess_system_call_filter( + } + } else { + if (bad) { +- (void) asprintf(&d, "System call blacklist defined for service, and %s is not included", f->name); ++ (void) asprintf(&d, "System call blacklist defined for service, and %s is not included " ++ "(e.g. %s is allowed)", ++ f->name, offender); + b = 10; + } else { + (void) asprintf(&d, "System call blacklist defined for service, and %s is included", f->name); diff --git a/SOURCES/1002-udev-net_id-introduce-naming-scheme-for-RHEL-8.10.patch b/SOURCES/1002-udev-net_id-introduce-naming-scheme-for-RHEL-8.10.patch new file mode 100644 index 0000000..5da176e --- /dev/null +++ b/SOURCES/1002-udev-net_id-introduce-naming-scheme-for-RHEL-8.10.patch @@ -0,0 +1,50 @@ +From 9d9c3d38451befec0494aea4fdb12c65289b0b46 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 23 Jan 2024 15:15:00 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.10 + +rhel-only + +Resolves: RHEL-22426 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index ddd41646ae..25e8bd9aea 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -340,6 +340,12 @@ + Same as naming scheme rhel-8.7. + + ++ ++ rhel-8.10 ++ ++ Same as naming scheme rhel-8.7. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 0f42c1c007..ece5d29205 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -143,6 +143,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, + NAMING_RHEL_8_8 = NAMING_RHEL_8_7, + NAMING_RHEL_8_9 = NAMING_RHEL_8_7, ++ NAMING_RHEL_8_10 = NAMING_RHEL_8_7, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -165,6 +166,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.7", NAMING_RHEL_8_7 }, + { "rhel-8.8", NAMING_RHEL_8_8 }, + { "rhel-8.9", NAMING_RHEL_8_9 }, ++ { "rhel-8.10", NAMING_RHEL_8_10 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/SOURCES/1003-doc-add-missing-listitem-to-systemd.net-naming-schem.patch b/SOURCES/1003-doc-add-missing-listitem-to-systemd.net-naming-schem.patch new file mode 100644 index 0000000..9f756e0 --- /dev/null +++ b/SOURCES/1003-doc-add-missing-listitem-to-systemd.net-naming-schem.patch @@ -0,0 +1,79 @@ +From 8ac0c00fa9699f1cd096a4775cf0cf7879b81f37 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 9 Feb 2024 14:42:28 +0100 +Subject: [PATCH] doc: add missing `` to + `systemd.net-naming-scheme.xml` + +rhel-only + +Related: RHEL-22426 +--- + man/systemd.net-naming-scheme.xml | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index 25e8bd9aea..11ef2ea02f 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -276,19 +276,19 @@ + + rhel-8.1 + +- Same as naming scheme rhel-8.0. ++ Same as naming scheme rhel-8.0. + + + + rhel-8.2 + +- Same as naming scheme rhel-8.0. ++ Same as naming scheme rhel-8.0. + + + + rhel-8.3 + +- Same as naming scheme rhel-8.0. ++ Same as naming scheme rhel-8.0. + + + +@@ -304,13 +304,13 @@ + + rhel-8.5 + +- Same as naming scheme rhel-8.4. ++ Same as naming scheme rhel-8.4. + + + + rhel-8.6 + +- Same as naming scheme rhel-8.4. ++ Same as naming scheme rhel-8.4. + + + +@@ -331,19 +331,19 @@ + + rhel-8.8 + +- Same as naming scheme rhel-8.7. ++ Same as naming scheme rhel-8.7. + + + + rhel-8.9 + +- Same as naming scheme rhel-8.7. ++ Same as naming scheme rhel-8.7. + + + + rhel-8.10 + +- Same as naming scheme rhel-8.7. ++ Same as naming scheme rhel-8.7. + + + Note that latest may be used to denote the latest scheme known to this diff --git a/SOURCES/1004-service-schedule-cleanup-of-PID-hashmaps-when-we-now.patch b/SOURCES/1004-service-schedule-cleanup-of-PID-hashmaps-when-we-now.patch new file mode 100644 index 0000000..973bd7f --- /dev/null +++ b/SOURCES/1004-service-schedule-cleanup-of-PID-hashmaps-when-we-now.patch @@ -0,0 +1,34 @@ +From 8bf7a6f42efba3ebe59872ba75233e75ffdf7c87 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 11 Dec 2023 16:09:02 +0100 +Subject: [PATCH] service: schedule cleanup of PID hashmaps when we now longer + have main_pid and we are in container + +RHEL-only + +Resolves: RHEL-5863 +--- + src/core/service.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 0423f2c73e..82c09d59f0 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -34,6 +34,7 @@ + #include "string-table.h" + #include "string-util.h" + #include "strv.h" ++#include "virt.h" + #include "unit-name.h" + #include "unit.h" + #include "utf8.h" +@@ -3535,7 +3536,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + * detect when the cgroup becomes empty. Note that the control process is always + * our child so it's pointless to watch all other processes. */ + if (!control_pid_good(s)) +- if (!s->main_pid_known || s->main_pid_alien) ++ if (!s->main_pid_known || s->main_pid_alien || (s->main_pid == 0 && detect_container() > 0)) + (void) unit_enqueue_rewatch_pids(u); + } + diff --git a/SOURCES/1005-man-update-link-to-RHEL-documentation.patch b/SOURCES/1005-man-update-link-to-RHEL-documentation.patch new file mode 100644 index 0000000..395a03f --- /dev/null +++ b/SOURCES/1005-man-update-link-to-RHEL-documentation.patch @@ -0,0 +1,24 @@ +From 9cb89ed011a12a210dce977aaa65f6b90e0ed928 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 22 Feb 2024 14:28:09 +0100 +Subject: [PATCH] man: update link to RHEL documentation + +Resolves: RHEL-26355 +RHEL-only +--- + man/systemctl.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index abc386e6fb..445d35fefd 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2018,7 +2018,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + For examples how to use systemctl in comparsion + with old service and chkconfig command please see: +- ++ + Managing System Services + + diff --git a/SOURCES/20-grubby.install b/SOURCES/20-grubby.install new file mode 100755 index 0000000..a67856c --- /dev/null +++ b/SOURCES/20-grubby.install @@ -0,0 +1,58 @@ +#!/bin/bash + +if [[ ! -x /sbin/new-kernel-pkg ]]; then + exit 0 +fi + +COMMAND="$1" +KERNEL_VERSION="$2" +BOOT_DIR_ABS="$3" +KERNEL_IMAGE="$4" + +KERNEL_DIR="${KERNEL_IMAGE%/*}" +[[ "$KERNEL_VERSION" == *\+* ]] && flavor=-"${KERNEL_VERSION##*+}" +case "$COMMAND" in + add) + if [[ "${KERNEL_DIR}" != "/boot" ]]; then + for i in \ + "$KERNEL_IMAGE" \ + "$KERNEL_DIR"/System.map \ + "$KERNEL_DIR"/config \ + "$KERNEL_DIR"/zImage.stub \ + "$KERNEL_DIR"/dtb \ + ; do + [[ -e "$i" ]] || continue + cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}" + command -v restorecon &>/dev/null && \ + restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}" + done + # hmac is .vmlinuz-.hmac so needs a special treatment + i="$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac" + if [[ -e "$i" ]]; then + cp -a "$i" "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" + command -v restorecon &>/dev/null && \ + restorecon "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" + fi + # symvers is symvers-.gz so needs a special treatment + i="$KERNEL_DIR/symvers.gz" + if [[ -e "$i" ]]; then + cp -a "$i" "/boot/symvers-${KERNEL_VERSION}.gz" + command -v restorecon &>/dev/null && \ + restorecon "/boot/symvers-${KERNEL_VERSION}.gz" + fi + fi + /sbin/new-kernel-pkg --package "kernel${flavor}" --install "$KERNEL_VERSION" || exit $? + /sbin/new-kernel-pkg --package "kernel${flavor}" --mkinitrd --dracut --depmod --update "$KERNEL_VERSION" || exit $? + /sbin/new-kernel-pkg --package "kernel${flavor}" --rpmposttrans "$KERNEL_VERSION" || exit $? + ;; + remove) + /sbin/new-kernel-pkg --package "kernel${flavor+-$flavor}" --rminitrd --rmmoddep --remove "$KERNEL_VERSION" || exit $? + ;; + *) + ;; +esac + +# skip other installation plugins, if we can't find a boot loader spec conforming setup +if ! [[ -d /boot/loader/entries || -L /boot/loader/entries ]]; then + exit 77 +fi diff --git a/SOURCES/20-yama-ptrace.conf b/SOURCES/20-yama-ptrace.conf new file mode 100644 index 0000000..4fbaf97 --- /dev/null +++ b/SOURCES/20-yama-ptrace.conf @@ -0,0 +1,42 @@ +# The ptrace system call is used for interprocess services, +# communication and introspection (like synchronisation, signaling, +# debugging, tracing and profiling) of processes. +# +# Usage of ptrace is restricted by normal user permissions. Normal +# unprivileged processes cannot use ptrace on processes that they +# cannot send signals to or processes that are running set-uid or +# set-gid. Nevertheless, processes running under the same uid will +# usually be able to ptrace one another. +# +# Fedora enables the Yama security mechanism which restricts ptrace +# even further. Sysctl setting kernel.yama.ptrace_scope can have one +# of the following values: +# +# 0 - Normal ptrace security permissions. +# 1 - Restricted ptrace. Only child processes plus normal permissions. +# 2 - Admin-only attach. Only executables with CAP_SYS_PTRACE. +# 3 - No attach. No process may call ptrace at all. Irrevocable. +# +# For more information see Documentation/security/Yama.txt in the +# kernel sources. +# +# The default is 1., which allows tracing of child processes, but +# forbids tracing of arbitrary processes. This allows programs like +# gdb or strace to work when the most common way of having the +# debugger start the debuggee is used: +# gdb /path/to/program ... +# Attaching to already running programs is NOT allowed: +# gdb -p ... +# This default setting is suitable for the common case, because it +# reduces the risk that one hacked process can be used to attack other +# processes. (For example, a hacked firefox process in a user session +# will not be able to ptrace the keyring process and extract passwords +# stored only in memory.) +# +# Developers and administrators might want to disable those protections +# to be able to attach debuggers to existing processes. Use +# sysctl kernel.yama.ptrace_scope=0 +# for change the setting temporarily, or copy this file to +# /etc/sysctl.d/20-yama-ptrace.conf to set it for future boots. + +kernel.yama.ptrace_scope = 0 diff --git a/SOURCES/inittab b/SOURCES/inittab new file mode 100644 index 0000000..3f5e83c --- /dev/null +++ b/SOURCES/inittab @@ -0,0 +1,16 @@ +# inittab is no longer used. +# +# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. +# +# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target +# +# systemd uses 'targets' instead of runlevels. By default, there are two main targets: +# +# multi-user.target: analogous to runlevel 3 +# graphical.target: analogous to runlevel 5 +# +# To view current default target, run: +# systemctl get-default +# +# To set a default target, run: +# systemctl set-default TARGET.target diff --git a/SOURCES/purge-nobody-user b/SOURCES/purge-nobody-user new file mode 100755 index 0000000..66404fe --- /dev/null +++ b/SOURCES/purge-nobody-user @@ -0,0 +1,101 @@ +#!/bin/bash -eu + +if [ $UID -ne 0 ]; then + echo "WARNING: This script needs to run as root to be effective" + exit 1 +fi + +export SYSTEMD_NSS_BYPASS_SYNTHETIC=1 + +if [ "${1:-}" = "--ignore-journal" ]; then + shift + ignore_journal=1 +else + ignore_journal=0 +fi + +echo "Checking processes..." +if ps h -u 99 | grep .; then + echo "ERROR: ps reports processes with UID 99!" + exit 2 +fi +echo "... not found" + +echo "Checking UTMP..." +if w -h 199 | grep . ; then + echo "ERROR: w reports UID 99 as active!" + exit 2 +fi +if w -h nobody | grep . ; then + echo "ERROR: w reports user nobody as active!" + exit 2 +fi +echo "... not found" + +echo "Checking the journal..." +if [ "$ignore_journal" = 0 ] && journalctl -q -b -n10 _UID=99 | grep . ; then + echo "ERROR: journalctl reports messages from UID 99 in current boot!" + exit 2 +fi +echo "... not found" + +echo "Looking for files in /etc, /run, /tmp, and /var..." +if find /etc /run /tmp /var -uid 99 -print | grep -m 10 . ; then + echo "ERROR: found files belonging to UID 99" + exit 2 +fi +echo "... not found" + +echo "Checking if nobody is defined correctly..." +if getent passwd nobody | + grep '^nobody:[x*]:65534:65534:.*:/:/sbin/nologin'; +then + echo "OK, nothing to do." + exit 0 +else + echo "NOTICE: User nobody is not defined correctly" +fi + +echo "Checking if nfsnobody or something else is using the uid..." +if getent passwd 65534 | grep . ; then + echo "NOTICE: will have to remove this user" +else + echo "... not found" +fi + +if [ "${1:-}" = "-x" ]; then + if getent passwd nobody >/dev/null; then + # this will remove both the user and the group. + ( set -x + userdel nobody + ) + fi + + if getent passwd 65534 >/dev/null; then + # Make sure the uid is unused. This should free gid too. + name="$(getent passwd 65534 | cut -d: -f1)" + ( set -x + userdel "$name" + ) + fi + + if grep -qE '^(passwd|group):.*\bsss\b' /etc/nsswitch.conf; then + echo "Sleeping, so sss can catch up" + sleep 3 + fi + + if getent group 65534; then + # Make sure the gid is unused, even if uid wasn't. + name="$(getent group 65534 | cut -d: -f1)" + ( set -x + groupdel "$name" + ) + fi + + # systemd-sysusers uses the same gid and uid + ( set -x + systemd-sysusers --inline 'u nobody 65534 "Kernel Overflow User" / /sbin/nologin' + ) +else + echo "Pass '-x' to perform changes" +fi diff --git a/SOURCES/rc.local b/SOURCES/rc.local new file mode 100644 index 0000000..4666070 --- /dev/null +++ b/SOURCES/rc.local @@ -0,0 +1,14 @@ +#!/bin/bash +# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES +# +# It is highly advisable to create own systemd services or udev rules +# to run scripts during boot instead of using this file. +# +# In contrast to previous versions due to parallel execution during boot +# this script will NOT be run after all other services. +# +# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure +# that this script will be executed during boot. + +touch /var/lock/subsys/local + diff --git a/SOURCES/split-files.py b/SOURCES/split-files.py new file mode 100644 index 0000000..262ee04 --- /dev/null +++ b/SOURCES/split-files.py @@ -0,0 +1,116 @@ +import re, sys, os, collections + +buildroot = sys.argv[1] +known_files = sys.stdin.read().splitlines() +known_files = {line.split()[-1]:line for line in known_files} + +def files(root): + os.chdir(root) + todo = collections.deque(['.']) + while todo: + n = todo.pop() + files = os.scandir(n) + for file in files: + yield file + if file.is_dir() and not file.is_symlink(): + todo.append(file) + +o_libs = open('.file-list-libs', 'w') +o_udev = open('.file-list-udev', 'w') +o_pam = open('.file-list-pam', 'w') +o_devel = open('.file-list-devel', 'w') +o_container = open('.file-list-container', 'w') +o_remote = open('.file-list-remote', 'w') +o_tests = open('.file-list-tests', 'w') +o_rest = open('.file-list-rest', 'w') +for file in files(buildroot): + n = file.path[1:] + if re.match(r'''/usr/(share|include)$| + /usr/share/man(/man.|)$| + /usr/share/zsh(/site-functions|)$| + /usr/share/dbus-1$| + /usr/share/dbus-1/system.d$| + /usr/share/dbus-1/(system-|)services$| + /usr/share/polkit-1(/actions|/rules.d|)$| + /usr/share/pkgconfig$| + /usr/share/bash-completion(/completions|)$| + /usr(/lib|/lib64|/bin|/sbin|)$| + /usr/lib.*/(security|pkgconfig)$| + /usr/lib/rpm(/macros.d|)$| + /usr/lib/firewalld(/services|)$| + /usr/share/(locale|licenses|doc)| # no $ + /etc(/pam\.d|/xdg|/X11|/X11/xinit|/X11.*\.d|)$| + /etc/(dnf|dnf/protected.d)$| + /usr/(src|lib/debug)| # no $ + /var(/cache|/log|/lib|/run|)$ + ''', n, re.X): + continue + if '/security/pam_' in n: + o = o_pam + elif re.search(r'/lib.*\.pc|/man3/|/usr/include|(? + + systemd-journal-gatewayd + Journal Gateway Service + + diff --git a/SOURCES/systemd-journal-remote.xml b/SOURCES/systemd-journal-remote.xml new file mode 100644 index 0000000..e115a12 --- /dev/null +++ b/SOURCES/systemd-journal-remote.xml @@ -0,0 +1,6 @@ + + + systemd-journal-remote + Journal Remote Sink + + diff --git a/SOURCES/systemd-udev-trigger-no-reload.conf b/SOURCES/systemd-udev-trigger-no-reload.conf new file mode 100644 index 0000000..c879427 --- /dev/null +++ b/SOURCES/systemd-udev-trigger-no-reload.conf @@ -0,0 +1,3 @@ +[Unit] +# https://bugzilla.redhat.com/show_bug.cgi?id=1378974#c17 +RefuseManualStop=true diff --git a/SOURCES/systemd-user b/SOURCES/systemd-user new file mode 100644 index 0000000..d1f64c1 --- /dev/null +++ b/SOURCES/systemd-user @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# Used by systemd --user instances. + +account sufficient pam_unix.so no_pass_expiry +account include system-auth + +session required pam_selinux.so close +session required pam_selinux.so nottys open +session required pam_loginuid.so +session required pam_namespace.so +session include system-auth diff --git a/SOURCES/triggers.systemd b/SOURCES/triggers.systemd new file mode 100644 index 0000000..90906e3 --- /dev/null +++ b/SOURCES/triggers.systemd @@ -0,0 +1,111 @@ +# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# Copyright 2015 Zbigniew Jędrzejewski-Szmek +# Copyright 2018 Neal Gompa +# +# 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 . + +# The contents of this are an example to be copied into systemd.spec. +# +# Minimum rpm version supported: 4.13.0 + +%transfiletriggerin -P 900900 -- /usr/lib/systemd/system /etc/systemd/system +# This script will run after any package is initially installed or +# upgraded. We care about the case where a package is initially +# installed, because other cases are covered by the *un scriptlets, +# so sometimes we will reload needlessly. +if test -d /run/systemd/system; then + %{_bindir}/systemctl daemon-reload +fi + +%transfiletriggerun -- /usr/lib/systemd/system /etc/systemd/system +# On removal, we need to run daemon-reload after any units have been +# removed. %transfiletriggerpostun would be ideal, but it does not get +# executed for some reason. +# On upgrade, we need to run daemon-reload after any new unit files +# have been installed, but before %postun scripts in packages get +# executed. %transfiletriggerun gets the right list of files +# but it is invoked too early (before changes happen). +# %filetriggerpostun happens at the right time, but it fires for +# every package. +# To execute the reload at the right time, we create a state +# file in %transfiletriggerun and execute the daemon-reload in +# the first %filetriggerpostun. + +if test -d "/run/systemd/system"; then + mkdir -p "%{_localstatedir}/lib/rpm-state/systemd" + touch "%{_localstatedir}/lib/rpm-state/systemd/needs-reload" +fi + +%filetriggerpostun -P 1000100 -- /usr/lib/systemd/system /etc/systemd/system +if test -f "%{_localstatedir}/lib/rpm-state/systemd/needs-reload"; then + rm -rf "%{_localstatedir}/lib/rpm-state/systemd" + %{_bindir}/systemctl daemon-reload +fi + +%transfiletriggerin -P 100700 -- /usr/lib/sysusers.d +# This script will process files installed in /usr/lib/sysusers.d to create +# specified users automatically. The priority is set such that it +# will run before the tmpfiles file trigger. +if test -d /run/systemd/system; then + %{_bindir}/systemd-sysusers +fi + +%transfiletriggerin -P 100500 -- /usr/lib/tmpfiles.d +# This script will process files installed in /usr/lib/tmpfiles.d to create +# tmpfiles automatically. The priority is set such that it will run +# after the sysusers file trigger, but before any other triggers. +if test -d /run/systemd/system; then + %{_bindir}/systemd-tmpfiles --create +fi + +%transfiletriggerin udev -- /usr/lib/udev/hwdb.d +# This script will automatically invoke hwdb update if files have been +# installed or updated in /usr/lib/udev/hwdb.d. +if test -d /run/systemd/system; then + %{_bindir}/systemd-hwdb update +fi + +%transfiletriggerin -- /usr/lib/systemd/catalog +# This script will automatically invoke journal catalog update if files +# have been installed or updated in /usr/lib/systemd/catalog. +if test -d /run/systemd/system; then + %{_bindir}/journalctl --update-catalog +fi + +%transfiletriggerin udev -- /usr/lib/udev/rules.d +# This script will automatically update udev with new rules if files +# have been installed or updated in /usr/lib/udev/rules.d. +if test -d /run/systemd/system; then + %{_bindir}/udevadm control --reload +fi + +%transfiletriggerin -- /usr/lib/sysctl.d +# This script will automatically apply sysctl rules if files have been +# installed or updated in /usr/lib/sysctl.d. +if test -d /run/systemd/system; then + /usr/lib/systemd/systemd-sysctl +fi + +%transfiletriggerin -- /usr/lib/binfmt.d +# This script will automatically apply binfmt rules if files have been +# installed or updated in /usr/lib/binfmt.d. +if test -d /run/systemd/system; then + # systemd-binfmt might fail if binfmt_misc kernel module is not loaded + # during install + /usr/lib/systemd/systemd-binfmt || : +fi diff --git a/SOURCES/yum-protect-systemd.conf b/SOURCES/yum-protect-systemd.conf new file mode 100644 index 0000000..39426d7 --- /dev/null +++ b/SOURCES/yum-protect-systemd.conf @@ -0,0 +1,2 @@ +systemd +systemd-udev diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec new file mode 100644 index 0000000..185a124 --- /dev/null +++ b/SPECS/systemd.spec @@ -0,0 +1,4469 @@ +#global gitcommit 10e465b5321bd53c1fc59ffab27e724535c6bc0f +%{?gitcommit:%global gitcommitshort %(c=%{gitcommit}; echo ${c:0:7})} + +# We ship a .pc file but don't want to have a dep on pkg-config. We +# strip the automatically generated dep here and instead co-own the +# directory. +%global __requires_exclude pkg-config + +%global pkgdir %{_prefix}/lib/systemd +%global system_unit_dir %{pkgdir}/system +%global user_unit_dir %{pkgdir}/user + +Name: systemd +Url: http://www.freedesktop.org/wiki/Software/systemd +Version: 239 +Release: 81%{?dist} +# For a breakdown of the licensing, see README +License: LGPLv2+ and MIT and GPLv2+ +Summary: System and Service Manager + +# download tarballs with "spectool -g systemd.spec" +%if %{defined gitcommit} +Source0: https://github.com/systemd/systemd-stable/archive/%{?gitcommit}.tar.gz#/%{name}-%{gitcommitshort}.tar.gz +%else +Source0: https://github.com/systemd/systemd/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz +%endif +# This file must be available before %%prep. +# It is generated during systemd build and can be found in src/core/. +Source1: triggers.systemd +Source2: split-files.py +Source3: purge-nobody-user + +# Prevent accidental removal of the systemd package +Source4: yum-protect-systemd.conf + +Source5: inittab +Source6: sysctl.conf.README +Source7: systemd-journal-remote.xml +Source8: systemd-journal-gatewayd.xml +Source9: 20-yama-ptrace.conf +Source10: systemd-udev-trigger-no-reload.conf +Source11: 20-grubby.install +Source12: systemd-user +Source13: rc.local + +%if 0 +GIT_DIR=../../src/systemd/.git git format-patch-ab --no-signature -M -N v235..v235-stable +i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done|xclip +GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[67]* hwdb/parse_hwdb.py > hwdb.patch +%endif + +# RHEL-specific +Patch0001: 0001-build-sys-Detect-whether-struct-statx-is-defined-in-.patch +Patch0002: 0002-logind-set-RemoveIPC-to-false-by-default.patch +Patch0003: 0003-pid1-bump-DefaultTasksMax-to-80-of-the-kernel-pid.ma.patch +Patch0004: 0004-Avoid-tmp-being-mounted-as-tmpfs-without-the-user-s-.patch +Patch0005: 0005-pid1-bump-maximum-number-of-process-in-user-slice-to.patch +Patch0006: 0006-rules-automatically-online-hot-plugged-CPUs.patch +Patch0007: 0007-rules-add-rule-for-naming-Dell-iDRAC-USB-Virtual-NIC.patch +Patch0008: 0008-rules-enable-memory-hotplug.patch +Patch0009: 0009-rules-reload-sysctl-settings-when-the-bridge-module-.patch +Patch0010: 0010-rules-load-sg-module.patch +Patch0011: 0011-rules-prandom-character-device-node-permissions.patch +Patch0012: 0012-rules-load-sg-driver-also-when-scsi_target-appears-4.patch +Patch0013: 0013-rules-don-t-hoplug-memory-on-s390x.patch +Patch0014: 0014-rules-disable-auto-online-of-hot-plugged-memory-on-I.patch +Patch0015: 0015-rules-introduce-old-style-by-path-symlinks-for-FCP-b.patch +Patch0016: 0016-Revert-udev-remove-WAIT_FOR-key.patch +Patch0017: 0017-net_setup_link-allow-renaming-interfaces-that-were-r.patch +Patch0018: 0018-units-drop-DynamicUser-yes-from-systemd-resolved.ser.patch +Patch0019: 0019-journal-remove-journal-audit-socket.patch +Patch0020: 0020-bus-move-BUS_DONT_DESTROY-calls-after-asserts.patch +Patch0021: 0021-random-seed-raise-POOL_SIZE_MIN-constant-to-1024.patch +Patch0022: 0022-cryptsetup-add-support-for-sector-size-option-9936.patch +Patch0023: 0023-cryptsetup-do-not-define-arg_sector_size-if-libgcryp.patch +Patch0024: 0024-units-don-t-enable-per-service-IP-firewall-by-defaul.patch +Patch0025: 0025-bus-message-do-not-crash-on-message-with-a-string-of.patch +Patch0026: 0026-Introduce-free_and_strndup-and-use-it-in-bus-message.patch +Patch0027: 0027-tests-backport-test_setup_logging.patch +Patch0028: 0028-journal-change-support-URL-shown-in-the-catalog-entr.patch +Patch0029: 0029-resolved-create-etc-resolv.conf-symlink-at-runtime.patch +Patch0030: 0030-dissect-image-use-right-comparison-function.patch +Patch0031: 0031-login-avoid-leak-of-name-returned-by-uid_to_name.patch +Patch0032: 0032-firewall-util-add-an-assert-that-we-re-not-overwriti.patch +Patch0033: 0033-journal-file-avoid-calling-ftruncate-with-invalid-fd.patch +Patch0034: 0034-dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-o.patch +Patch0035: 0035-core-rename-queued_message-pending_reload_message.patch +Patch0036: 0036-core-when-we-can-t-send-the-pending-reload-message-s.patch +Patch0037: 0037-core-make-sure-we-don-t-throttle-change-signal-gener.patch +Patch0038: 0038-proc-cmdline-introduce-PROC_CMDLINE_RD_STRICT.patch +Patch0039: 0039-debug-generator-introduce-rd.-version-of-all-options.patch +Patch0040: 0040-chown-recursive-let-s-rework-the-recursive-logic-to-.patch +Patch0041: 0041-chown-recursive-also-drop-ACLs-when-recursively-chow.patch +Patch0042: 0042-chown-recursive-TAKE_FD-is-your-friend.patch +Patch0043: 0043-test-add-test-case-for-recursive-chown-ing.patch +Patch0044: 0044-Revert-sysctl.d-request-ECN-on-both-in-and-outgoing-.patch +Patch0045: 0045-detect-virt-do-not-try-to-read-all-of-proc-cpuinfo.patch +Patch0046: 0046-sd-bus-unify-three-code-paths-which-free-struct-bus_.patch +Patch0047: 0047-sd-bus-properly-initialize-containers.patch +Patch0048: 0048-cryptsetup-generator-introduce-basic-keydev-support.patch +Patch0049: 0049-cryptsetup-don-t-use-m-if-there-s-no-error-to-show.patch +Patch0050: 0050-cryptsetup-generator-don-t-return-error-if-target-di.patch +Patch0051: 0051-cryptsetup-generator-allow-whitespace-characters-in-.patch +Patch0052: 0052-rules-watch-metadata-changes-on-DASD-devices.patch +Patch0053: 0053-sysctl.d-switch-net.ipv4.conf.all.rp_filter-from-1-t.patch +Patch0054: 0054-tests-explicitly-enable-user-namespaces-for-TEST-13-.patch +Patch0055: 0055-nspawn-beef-up-netns-checking-a-bit-for-compat-with-.patch +Patch0056: 0056-test-Drop-SKIP_INITRD-for-QEMU-based-tests.patch +Patch0057: 0057-meson-rename-Ddebug-to-Ddebug-extra.patch +Patch0058: 0058-meson-check-whether-gnutls-supports-TCP-fast-open.patch +Patch0059: 0059-unit-don-t-add-Requires-for-tmp.mount.patch +Patch0060: 0060-tests-drop-the-precondition-check-for-inherited-flag.patch +Patch0061: 0061-core-when-deserializing-state-always-use-read_line-L.patch +Patch0062: 0062-core-enforce-a-limit-on-STATUS-texts-recvd-from-serv.patch +Patch0063: 0063-travis-enable-Travis-CI-on-CentOS-7.patch +Patch0064: 0064-travis-RHEL8-support.patch +Patch0065: 0065-travis-drop-the-SELinux-Fedora-workaround.patch +Patch0066: 0066-travis-fix-syntax-error-in-.travis.yml.patch +Patch0067: 0067-travis-reboot-the-container-before-running-tests.patch +Patch0068: 0068-coredump-remove-duplicate-MESSAGE-prefix-from-messag.patch +Patch0069: 0069-journald-remove-unnecessary.patch +Patch0070: 0070-journald-do-not-store-the-iovec-entry-for-process-co.patch +Patch0071: 0071-basic-process-util-limit-command-line-lengths-to-_SC.patch +Patch0072: 0072-coredump-fix-message-when-we-fail-to-save-a-journald.patch +Patch0073: 0073-procfs-util-expose-functionality-to-query-total-memo.patch +Patch0074: 0074-basic-prioq-add-prioq_peek_item.patch +Patch0075: 0075-journal-limit-the-number-of-entries-in-the-cache-bas.patch +Patch0076: 0076-journald-periodically-drop-cache-for-all-dead-PIDs.patch +Patch0077: 0077-process-util-don-t-use-overly-large-buffer-to-store-.patch +Patch0078: 0078-Revert-sysctl.d-switch-net.ipv4.conf.all.rp_filter-f.patch +Patch0079: 0079-journal-fix-syslog_parse_identifier.patch +Patch0080: 0080-journald-set-a-limit-on-the-number-of-fields-1k.patch +Patch0081: 0081-journald-when-processing-a-native-message-bail-more-.patch +Patch0082: 0082-journald-lower-the-maximum-entry-size-limit-to-for-n.patch +Patch0083: 0083-httpd-use-a-cleanup-function-to-call-MHD_destroy_res.patch +Patch0084: 0084-journal-remote-verify-entry-length-from-header.patch +Patch0085: 0085-journal-remote-set-a-limit-on-the-number-of-fields-i.patch +Patch0086: 0086-journald-correctly-attribute-log-messages-also-with-.patch +Patch0087: 0087-test-replace-echo-with-socat.patch +Patch0088: 0088-test-network-ignore-tunnel-devices-automatically-add.patch +Patch0089: 0089-rules-add-elevator-kernel-command-line-parameter.patch +Patch0090: 0090-rule-syntax-check-allow-PROGRAM-as-an-assignment.patch +Patch0091: 0091-rules-implement-new-memory-hotplug-policy.patch +Patch0092: 0092-LGTM-make-LGTM.com-use-meson-from-pip.patch +Patch0093: 0093-lgtm-use-python3.patch +Patch0094: 0094-tools-use-print-function-in-Python-3-code.patch +Patch0095: 0095-lgtm-add-a-custom-query-for-catching-the-use-of-fget.patch +Patch0096: 0096-lgtm-drop-redundant-newlines.patch +Patch0097: 0097-rules-add-the-rule-that-adds-elevator-kernel-command.patch +Patch0098: 0098-test-add-TEST-24-UNIT-TESTS-running-all-basic-tests-.patch +Patch0099: 0099-tests-create-the-asan-wrapper-automatically-if-syste.patch +Patch0100: 0100-tests-add-a-wrapper-for-when-systemd-is-built-with-A.patch +Patch0101: 0101-tests-redirect-ASAN-reports-on-journald-to-a-file.patch +Patch0102: 0102-tests-use-the-asan-wrapper-to-boot-a-VM-container-if.patch +Patch0103: 0103-tests-allow-passing-additional-arguments-to-nspawn-v.patch +Patch0104: 0104-tests-also-run-TEST-01-BASIC-in-an-unprivileged-cont.patch +Patch0105: 0105-test-don-t-overwrite-TESTDIR-if-already-set.patch +Patch0106: 0106-bus-socket-Fix-line_begins-to-accept-word-matching-f.patch +Patch0107: 0107-Refuse-dbus-message-paths-longer-than-BUS_PATH_SIZE_.patch +Patch0108: 0108-Allocate-temporary-strings-to-hold-dbus-paths-on-the.patch +Patch0109: 0109-sd-bus-if-we-receive-an-invalid-dbus-message-ignore-.patch +Patch0110: 0110-meson-drop-misplaced-Wl-undefined-argument.patch +Patch0111: 0111-Revert-core-one-step-back-again-for-nspawn-we-actual.patch +Patch0112: 0112-tree-wide-shorten-error-logging-a-bit.patch +Patch0113: 0113-nspawn-simplify-machine-terminate-bus-call.patch +Patch0114: 0114-nspawn-merge-two-variable-declaration-lines.patch +Patch0115: 0115-nspawn-rework-how-we-allocate-kill-scopes.patch +Patch0116: 0116-unit-enqueue-cgroup-empty-check-event-if-the-last-re.patch +Patch0117: 0117-Revert-journal-remove-journal-audit-socket.patch +Patch0118: 0118-journal-don-t-enable-systemd-journald-audit.socket-b.patch +Patch0119: 0119-logs-show-use-grey-color-for-de-emphasizing-journal-.patch +Patch0120: 0120-units-add-Install-section-to-tmp.mount.patch +Patch0121: 0121-nss-do-not-modify-errno-when-NSS_STATUS_NOTFOUND-or-.patch +Patch0122: 0122-util.h-add-new-UNPROTECT_ERRNO-macro.patch +Patch0123: 0123-nss-unportect-errno-before-writing-to-NSS-errnop.patch +Patch0124: 0124-seccomp-reduce-logging-about-failure-to-add-syscall-.patch +Patch0125: 0125-format-table-when-duplicating-a-cell-also-copy-the-c.patch +Patch0126: 0126-format-table-optionally-make-specific-cells-clickabl.patch +Patch0127: 0127-format-table-before-outputting-a-color-check-if-colo.patch +Patch0128: 0128-format-table-add-option-to-store-format-percent-and-.patch +Patch0129: 0129-format-table-optionally-allow-reversing-the-sort-ord.patch +Patch0130: 0130-format-table-add-table_update-to-update-existing-ent.patch +Patch0131: 0131-format-table-add-an-API-for-getting-the-cell-at-a-sp.patch +Patch0132: 0132-format-table-always-underline-header-line.patch +Patch0133: 0133-format-table-add-calls-to-query-the-data-in-a-specif.patch +Patch0134: 0134-format-table-make-sure-we-never-call-memcmp-with-NUL.patch +Patch0135: 0135-format-table-use-right-field-for-display.patch +Patch0136: 0136-format-table-add-option-to-uppercase-cells-on-displa.patch +Patch0137: 0137-format-table-never-try-to-reuse-cells-that-have-colo.patch +Patch0138: 0138-locale-util-add-logic-to-output-smiley-emojis-at-var.patch +Patch0139: 0139-analyze-add-new-security-verb.patch +Patch0140: 0140-tests-add-a-rudimentary-fuzzer-for-server_process_sy.patch +Patch0141: 0141-journald-make-it-clear-that-dev_kmsg_record-modifies.patch +Patch0142: 0142-journald-free-the-allocated-memory-before-returning-.patch +Patch0143: 0143-tests-rework-the-code-fuzzing-journald.patch +Patch0144: 0144-journald-make-server_process_native_message-compatib.patch +Patch0145: 0145-tests-add-a-fuzzer-for-server_process_native_message.patch +Patch0146: 0146-tests-add-a-fuzzer-for-sd-ndisc.patch +Patch0147: 0147-ndisc-fix-two-infinite-loops.patch +Patch0148: 0148-tests-add-reproducers-for-several-issues-uncovered-w.patch +Patch0149: 0149-tests-add-a-reproducer-for-an-infinite-loop-in-ndisc.patch +Patch0150: 0150-tests-add-a-reproducer-for-another-infinite-loop-in-.patch +Patch0151: 0151-fuzz-rename-fuzz-corpus-directory-to-just-fuzz.patch +Patch0152: 0152-test-add-testcase-for-issue-10007-by-oss-fuzz.patch +Patch0153: 0153-fuzz-unify-the-fuzz-regressions-directory-with-the-m.patch +Patch0154: 0154-test-bus-marshal-use-cescaping-instead-of-hexmem.patch +Patch0155: 0155-meson-add-Dlog-trace-to-set-LOG_TRACE.patch +Patch0156: 0156-meson-allow-building-resolved-and-machined-without-n.patch +Patch0157: 0157-meson-drop-duplicated-condition.patch +Patch0158: 0158-meson-use-.source_root-in-more-places.patch +Patch0159: 0159-meson-treat-all-fuzz-cases-as-unit-tests.patch +Patch0160: 0160-fuzz-bus-message-add-fuzzer-for-message-parsing.patch +Patch0161: 0161-bus-message-use-structured-initialization-to-avoid-u.patch +Patch0162: 0162-bus-message-avoid-an-infinite-loop-on-empty-structur.patch +Patch0163: 0163-bus-message-let-s-always-use-EBADMSG-when-the-messag.patch +Patch0164: 0164-bus-message-rename-function-for-clarity.patch +Patch0165: 0165-bus-message-use-define.patch +Patch0166: 0166-bus-do-not-print-null-if-the-message-has-unknown-typ.patch +Patch0167: 0167-bus-message-fix-calculation-of-offsets-table.patch +Patch0168: 0168-bus-message-remove-duplicate-assignment.patch +Patch0169: 0169-bus-message-fix-calculation-of-offsets-table-for-arr.patch +Patch0170: 0170-bus-message-drop-asserts-in-functions-which-are-wrap.patch +Patch0171: 0171-bus-message-output-debug-information-about-offset-tr.patch +Patch0172: 0172-bus-message-fix-skipping-of-array-fields-in-gvariant.patch +Patch0173: 0173-bus-message-also-properly-copy-struct-signature-when.patch +Patch0174: 0174-fuzz-bus-message-add-two-test-cases-that-pass-now.patch +Patch0175: 0175-bus-message-return-EBADMSG-not-EINVAL-on-invalid-gva.patch +Patch0176: 0176-bus-message-avoid-wrap-around-when-using-length-read.patch +Patch0177: 0177-util-do-not-use-stack-frame-for-parsing-arbitrary-in.patch +Patch0178: 0178-travis-enable-ASan-and-UBSan-on-RHEL8.patch +Patch0179: 0179-tests-keep-SYS_PTRACE-when-running-under-ASan.patch +Patch0180: 0180-tree-wide-various-ubsan-zero-size-memory-fixes.patch +Patch0181: 0181-util-introduce-memcmp_safe.patch +Patch0182: 0182-test-socket-util-avoid-memleak-reported-by-valgrind.patch +Patch0183: 0183-sd-journal-escape-binary-data-in-match_make_string.patch +Patch0184: 0184-capability-introduce-CAP_TO_MASK_CORRECTED-macro-rep.patch +Patch0185: 0185-sd-bus-use-size_t-when-dealing-with-memory-offsets.patch +Patch0186: 0186-sd-bus-call-cap_last_cap-only-once-in-has_cap.patch +Patch0187: 0187-mount-point-honour-AT_SYMLINK_FOLLOW-correctly.patch +Patch0188: 0188-travis-switch-from-trusty-to-xenial.patch +Patch0189: 0189-test-socket-util-Add-tests-for-receive_fd_iov-and-fr.patch +Patch0190: 0190-socket-util-Introduce-send_one_fd_iov-and-receive_on.patch +Patch0191: 0191-core-swap-order-of-n_storage_fds-and-n_socket_fds-pa.patch +Patch0192: 0192-execute-use-our-usual-syntax-for-defining-bit-masks.patch +Patch0193: 0193-core-introduce-new-Type-exec-service-type.patch +Patch0194: 0194-man-document-the-new-Type-exec-type.patch +Patch0195: 0195-sd-bus-allow-connecting-to-the-pseudo-container-.hos.patch +Patch0196: 0196-sd-login-let-s-also-make-sd-login-understand-.host.patch +Patch0197: 0197-test-add-test-for-Type-exec.patch +Patch0198: 0198-journal-gateway-explicitly-declare-local-variables.patch +Patch0199: 0199-tools-drop-unused-variable.patch +Patch0200: 0200-journal-gateway-use-localStorage-cursor-only-when-it.patch +Patch0201: 0201-sd-bus-deal-with-cookie-overruns.patch +Patch0202: 0202-journal-remote-do-not-request-Content-Length-if-Tran.patch +Patch0203: 0203-journal-do-not-remove-multiple-spaces-after-identifi.patch +Patch0204: 0204-cryptsetup-Do-not-fallback-to-PLAIN-mapping-if-LUKS-.patch +Patch0205: 0205-cryptsetup-call-crypt_load-for-LUKS-only-once.patch +Patch0206: 0206-cryptsetup-Add-LUKS2-token-support.patch +Patch0207: 0207-udev-scsi_id-fix-incorrect-page-length-when-get-devi.patch +Patch0208: 0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch +Patch0209: 0209-bash-completion-analyze-support-security.patch +Patch0210: 0210-man-note-that-journal-does-not-validate-syslog-field.patch +Patch0211: 0211-rules-skip-memory-hotplug-on-ppc64.patch +Patch0212: 0212-mount-simplify-proc-self-mountinfo-handler.patch +Patch0213: 0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch +Patch0214: 0214-swap-scan-proc-swaps-before-processing-waitid-result.patch +Patch0215: 0215-analyze-security-fix-potential-division-by-zero.patch +Patch0216: 0216-core-never-propagate-reload-failure-to-service-resul.patch +Patch0217: 0217-man-document-systemd-analyze-security.patch +Patch0218: 0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch +Patch0219: 0219-travis-move-to-CentOS-8-docker-images.patch +Patch0220: 0220-travis-drop-SCL-remains.patch +Patch0221: 0221-syslog-fix-segfault-in-syslog_parse_priority.patch +Patch0222: 0222-sd-bus-make-strict-asan-shut-up.patch +Patch0223: 0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch +Patch0224: 0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch +Patch0225: 0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch +Patch0226: 0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch +Patch0227: 0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch +Patch0228: 0228-udev-introduce-CONST-key-name.patch +Patch0229: 0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch +Patch0230: 0230-Consider-smb3-as-remote-filesystem.patch +Patch0231: 0231-process-util-introduce-pid_is_my_child-helper.patch +Patch0232: 0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch +Patch0233: 0233-core-only-watch-processes-when-it-s-really-necessary.patch +Patch0234: 0234-core-implement-per-unit-journal-rate-limiting.patch +Patch0235: 0235-path-stop-watching-path-specs-once-we-triggered-the-.patch +Patch0236: 0236-journald-fixed-assertion-failure-when-system-journal.patch +Patch0237: 0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch +Patch0238: 0238-test-mask-several-unnecessary-services.patch +Patch0239: 0239-test-bump-the-second-partition-s-size-to-50M.patch +Patch0240: 0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch +Patch0241: 0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch +Patch0242: 0242-sd-device-introduce-log_device_-macros.patch +Patch0243: 0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch +Patch0244: 0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch +Patch0245: 0245-sd-bus-adjust-indentation-of-comments.patch +Patch0246: 0246-resolved-do-not-run-loop-twice.patch +Patch0247: 0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch +Patch0248: 0248-resolved-query-polkit-only-after-parsing-the-data.patch +Patch0249: 0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch +Patch0250: 0250-basic-user-util-allow-dots-in-user-names.patch +Patch0251: 0251-sd-bus-bump-message-queue-size-again.patch +Patch0252: 0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch +Patch0253: 0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch +Patch0254: 0254-basic-remove-an-assertion-from-cunescape_one.patch +Patch0255: 0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch +Patch0256: 0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch +Patch0257: 0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch +Patch0258: 0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch +Patch0259: 0259-tests-add-a-fuzzer-for-process_audit_string.patch +Patch0260: 0260-journald-check-whether-sscanf-has-changed-the-value-.patch +Patch0261: 0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch +Patch0262: 0262-tests-add-a-fuzzer-for-journald-streams.patch +Patch0263: 0263-tests-add-a-fuzzer-for-server_process_native_file.patch +Patch0264: 0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch +Patch0265: 0265-journald-take-leading-spaces-into-account-in-syslog_.patch +Patch0266: 0266-Add-a-warning-about-the-difference-in-permissions-be.patch +Patch0267: 0267-execute-remove-one-redundant-comparison-check.patch +Patch0268: 0268-core-change-ownership-mode-of-the-execution-director.patch +Patch0269: 0269-core-dbus-execute-remove-unnecessary-initialization.patch +Patch0270: 0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch +Patch0271: 0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch +Patch0272: 0272-Rework-cpu-affinity-parsing.patch +Patch0273: 0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch +Patch0274: 0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch +Patch0275: 0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch +Patch0276: 0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch +Patch0277: 0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch +Patch0278: 0278-pid1-when-reloading-configuration-forget-old-setting.patch +Patch0279: 0279-test-execute-use-CPUSet-too.patch +Patch0280: 0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch +Patch0281: 0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch +Patch0282: 0282-test-cpu-set-util-add-test-for-dbus-conversions.patch +Patch0283: 0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch +Patch0284: 0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch +Patch0285: 0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch +Patch0286: 0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch +Patch0287: 0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch +Patch0288: 0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch +Patch0289: 0289-core-disable-CPUAccounting-by-default.patch +Patch0290: 0290-set-kptr_restrict-1.patch +Patch0291: 0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch +Patch0292: 0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch +Patch0293: 0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch +Patch0294: 0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch +Patch0295: 0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch +Patch0296: 0296-catalog-fix-name-of-variable.patch +Patch0297: 0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch +Patch0298: 0298-cryptsetup-add-documentation-for-keyfile-timeout.patch +Patch0299: 0299-cryptsetup-use-unabbrieviated-variable-names.patch +Patch0300: 0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch +Patch0301: 0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch +Patch0302: 0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch +Patch0303: 0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch +Patch0304: 0304-cryptsetup-downgrade-a-log-message-we-ignore.patch +Patch0305: 0305-cryptsetup-rework-how-we-log-about-activation-failur.patch +Patch0306: 0306-rules-reintroduce-60-alias-kmsg.rules.patch +Patch0307: 0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch +Patch0308: 0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch +Patch0309: 0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch +Patch0310: 0310-sd-bus-drop-two-inappropriate-empty-lines.patch +Patch0311: 0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch +Patch0312: 0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch +Patch0313: 0313-bus-message-introduce-two-kinds-of-references-to-bus.patch +Patch0314: 0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch +Patch0315: 0315-sd-event-add-sd_event_source_disable_unref-helper.patch +Patch0316: 0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch +Patch0317: 0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch +Patch0318: 0318-journal-do-not-trigger-assertion-when-journal_file_c.patch +Patch0319: 0319-journal-use-cleanup-attribute-at-one-more-place.patch +Patch0320: 0320-sd-bus-use-queue-message-references-for-managing-r-w.patch +Patch0321: 0321-pid1-make-sure-to-restore-correct-default-values-for.patch +Patch0322: 0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch +Patch0323: 0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch +Patch0324: 0324-test-add-test-case-for-restrict_suid_sgid.patch +Patch0325: 0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch +Patch0326: 0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch +Patch0327: 0327-man-document-the-new-RestrictSUIDSGID-setting.patch +Patch0328: 0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch +Patch0329: 0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch +Patch0330: 0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch +Patch0331: 0331-pid1-fix-DefaultTasksMax-initialization.patch +Patch0332: 0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch +Patch0333: 0333-test-introduce-TEST-36-NUMAPOLICY.patch +Patch0334: 0334-test-replace-tail-f-with-journal-cursor-which-should.patch +Patch0335: 0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch +Patch0336: 0336-test-make-sure-the-strace-process-is-indeed-dead.patch +Patch0337: 0337-test-skip-the-test-on-systems-without-NUMA-support.patch +Patch0338: 0338-test-give-strace-some-time-to-initialize.patch +Patch0339: 0339-test-add-a-simple-sanity-check-for-systems-without-N.patch +Patch0340: 0340-test-drop-the-missed-exit-1-expression.patch +Patch0341: 0341-test-replace-cursor-file-with-a-plain-cursor.patch +Patch0342: 0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch +Patch0343: 0343-swap-finish-the-secondary-swap-units-jobs-if-deactiv.patch +Patch0344: 0344-resolved-Recover-missing-PrivateTmp-yes-and-ProtectS.patch +Patch0345: 0345-bus_open-leak-sd_event_source-when-udevadm-trigger.patch +Patch0346: 0346-core-rework-StopWhenUnneeded-logic.patch +Patch0347: 0347-pid1-fix-the-names-of-AllowedCPUs-and-AllowedMemoryN.patch +Patch0348: 0348-core-fix-re-realization-of-cgroup-siblings.patch +Patch0349: 0349-basic-use-comma-as-separator-in-cpuset-cgroup-cpu-ra.patch +Patch0350: 0350-core-transition-to-FINAL_SIGTERM-state-after-ExecSto.patch +Patch0351: 0351-sd-journal-close-journal-files-that-were-deleted-by-.patch +Patch0352: 0352-sd-journal-remove-the-dead-code-and-actually-fix-146.patch +Patch0353: 0353-udev-downgrade-message-when-we-fail-to-set-inotify-w.patch +Patch0354: 0354-logind-check-PolicyKit-before-allowing-VT-switch.patch +Patch0355: 0355-test-do-not-use-global-variable-to-pass-error.patch +Patch0356: 0356-test-install-libraries-required-by-tests.patch +Patch0357: 0357-test-introduce-install_zoneinfo.patch +Patch0358: 0358-test-replace-duplicated-Makefile-by-symbolic-link.patch +Patch0359: 0359-test-add-paths-of-keymaps-in-install_keymaps.patch +Patch0360: 0360-test-make-install_keymaps-optionally-install-more-ke.patch +Patch0361: 0361-test-fs-util-skip-some-tests-when-running-in-unprivi.patch +Patch0362: 0362-test-process-util-skip-several-verifications-when-ru.patch +Patch0363: 0363-test-execute-also-check-python3-is-installed-or-not.patch +Patch0364: 0364-test-execute-skip-several-tests-when-running-in-cont.patch +Patch0365: 0365-test-introduce-test_is_running_from_builddir.patch +Patch0366: 0366-test-make-test-catalog-relocatable.patch +Patch0367: 0367-test-parallelize-tasks-in-TEST-24-UNIT-TESTS.patch +Patch0368: 0368-test-try-to-determine-QEMU_SMP-dynamically.patch +Patch0369: 0369-test-store-coredumps-in-journal.patch +Patch0370: 0370-pid1-add-new-kernel-cmdline-arg-systemd.cpu_affinity.patch +Patch0371: 0371-udev-rules-make-tape-changers-also-apprear-in-dev-ta.patch +Patch0372: 0372-man-be-clearer-that-.timer-time-expressions-need-to-.patch +Patch0373: 0373-Add-support-for-opening-files-for-appending.patch +Patch0374: 0374-nspawn-move-payload-to-sub-cgroup-first-then-sync-cg.patch +Patch0375: 0375-nspawn-chown-the-legacy-hierarchy-when-it-s-used-in-.patch +Patch0376: 0376-core-move-unit_status_emit_starting_stopping_reloadi.patch +Patch0377: 0377-job-when-a-job-was-skipped-due-to-a-failed-condition.patch +Patch0378: 0378-core-split-out-all-logic-that-updates-a-Job-on-a-uni.patch +Patch0379: 0379-core-make-log-messages-about-units-entering-a-failed.patch +Patch0380: 0380-core-log-a-recognizable-message-when-a-unit-succeeds.patch +Patch0381: 0381-tests-always-use-the-right-vtable-wrapper-calls.patch +Patch0382: 0382-test-execute-allow-filtering-test-cases-by-pattern.patch +Patch0383: 0383-test-execute-provide-custom-failure-message.patch +Patch0384: 0384-core-ExecCondition-for-services.patch +Patch0385: 0385-Drop-support-for-lz4-1.3.0.patch +Patch0386: 0386-test-compress-add-test-for-short-decompress_startswi.patch +Patch0387: 0387-journal-adapt-for-new-improved-LZ4_decompress_safe_p.patch +Patch0388: 0388-fuzz-compress-add-fuzzer-for-compression-and-decompr.patch +Patch0389: 0389-seccomp-fix-__NR__sysctl-usage.patch +Patch0390: 0390-tmpfiles-fix-crash-with-NULL-in-arg_root-and-other-f.patch +Patch0391: 0391-sulogin-shell-Use-force-if-SYSTEMD_SULOGIN_FORCE-set.patch +Patch0392: 0392-resolvconf-fixes-for-the-compatibility-interface.patch +Patch0393: 0393-mount-don-t-add-Requires-for-tmp.mount.patch +Patch0394: 0394-core-coldplug-possible-nop_job.patch +Patch0395: 0395-core-add-IODeviceLatencyTargetSec.patch +Patch0396: 0396-time-util-Introduce-parse_sec_def_infinity.patch +Patch0397: 0397-cgroup-use-structured-initialization.patch +Patch0398: 0398-core-add-CPUQuotaPeriodSec.patch +Patch0399: 0399-core-downgrade-CPUQuotaPeriodSec-clamping-logs-to-de.patch +Patch0400: 0400-sd-bus-avoid-magic-number-in-SASL-length-calculation.patch +Patch0401: 0401-sd-bus-fix-SASL-reply-to-empty-AUTH.patch +Patch0402: 0402-sd-bus-skip-sending-formatted-UIDs-via-SASL.patch +Patch0403: 0403-core-add-MemoryMin.patch +Patch0404: 0404-core-introduce-cgroup_add_device_allow.patch +Patch0405: 0405-test-remove-support-for-suffix-in-get_testdata_dir.patch +Patch0406: 0406-cgroup-Implement-default-propagation-of-MemoryLow-wi.patch +Patch0407: 0407-cgroup-Create-UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP.patch +Patch0408: 0408-unit-Add-DefaultMemoryMin.patch +Patch0409: 0409-cgroup-Polish-hierarchically-aware-protection-docs-a.patch +Patch0410: 0410-cgroup-Readd-some-plumbing-for-DefaultMemoryMin.patch +Patch0411: 0411-cgroup-Support-0-value-for-memory-protection-directi.patch +Patch0412: 0412-cgroup-Test-that-it-s-possible-to-set-memory-protect.patch +Patch0413: 0413-cgroup-Check-ancestor-memory-min-for-unified-memory-.patch +Patch0414: 0414-cgroup-Respect-DefaultMemoryMin-when-setting-memory..patch +Patch0415: 0415-cgroup-Mark-memory-protections-as-explicitly-set-in-.patch +Patch0416: 0416-meson-allow-setting-the-version-string-during-config.patch +Patch0417: 0417-core-don-t-consider-SERVICE_SKIP_CONDITION-for-abnor.patch +Patch0418: 0418-selinux-do-preprocessor-check-only-in-selinux-access.patch +Patch0419: 0419-basic-cgroup-util-introduce-cg_get_keyed_attribute_f.patch +Patch0420: 0420-shared-add-generic-logic-for-waiting-for-a-unit-to-e.patch +Patch0421: 0421-shared-fix-assert-call.patch +Patch0422: 0422-shared-Don-t-try-calling-NULL-callback-in-bus_wait_f.patch +Patch0423: 0423-shared-add-NULL-callback-check-in-one-more-place.patch +Patch0424: 0424-core-introduce-support-for-cgroup-freezer.patch +Patch0425: 0425-core-cgroup-fix-return-value-of-unit_cgorup_freezer_.patch +Patch0426: 0426-core-fix-the-return-value-in-order-to-make-sure-we-d.patch +Patch0427: 0427-test-add-test-for-cgroup-v2-freezer-support.patch +Patch0428: 0428-fix-mis-merge.patch +Patch0429: 0429-tests-sleep-a-bit-and-give-kernel-time-to-perform-th.patch +Patch0430: 0430-device-make-sure-we-emit-PropertiesChanged-signal-on.patch +Patch0431: 0431-device-don-t-emit-PropetiesChanged-needlessly.patch +Patch0432: 0432-units-add-generic-boot-complete.target.patch +Patch0433: 0433-man-document-new-boot-complete.target-unit.patch +Patch0434: 0434-core-make-sure-to-restore-the-control-command-id-too.patch +Patch0435: 0435-cgroup-freezer-action-must-be-NOP-when-cgroup-v2-fre.patch +Patch0436: 0436-logind-don-t-print-warning-when-user-.service-templa.patch +Patch0437: 0437-build-use-simple-project-version-in-pkgconfig-files.patch +Patch0438: 0438-basic-virt-try-the-proc-1-sched-hack-also-for-PID1.patch +Patch0439: 0439-seccomp-rework-how-the-S-UG-ID-filter-is-installed.patch +Patch0440: 0440-vconsole-setup-downgrade-log-message-when-setting-fo.patch +Patch0441: 0441-units-fix-systemd.special-man-page-reference-in-syst.patch +Patch0442: 0442-units-drop-reference-to-sushell-man-page.patch +Patch0443: 0443-sd-bus-break-the-loop-in-bus_ensure_running-if-the-b.patch +Patch0444: 0444-core-add-new-API-for-enqueing-a-job-with-returning-t.patch +Patch0445: 0445-systemctl-replace-switch-statement-by-table-of-struc.patch +Patch0446: 0446-systemctl-reindent-table.patch +Patch0447: 0447-systemctl-Only-wait-when-there-s-something-to-wait-f.patch +Patch0448: 0448-systemctl-clean-up-start_unit_one-error-handling.patch +Patch0449: 0449-systemctl-split-out-extra-args-generation-into-helpe.patch +Patch0450: 0450-systemctl-add-new-show-transaction-switch.patch +Patch0451: 0451-test-add-some-basic-testing-that-systemctl-start-T-d.patch +Patch0452: 0452-man-document-the-new-systemctl-show-transaction-opti.patch +Patch0453: 0453-socket-New-option-FlushPending-boolean-to-flush-sock.patch +Patch0454: 0454-core-remove-support-for-API-bus-started-outside-our-.patch +Patch0455: 0455-mount-setup-fix-segfault-in-mount_cgroup_controllers.patch +Patch0456: 0456-dbus-execute-make-transfer-of-CPUAffinity-endian-saf.patch +Patch0457: 0457-core-add-support-for-setting-CPUAffinity-to-special-.patch +Patch0458: 0458-basic-user-util-always-use-base-10-for-user-group-nu.patch +Patch0459: 0459-parse-util-sometimes-it-is-useful-to-check-if-a-stri.patch +Patch0460: 0460-basic-parse-util-add-safe_atoux64.patch +Patch0461: 0461-parse-util-allow-tweaking-how-to-parse-integers.patch +Patch0462: 0462-parse-util-allow-0-as-alternative-to-0-and-0.patch +Patch0463: 0463-parse-util-make-return-parameter-optional-in-safe_at.patch +Patch0464: 0464-parse-util-rewrite-parse_mode-on-top-of-safe_atou_fu.patch +Patch0465: 0465-user-util-be-stricter-in-parse_uid.patch +Patch0466: 0466-strv-add-new-macro-STARTSWITH_SET.patch +Patch0467: 0467-parse-util-also-parse-integers-prefixed-with-0b-and-.patch +Patch0468: 0468-tests-beef-up-integer-parsing-tests.patch +Patch0469: 0469-shared-user-util-add-compat-forms-of-user-name-check.patch +Patch0470: 0470-shared-user-util-emit-a-warning-on-names-with-dots.patch +Patch0471: 0471-user-util-Allow-names-starting-with-a-digit.patch +Patch0472: 0472-shared-user-util-allow-usernames-with-dots-in-specif.patch +Patch0473: 0473-user-util-switch-order-of-checks-in-valid_user_group.patch +Patch0474: 0474-user-util-rework-how-we-validate-user-names.patch +Patch0475: 0475-man-mention-System-Administrator-s-Guide-in-systemct.patch +Patch0476: 0476-udev-introduce-udev-net_id-naming-schemes.patch +Patch0477: 0477-meson-make-net.naming-scheme-default-configurable.patch +Patch0478: 0478-man-describe-naming-schemes-in-a-new-man-page.patch +Patch0479: 0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch +Patch0480: 0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch +Patch0481: 0481-fix-typo-in-ProtectSystem-option.patch +Patch0482: 0482-remove-references-of-non-existent-man-pages.patch +Patch0483: 0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch +Patch0484: 0484-locale-util-add-new-helper-locale_is_installed.patch +Patch0485: 0485-test-add-test-case-for-locale_is_installed.patch +Patch0486: 0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch +Patch0487: 0487-install-allow-instantiated-units-to-be-enabled-via-p.patch +Patch0488: 0488-install-small-refactor-to-combine-two-function-calls.patch +Patch0489: 0489-test-fix-a-memleak.patch +Patch0490: 0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch +Patch0491: 0491-shared-install-fix-preset-operations-for-non-service.patch +Patch0492: 0492-introduce-setsockopt_int-helper.patch +Patch0493: 0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch +Patch0494: 0494-core-add-new-PassPacketInfo-socket-unit-property.patch +Patch0495: 0495-resolved-tweak-cmsg-calculation.patch +Patch0496: 0496-ci-PowerTools-repo-was-renamed-to-powertools-in-RHEL.patch +Patch0497: 0497-ci-use-quay.io-instead-of-Docker-Hub-to-avoid-rate-l.patch +Patch0498: 0498-ci-move-jobs-from-Travis-CI-to-GH-Actions.patch +Patch0499: 0499-unit-make-UNIT-cast-function-deal-with-NULL-pointers.patch +Patch0500: 0500-use-link-to-RHEL-8-docs.patch +Patch0501: 0501-cgroup-Also-set-blkio.bfq.weight.patch +Patch0502: 0502-units-make-sure-initrd-cleanup.service-terminates-be.patch +Patch0503: 0503-core-reload-SELinux-label-cache-on-daemon-reload.patch +Patch0504: 0504-selinux-introduce-mac_selinux_create_file_prepare_at.patch +Patch0505: 0505-selinux-add-trigger-for-policy-reload-to-refresh-int.patch +Patch0506: 0506-udev-net_id-give-RHEL-8.4-naming-scheme-a-name.patch +Patch0507: 0507-basic-stat-util-make-mtime-check-stricter-and-use-en.patch +Patch0508: 0508-udev-make-algorithm-that-selects-highest-priority-de.patch +Patch0509: 0509-test-create-dev-null-in-test-udev.pl.patch +Patch0510: 0510-test-missing-die.patch +Patch0511: 0511-udev-test-remove-a-check-for-whether-the-test-is-run.patch +Patch0512: 0512-udev-test-skip-the-test-only-if-it-can-t-setup-its-e.patch +Patch0513: 0513-udev-test-fix-test-skip-condition.patch +Patch0514: 0514-udev-test-fix-missing-directory-test-run.patch +Patch0515: 0515-udev-test-check-if-permitted-to-create-block-device-.patch +Patch0516: 0516-test-udev-add-a-testcase-of-too-long-line.patch +Patch0517: 0517-test-udev-use-proper-semantics-for-too-long-line-wit.patch +Patch0518: 0518-test-udev-add-more-tests-for-line-continuations-and-.patch +Patch0519: 0519-test-udev-add-more-tests-for-line-continuation.patch +Patch0520: 0520-test-udev-fix-alignment-and-drop-unnecessary-white-s.patch +Patch0521: 0521-test-udev-test.pl-cleanup-if-skipping-test.patch +Patch0522: 0522-test-add-test-cases-for-empty-string-match.patch +Patch0523: 0523-test-add-test-case-for-multi-matches-when-use.patch +Patch0524: 0524-udev-test-do-not-rely-on-mail-group-being-defined.patch +Patch0525: 0525-test-udev-test.pl-allow-multiple-devices-per-test.patch +Patch0526: 0526-test-udev-test.pl-create-rules-only-once.patch +Patch0527: 0527-test-udev-test.pl-allow-concurrent-additions-and-rem.patch +Patch0528: 0528-test-udev-test.pl-use-computed-devnode-name.patch +Patch0529: 0529-test-udev-test.pl-test-correctness-of-symlink-target.patch +Patch0530: 0530-test-udev-test.pl-allow-checking-multiple-symlinks.patch +Patch0531: 0531-test-udev-test.pl-fix-wrong-test-descriptions.patch +Patch0532: 0532-test-udev-test.pl-last_rule-is-unsupported.patch +Patch0533: 0533-test-udev-test.pl-Make-some-tests-a-little-harder.patch +Patch0534: 0534-test-udev-test.pl-remove-bogus-rules-from-magic-subs.patch +Patch0535: 0535-test-udev-test.pl-merge-space-and-var-with-space-tes.patch +Patch0536: 0536-test-udev-test.pl-merge-import-parent-tests-into-one.patch +Patch0537: 0537-test-udev-test.pl-count-good-results.patch +Patch0538: 0538-tests-udev-test.pl-add-multiple-device-test.patch +Patch0539: 0539-test-udev-test.pl-add-repeat-count.patch +Patch0540: 0540-test-udev-test.pl-generator-for-large-list-of-block-.patch +Patch0541: 0541-test-udev-test.pl-suppress-umount-error-message-at-s.patch +Patch0542: 0542-test-udev_test.pl-add-expected-good-count.patch +Patch0543: 0543-test-udev-test-gracefully-exit-when-imports-fail.patch +Patch0544: 0544-Revert-test-add-test-cases-for-empty-string-match-an.patch +Patch0545: 0545-test-sys-script.py-add-missing-DEVNAME-entries-to-ue.patch +Patch0546: 0546-sd-event-split-out-helper-functions-for-reshuffling-.patch +Patch0547: 0547-sd-event-split-out-enable-and-disable-codepaths-from.patch +Patch0548: 0548-sd-event-mention-that-two-debug-logged-events-are-ig.patch +Patch0549: 0549-sd-event-split-clock-data-allocation-out-of-sd_event.patch +Patch0550: 0550-sd-event-split-out-code-to-add-remove-timer-event-so.patch +Patch0551: 0551-sd-event-fix-delays-assert-brain-o-17790.patch +Patch0552: 0552-sd-event-let-s-suffix-last_run-last_log-with-_usec.patch +Patch0553: 0553-sd-event-refuse-running-default-event-loops-in-any-o.patch +Patch0554: 0554-sd-event-ref-event-loop-while-in-sd_event_prepare-ot.patch +Patch0555: 0555-sd-event-follow-coding-style-with-naming-return-para.patch +Patch0556: 0556-sd-event-remove-earliest_index-latest_index-into-com.patch +Patch0557: 0557-sd-event-update-state-at-the-end-in-event_source_ena.patch +Patch0558: 0558-sd-event-increase-n_enabled_child_sources-just-once.patch +Patch0559: 0559-sd-event-add-ability-to-ratelimit-event-sources.patch +Patch0560: 0560-test-add-ratelimiting-test.patch +Patch0561: 0561-core-prevent-excessive-proc-self-mountinfo-parsing.patch +Patch0562: 0562-udev-run-link_update-with-increased-retry-count-in-s.patch +Patch0563: 0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch +Patch0564: 0564-Revert-udev-run-link_update-with-increased-retry-cou.patch +Patch0565: 0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch +Patch0566: 0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch +Patch0567: 0567-cgroup-Also-set-io.bfq.weight.patch +Patch0568: 0568-seccomp-allow-turning-off-of-seccomp-filtering-via-e.patch +Patch0569: 0569-meson-remove-strange-dep-that-causes-meson-to-enter-.patch +Patch0570: 0570-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch +Patch0571: 0571-core-Hide-Deactivated-successfully-message.patch +Patch0572: 0572-util-rework-in_initrd-to-make-use-of-path_is_tempora.patch +Patch0573: 0573-initrd-extend-SYSTEMD_IN_INITRD-to-accept-non-ramfs-.patch +Patch0574: 0574-initrd-do-a-debug-log-if-failed-to-detect-rootfs-typ.patch +Patch0575: 0575-initrd-do-a-debug-log-if-etc-initrd-release-doesn-t-.patch +Patch0576: 0576-units-assign-user-runtime-dir-.service-to-user-i.sli.patch +Patch0577: 0577-units-order-user-runtime-dir-.service-after-systemd-.patch +Patch0578: 0578-units-make-sure-user-runtime-dir-.service-is-Type-on.patch +Patch0579: 0579-user-runtime-dir-downgrade-a-few-log-messages-to-LOG.patch +Patch0580: 0580-shared-install-Preserve-escape-characters-for-escape.patch +Patch0581: 0581-basic-virt-Detect-PowerVM-hypervisor.patch +Patch0582: 0582-man-document-differences-in-clean-exit-status-for-Ty.patch +Patch0583: 0583-busctl-add-a-timestamp-to-the-output-of-the-busctl-m.patch +Patch0584: 0584-basic-cap-list-parse-print-numerical-capabilities.patch +Patch0585: 0585-shared-mount-util-convert-to-libmount.patch +Patch0586: 0586-mount-util-bind_remount-avoid-calling-statvfs.patch +Patch0587: 0587-mount-util-use-UMOUNT_NOFOLLOW-in-recursive-umounter.patch +Patch0588: 0588-test-install-root-create-referenced-targets.patch +Patch0589: 0589-install-warn-if-WantedBy-targets-don-t-exist.patch +Patch0590: 0590-test-install-root-add-test-for-unknown-WantedBy-targ.patch +Patch0591: 0591-ceph-is-a-network-filesystem.patch +Patch0592: 0592-sysctl-set-kernel.core_pipe_limit-16.patch +Patch0593: 0593-core-don-t-drop-timer-expired-but-not-yet-processed-.patch +Patch0594: 0594-core-Detect-initial-timer-state-from-serialized-data.patch +Patch0595: 0595-rc-local-order-after-network-online.target.patch +Patch0596: 0596-set-core-ulimit-to-0-like-on-RHEL-7.patch +Patch0597: 0597-test-mountpointutil-util-do-not-assert-in-test_mnt_i.patch +Patch0598: 0598-remove-a-left-over-break.patch +Patch0599: 0599-basic-unit-name-do-not-use-strdupa-on-a-path.patch +Patch0600: 0600-sd-event-change-ordering-of-pending-ratelimited-even.patch +Patch0601: 0601-sd-event-drop-unnecessary-else.patch +Patch0602: 0602-sd-event-use-CMP-macro.patch +Patch0603: 0603-sd-event-use-usec_add.patch +Patch0604: 0604-sd-event-make-event_source_time_prioq_reshuffle-acce.patch +Patch0605: 0605-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch +Patch0606: 0606-ci-run-unit-tests-on-z-stream-branches-as-well.patch +Patch0607: 0607-ci-drop-forgotten-Travis-references.patch +Patch0608: 0608-ci-run-unit-tests-on-CentOS-8-Stream-as-well.patch +Patch0609: 0609-ci-add-missing-test-dependencies.patch +Patch0610: 0610-meson-bump-timeout-for-test-udev-to-180s.patch +Patch0611: 0611-Added-option-check-inhibitors-for-non-tty-usage.patch +Patch0612: 0612-logind-Introduce-RebootWithFlags-and-others.patch +Patch0613: 0613-logind-add-WithFlags-methods-to-policy.patch +Patch0614: 0614-logind-simplify-flags-handling-a-bit.patch +Patch0615: 0615-Update-link-to-RHEL-documentation.patch +Patch0616: 0616-Set-default-core-ulimit-to-0-but-keep-the-hard-limit.patch +Patch0617: 0617-shared-seccomp-util-address-family-filtering-is-brok.patch +Patch0618: 0618-logind-rework-Seat-Session-User-object-allocation-an.patch +Patch0619: 0619-logind-fix-serialization-deserialization-of-user-s-d.patch +Patch0620: 0620-logind-turn-of-stdio-locking-when-writing-session-fi.patch +Patch0621: 0621-units-set-StopWhenUnneeded-for-the-user-slice-units-.patch +Patch0622: 0622-units-improve-Description-string-a-bit.patch +Patch0623: 0623-logind-improve-logging-in-manager_connect_console.patch +Patch0624: 0624-logind-save-restore-User-object-s-stopping-field-dur.patch +Patch0625: 0625-logind-correct-bad-clean-up-path.patch +Patch0626: 0626-logind-fix-bad-error-propagation.patch +Patch0627: 0627-logind-never-elect-a-session-that-is-stopping-as-dis.patch +Patch0628: 0628-logind-introduce-little-helper-that-checks-whether-a.patch +Patch0629: 0629-logind-propagate-session-stop-errors.patch +Patch0630: 0630-logind-rework-how-we-manage-the-slice-and-user-runti.patch +Patch0631: 0631-logind-optionally-keep-the-user-.service-instance-fo.patch +Patch0632: 0632-logind-add-a-RequiresMountsFor-dependency-from-the-s.patch +Patch0633: 0633-logind-improve-error-propagation-of-user_check_linge.patch +Patch0634: 0634-logind-automatically-GC-lingering-users-for-who-now-.patch +Patch0635: 0635-pam_systemd-simplify-code-which-with-we-set-environm.patch +Patch0636: 0636-logind-validate-run-user-1000-before-we-set-it.patch +Patch0637: 0637-sd-hwdb-allow-empty-properties.patch +Patch0638: 0638-Update-hwdb.patch +Patch0639: 0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch +Patch0640: 0640-rpm-Fix-typo-in-_environmentdir.patch +Patch0641: 0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch +Patch0642: 0642-rpm-emit-warning-when-macro-with-typo-is-used.patch +Patch0643: 0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch +Patch0644: 0644-Disable-iptables-for-CI.patch +Patch0645: 0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch +Patch0646: 0646-core-service-also-check-path-in-exec-commands.patch +Patch0647: 0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch +Patch0648: 0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch +Patch0649: 0649-pam-do-not-require-a-non-expired-password-for-user-..patch +Patch0650: 0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch +Patch0651: 0651-process-util-explicitly-handle-processes-lacking-par.patch +Patch0652: 0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch +Patch0653: 0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch +Patch0654: 0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch +Patch0655: 0655-journal-refresh-cached-credentials-of-stdout-streams.patch +Patch0656: 0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch +Patch0657: 0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch +Patch0658: 0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch +Patch0659: 0659-test-accept-that-char-device-0-0-can-now-be-created-.patch +Patch0660: 0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch +Patch0661: 0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch +Patch0662: 0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch +Patch0663: 0663-core-consider-service-with-no-start-command-immediat.patch +Patch0664: 0664-man-move-description-of-Action-modes-to-FailureActio.patch +Patch0665: 0665-core-define-exit-and-exit-force-actions-for-user-uni.patch +Patch0666: 0666-core-accept-system-mode-emergency-action-specifiers-.patch +Patch0667: 0667-core-allow-services-with-no-commands-but-SuccessActi.patch +Patch0668: 0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch +Patch0669: 0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch +Patch0670: 0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch +Patch0671: 0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch +Patch0672: 0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch +Patch0673: 0673-core-do-not-warn-about-mundane-emergency-actions.patch +Patch0674: 0674-core-return-true-from-cg_is_empty-on-ENOENT.patch +Patch0675: 0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch +Patch0676: 0676-tests-add-helper-function-to-autodetect-CI-environme.patch +Patch0677: 0677-strv-rework-FOREACH_STRING-macro.patch +Patch0678: 0678-test-systemctl-use-const-char-instead-of-char.patch +Patch0679: 0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch +Patch0680: 0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch +Patch0681: 0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch +Patch0682: 0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch +Patch0683: 0683-lgtm-warn-about-strerror-use.patch +Patch0684: 0684-lgtm-complain-about-accept-people-should-use-accept4.patch +Patch0685: 0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch +Patch0686: 0686-lgtm-ignore-certain-cleanup-functions.patch +Patch0687: 0687-lgtm-detect-more-possible-problematic-scenarios.patch +Patch0688: 0688-lgtm-enable-more-and-potentially-useful-queries.patch +Patch0689: 0689-meson-avoid-bogus-meson-warning.patch +Patch0690: 0690-test-make-TEST-47-less-racy.patch +Patch0691: 0691-core-rename-unit_-start_limit-condition-assert-_test.patch +Patch0692: 0692-core-Check-unit-start-rate-limiting-earlier.patch +Patch0693: 0693-sd-event-introduce-callback-invoked-when-event-sourc.patch +Patch0694: 0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch +Patch0695: 0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch +Patch0696: 0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch +Patch0697: 0697-pid1-add-a-manager_trigger_run_queue-helper.patch +Patch0698: 0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch +Patch0699: 0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch +Patch0700: 0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch +Patch0701: 0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch +Patch0702: 0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch +Patch0703: 0703-udev-net_id-remove-extraneous-bracket.patch +Patch0704: 0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch +Patch0705: 0705-define-newly-needed-constants.patch +Patch0706: 0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch +Patch0707: 0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch +Patch0708: 0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch +Patch0709: 0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch +Patch0710: 0710-util-introduce-ifname_valid_full.patch +Patch0711: 0711-rename-function.patch +Patch0712: 0712-udev-support-AlternativeName-setting-in-.link-file.patch +Patch0713: 0713-network-make-Name-in-Match-support-alternative-names.patch +Patch0714: 0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch +Patch0715: 0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch +Patch0716: 0716-udev-introduce-AlternativeNamesPolicy-setting.patch +Patch0717: 0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch +Patch0718: 0718-random-util-call-initialize_srand-after-fork.patch +Patch0719: 0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch +Patch0720: 0720-udev-sort-alternative-names.patch +Patch0721: 0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch +Patch0722: 0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch +Patch0723: 0723-udev-do-not-try-to-reassign-alternative-names.patch +Patch0724: 0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch +Patch0725: 0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch +Patch0726: 0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch +Patch0727: 0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch +Patch0728: 0728-core-make-destructive-transaction-error-a-bit-more-u.patch +Patch0729: 0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch +Patch0730: 0730-tmpfiles-rework-condition-check.patch +Patch0731: 0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch +Patch0732: 0732-core-make-sure-we-don-t-get-confused-when-setting-TE.patch +Patch0733: 0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch +Patch0734: 0734-hash-func-add-destructors-for-key-and-value.patch +Patch0735: 0735-util-define-free_func_t.patch +Patch0736: 0736-hash-funcs-make-basic-hash_ops-typesafe.patch +Patch0737: 0737-test-add-tests-for-destructors-of-hashmap-or-set.patch +Patch0738: 0738-man-document-the-new-sysctl.d-prefix.patch +Patch0739: 0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch +Patch0740: 0740-sysctl-fix-segfault.patch +Patch0741: 0741-ci-drop-CentOS-8-CI.patch +Patch0742: 0742-test-adapt-to-the-new-capsh-format.patch +Patch0743: 0743-test-ignore-IAB-capabilities-in-test-execute.patch +Patch0744: 0744-core-disallow-using-.service-as-a-service-name.patch +Patch0745: 0745-shared-dropin-support-.service.d-top-level-drop-in-f.patch +Patch0746: 0746-core-change-top-level-drop-in-from-.service.d-to-ser.patch +Patch0747: 0747-shared-dropin-fix-assert-for-invalid-drop-in.patch +Patch0748: 0748-udev-fix-slot-based-network-names-on-s390.patch +Patch0749: 0749-udev-add-missing-initialization-to-fix-freeing-inval.patch +Patch0750: 0750-udev-it-is-not-necessary-that-the-path-is-readable.patch +Patch0751: 0751-udev-allow-onboard-index-up-to-65535.patch +Patch0752: 0752-Revert-basic-use-comma-as-separator-in-cpuset-cgroup.patch +Patch0753: 0753-acpi-fpdt-mark-structures-as-packed.patch +Patch0754: 0754-core-slice-make-slice_freezer_action-return-0-if-fre.patch +Patch0755: 0755-core-unit-fix-use-after-free.patch +Patch0756: 0756-sd-bus-fix-reference-counter-to-be-incremented.patch +Patch0757: 0757-sd-bus-do-not-read-unused-value.patch +Patch0758: 0758-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch +Patch0759: 0759-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch +Patch0760: 0760-resolved-let-s-preferably-route-reverse-lookups-for-.patch +Patch0761: 0761-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch +Patch0762: 0762-tests-make-inverted-tests-actually-count.patch +Patch0763: 0763-TEST-make-failure-tests-actually-fail-on-failure.patch +Patch0764: 0764-ci-Mergify-configuration-update.patch +Patch0765: 0765-core-propagate-triggered-unit-in-more-load-states.patch +Patch0766: 0766-core-propagate-unit-start-limit-hit-state-to-trigger.patch +Patch0767: 0767-core-Move-r-variable-declaration-to-start-of-unit_st.patch +Patch0768: 0768-core-Delay-start-rate-limit-check-when-starting-a-un.patch +Patch0769: 0769-core-Propagate-condition-failed-state-to-triggering-.patch +Patch0770: 0770-unit-check-for-mount-rate-limiting-before-checking-a.patch +Patch0771: 0771-mkosi-Add-gnutls-package.patch +Patch0772: 0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch +Patch0773: 0773-core-shorten-long-unit-names-that-are-based-on-paths.patch +Patch0774: 0774-test-add-extended-test-for-triggering-mount-rate-lim.patch +Patch0775: 0775-tests-add-test-case-for-long-unit-names.patch +Patch0776: 0776-core-unset-HOME-that-the-kernel-gives-us.patch +Patch0777: 0777-journal-remote-check-return-value-from-MHD_add_respo.patch +Patch0778: 0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch +Patch0779: 0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch +Patch0780: 0780-fstab-generator-fix-debug-log.patch +Patch0781: 0781-logind-session-dbus-allow-to-set-display-name-via-db.patch +Patch0782: 0782-Allow-restart-for-oneshot-units.patch +Patch0783: 0783-test-correct-TEST-41-StartLimitBurst-test.patch +Patch0784: 0784-core-fix-assert-about-number-of-built-environment-va.patch +Patch0785: 0785-core-add-one-more-assert.patch +Patch0786: 0786-strv-introduce-strv_join_prefix.patch +Patch0787: 0787-test-add-tests-for-strv_join_prefix.patch +Patch0788: 0788-test-replace-swear-words-by-hoge.patch +Patch0789: 0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch +Patch0790: 0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch +Patch0791: 0791-man-document-RUNTIME_DIRECTORY-or-friends.patch +Patch0792: 0792-ci-bump-the-worker-Ubuntu-version-to-Jammy.patch +Patch0793: 0793-test-make-test-execute-pass-on-Linux-5.15.patch +Patch0794: 0794-ci-install-iputils.patch +Patch0795: 0795-ci-Mergify-Add-ci-waived-logic.patch +Patch0796: 0796-sd-event-don-t-invalidate-source-type-on-disconnect.patch +Patch0797: 0797-tests-make-sure-we-delay-running-mount-start-jobs-wh.patch +Patch0798: 0798-core-drop-references-to-StandardOutputFileToCreate.patch +Patch0799: 0799-dbus-execute-fix-indentation.patch +Patch0800: 0800-dbus-execute-generate-the-correct-transient-unit-set.patch +Patch0801: 0801-bus-unit-util-properly-accept-StandardOutput-append-.patch +Patch0802: 0802-core-be-more-careful-when-inheriting-stdout-fds-to-s.patch +Patch0803: 0803-test-add-a-test-for-StandardError-file.patch +Patch0804: 0804-tree-wide-allow-ASCII-fallback-for-in-logs.patch +Patch0805: 0805-tree-wide-allow-ASCII-fallback-for-in-logs.patch +Patch0806: 0806-core-allow-to-set-default-timeout-for-devices.patch +Patch0807: 0807-man-document-DefaultDeviceTimeoutSec.patch +Patch0808: 0808-Revert-core-Propagate-condition-failed-state-to-trig.patch +Patch0809: 0809-core-Check-unit-start-rate-limiting-earlier.patch +Patch0810: 0810-core-Add-trigger-limit-for-path-units.patch +Patch0811: 0811-meson-add-syscall-names-update-target.patch +Patch0812: 0812-syscall-names-add-process_madvise-which-is-planned-f.patch +Patch0813: 0813-shared-add-known-syscall-list.patch +Patch0814: 0814-generate-syscall-list-require-python3.patch +Patch0815: 0815-shared-seccomp-reduce-scope-of-indexing-variables.patch +Patch0816: 0816-shared-syscall-list-filter-out-some-obviously-platfo.patch +Patch0817: 0817-seccomp-tighten-checking-of-seccomp-filter-creation.patch +Patch0818: 0818-shared-seccomp-util-added-functionality-to-make-list.patch +Patch0819: 0819-nspawn-return-ENOSYS-by-default-EPERM-for-known-call.patch +Patch0820: 0820-test-procfs-util-skip-test-on-certain-errors.patch +Patch0821: 0821-Try-stopping-MD-RAID-devices-in-shutdown-too.patch +Patch0822: 0822-shutdown-get-only-active-md-arrays.patch +Patch0823: 0823-scope-allow-unprivileged-delegation-on-scopes.patch +Patch0824: 0824-resolved-pin-stream-while-calling-callbacks-for-it.patch +Patch0825: 0825-ci-functions-Add-useradd-and-userdel.patch +Patch0826: 0826-logind-optionally-watch-utmp-for-login-data.patch +Patch0827: 0827-logind-add-hashtable-for-finding-session-by-leader-P.patch +Patch0828: 0828-core-load-fragment-move-config_parse_sec_fix_0-to-sr.patch +Patch0829: 0829-sd-event-add-relative-timer-calls.patch +Patch0830: 0830-logind-add-option-to-stop-idle-sessions-after-specif.patch +Patch0831: 0831-logind-schedule-idle-check-full-interval-from-now-if.patch +Patch0832: 0832-ci-lint-add-shell-linter-Differential-ShellCheck.patch +Patch0833: 0833-meson-do-not-compare-objects-of-different-types.patch +Patch0834: 0834-journal-remote-use-MHD_HTTP_CONTENT_TOO_LARGE-as-MHD.patch +Patch0835: 0835-Fix-build-with-httpd-0.9.71.patch +Patch0836: 0836-ci-replace-LGTM-with-CodeQL.patch +Patch0837: 0837-ci-mergify-Update-policy-Drop-LGTM-checks.patch +Patch0838: 0838-time-util-fix-buffer-over-run.patch +Patch0839: 0839-basic-recognize-pdfs-filesystem-as-a-network-filesys.patch +Patch0840: 0840-core-move-reset_arguments-to-the-end-of-main-s-finis.patch +Patch0841: 0841-manager-move-inc.-of-n_reloading-into-a-function.patch +Patch0842: 0842-core-Add-new-DBUS-properties-UnitsReloadStartTimesta.patch +Patch0843: 0843-core-Indicate-the-time-when-the-manager-started-load.patch +Patch0844: 0844-core-do-not-touch-run-systemd-systemd-units-load-fro.patch +Patch0845: 0845-sysctl-downgrade-message-when-we-have-no-permission.patch +Patch0846: 0846-core-respect-SELinuxContext-for-socket-creation.patch +Patch0847: 0847-manager-use-target-process-context-to-set-socket-con.patch +Patch0848: 0848-virt-detect-Amazon-EC2-Nitro-instance.patch +Patch0849: 0849-machine-id-setup-generate-machine-id-from-DMI-produc.patch +Patch0850: 0850-virt-use-string-table-to-detect-VM-or-container.patch +Patch0851: 0851-fileio-introduce-read_full_virtual_file-for-reading-.patch +Patch0852: 0852-Use-BIOS-characteristics-to-distinguish-EC2-bare-met.patch +Patch0853: 0853-device-drop-refuse_after.patch +Patch0854: 0854-manager-limit-access-to-private-dbus-socket.patch +Patch0855: 0855-journalctl-do-not-treat-EINTR-as-an-error-when-waiti.patch +Patch0856: 0856-core-bring-manager_startup-and-manager_reload-more-i.patch +Patch0857: 0857-pam-add-a-call-to-pam_namespace.patch +Patch0858: 0858-virt-Support-detection-for-ARM64-Hyper-V-guests.patch +Patch0859: 0859-virt-Fix-the-detection-for-Hyper-V-VMs.patch +Patch0860: 0860-basic-add-STRERROR-wrapper-for-strerror_r.patch +Patch0861: 0861-coredump-put-context-array-into-a-struct.patch +Patch0862: 0862-coredump-do-not-allow-user-to-access-coredumps-with-.patch +Patch0863: 0863-logind-remember-our-idle-state-and-use-it-to-detect-.patch +Patch0864: 0864-test-import-logind-test-from-debian-ubuntu-test-suit.patch +Patch0865: 0865-test-introduce-inst_recursive-helper-function.patch +Patch0866: 0866-tests-verify-that-Lock-D-Bus-signal-is-sent-when-Idl.patch +Patch0867: 0867-systemctl-simplify-halt_main.patch +Patch0868: 0868-systemctl-shutdown-don-t-fallback-on-auth-fail.patch +Patch0869: 0869-systemctl-reintroduce-the-original-halt_main.patch +Patch0870: 0870-systemctl-preserve-old-behavior-unless-requested.patch +Patch0871: 0871-pam_systemd-suppress-LOG_DEBUG-log-messages-if-debug.patch +Patch0872: 0872-udev-net_id-introduce-naming-scheme-for-RHEL-8.8.patch +Patch0873: 0873-journald-add-API-to-move-logging-from-var-to-run-aga.patch +Patch0874: 0874-journalctl-add-new-relinquish-and-smart-relinquish-o.patch +Patch0875: 0875-units-automatically-revert-to-run-logging-on-shutdow.patch +Patch0876: 0876-pstore-Tool-to-archive-contents-of-pstore.patch +Patch0877: 0877-meson-drop-redundant-line.patch +Patch0878: 0878-pstore-drop-unnecessary-initializations.patch +Patch0879: 0879-pstopre-fix-return-value-of-list_files.patch +Patch0880: 0880-pstore-remove-temporary-file-on-failure.patch +Patch0881: 0881-pstore-do-not-add-FILE-journal-entry-if-content_size.patch +Patch0882: 0882-pstore-run-only-when-sys-fs-pstore-is-not-empty.patch +Patch0883: 0883-pstore-fix-use-after-free.patch +Patch0884: 0884-pstore-refuse-to-run-if-arguments-are-specified.patch +Patch0885: 0885-pstore-allow-specifying-src-and-dst-dirs-are-argumen.patch +Patch0886: 0886-pstore-rework-memory-handling-for-dmesg.patch +Patch0887: 0887-pstore-fixes-for-dmesg.txt-reconstruction.patch +Patch0888: 0888-pstore-Don-t-start-systemd-pstore.service-in-contain.patch +Patch0889: 0889-units-pull-in-systemd-pstore.service-from-sysinit.ta.patch +Patch0890: 0890-units-drop-dependency-on-systemd-remount-fs.service-.patch +Patch0891: 0891-units-make-sure-systemd-pstore-stops-at-shutdown.patch +Patch0892: 0892-pstore-Run-after-modules-are-loaded.patch +Patch0893: 0893-pstore-do-not-try-to-load-all-known-pstore-modules.patch +Patch0894: 0894-logind-session-make-stopping-of-idle-session-visible.patch +Patch0895: 0895-journald-Increase-stdout-buffer-size-sooner-when-alm.patch +Patch0896: 0896-journald-rework-end-of-line-marker-handling-to-use-a.patch +Patch0897: 0897-journald-use-the-fact-that-client_context_release-re.patch +Patch0898: 0898-journald-rework-pid-change-handling.patch +Patch0899: 0899-test-Add-a-test-case-for-15654.patch +Patch0900: 0900-test-Stricter-test-case-for-15654-Add-more-checks.patch +Patch0901: 0901-man-document-the-new-_LINE_BREAK-type.patch +Patch0902: 0902-journald-server-always-create-state-file-in-signal-h.patch +Patch0903: 0903-journald-server-move-relinquish-code-into-function.patch +Patch0904: 0904-journald-server-always-touch-state-file-in-signal-ha.patch +Patch0905: 0905-test-make-TEST-35-LOGIN-stable-again.patch +Patch0906: 0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch +Patch0907: 0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch +Patch0908: 0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch +Patch0909: 0909-ci-trigger-differential-shellcheck-workflow-on-push.patch +Patch0910: 0910-ci-codeql-master-main.patch +Patch0911: 0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch +Patch0912: 0912-ci-Mergify-drop-requirements-on-linting-workflows.patch +Patch0913: 0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch +Patch0914: 0914-ci-first-part-of-the-source-git-automation-commit-li.patch +Patch0915: 0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch +Patch0916: 0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch +Patch0917: 0917-pstore-explicitly-set-the-base-when-converting-recor.patch +Patch0918: 0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch +Patch0919: 0919-test-add-a-couple-of-tests-for-systemd-pstore.patch +Patch0920: 0920-ci-update-permissions-for-source-git-automation-work.patch +Patch0921: 0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch +Patch0922: 0922-parse-util-in-parse_permille-check-negative-earlier.patch +Patch0923: 0923-tree-wide-increase-granularity-of-percent-specificat.patch +Patch0924: 0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch +Patch0925: 0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch +Patch0926: 0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch +Patch0927: 0927-sd-bus-handle-EINTR-return-from-bus_poll.patch +Patch0928: 0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch +Patch0929: 0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch +Patch0930: 0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch +Patch0931: 0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch +Patch0932: 0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch +Patch0933: 0933-journal-vacuum-count-size-of-all-journal-files.patch +Patch0934: 0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch +Patch0935: 0935-resolved-close-UDP-socket-when-we-received-a-network.patch +Patch0936: 0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch +Patch0937: 0937-man-tweak-markup-in-systemd-pstore.service-8.patch +Patch0938: 0938-man-add-.service-suffix-to-systemd-pstore-8.patch +Patch0939: 0939-presets-enable-systemd-pstore.service-by-default.patch +Patch0940: 0940-logind-simplify-code.patch +Patch0941: 0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch +Patch0942: 0942-loginctl-shorten-variable-name.patch +Patch0943: 0943-loginctl-use-bus_map_all_properties.patch +Patch0944: 0944-loginctl-show-session-idle-status-in-list-sessions.patch +Patch0945: 0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch +Patch0946: 0946-loginctl-also-show-idle-hint-in-session-status.patch +Patch0947: 0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch +Patch0948: 0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch +Patch0949: 0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch +Patch0950: 0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch +Patch0951: 0951-login-add-a-missing-error-check-for-session_set_lead.patch +Patch0952: 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch +Patch0953: 0953-test-login-skip-consistency-checks-when-logind-is-no.patch +Patch0954: 0954-sd-event-remove-dead-code-and-use-_cleanup_.patch +Patch0955: 0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch +Patch0956: 0956-sd-event-add-sd_event_add_inotify_fd-call.patch +Patch0957: 0957-test-add-test-case-for-self-destroy-inotify-handler.patch +Patch0958: 0958-doc-add-downstream-CONTRIBUTING-document.patch +Patch0959: 0959-doc-use-link-with-prefilled-Jira-issue.patch +Patch0960: 0960-docs-link-downstream-CONTRIBUTING-in-README.patch +Patch0961: 0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch +Patch0962: 0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch +Patch0963: 0963-test-set-indentation-to-4-spaces.patch +Patch0964: 0964-test-TEST-15-remove-all-created-unit-files.patch +Patch0965: 0965-test-use-quotes-where-necessary.patch +Patch0966: 0966-tree-wide-drop-manually-crafted-message-for-missing-.patch +Patch0967: 0967-manager-reformat-boolean-expression-in-unit_is_prist.patch +Patch0968: 0968-manager-allow-transient-units-to-have-drop-ins.patch +Patch0969: 0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch +Patch0970: 0970-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch +Patch0971: 0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch +Patch0972: 0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch +Patch0973: 0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch +Patch0974: 0974-meson-remove-libdw-dependency-from-pstore.patch +Patch0975: 0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch +Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch +Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch +Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch +Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch +Patch0980: 0980-ci-Extend-source-git-automation.patch +Patch0981: 0981-ci-add-missing-configuration-for-commit-linter.patch +Patch0982: 0982-ci-add-Red-Hat-Enterprise-Linux-8-to-the-list-of-sup.patch +Patch0983: 0983-ci-enable-source-git-automation-to-validate-reviews-.patch +Patch0984: 0984-ci-remove-Mergify-config-replaced-by-Pull-Request-Va.patch +Patch0985: 0985-ci-enable-auto-merge-GH-Action.patch +Patch0986: 0986-fstab-generator-allow-overriding-etc-fstab-with-SYST.patch +Patch0987: 0987-fstab-generator-allow-overriding-path-to-sysroot-etc.patch +Patch0988: 0988-test-backport-TEST-81-GENERATORS-fstab-generator-onl.patch +Patch0989: 0989-resolved-actually-check-authenticated-flag-of-SOA-tr.patch +Patch0990: 0990-fd-util-rework-how-we-determine-highest-possible-fd.patch +Patch0991: 0991-basic-fd-util-refuse-infinite-loop-in-close_all_fds.patch +Patch0992: 0992-fd-util-split-out-inner-fallback-loop-of-close_all_f.patch +Patch0993: 0993-exec-util-use-close_all_fds_without_malloc-from-free.patch +Patch0994: 0994-ci-use-source-git-automation-composite-Action.patch +Patch0995: 0995-ci-increase-the-cron-interval-to-45-minutes.patch +Patch0996: 0996-ci-add-all-Z-Stream-versions-to-array-of-allowed-ver.patch +Patch0997: 0997-tree-wide-always-declare-bitflag-enums-the-same-way.patch +Patch0998: 0998-login-Add-KEY_RESTART-handling.patch +Patch0999: 0999-analyze-security-fix-recursive-call-of-syscall_names.patch +Patch1000: 1000-analyze-security-do-not-assign-badness-to-filtered-o.patch +Patch1001: 1001-analyze-security-include-an-actual-syscall-name-in-t.patch +Patch1002: 1002-udev-net_id-introduce-naming-scheme-for-RHEL-8.10.patch +Patch1003: 1003-doc-add-missing-listitem-to-systemd.net-naming-schem.patch +Patch1004: 1004-service-schedule-cleanup-of-PID-hashmaps-when-we-now.patch +Patch1005: 1005-man-update-link-to-RHEL-documentation.patch + +%ifarch %{ix86} x86_64 aarch64 +%global have_gnu_efi 1 +%endif + +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: libcap-devel +BuildRequires: libmount-devel +BuildRequires: pam-devel +BuildRequires: libselinux-devel +BuildRequires: audit-libs-devel +BuildRequires: cryptsetup-devel +BuildRequires: dbus-devel +BuildRequires: libacl-devel +BuildRequires: gobject-introspection-devel +BuildRequires: libblkid-devel +BuildRequires: xz-devel +BuildRequires: xz +BuildRequires: lz4-devel +BuildRequires: lz4 +BuildRequires: bzip2-devel +BuildRequires: libidn2-devel +BuildRequires: libcurl-devel +BuildRequires: kmod-devel +BuildRequires: elfutils-devel +BuildRequires: libgcrypt-devel +BuildRequires: libgpg-error-devel +BuildRequires: gnutls-devel +BuildRequires: libmicrohttpd-devel +BuildRequires: libxkbcommon-devel +BuildRequires: libxslt +BuildRequires: docbook-style-xsl +BuildRequires: pkgconfig +BuildRequires: gperf +BuildRequires: gawk +BuildRequires: tree +BuildRequires: python3-devel +BuildRequires: python3-lxml +BuildRequires: firewalld-filesystem +%if 0%{?have_gnu_efi} +BuildRequires: gnu-efi gnu-efi-devel +%endif +BuildRequires: libseccomp-devel +BuildRequires: git +BuildRequires: meson >= 0.43 +BuildRequires: gettext + +Requires(post): coreutils +Requires(post): sed +Requires(post): acl +Requires(post): grep +# systemd-machine-id-setup requires libssl +Requires(post): openssl-libs +Requires(pre): coreutils +Requires(pre): /usr/bin/getent +Requires(pre): /usr/sbin/groupadd +Requires: dbus >= 1.9.18 +Requires: %{name}-pam = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} +Recommends: diffutils +Requires: util-linux +Recommends: libxkbcommon%{?_isa} +Provides: /bin/systemctl +Provides: /sbin/shutdown +Provides: syslog +Provides: systemd-units = %{version}-%{release} +Provides: systemd-rpm-macros = %{version}-%{release} +Obsoletes: system-setup-keyboard < 0.9 +Provides: system-setup-keyboard = 0.9 +# systemd-sysv-convert was removed in f20: https://fedorahosted.org/fpc/ticket/308 +Obsoletes: systemd-sysv < 206 +# self-obsoletes so that dnf will install new subpackages on upgrade (#1260394) +Obsoletes: %{name} < 229-5 +Provides: systemd-sysv = 206 +Conflicts: initscripts < 9.56.1 +%if 0%{?fedora} +Conflicts: fedora-release < 23-0.12 +%endif + +%description +systemd is a system and service manager that runs as PID 1 and starts +the rest of the system. It provides aggressive parallelization +capabilities, uses socket and D-Bus activation for starting services, +offers on-demand starting of daemons, keeps track of processes using +Linux control groups, maintains mount and automount points, and +implements an elaborate transactional dependency-based service control +logic. systemd supports SysV and LSB init scripts and works as a +replacement for sysvinit. Other parts of this package are a logging daemon, +utilities to control basic system configuration like the hostname, +date, locale, maintain a list of logged-in users, system accounts, +runtime directories and settings, and daemons to manage simple network +configuration, network time synchronization, log forwarding, and name +resolution. + +%package libs +Summary: systemd libraries +License: LGPLv2+ and MIT +Obsoletes: libudev < 183 +Obsoletes: systemd < 185-4 +Conflicts: systemd < 185-4 +Obsoletes: systemd-compat-libs < 230 +Obsoletes: nss-myhostname < 0.4 +Provides: nss-myhostname = 0.4 +Provides: nss-myhostname%{_isa} = 0.4 +Requires(post): coreutils +Requires(post): sed +Requires(post): grep +Requires(post): /usr/bin/getent + +%description libs +Libraries for systemd and udev. + +%package pam +Summary: systemd PAM module +Requires: %{name} = %{version}-%{release} + +%description pam +Systemd PAM module registers the session with systemd-logind. + +%package devel +Summary: Development headers for systemd +License: LGPLv2+ and MIT +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: libudev-devel = %{version} +Provides: libudev-devel%{_isa} = %{version} +Obsoletes: libudev-devel < 183 +# Fake dependency to make sure systemd-pam is pulled into multilib (#1414153) +Requires: %{name}-pam = %{version}-%{release} + +%description devel +Development headers and auxiliary files for developing applications linking +to libudev or libsystemd. + +%package udev +Summary: Rule-based device node and kernel event manager +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(post): grep +Requires: kmod >= 18-4 +# obsolete parent package so that dnf will install new subpackage on upgrade (#1260394) +Obsoletes: %{name} < 229-5 +Provides: udev = %{version} +Provides: udev%{_isa} = %{version} +Obsoletes: udev < 183 +# https://bugzilla.redhat.com/show_bug.cgi?id=1408878 +Recommends: kbd +License: LGPLv2+ + +%description udev +This package contains systemd-udev and the rules and hardware database +needed to manage device nodes. This package is necessary on physical +machines and in virtual machines, but not in containers. + +%package container +# Name is the same as in Debian +Summary: Tools for containers and VMs +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +# obsolete parent package so that dnf will install new subpackage on upgrade (#1260394) +Obsoletes: %{name} < 229-5 +License: LGPLv2+ + +%description container +Systemd tools to spawn and manage containers and virtual machines. + +This package contains systemd-nspawn, machinectl, systemd-machined, +and systemd-importd. + +%package journal-remote +# Name is the same as in Debian +Summary: Tools to send journal events over the network +Requires: %{name}%{?_isa} = %{version}-%{release} +License: LGPLv2+ +Requires(pre): /usr/bin/getent +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires: firewalld-filesystem +Provides: %{name}-journal-gateway = %{version}-%{release} +Provides: %{name}-journal-gateway%{_isa} = %{version}-%{release} +Obsoletes: %{name}-journal-gateway < 227-7 + +%description journal-remote +Programs to forward journal entries over the network, using encrypted HTTP, +and to write journal files from serialized journal contents. + +This package contains systemd-journal-gatewayd, +systemd-journal-remote, and systemd-journal-upload. + +%package tests +Summary: Internal unit tests for systemd +Requires: %{name}%{?_isa} = %{version}-%{release} +License: LGPLv2+ + +%description tests +"Installed tests" that are usually run as part of the build system. +They can be useful to test systemd internals. + +%prep +%autosetup %{?gitcommit:-n %{name}-%{gitcommit}} -S git_am + +%build +%define ntpvendor %(source /etc/os-release; echo ${ID}) +%{!?ntpvendor: echo 'NTP vendor zone is not set!'; exit 1} + +CONFIGURE_OPTS=( + -Dsysvinit-path=/etc/rc.d/init.d + -Drc-local=/etc/rc.d/rc.local + -Dntp-servers='0.%{ntpvendor}.pool.ntp.org 1.%{ntpvendor}.pool.ntp.org 2.%{ntpvendor}.pool.ntp.org 3.%{ntpvendor}.pool.ntp.org' + -Ddns-servers='' + -Ddev-kvm-mode=0666 + -Dkmod=true + -Dxkbcommon=true + -Dblkid=true + -Dseccomp=true + -Dima=true + -Dselinux=true + -Dapparmor=false + -Dpolkit=true + -Dxz=true + -Dzlib=true + -Dbzip2=true + -Dlz4=true + -Dpam=true + -Dacl=true + -Dsmack=true + -Dgcrypt=true + -Daudit=true + -Delfutils=true + -Dlibcryptsetup=true + -Delfutils=true + -Dqrencode=false + -Dgnutls=true + -Dmicrohttpd=true + -Dlibidn2=true + -Dlibiptc=false + -Dlibcurl=true + -Defi=true + -Dgnu-efi=%{?have_gnu_efi:true}%{?!have_gnu_efi:false} + -Dtpm=true + -Dhwdb=true + -Dsysusers=true + -Ddefault-kill-user-processes=false + -Dtests=unsafe + -Dinstall-tests=true + -Dtty-gid=5 + -Dusers-gid=100 + -Dnobody-user=nobody + -Dnobody-group=nobody + -Dsplit-usr=false + -Dsplit-bin=true + -Db_lto=false + -Dnetworkd=false + -Dtimesyncd=false + -Ddefault-hierarchy=legacy + -Dversion-tag=%{version}-%{release} +) + +# Don't ship /var/log/README. The relationship between journal and syslog should be documented +# in the official documentation. +sed -ie "/subdir('doc\/var-log')/d" meson.build + +%meson "${CONFIGURE_OPTS[@]}" +%meson_build + +if diff %{SOURCE1} %{_vpath_builddir}/triggers.systemd; then + echo -e "\n\n\nWARNING: triggers.systemd in Source1 is different!" + echo -e " cp %{_vpath_builddir}/triggers.systemd %{SOURCE1}\n\n\n" +fi + +%install +%meson_install + +# udev links +mkdir -p %{buildroot}/%{_sbindir} +ln -sf ../bin/udevadm %{buildroot}%{_sbindir}/udevadm + +# Compatiblity and documentation files +touch %{buildroot}/etc/crypttab +chmod 600 %{buildroot}/etc/crypttab + +# /etc/initab +install -Dm0644 -t %{buildroot}/etc/ %{SOURCE5} + +# /etc/sysctl.conf compat +install -Dm0644 %{SOURCE6} %{buildroot}/etc/sysctl.conf +ln -s ../sysctl.conf %{buildroot}/etc/sysctl.d/99-sysctl.conf + +# We create all wants links manually at installation time to make sure +# they are not owned and hence overriden by rpm after the user deleted +# them. +rm -r %{buildroot}%{_sysconfdir}/systemd/system/*.target.wants + +# Make sure these directories are properly owned +mkdir -p %{buildroot}%{system_unit_dir}/basic.target.wants +mkdir -p %{buildroot}%{system_unit_dir}/default.target.wants +mkdir -p %{buildroot}%{system_unit_dir}/dbus.target.wants +mkdir -p %{buildroot}%{system_unit_dir}/syslog.target.wants +mkdir -p %{buildroot}%{_localstatedir}/run +mkdir -p %{buildroot}%{_localstatedir}/log +touch %{buildroot}%{_localstatedir}/log/lastlog +chmod 0664 %{buildroot}%{_localstatedir}/log/lastlog +touch %{buildroot}%{_localstatedir}/run/utmp +touch %{buildroot}%{_localstatedir}/log/{w,b}tmp + +# Make sure the user generators dir exists too +mkdir -p %{buildroot}%{pkgdir}/system-generators +mkdir -p %{buildroot}%{pkgdir}/user-generators + +# Create new-style configuration files so that we can ghost-own them +touch %{buildroot}%{_sysconfdir}/hostname +touch %{buildroot}%{_sysconfdir}/vconsole.conf +touch %{buildroot}%{_sysconfdir}/locale.conf +touch %{buildroot}%{_sysconfdir}/machine-id +touch %{buildroot}%{_sysconfdir}/machine-info +touch %{buildroot}%{_sysconfdir}/localtime +mkdir -p %{buildroot}%{_sysconfdir}/X11/xorg.conf.d +touch %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/00-keyboard.conf + +# Make sure the shutdown/sleep drop-in dirs exist +mkdir -p %{buildroot}%{pkgdir}/system-shutdown/ +mkdir -p %{buildroot}%{pkgdir}/system-sleep/ + +# Make sure directories in /var exist +mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/coredump +mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/catalog +mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/backlight +mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/rfkill +mkdir -p %{buildroot}%{_localstatedir}/lib/systemd/linger +mkdir -p %{buildroot}%{_localstatedir}/lib/private +mkdir -p %{buildroot}%{_localstatedir}/log/private +mkdir -p %{buildroot}%{_localstatedir}/cache/private +mkdir -p %{buildroot}%{_localstatedir}/lib/private/systemd/journal-upload +ln -s ../private/systemd/journal-upload %{buildroot}%{_localstatedir}/lib/systemd/journal-upload +mkdir -p %{buildroot}%{_localstatedir}/log/journal +touch %{buildroot}%{_localstatedir}/lib/systemd/catalog/database +touch %{buildroot}%{_sysconfdir}/udev/hwdb.bin +touch %{buildroot}%{_localstatedir}/lib/systemd/random-seed +touch %{buildroot}%{_localstatedir}/lib/private/systemd/journal-upload/state + +# Install rc.local +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/ +install -m 0644 %{SOURCE13} %{buildroot}%{_sysconfdir}/rc.d/rc.local +ln -s rc.d/rc.local %{buildroot}%{_sysconfdir}/rc.local + +# Install yum protection fragment +install -Dm0644 %{SOURCE4} %{buildroot}%{_sysconfdir}/dnf/protected.d/systemd.conf + +install -Dm0644 -t %{buildroot}/usr/lib/firewalld/services/ %{SOURCE7} %{SOURCE8} + +# Restore systemd-user pam config from before "removal of Fedora-specific bits" +install -Dm0644 -t %{buildroot}/etc/pam.d/ %{SOURCE12} + +# Install additional docs +# https://bugzilla.redhat.com/show_bug.cgi?id=1234951 +install -Dm0644 -t %{buildroot}%{_pkgdocdir}/ %{SOURCE9} + +# https://bugzilla.redhat.com/show_bug.cgi?id=1378974 +install -Dm0644 -t %{buildroot}%{system_unit_dir}/systemd-udev-trigger.service.d/ %{SOURCE10} + +install -Dm0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE11} + +install -D -t %{buildroot}/usr/lib/systemd/ %{SOURCE3} + +# No tmp-on-tmpfs by default in RHEL. bz#876122 bz#1578772 +rm -f %{buildroot}%{_prefix}/lib/systemd/system/local-fs.target.wants/tmp.mount + +# bz#1844465 +rm -f %{buildroot}/etc/systemd/system/dbus-org.freedesktop.resolve1.service + +%find_lang %{name} + +# Split files in build root into rpms. See split-files.py for the +# rules towards the end, anything which is an exception needs a line +# here. +python3 %{SOURCE2} %buildroot </dev/null || groupadd -r -g 11 cdrom &>/dev/null || : +getent group utmp &>/dev/null || groupadd -r -g 22 utmp &>/dev/null || : +getent group tape &>/dev/null || groupadd -r -g 33 tape &>/dev/null || : +getent group dialout &>/dev/null || groupadd -r -g 18 dialout &>/dev/null || : +getent group input &>/dev/null || groupadd -r input &>/dev/null || : +getent group kvm &>/dev/null || groupadd -r -g 36 kvm &>/dev/null || : +getent group render &>/dev/null || groupadd -r render &>/dev/null || : +getent group systemd-journal &>/dev/null || groupadd -r -g 190 systemd-journal 2>&1 || : + +getent group systemd-coredump &>/dev/null || groupadd -r systemd-coredump 2>&1 || : +getent passwd systemd-coredump &>/dev/null || useradd -r -l -g systemd-coredump -d / -s /sbin/nologin -c "systemd Core Dumper" systemd-coredump &>/dev/null || : + +getent group systemd-resolve &>/dev/null || groupadd -r -g 193 systemd-resolve 2>&1 || : +getent passwd systemd-resolve &>/dev/null || useradd -r -u 193 -l -g systemd-resolve -d / -s /sbin/nologin -c "systemd Resolver" systemd-resolve &>/dev/null || : + +%post +systemd-machine-id-setup &>/dev/null || : +systemctl daemon-reexec &>/dev/null || : +journalctl --update-catalog &>/dev/null || : +systemd-tmpfiles --create &>/dev/null || : + +# Make sure new journal files will be owned by the "systemd-journal" group +chgrp systemd-journal /run/log/journal/ /run/log/journal/`cat /etc/machine-id 2>/dev/null` /var/log/journal/ /var/log/journal/`cat /etc/machine-id 2>/dev/null` &>/dev/null || : +chmod g+s /run/log/journal/ /run/log/journal/`cat /etc/machine-id 2>/dev/null` /var/log/journal/ /var/log/journal/`cat /etc/machine-id 2>/dev/null` &>/dev/null || : + +# Apply ACL to the journal directory +setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/ &>/dev/null || : + +# Stop-gap until rsyslog.rpm does this on its own. (This is supposed +# to fail when the link already exists) +ln -s /usr/lib/systemd/system/rsyslog.service /etc/systemd/system/syslog.service &>/dev/null || : + +# Remove spurious /etc/fstab entries from very old installations +# https://bugzilla.redhat.com/show_bug.cgi?id=1009023 +if [ -e /etc/fstab ]; then + grep -v -E -q '^(devpts|tmpfs|sysfs|proc)' /etc/fstab || \ + sed -i.rpm.bak -r '/^devpts\s+\/dev\/pts\s+devpts\s+defaults\s+/d; /^tmpfs\s+\/dev\/shm\s+tmpfs\s+defaults\s+/d; /^sysfs\s+\/sys\s+sysfs\s+defaults\s+/d; /^proc\s+\/proc\s+proc\s+defaults\s+/d' /etc/fstab || : +fi + +# We reset the enablement of all services upon initial installation +# https://bugzilla.redhat.com/show_bug.cgi?id=1118740#c23 +# This will fix up enablement of any preset services that got installed +# before systemd due to rpm ordering problems: +# Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1647172 +# RHEL: https://bugzilla.redhat.com/show_bug.cgi?id=1783263 +if [ $1 -eq 1 ] ; then + systemctl preset-all &>/dev/null || : +fi + +# remove obsolete systemd-readahead file +rm -f /.readahead &>/dev/null || : + +%preun +if [ $1 -eq 0 ] ; then + systemctl disable --quiet \ + remote-fs.target \ + getty@.service \ + serial-getty@.service \ + console-getty.service \ + debug-shell.service \ + systemd-readahead-replay.service \ + systemd-readahead-collect.service \ + systemd-resolved.service \ + >/dev/null || : + + rm -f /etc/systemd/system/default.target &>/dev/null || : +fi + +%post libs +%{?ldconfig} + +function mod_nss() { + if [ $1 -eq 1 ] && [ -f "$2" ]; then + # sed-fu to add myhostname to hosts line (only once, on install) + grep -E -q '^hosts:.* myhostname' "$2" || + sed -i.bak -e ' + /^hosts:/ !b + /\/ b + s/[[:blank:]]*$/ myhostname/ + ' "$2" &>/dev/null || : + + # Add nss-systemd to passwd and group (only once, on install) + grep -E -q '^(passwd|group):.* systemd' "$2" || + sed -i.bak -r -e ' + s/^(passwd|group):(.*)/\1: \2 systemd/ + ' "$2" &>/dev/null || : + fi +} + +FILE="$(readlink /etc/nsswitch.conf || echo /etc/nsswitch.conf)" +if [ "$FILE" = "/etc/authselect/nsswitch.conf" ] && authselect check &>/dev/null; then + mod_nss $1 "/etc/authselect/user-nsswitch.conf" + authselect apply-changes &> /dev/null || : +else + mod_nss $1 "$FILE" + # also apply the same changes to user-nsswitch.conf to affect + # possible future authselect configuration + mod_nss $1 "/etc/authselect/user-nsswitch.conf" +fi + +# check if nobody or nfsnobody is defined +export SYSTEMD_NSS_BYPASS_SYNTHETIC=1 +if getent passwd nfsnobody &>/dev/null; then + test -f /etc/systemd/dont-synthesize-nobody || { + echo 'Detected system with nfsnobody defined, creating /etc/systemd/dont-synthesize-nobody' + mkdir -p /etc/systemd || : + : >/etc/systemd/dont-synthesize-nobody || : + } +elif getent passwd nobody 2>/dev/null | grep -v 'nobody:[x*]:65534:65534:.*:/:/sbin/nologin' &>/dev/null; then + test -f /etc/systemd/dont-synthesize-nobody || { + echo 'Detected system with incompatible nobody defined, creating /etc/systemd/dont-synthesize-nobody' + mkdir -p /etc/systemd || : + : >/etc/systemd/dont-synthesize-nobody || : + } +fi + +%{?ldconfig:%postun libs -p %ldconfig} + +%global udev_services systemd-udev{d,-settle,-trigger}.service systemd-udevd-{control,kernel}.socket + +%post udev +# Move old stuff around in /var/lib +mv %{_localstatedir}/lib/random-seed %{_localstatedir}/lib/systemd/random-seed &>/dev/null +mv %{_localstatedir}/lib/backlight %{_localstatedir}/lib/systemd/backlight &>/dev/null + +udevadm hwdb --update &>/dev/null +%systemd_post %udev_services +/usr/lib/systemd/systemd-random-seed save 2>&1 + +# Replace obsolete keymaps +# https://bugzilla.redhat.com/show_bug.cgi?id=1151958 +grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null && + sed -i.rpm.bak -r 's/^KEYMAP="?fi-latin[19]"?/KEYMAP="fi"/' /etc/vconsole.conf || : + +%postun udev +# Only restart systemd-udev, to run the upgraded dameon. +# Others are either oneshot services, or sockets, and restarting them causes issues (#1378974) +%systemd_postun_with_restart systemd-udevd.service + +%pre journal-remote +getent group systemd-journal-remote &>/dev/null || groupadd -r systemd-journal-remote 2>&1 || : +getent passwd systemd-journal-remote &>/dev/null || useradd -r -l -g systemd-journal-remote -d %{_localstatedir}/log/journal/remote -s /sbin/nologin -c "Journal Remote" systemd-journal-remote &>/dev/null || : + +%post journal-remote +%systemd_post systemd-journal-gatewayd.socket systemd-journal-gatewayd.service +%systemd_post systemd-journal-remote.socket systemd-journal-remote.service +%systemd_post systemd-journal-upload.service +%firewalld_reload + +%preun journal-remote +%systemd_preun systemd-journal-gatewayd.socket systemd-journal-gatewayd.service +%systemd_preun systemd-journal-remote.socket systemd-journal-remote.service +%systemd_preun systemd-journal-upload.service +if [ $1 -eq 1 ] ; then + if [ -f %{_localstatedir}/lib/systemd/journal-upload/state -a ! -L %{_localstatedir}/lib/systemd/journal-upload ] ; then + mkdir -p %{_localstatedir}/lib/private/systemd/journal-upload + mv %{_localstatedir}/lib/systemd/journal-upload/state %{_localstatedir}/lib/private/systemd/journal-upload/. + rmdir %{_localstatedir}/lib/systemd/journal-upload || : + fi +fi + +%postun journal-remote +%systemd_postun_with_restart systemd-journal-gatewayd.service +%systemd_postun_with_restart systemd-journal-remote.service +%systemd_postun_with_restart systemd-journal-upload.service +%firewalld_reload + +%global _docdir_fmt %{name} + +%files -f %{name}.lang -f .file-list-rest +%doc %{_pkgdocdir} +%exclude %{_pkgdocdir}/LICENSE.* +%license LICENSE.GPL2 LICENSE.LGPL2.1 +%ghost %dir %attr(0755,-,-) /etc/systemd/system/basic.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/bluetooth.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/default.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/getty.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/graphical.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/local-fs.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/machines.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/multi-user.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/printer.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/remote-fs.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/sockets.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/sysinit.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/system-update.target.wants +%ghost %dir %attr(0755,-,-) /etc/systemd/system/timers.target.wants +%ghost %dir %attr(0755,-,-) /var/lib/rpm-state/systemd + +%files libs -f .file-list-libs +%license LICENSE.LGPL2.1 + +%files pam -f .file-list-pam + +%files devel -f .file-list-devel + +%files udev -f .file-list-udev + +%files container -f .file-list-container + +%files journal-remote -f .file-list-remote + +%files tests -f .file-list-tests + +%changelog +* Mon Feb 26 2024 systemd maintenance team - 239-81 +- man: update link to RHEL documentation (RHEL-26355) + +* Thu Feb 15 2024 systemd maintenance team - 239-80 +- fd-util: rework how we determine highest possible fd (RHEL-18302) +- basic/fd-util: refuse "infinite" loop in close_all_fds() (RHEL-18302) +- fd-util: split out inner fallback loop of close_all_fds() as close_all_fds_without_malloc() (RHEL-18302) +- exec-util: use close_all_fds_without_malloc() from freeze() (RHEL-18302) +- ci: use source-git-automation composite Action (RHEL-1087) +- ci: increase the cron interval to 45 minutes (RHEL-1087) +- ci: add all Z-Stream versions to array of allowed versions (RHEL-1087) +- tree-wide: always declare bitflag enums the same way (RHEL-2857) +- login: Add KEY_RESTART handling (RHEL-2857) +- analyze security: fix recursive call of syscall_names_in_filter() (RHEL-5991) +- analyze-security: do not assign badness to filtered-out syscalls (RHEL-5991) +- analyze-security: include an actual syscall name in the message (RHEL-5991) +- udev/net_id: introduce naming scheme for RHEL-8.10 (RHEL-22426) +- doc: add missing `` to `systemd.net-naming-scheme.xml` (RHEL-22426) +- service: schedule cleanup of PID hashmaps when we now longer have main_pid and we are in container (RHEL-5863) + +* Mon Jan 08 2024 systemd maintenance team - 239-79 +- ci: Extend source-git-automation (RHEL-1087) +- ci: add missing configuration for commit linter (RHEL-1087) +- ci: add `Red Hat Enterprise Linux 8` to the list of supported products (RHEL-1087) +- ci: enable source-git automation to validate reviews and ci results (RHEL-1087) +- ci: remove Mergify config - replaced by Pull Request Validator (RHEL-1087) +- ci: enable auto-merge GH Action (RHEL-1087) +- fstab-generator: allow overriding /etc/fstab with $SYSTEMD_FSTAB (RHEL-1087) +- fstab-generator: allow overriding path to /sysroot/etc/fstab too (RHEL-1087) +- test: backport TEST-81-GENERATORS (fstab-generator only) (RHEL-1087) +- resolved: actually check authenticated flag of SOA transaction (RHEL-6213) + +* Tue Aug 22 2023 systemd maintenance team - 239-78 +- login: add a missing error check for session_set_leader() (#2158167) +- logind: reset session leader if we know for a fact that it is gone (#2158167) +- test-login: skip consistency checks when logind is not active (#2223582) +- sd-event: remove dead code and use _cleanup_ (#2211358) +- sd-event: don't destroy inotify data structures from inotify event handler (#2211358) +- sd-event: add sd_event_add_inotify_fd() call (#2211358) +- test: add test case for self-destroy inotify handler (#2211358) +- doc: add downstream CONTRIBUTING document (#2179309) +- doc: use link with prefilled Jira issue (#2179309) +- docs: link downstream CONTRIBUTING in README (#2179309) +- unit drop-in: Fix ordering of special type.d drop-ins (#2156620) +- Add failing test to show service.d global drop-in does not get overridden by more specific dropins (#2156620) +- test: set indentation to 4 spaces (#2156620) +- test/TEST-15: remove all created unit files (#2156620) +- test: use quotes where necessary (#2156620) +- tree-wide: drop manually-crafted message for missing variables (#2156620) +- manager: reformat boolean expression in unit_is_pristine() (#2156620) +- manager: allow transient units to have drop-ins (#2156620) +- TEST-15: allow helper functions to accept other unit types (#2156620) +- TEST-15: also test hierarchical drop-ins for slices (#2156620) +- TEST-15: add test for transient units with drop-ins (#2156620) +- TEST-15: add one more test for drop-in precedence (#2156620) +- udev/net_id: introduce naming scheme for RHEL-8.9 (#2231846) +- meson: remove libdw dependency from pstore (#2211416) +- pstore: introduce tmpfiles.d/systemd-pstore.conf (#2211416) +- tmpfiles: don't complain if we can't enable pstore in containers (#2211416) +- pstore: don't enable crash_kexec_post_notifiers by default (#2211416) +- core: when Delegate=yes is set for a unit, run ExecStartPre= and friends in a subcgroup of the unit (#2215925) +- man: link Delegate= documentation up with the markdown docs (#2215925) + +* Mon Jul 17 2023 systemd maintenance team - 239-77 +- ci: update permissions for source-git automation workflows (#2179309) +- sulogin: fix control lost of the current terminal when default.target is rescue.target (#2169932) +- parse-util: in parse_permille() check negative earlier (#2178179) +- tree-wide: increase granularity of percent specifications all over the place to permille (#2178179) +- errno-util: introduce ERRNO_IS_TRANSIENT() (#2172846) +- tree-wide: use ERRNO_IS_TRANSIENT() (#2172846) +- libsystemd: ignore both EINTR and EAGAIN (#2172846) +- sd-bus: handle -EINTR return from bus_poll() (#2172846) +- stdio-bridge: don't be bothered with EINTR (#2172846) +- sd-netlink: handle EINTR from poll() gracefully, as success (#2172846) +- resolved: handle -EINTR returned from fd_wait_for_event() better (#2172846) +- utmp-wtmp: fix error in case isatty() fails (#2172846) +- utmp-wtmp: handle EINTR gracefully when waiting to write to tty (#2172846) +- journal-vacuum: count size of all journal files (#2180380) +- resolved: instead of closing DNS UDP transaction fds right-away, add them to a socket "graveyard" (#2156751) +- resolved: close UDP socket when we received a network error on it (#2156751) +- ci: allow RHEL-only labels to mark downstream-only commits (#2179309) +- man: tweak markup in systemd-pstore.service(8) (#2217786) +- man: add .service suffix to systemd-pstore(8) (#2217786) +- presets: enable systemd-pstore.service by default (#2217786) +- logind: simplify code (#2209328) +- format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE (#2156786) +- loginctl: shorten variable name (#2156786) +- loginctl: use bus_map_all_properties (#2156786) +- loginctl: show session idle status in list-sessions (#2156786) +- loginctl: list-sessions: fix timestamp for idle hint (#2156786) +- loginctl: also show idle hint in session-status (#2156786) +- core/timer: Always use inactive_exit_timestamp if it is set (#1719364) +- timer: Use dual_timestamp_is_set() in one more place (#1719364) +- ci: drop systemd-stable from advanced-commit-linter config (#2179309) +- core/mount: escape invalid UTF8 char in dbus reply (#2158724) + +* Thu May 18 2023 systemd maintenance team - 239-76 +- ci(Mergify): drop requirements on linting workflows (#2179309) +- ci: workflow for gathering metadata for source-git automation (#2179309) +- ci: first part of the source-git automation - commit linter (#2179309) +- pstore: fix crash and forward dummy arguments instead of NULL (#2190151) +- test: Disable LUKS devices from initramfs in QEMU tests (#2190151) +- pstore: explicitly set the base when converting record ID (#2190151) +- pstore: avoid opening the dmesg.txt file if not requested (#2190151) +- test: add a couple of tests for systemd-pstore (#2190151) + +* Tue Apr 18 2023 systemd maintenance team - 239-75 +- journald-server: always create state file in signal handler (#2176892) +- journald-server: move relinquish code into function (#2176892) +- journald-server: always touch state file in signal handler (#2176892) +- test: make TEST-35-LOGIN stable again (#2179309) +- pager: set $LESSSECURE whenver we invoke a pager (#2175624) +- test-login: always test sd_pid_get_owner_uid(), modernize (#2175624) +- pager: make pager secure when under euid is changed or explicitly requested (#2175624) +- ci: trigger differential-shellcheck workflow on push (#2179309) +- ci: codeql `master` -> `main` (#2179309) +- test: ignore ENOMEDIUM error from sd_pid_get_cgroup() (#2175622) + +* Tue Mar 14 2023 systemd maintenance team - 239-74 +- journald-server: always create state file in signal handler (#2174645) +- journald-server: move relinquish code into function (#2174645) +- journald-server: always touch state file in signal handler (#2174645) + +* Mon Feb 27 2023 systemd maintenance team - 239-73 +- journald: add API to move logging from /var to /run again (#1873540) +- journalctl: add new --relinquish and --smart-relinquish options (#1873540) +- units: automatically revert to /run logging on shutdown if necessary (#1873540) +- pstore: Tool to archive contents of pstore (#2158832) +- meson: drop redundant line (#2158832) +- pstore: drop unnecessary initializations (#2158832) +- pstopre: fix return value of list_files() (#2158832) +- pstore: remove temporary file on failure (#2158832) +- pstore: do not add FILE= journal entry if content_size == 0 (#2158832) +- pstore: run only when /sys/fs/pstore is not empty (#2158832) +- pstore: fix use after free (#2158832) +- pstore: refuse to run if arguments are specified (#2158832) +- pstore: allow specifying src and dst dirs are arguments (#2158832) +- pstore: rework memory handling for dmesg (#2158832) +- pstore: fixes for dmesg.txt reconstruction (#2158832) +- pstore: Don't start systemd-pstore.service in containers (#2158832) +- units: pull in systemd-pstore.service from sysinit.target (#2158832) +- units: drop dependency on systemd-remount-fs.service from systemd-pstore.service (#2158832) +- units: make sure systemd-pstore stops at shutdown (#2158832) +- pstore: Run after modules are loaded (#2158832) +- pstore: do not try to load all known pstore modules (#2158832) +- logind-session: make stopping of idle session visible to admins (#2156780) +- journald: Increase stdout buffer size sooner, when almost full (#2029426) +- journald: rework end of line marker handling to use a field table (#2029426) +- journald: use the fact that client_context_release() returns NULL (#2029426) +- journald: rework pid change handling (#2029426) +- test: Add a test case for #15654 (#2029426) +- test: Stricter test case for #15654 (Add more checks) (#2029426) +- man: document the new _LINE_BREAK= type (#2029426) + +* Fri Feb 17 2023 systemd maintenance team - 239-72 +- test: import logind test from debian/ubuntu test suite (#1866955) +- test: introduce inst_recursive() helper function (#1866955) +- tests: verify that Lock D-Bus signal is sent when IdleAction=lock (#1866955) +- systemctl: simplify halt_main() (#2053273) +- systemctl: shutdown don't fallback on auth fail (#2053273) +- systemctl: reintroduce the original halt_main() (#2053273) +- systemctl: preserve old behavior unless requested (#2053273) +- pam_systemd: suppress LOG_DEBUG log messages if debugging is off (#2170084) +- udev/net_id: introduce naming scheme for RHEL-8.8 (#2170499) +- pam: add a call to pam_namespace (#1861836) + +* Tue Jan 31 2023 systemd maintenance team - 239-71 +- manager: limit access to private dbus socket (#2119405) +- journalctl: do not treat EINTR as an error when waiting for events (#2161683) +- core: bring manager_startup() and manager_reload() more inline (#2059633) +- pam: add a call to pam_namespace (#1861836) +- virt: Support detection for ARM64 Hyper-V guests (#2158307) +- virt: Fix the detection for Hyper-V VMs (#2158307) +- basic: add STRERROR() wrapper for strerror_r() (#2155520) +- coredump: put context array into a struct (#2155520) +- coredump: do not allow user to access coredumps with changed uid/gid/capabilities (#2155520) + +* Mon Jan 16 2023 systemd maintenance team - 239-70 +- basic: recognize pdfs filesystem as a network filesystem (#2094661) +- core: move reset_arguments() to the end of main's finish (#2127131) +- manager: move inc. of n_reloading into a function (#2136869) +- core: Add new DBUS properties UnitsReloadStartTimestamp and UnitsLoadTimestampMontonic (#2136869) +- core: Indicate the time when the manager started loading units the last time (#2136869) +- core: do not touch /run/systemd/systemd-units-load from user session instances (#2136869) +- sysctl: downgrade message when we have no permission (#2158160) +- core: respect SELinuxContext= for socket creation (#2136738) +- manager: use target process context to set socket context (#2136738) +- virt: detect Amazon EC2 Nitro instance (#2117948) +- machine-id-setup: generate machine-id from DMI product ID on Amazon EC2 (#2117948) +- virt: use string table to detect VM or container (#2117948) +- fileio: introduce read_full_virtual_file() for reading virtual files in sysfs, procfs (#2117948) +- Use BIOS characteristics to distinguish EC2 bare-metal from VMs (#2117948) +- device: drop refuse_after (#2043524) + +* Tue Nov 08 2022 systemd maintenance team - 239-69 +- logind: optionally watch utmp for login data (#2122288) +- logind: add hashtable for finding session by leader PID (#2122288) +- core/load-fragment: move config_parse_sec_fix_0 to src/shared (#2122288) +- sd-event: add relative timer calls (#2122288) +- logind: add option to stop idle sessions after specified timeout (#2122288) +- logind: schedule idle check full interval from now if we couldn't figure out atime timestamp (#2122288) +- ci(lint): add shell linter - Differential ShellCheck (#2122499) +- meson: do not compare objects of different types (#2122499) +- journal-remote: use MHD_HTTP_CONTENT_TOO_LARGE as MHD_HTTP_PAYLOAD_TOO_LARGE is deprecated since 0.9.74 (#2122499) +- Fix build with µhttpd 0.9.71 (#2122499) +- ci: replace LGTM with CodeQL (#2122499) +- ci(mergify): Update policy - Drop LGTM checks (#2122499) +- time-util: fix buffer-over-run (#2139391) + +* Fri Aug 26 2022 systemd maintenance team - 239-67 +- resolved: pin stream while calling callbacks for it (#2110549) +- ci(functions): Add `useradd` and `userdel` (#2110549) + +* Thu Aug 25 2022 systemd maintenance team - 239-66 +- Try stopping MD RAID devices in shutdown too (#1817706) +- shutdown: get only active md arrays. (#1817706) +- scope: allow unprivileged delegation on scopes (#2068575) + +* Fri Aug 19 2022 systemd maintenance team - 239-65 +- test-procfs-util: skip test on certain errors (#2087152) + +* Thu Aug 18 2022 systemd maintenance team - 239-64 +- ci: bump the worker Ubuntu version to Jammy (#2087152) +- test: make test-execute pass on Linux 5.15 (#2087152) +- ci: install iputils (#2087152) +- ci(Mergify): Add `ci-waived` logic (#2087152) +- sd-event: don't invalidate source type on disconnect (#2115396) +- tests: make sure we delay running mount start jobs when /p/s/mountinfo is rate limited (#2095744) +- core: drop references to 'StandardOutputFileToCreate' (#2093479) +- dbus-execute: fix indentation (#2093479) +- dbus-execute: generate the correct transient unit setting (#2093479) +- bus-unit-util: properly accept StandardOutput=append:… settings (#2093479) +- core: be more careful when inheriting stdout fds to stderr (#2093479) +- test: add a test for StandardError=file:… (#2093479) +- tree-wide: allow ASCII fallback for → in logs (#2093479) +- tree-wide: allow ASCII fallback for … in logs (#2093479) +- core: allow to set default timeout for devices (#1967245) +- man: document DefaultDeviceTimeoutSec= (#1967245) +- Revert "core: Propagate condition failed state to triggering units." (#2114005) +- core: Check unit start rate limiting earlier (#2114005) +- core: Add trigger limit for path units (#2114005) +- meson: add syscall-names-update target (#2040247) +- syscall-names: add process_madvise which is planned for 5.10 (#2040247) +- shared: add @known syscall list (#2040247) +- generate-syscall-list: require python3 (#2040247) +- shared/seccomp: reduce scope of indexing variables (#2040247) +- shared/syscall-list: filter out some obviously platform-specific syscalls (#2040247) +- seccomp: tighten checking of seccomp filter creation (#2040247) +- shared/seccomp-util: added functionality to make list of filtred syscalls (#2040247) +- nspawn: return ENOSYS by default, EPERM for "known" calls (#2040247) +- revert: resolved: pin stream while calling callbacks for it (#2110549) + +* Wed Aug 03 2022 systemd maintenance team - 239-63 +- resolved: pin stream while calling callbacks for it (#2110549) + +* Mon Jul 18 2022 systemd maintenance team - 239-62 +- spec: Remove dependency on timedatex (#2066946) + +* Thu Jul 14 2022 systemd maintenance team - 239-61 +- mkosi: Add gnutls package (#2101227) +- unit-name: tighten checks for building valid unit names (#1940973) +- core: shorten long unit names that are based on paths and append path hash at the end (#1940973) +- test: add extended test for triggering mount rate limit (#1940973) +- tests: add test case for long unit names (#1940973) +- core: unset HOME=/ that the kernel gives us (#2056527) +- journal-remote: check return value from MHD_add_response_header (#2051981) +- journalctl: in --follow mode watch stdout for POLLHUP/POLLERR and exit (#2003236) +- sd-bus: make BUS_DEFAULT_TIMEOUT configurable (#2039461) +- fstab-generator: fix debug log (#2101433) +- logind-session-dbus: allow to set display name via dbus (#1857969) +- Allow restart for oneshot units (#2042896) +- test: correct TEST-41 StartLimitBurst test (#2042896) +- core: fix assert() about number of built environment variables (#2049788) +- core: add one more assert() (#2049788) +- strv: introduce strv_join_prefix() (#2049788) +- test: add tests for strv_join_prefix() (#2049788) +- test: replace swear words by 'hoge' (#2049788) +- core: add new environment variable $RUNTIME_DIRECTORY= or friends (#2049788) +- test-execute: add tests for $RUNTIME_DIRECTORY= or friends (#2049788) +- man: document RUNTIME_DIRECTORY= or friends (#2049788) + +* Thu Jun 23 2022 systemd maintenance team - 239-60 +- unit: don't emit PropertiesChanged signal if adding a dependency to a unit is a no-op (#1948480) +- tests: make inverted tests actually count (#2087152) +- TEST-*: make failure tests actually fail on failure (#2087152) +- ci(Mergify): configuration update (#2087152) +- core: propagate triggered unit in more load states (#2065322) +- core: propagate unit start limit hit state to triggering path unit (#2065322) +- core: Move 'r' variable declaration to start of unit_start() (#2065322) +- core: Delay start rate limit check when starting a unit (#2065322) +- core: Propagate condition failed state to triggering units. (#2065322) +- unit: check for mount rate limiting before checking active state (#2095744) + +* Wed May 18 2022 systemd maintenance team - 239-59 +- core: disallow using '-.service' as a service name (#2051520) +- shared/dropin: support -.service.d/ top level drop-in for service units (#2051520) +- core: change top-level drop-in from -.service.d to service.d (#2051520) +- shared/dropin: fix assert for invalid drop-in (#2051520) +- udev: fix slot based network names on s390 (#1939914) +- udev: it is not necessary that the path is readable (#1939914) +- udev: allow onboard index up to 65535 (#1939914) +- Revert "basic: use comma as separator in cpuset cgroup cpu ranges" (#1858220) +- acpi-fpdt: mark structures as packed (#2047373) +- core/slice: make slice_freezer_action() return 0 if freezing state is unchanged (#2047373) +- core/unit: fix use-after-free (#2047373) +- sd-bus: fix reference counter to be incremented (#2047373) +- sd-bus: do not read unused value (#2047373) +- sd-bus: do not return negative errno when unknown name is specified (#2047373) +- sd-bus: switch to a manual overflow check in sd_bus_track_add_name() (#2047373) +- spec: Add dependency on timedatex (#2066946) + +* Tue Feb 08 2022 systemd maintenance team - 239-58 +- ci: drop CentOS 8 CI (#2017033) +- test: adapt to the new capsh format (#2017033) +- test: ignore IAB capabilities in `test-execute` (#2017033) + +* Mon Feb 07 2022 systemd maintenance team - 239-57 +- udev/net_id: introduce naming scheme for RHEL-8.5 (#2039797) +- udev/net_id: remove extraneous bracket (#2039797) +- udev/net_id: introduce naming scheme for RHEL-8.6 (#2039797) +- define newly needed constants (#2005008) +- sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME attributes (#2005008) +- sd-netlink: introduce sd_netlink_message_read_strv() (#2005008) +- sd-netlink: introduce sd_netlink_message_append_strv() (#2005008) +- test: add a test for sd_netlink_message_{append,read}_strv() (#2005008) +- util: introduce ifname_valid_full() (#2005008) +- rename function (#2005008) +- udev: support AlternativeName= setting in .link file (#2005008) +- network: make Name= in [Match] support alternative names of interfaces (#2005008) +- udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ (#2005008) +- udev: do not fail if kernel does not support alternative names (#2005008) +- udev: introduce AlternativeNamesPolicy= setting (#2005008) +- network: set AlternativeNamesPolicy= in 99-default.link (#2005008) +- random-util: call initialize_srand() after fork() (#2005008) +- sd-netlink: introduce rtnl_resolve_link_alternative_names() (#2005008) +- udev: sort alternative names (#2005008) +- netlink: introduce rtnl_get/delete_link_alternative_names() (#2005008) +- netlink: do not fail when new interface name is already used as an alternative name (#2005008) +- udev: do not try to reassign alternative names (#2005008) +- Do not fail if the same alt. name is set again (#2005008) +- mount: do not update exec deps on mountinfo changes (#2008825) +- core/mount: add implicit unit dependencies even if when mount unit is generated from /proc/self/mountinfo (#2008825) +- core: fix unfortunate typo in unit_is_unneeded() (#2040147) +- core: make destructive transaction error a bit more useful (#2040147) +- tmpfiles: use a entry in hashmap as ItemArray in read_config_file() (#1944468) +- tmpfiles: rework condition check (#1944468) +- TEST-22-TMPFILES: add reproducer for bug with X (#1944468) +- core: make sure we don't get confused when setting TERM for a tty fd (#2045307) +- hash-funcs: introduce macro to create typesafe hash_ops (#2037807) +- hash-func: add destructors for key and value (#2037807) +- util: define free_func_t (#2037807) +- hash-funcs: make basic hash_ops typesafe (#2037807) +- test: add tests for destructors of hashmap or set (#2037807) +- man: document the new sysctl.d/ - prefix (#2037807) +- sysctl: if options are prefixed with "-" ignore write errors (#2037807) +- sysctl: fix segfault (#2037807) + +* Tue Jan 25 2022 systemd maintenance team - 239-56 +- Take ghost ownership of /var/log/lastlog (#1798685) + +* Mon Jan 10 2022 systemd maintenance team - 239-55 +- lgtm: detect uninitialized variables using the __cleanup__ attribute (#2017033) +- lgtm: replace the query used for looking for fgets with a more general query (#2017033) +- lgtm: beef up list of dangerous/questionnable API calls not to make (#2017033) +- lgtm: warn about strerror() use (#2017033) +- lgtm: complain about accept() [people should use accept4() instead, due to O_CLOEXEC] (#2017033) +- lgtm: don't treat the custom note as a list of tags (#2017033) +- lgtm: ignore certain cleanup functions (#2017033) +- lgtm: detect more possible problematic scenarios (#2017033) +- lgtm: enable more (and potentially useful) queries (#2017033) +- test: make TEST-47 less racy (#2017033) +- core: rename unit_{start_limit|condition|assert}_test() to unit_test_xyz() (#2036608) +- core: Check unit start rate limiting earlier (#2036608) +- sd-event: introduce callback invoked when event source ratelimit expires (#2036608) +- core: rename/generalize UNIT(u)->test_start_limit() hook (#2036608) +- mount: make mount units start jobs not runnable if /p/s/mountinfo ratelimit is in effect (#2036608) +- mount: retrigger run queue after ratelimit expired to run delayed mount start jobs (#2036608) +- pid1: add a manager_trigger_run_queue() helper (#2036608) +- unit: add jobs that were skipped because of ratelimit back to run_queue (#2036608) +- Revert "Revert "sysctl: Enable ping(8) inside rootless Podman containers"" (#2037807) +- sysctl: prefix ping port range setting with a dash (#2037807) +- mount: don't propagate errors from mount_setup_unit() further up (#2036853) + +* Wed Dec 01 2021 systemd maintenance team - 239-54 +- core: consider service with no start command immediately started (#1860899) +- man: move description of *Action= modes to FailureAction=/SuccessAction= (#1860899) +- core: define "exit" and "exit-force" actions for user units and only accept that (#1860899) +- core: accept system mode emergency action specifiers with a warning (#1860899) +- core: allow services with no commands but SuccessAction set (#1860899) +- core: limit service-watchdogs=no to actual "watchdog" commands (#1860899) +- units: use SuccessAction=exit-force in systemd-exit.service (#1860899) +- units: use SuccessAction=reboot-force in systemd-reboot.service (#1860899) +- units: use SuccessAction=poweroff-force in systemd-poweroff.service (#1860899) +- units: allow and use SuccessAction=exit-force in system systemd-exit.service (#1860899) +- core: do not "warn" about mundane emergency actions (#1860899) +- core: return true from cg_is_empty* on ENOENT (#1860899) +- macro: define HAS_FEATURE_ADDRESS_SANITIZER also on gcc (#2017033) +- tests: add helper function to autodetect CI environments (#2017033) +- strv: rework FOREACH_STRING() macro (#2017033) +- test,systemctl: use "const char*" instead of "char*" (#2017033) +- ci: pass the $GITHUB_ACTIONS variable to the CentOS container (#2017033) + +* Wed Nov 24 2021 systemd maintenance team - 239-53 +- sd-hwdb: allow empty properties (#2005009) +- Update hwdb (#2005009) +- Disable libpitc to fix CentOS Stream CI (#2017033) +- rpm: Fix typo in %_environmentdir (#2018024) +- rpm: Add misspelled %_environmentdir macro for temporary compatibility (#2018024) +- rpm: emit warning when macro with typo is used (#2018024) +- Remove unintended additions to systemd-analyze man page (#2004765) +- core: fix SIGABRT on empty exec command argv (#2020239) +- core/service: also check path in exec commands (#2020239) +- mount-util: fix fd_is_mount_point() when both the parent and directory are network fs (#2015057) +- basic: add vmware hypervisor detection from device-tree (#1959150) +- pam: do not require a non-expired password for user@.service (#1961746) +- udev rules: add rule to create /dev/ptp_hyperv (#1991834) +- process-util: explicitly handle processes lacking parents in get_process_ppid() (#1977569) +- errno-util: add ERRNO_IS_PRIVILEGE() helper (#1977569) +- procfs-util: fix confusion wrt. quantity limit and maximum value (#1977569) +- test-process-util: also add EROFS to the list of "good" errors (#1977569) +- journal: refresh cached credentials of stdout streams (#1931806) +- util-lib: introduce HAS_FEATURE_ADDRESS_SANITIZER (#2017033) +- ci: skip test-execute on GH Actions under ASan (#2017033) +- test-seccomp: accept ENOSYS from sysctl(2) too (#2017033) +- test: accept that char device 0/0 can now be created witout privileges (#2017033) +- meson: do not fail if rsync is not installed with meson 0.57.2 (#2017033) +- pid1: fix free of uninitialized pointer in unit_fail_if_noncanonical() (#1970945) +- sd-event: take ref on event loop object before dispatching event sources (#1970945) + +* Fri Aug 27 2021 systemd maintenance team - 239-50 +- Added option --check-inhibitors for non-tty usage (#1269726) +- logind: Introduce RebootWithFlags and others (#1269726) +- logind: add …WithFlags methods to policy (#1269726) +- logind: simplify flags handling a bit (#1269726) +- Update link to RHEL documentation (#1982584) +- Set default core ulimit to 0, but keep the hard limit ulimited (#1905582) +- shared/seccomp-util: address family filtering is broken on ppc (#1982650) +- logind: rework Seat/Session/User object allocation and freeing a bit (#1642460) +- logind: fix serialization/deserialization of user's "display session" (#1642460) +- logind: turn of stdio locking when writing session files too (#1642460) +- units: set StopWhenUnneeded= for the user slice units too (#1642460) +- units: improve Description= string a bit (#1642460) +- logind: improve logging in manager_connect_console() (#1642460) +- logind: save/restore User object's "stopping" field during restarts (#1642460) +- logind: correct bad clean-up path (#1642460) +- logind: fix bad error propagation (#1642460) +- logind: never elect a session that is stopping as display (#1642460) +- logind: introduce little helper that checks whether a session is ready (#1642460) +- logind: propagate session stop errors (#1642460) +- logind: rework how we manage the slice and user-runtime-dir@.service unit for each user (#1642460) +- logind: optionally, keep the user@.service instance for eached logged in user around for a while (#1642460) +- logind: add a RequiresMountsFor= dependency from the session scope unit to the home directory of the user (#1642460) +- logind: improve error propagation of user_check_linger_file() (#1642460) +- logind: automatically GC lingering users for who now user@.service (nor slice, not runtime dir service) is running anymore (#1642460) +- pam_systemd: simplify code which with we set environment variables (#1642460) +- logind: validate /run/user/1000 before we set it (#1642460) + +* Fri Jul 23 2021 systemd maintenance team - 239-49 +- remove a left-over break (#1970860) +- basic/unit-name: do not use strdupa() on a path (#1974700) +- sd-event: change ordering of pending/ratelimited events (#1968528) +- sd-event: drop unnecessary "else" (#1968528) +- sd-event: use CMP() macro (#1968528) +- sd-event: use usec_add() (#1968528) +- sd-event: make event_source_time_prioq_reshuffle() accept all event source type (#1968528) +- sd-event: always reshuffle time prioq on changing online/offline state (#1968528) +- ci: run unit tests on z-stream branches as well (#1970860) +- ci: drop forgotten Travis references (#1934504) +- ci: run unit tests on CentOS 8 Stream as well (#1934504) +- ci: add missing test dependencies (#1934504) +- meson: bump timeout for test-udev to 180s (#1934504) + +* Thu Jun 24 2021 systemd maintenance team - 239-48 +- cgroup: Also set io.bfq.weight (#1927290) +- seccomp: allow turning off of seccomp filtering via env var (#1916835) +- meson: remove strange dep that causes meson to enter infinite loop (#1970860) +- copy: handle copy_file_range() weirdness on procfs/sysfs (#1970860) +- core: Hide "Deactivated successfully" message (#1954802) +- util: rework in_initrd() to make use of path_is_temporary_fs() (#1959339) +- initrd: extend SYSTEMD_IN_INITRD to accept non-ramfs rootfs (#1959339) +- initrd: do a debug log if failed to detect rootfs type (#1959339) +- initrd: do a debug log if /etc/initrd-release doesn't take effect (#1959339) +- units: assign user-runtime-dir@.service to user-%i.slice (#1946453) +- units: order user-runtime-dir@.service after systemd-user-sessions.service (#1946453) +- units: make sure user-runtime-dir@.service is Type=oneshot (#1946453) +- user-runtime-dir: downgrade a few log messages to LOG_DEBUG that we ignore (#1946453) +- shared/install: Preserve escape characters for escaped unit names (#1952686) +- basic/virt: Detect PowerVM hypervisor (#1937989) +- man: document differences in clean exit status for Type=oneshot (#1940078) +- busctl: add a timestamp to the output of the busctl monitor command (#1909214) +- basic/cap-list: parse/print numerical capabilities (#1946943) +- shared/mount-util: convert to libmount (#1885143) +- mount-util: bind_remount: avoid calling statvfs (#1885143) +- mount-util: use UMOUNT_NOFOLLOW in recursive umounter (#1885143) +- test-install-root: create referenced targets (#1835351) +- install: warn if WantedBy targets don't exist (#1835351) +- test-install-root: add test for unknown WantedBy= target (#1835351) +- ceph is a network filesystem (#1952013) +- sysctl: set kernel.core_pipe_limit=16 (#1949729) +- core: don't drop timer expired but not yet processed when system date is changed (#1899402) +- core: Detect initial timer state from serialized data (#1899402) +- rc-local: order after network-online.target (#1934028) +- set core ulimit to 0 like on RHEL-7 (#1905582) +- test-mountpointutil-util: do not assert in test_mnt_id() (#1910425) + +* Fri Jun 04 2021 Jan Macku - 239-47 +- systemd-binfmt: Add safeguard in triggers (#1787144) +- spec: Requires(post) openssl-libs to fix missing /etc/machine-id (#1947438) +- spec: Go back to using systemctl preset-all in post (#1783263, #1647172, #1118740) +- spec: Disable libiptc support (#1817265) + +* Wed May 19 2021 systemd maintenance team - 239-46 +- Revert "udev: run link_update() with increased retry count in second invocation" (#1942299) +- Revert "udev: make algorithm that selects highest priority devlink less susceptible to race conditions" (#1942299) +- test/udev-test.pl: drop test cases that add mutliple devices (#1942299) + +* Thu Mar 11 2021 systemd maintenance team - 239-45 +- Revert "test: add test cases for empty string match" and "test: add test case for multi matches when use ||" (#1935124) +- test/sys-script.py: add missing DEVNAME entries to uevents (#1935124) +- sd-event: split out helper functions for reshuffling prioqs (#1937315) +- sd-event: split out enable and disable codepaths from sd_event_source_set_enabled() (#1937315) +- sd-event: mention that two debug logged events are ignored (#1937315) +- sd-event: split clock data allocation out of sd_event_add_time() (#1937315) +- sd-event: split out code to add/remove timer event sources to earliest/latest prioq (#1937315) +- sd-event: fix delays assert brain-o (#17790) (#1937315) +- sd-event: let's suffix last_run/last_log with "_usec" (#1937315) +- sd-event: refuse running default event loops in any other thread than the one they are default for (#1937315) +- sd-event: ref event loop while in sd_event_prepare() ot sd_event_run() (#1937315) +- sd-event: follow coding style with naming return parameter (#1937315) +- sd-event: remove earliest_index/latest_index into common part of event source objects (#1937315) +- sd-event: update state at the end in event_source_enable (#1937315) +- sd-event: increase n_enabled_child_sources just once (#1937315) +- sd-event: add ability to ratelimit event sources (#1937315) +- test: add ratelimiting test (#1937315) +- core: prevent excessive /proc/self/mountinfo parsing (#1937315) +- udev: run link_update() with increased retry count in second invocation (#1935124) +- pam-systemd: use secure_getenv() rather than getenv() (#1936866) + +* Thu Jan 28 2021 systemd maintenance team - 239-44 +- ci: PowerTools repo was renamed to powertools in RHEL 8.3 (#1871827) +- ci: use quay.io instead of Docker Hub to avoid rate limits (#1871827) +- ci: move jobs from Travis CI to GH Actions (#1871827) +- unit: make UNIT() cast function deal with NULL pointers (#1871827) +- use link to RHEL-8 docs (#1623116) +- cgroup: Also set blkio.bfq.weight (#1657810) +- units: make sure initrd-cleanup.service terminates before switching to rootfs (#1657810) +- core: reload SELinux label cache on daemon-reload (#1888912) +- selinux: introduce mac_selinux_create_file_prepare_at() (#1888912) +- selinux: add trigger for policy reload to refresh internal selabel cache (#1888912) +- udev/net_id: give RHEL-8.4 naming scheme a name (#1827462) +- basic/stat-util: make mtime check stricter and use entire timestamp (#1642728) +- udev: make algorithm that selects highest priority devlink less susceptible to race conditions (#1642728) +- test: create /dev/null in test-udev.pl (#1642728) +- test: missing "die" (#1642728) +- udev-test: remove a check for whether the test is run in a container (#1642728) +- udev-test: skip the test only if it can't setup its environment (#1642728) +- udev-test: fix test skip condition (#1642728) +- udev-test: fix missing directory test/run (#1642728) +- udev-test: check if permitted to create block device nodes (#1642728) +- test-udev: add a testcase of too long line (#1642728) +- test-udev: use proper semantics for too long line with continuation (#1642728) +- test-udev: add more tests for line continuations and comments (#1642728) +- test-udev: add more tests for line continuation (#1642728) +- test-udev: fix alignment and drop unnecessary white spaces (#1642728) +- test/udev-test.pl: cleanup if skipping test (#1642728) +- test: add test cases for empty string match (#1642728) +- test: add test case for multi matches when use "||" (#1642728) +- udev-test: do not rely on "mail" group being defined (#1642728) +- test/udev-test.pl: allow multiple devices per test (#1642728) +- test/udev-test.pl: create rules only once (#1642728) +- test/udev-test.pl: allow concurrent additions and removals (#1642728) +- test/udev-test.pl: use computed devnode name (#1642728) +- test/udev-test.pl: test correctness of symlink targets (#1642728) +- test/udev-test.pl: allow checking multiple symlinks (#1642728) +- test/udev-test.pl: fix wrong test descriptions (#1642728) +- test/udev-test.pl: last_rule is unsupported (#1642728) +- test/udev-test.pl: Make some tests a little harder (#1642728) +- test/udev-test.pl: remove bogus rules from magic subsys test (#1642728) +- test/udev-test.pl: merge "space and var with space" tests (#1642728) +- test/udev-test.pl: merge import parent tests into one (#1642728) +- test/udev-test.pl: count "good" results (#1642728) +- tests/udev-test.pl: add multiple device test (#1642728) +- test/udev-test.pl: add repeat count (#1642728) +- test/udev-test.pl: generator for large list of block devices (#1642728) +- test/udev-test.pl: suppress umount error message at startup (#1642728) +- test/udev_test.pl: add "expected good" count (#1642728) +- test/udev-test: gracefully exit when imports fail (#1642728) + +* Thu Nov 26 2020 systemd maintenance team - 239-43 +- man: mention System Administrator's Guide in systemctl manpage (#1623116) +- udev: introduce udev net_id "naming schemes" (#1827462) +- meson: make net.naming-scheme= default configurable (#1827462) +- man: describe naming schemes in a new man page (#1827462) +- udev/net_id: parse _SUN ACPI index as a signed integer (#1827462) +- udev/net_id: don't generate slot based names if multiple devices might claim the same slot (#1827462) +- fix typo in ProtectSystem= option (#1871139) +- remove references of non-existent man pages (#1876807) +- log: Prefer logging to CLI unless JOURNAL_STREAM is set (#1865840) +- locale-util: add new helper locale_is_installed() (#1755287) +- test: add test case for locale_is_installed() (#1755287) +- tree-wide: port various bits over to locale_is_installed() (#1755287) +- install: allow instantiated units to be enabled via presets (#1812972) +- install: small refactor to combine two function calls into one function (#1812972) +- test: fix a memleak (#1812972) +- docs: Add syntax for templated units to systemd.preset man page (#1812972) +- shared/install: fix preset operations for non-service instantiated units (#1812972) +- introduce setsockopt_int() helper (#1887181) +- socket-util: add generic socket_pass_pktinfo() helper (#1887181) +- core: add new PassPacketInfo= socket unit property (#1887181) +- resolved: tweak cmsg calculation (#1887181) + +* Tue Nov 03 2020 systemd maintenance team - 239-42 +- logind: don't print warning when user@.service template is masked (#1880270) +- build: use simple project version in pkgconfig files (#1862714) +- basic/virt: try the /proc/1/sched hack also for PID1 (#1868877) +- seccomp: rework how the S[UG]ID filter is installed (#1860374) +- vconsole-setup: downgrade log message when setting font fails on dummy console (#1889996) +- units: fix systemd.special man page reference in system-update-cleanup.service (#1871827) +- units: drop reference to sushell man page (#1871827) +- sd-bus: break the loop in bus_ensure_running() if the bus is not connecting (#1885553) +- core: add new API for enqueing a job with returning the transaction data (#846319) +- systemctl: replace switch statement by table of structures (#846319) +- systemctl: reindent table (#846319) +- systemctl: Only wait when there's something to wait for. (#846319) +- systemctl: clean up start_unit_one() error handling (#846319) +- systemctl: split out extra args generation into helper function of its own (#846319) +- systemctl: add new --show-transaction switch (#846319) +- test: add some basic testing that "systemctl start -T" does something (#846319) +- man: document the new systemctl --show-transaction option (#846319) +- socket: New option 'FlushPending' (boolean) to flush socket before entering listening state (#1870638) +- core: remove support for API bus "started outside our own logic" (#1764282) +- mount-setup: fix segfault in mount_cgroup_controllers when using gcc9 compiler (#1868877) +- dbus-execute: make transfer of CPUAffinity endian safe (#12711) (#1740657) +- core: add support for setting CPUAffinity= to special "numa" value (#1740657) +- basic/user-util: always use base 10 for user/group numbers (#1848373) +- parse-util: sometimes it is useful to check if a string is a valid integer, but not actually parse it (#1848373) +- basic/parse-util: add safe_atoux64() (#1848373) +- parse-util: allow tweaking how to parse integers (#1848373) +- parse-util: allow '-0' as alternative to '0' and '+0' (#1848373) +- parse-util: make return parameter optional in safe_atou16_full() (#1848373) +- parse-util: rewrite parse_mode() on top of safe_atou_full() (#1848373) +- user-util: be stricter in parse_uid() (#1848373) +- strv: add new macro STARTSWITH_SET() (#1848373) +- parse-util: also parse integers prefixed with 0b and 0o (#1848373) +- tests: beef up integer parsing tests (#1848373) +- shared/user-util: add compat forms of user name checking functions (#1848373) +- shared/user-util: emit a warning on names with dots (#1848373) +- user-util: Allow names starting with a digit (#1848373) +- shared/user-util: allow usernames with dots in specific fields (#1848373) +- user-util: switch order of checks in valid_user_group_name_or_id_full() (#1848373) +- user-util: rework how we validate user names (#1848373) + +* Wed Oct 07 2020 systemd maintenance team - 239-41 +- cgroup: freezer action must be NOP when cgroup v2 freezer is not available (#1868831) + +* Fri Aug 28 2020 systemd maintenance team - 239-40 +- units: add generic boot-complete.target (#1872243) +- man: document new "boot-complete.target" unit (#1872243) +- core: make sure to restore the control command id, too (#1829867) + +* Thu Aug 06 2020 systemd maintenance team - 239-39 +- device: make sure we emit PropertiesChanged signal once we set sysfs (#1793533) +- device: don't emit PropetiesChanged needlessly (#1793533) + +* Tue Aug 04 2020 systemd maintenance team - 239-38 +- spec: fix rpm verification (#1702300) + +* Wed Jul 08 2020 systemd maintenance team - 239-37 +- spec: don't package /etc/systemd/system/dbus-org.freedesktop.resolve1.service (#1844465) + +* Fri Jun 26 2020 systemd maintenance team - 239-36 +- core: don't consider SERVICE_SKIP_CONDITION for abnormal or failure restarts (#1737283) +- selinux: do preprocessor check only in selinux-access.c (#1830861) +- basic/cgroup-util: introduce cg_get_keyed_attribute_full() (#1830861) +- shared: add generic logic for waiting for a unit to enter some state (#1830861) +- shared: fix assert call (#1830861) +- shared: Don't try calling NULL callback in bus_wait_for_units_clear (#1830861) +- shared: add NULL callback check in one more place (#1830861) +- core: introduce support for cgroup freezer (#1830861) +- core/cgroup: fix return value of unit_cgorup_freezer_action() (#1830861) +- core: fix the return value in order to make sure we don't dipatch method return too early (#1830861) +- test: add test for cgroup v2 freezer support (#1830861) +- fix mis-merge (#1848421) +- tests: sleep a bit and give kernel time to perform the action after manual freeze/thaw (#1848421) + +* Fri Jun 26 2020 systemd maintenance team - 239-35 +- spec: fix rpm verification (#1702300) + +* Thu Jun 18 2020 systemd maintenance team - 239-34 +- spec: fix rpm verification (#1702300) + +* Tue Jun 09 2020 systemd maintenance team - 239-33 +- tmpfiles: fix crash with NULL in arg_root and other fixes and tests (#1836024) +- sulogin-shell: Use force if SYSTEMD_SULOGIN_FORCE set (#1625929) +- resolvconf: fixes for the compatibility interface (#1835594) +- mount: don't add Requires for tmp.mount (#1748840) +- core: coldplug possible nop_job (#1829798) +- core: add IODeviceLatencyTargetSec (#1831519) +- time-util: Introduce parse_sec_def_infinity (#1770379) +- cgroup: use structured initialization (#1770379) +- core: add CPUQuotaPeriodSec= (#1770379) +- core: downgrade CPUQuotaPeriodSec= clamping logs to debug (#1770379) +- sd-bus: avoid magic number in SASL length calculation (#1838081) +- sd-bus: fix SASL reply to empty AUTH (#1838081) +- sd-bus: skip sending formatted UIDs via SASL (#1838081) +- core: add MemoryMin (#1763435) +- core: introduce cgroup_add_device_allow() (#1763435) +- test: remove support for suffix in get_testdata_dir() (#1763435) +- cgroup: Implement default propagation of MemoryLow with DefaultMemoryLow (#1763435) +- cgroup: Create UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP (#1763435) +- unit: Add DefaultMemoryMin (#1763435) +- cgroup: Polish hierarchically aware protection docs a bit (#1763435) +- cgroup: Readd some plumbing for DefaultMemoryMin (#1763435) +- cgroup: Support 0-value for memory protection directives (#1763435) +- cgroup: Test that it's possible to set memory protection to 0 again (#1763435) +- cgroup: Check ancestor memory min for unified memory config (#1763435) +- cgroup: Respect DefaultMemoryMin when setting memory.min (#1763435) +- cgroup: Mark memory protections as explicitly set in transient units (#1763435) +- meson: allow setting the version string during configuration (#1804252) + +* Thu Jun 04 2020 systemd maintenance team - 239-32 +- pid1: fix DefaultTasksMax initialization (#1809037) +- cgroup: make sure that cpuset is supported on cgroup v2 and disabled with v1 (#1808940) +- test: introduce TEST-36-NUMAPOLICY (#1808940) +- test: replace `tail -f` with journal cursor which should be... (#1808940) +- test: support MPOL_LOCAL matching in unpatched strace versions (#1808940) +- test: make sure the strace process is indeed dead (#1808940) +- test: skip the test on systems without NUMA support (#1808940) +- test: give strace some time to initialize (#1808940) +- test: add a simple sanity check for systems without NUMA support (#1808940) +- test: drop the missed || exit 1 expression (#1808940) +- test: replace cursor file with a plain cursor (#1808940) +- cryptsetup: Treat key file errors as a failed password attempt (#1763155) +- swap: finish the secondary swap units' jobs if deactivation of the primary swap unit fails (#1749622) +- resolved: Recover missing PrivateTmp=yes and ProtectSystem=strict (#1810869) +- bus_open leak sd_event_source when udevadm trigger。 (#1798504) +- core: rework StopWhenUnneeded= logic (#1798046) +- pid1: fix the names of AllowedCPUs= and AllowedMemoryNodes= (#1818054) +- core: fix re-realization of cgroup siblings (#1818054) +- basic: use comma as separator in cpuset cgroup cpu ranges (#1818054) +- core: transition to FINAL_SIGTERM state after ExecStopPost= (#1766479) +- sd-journal: close journal files that were deleted by journald before we've setup inotify watch (#1796128) +- sd-journal: remove the dead code and actually fix #14695 (#1796128) +- udev: downgrade message when we fail to set inotify watch up (#1808051) +- logind: check PolicyKit before allowing VT switch (#1797679) +- test: do not use global variable to pass error (#1823767) +- test: install libraries required by tests (#1823767) +- test: introduce install_zoneinfo() (#1823767) +- test: replace duplicated Makefile by symbolic link (#1823767) +- test: add paths of keymaps in install_keymaps() (#1823767) +- test: make install_keymaps() optionally install more keymaps (#1823767) +- test-fs-util: skip some tests when running in unprivileged container (#1823767) +- test-process-util: skip several verifications when running in unprivileged container (#1823767) +- test-execute: also check python3 is installed or not (#1823767) +- test-execute: skip several tests when running in container (#1823767) +- test: introduce test_is_running_from_builddir() (#1823767) +- test: make test-catalog relocatable (#1823767) +- test: parallelize tasks in TEST-24-UNIT-TESTS (#1823767) +- test: try to determine QEMU_SMP dynamically (#1823767) +- test: store coredumps in journal (#1823767) +- pid1: add new kernel cmdline arg systemd.cpu_affinity= (#1812894) +- udev-rules: make tape-changers also apprear in /dev/tape/by-path/ (#1820112) +- man: be clearer that .timer time expressions need to be reset to override them (#1816908) +- Add support for opening files for appending (#1809175) +- nspawn: move payload to sub-cgroup first, then sync cgroup trees (#1837094) +- core: move unit_status_emit_starting_stopping_reloading() and related calls to job.c (#1737283) +- job: when a job was skipped due to a failed condition, log about it (#1737283) +- core: split out all logic that updates a Job on a unit's unit_notify() invocation (#1737283) +- core: make log messages about units entering a 'failed' state recognizable (#1737283) +- core: log a recognizable message when a unit succeeds, too (#1737283) +- tests: always use the right vtable wrapper calls (#1737283) +- test-execute: allow filtering test cases by pattern (#1737283) +- test-execute: provide custom failure message (#1737283) +- core: ExecCondition= for services (#1737283) +- Drop support for lz4 < 1.3.0 (#1843871) +- test-compress: add test for short decompress_startswith calls (#1843871) +- journal: adapt for new improved LZ4_decompress_safe_partial() (#1843871) +- fuzz-compress: add fuzzer for compression and decompression (#1843871) +- seccomp: fix __NR__sysctl usage (#1843871) + +* Fri Feb 21 2020 systemd maintenance team - 239-27 +- cgroup: introduce support for cgroup v2 CPUSET controller (#1724617) + +* Wed Feb 19 2020 systemd maintenance team - 239-26 +- seccomp: introduce seccomp_restrict_suid_sgid() for blocking chmod() for suid/sgid files (#1687512) +- test: add test case for restrict_suid_sgid() (#1687512) +- core: expose SUID/SGID restriction as new unit setting RestrictSUIDSGID= (#1687512) +- analyze: check for RestrictSUIDSGID= in "systemd-analyze security" (#1687512) +- man: document the new RestrictSUIDSGID= setting (#1687512) +- units: turn on RestrictSUIDSGID= in most of our long-running daemons (#1687512) +- core: imply NNP and SUID/SGID restriction for DynamicUser=yes service (#1687512) + +* Mon Feb 17 2020 systemd maintenance team - 239-25 +- sd-bus: use "queue" message references for managing r/w message queues in connection objects (CVE-2020-1712) +- pid1: make sure to restore correct default values for some rlimits (#1789930) +- main: introduce a define HIGH_RLIMIT_MEMLOCK similar to HIGH_RLIMIT_NOFILE (#1789930) + +* Thu Feb 13 2020 systemd maintenance team - 239-24 +- rules: reintroduce 60-alias-kmsg.rules (#1739353) +- sd-bus: make rqueue/wqueue sizes of type size_t (CVE-2020-1712) +- sd-bus: reorder bus ref and bus message ref handling (CVE-2020-1712) +- sd-bus: make sure dispatch_rqueue() initializes return parameter on all types of success (CVE-2020-1712) +- sd-bus: drop two inappropriate empty lines (CVE-2020-1712) +- sd-bus: initialize mutex after we allocated the wqueue (CVE-2020-1712) +- sd-bus: always go through sd_bus_unref() to free messages (CVE-2020-1712) +- bus-message: introduce two kinds of references to bus messages (CVE-2020-1712) +- sd-bus: introduce API for re-enqueuing incoming messages (CVE-2020-1712) +- sd-event: add sd_event_source_disable_unref() helper (CVE-2020-1712) +- polkit: when authorizing via PK let's re-resolve callback/userdata instead of caching it (CVE-2020-1712) +- sysctl: let's by default increase the numeric PID range from 2^16 to 2^22 (#1744214) +- journal: do not trigger assertion when journal_file_close() get NULL (#1788085) +- journal: use cleanup attribute at one more place (#1788085) + +* Mon Jan 13 2020 systemd maintenance team - 239-23 +- catalog: fix name of variable (#1677768) +- cryptsetup: add keyfile-timeout to allow a keydev timeout and allow to fallback to a password if it fails. (#1763155) +- cryptsetup: add documentation for keyfile-timeout (#1763155) +- cryptsetup: use unabbrieviated variable names (#1763155) +- cryptsetup: don't assert on variable which is optional (#1763155) +- cryptsetup-generator: guess whether the keyfile argument is two items or one (#1763155) +- crypt-util: Translate libcryptsetup log level instead of using log_debug() (#1776408) +- cryptsetup: add some commenting about EAGAIN generation (#1776408) +- cryptsetup: downgrade a log message we ignore (#1776408) +- cryptsetup: rework how we log about activation failures (#1776408) + +* Tue Dec 17 2019 systemd maintenance team - 239-22 +- spec: don't ship /var/log/README +- spec: provide systemd-rpm-macros + +* Mon Dec 09 2019 systemd maintenance team - 239-21 +- test-cpu-set-util: fix comparison for allocation size (#1734787) +- test-cpu-set-util: fix allocation size check on i386 (#1734787) + +* Mon Dec 09 2019 systemd maintenance team - 239-20 +- journal: rely on _cleanup_free_ to free a temporary string used in client_context_read_cgroup (#1764560) +- basic/user-util: allow dots in user names (#1717603) +- sd-bus: bump message queue size again (#1770189) +- tests: put fuzz_journald_processing_function in a .c file (#1764560) +- tests: add a fuzzer for dev_kmsg_record (#1764560) +- basic: remove an assertion from cunescape_one (#1764560) +- journal: fix an off-by-one error in dev_kmsg_record (#1764560) +- tests: add a reproducer for a memory leak fixed in 30eddcd51b8a472e05d3b8d1 in August (#1764560) +- tests: add a reproducer for a heap-buffer-overflow fixed in 937b1171378bc1000a (#1764560) +- test: initialize syslog_fd in fuzz-journald-kmsg too (#1764560) +- tests: add a fuzzer for process_audit_string (#1764560) +- journald: check whether sscanf has changed the value corresponding to %n (#1764560) +- tests: introduce dummy_server_init and use it in all journald fuzzers (#1764560) +- tests: add a fuzzer for journald streams (#1764560) +- tests: add a fuzzer for server_process_native_file (#1764560) +- fuzz-journal-stream: avoid assertion failure on samples which don't fit in pipe (#1764560) +- journald: take leading spaces into account in syslog_parse_identifier (#1764560) +- Add a warning about the difference in permissions between existing directories and unit settings. (#1778384) +- execute: remove one redundant comparison check (#1778384) +- core: change ownership/mode of the execution directories also for static users (#1778384) +- core/dbus-execute: remove unnecessary initialization (#1734787) +- shared/cpu-set-util: move the part to print cpu-set into a separate function (#1734787) +- shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM() (#1734787) +- Rework cpu affinity parsing (#1734787) +- Move cpus_in_affinity_mask() to cpu-set-util.[ch] (#1734787) +- test-cpu-set-util: add simple test for cpus_in_affinity_mask() (#1734787) +- test-cpu-set-util: add a smoke test for test_parse_cpu_set_extend() (#1734787) +- pid1: parse CPUAffinity= in incremental fashion (#1734787) +- pid1: don't reset setting from /proc/cmdline upon restart (#1734787) +- pid1: when reloading configuration, forget old settings (#1734787) +- test-execute: use CPUSet too (#1734787) +- shared/cpu-set-util: drop now-unused cleanup function (#1734787) +- shared/cpu-set-util: make transfer of cpu_set_t over bus endian safe (#1734787) +- test-cpu-set-util: add test for dbus conversions (#1734787) +- shared/cpu-set-util: introduce cpu_set_to_range() (#1734787) +- systemctl: present CPUAffinity mask as a list of CPU index ranges (#1734787) +- shared/cpu-set-util: only force range printing one time (#1734787) +- execute: dump CPUAffinity as a range string instead of a list of CPUs (#1734787) +- cpu-set-util: use %d-%d format in cpu_set_to_range_string() only for actual ranges (#1734787) +- core: introduce NUMAPolicy and NUMAMask options (#1734787) +- core: disable CPUAccounting by default (#1734787) +- set kptr_restrict=1 (#1689346) +- cryptsetup: reduce the chance that we will be OOM killed (#1696602) +- core, job: fix breakage of ordering dependencies by systemctl reload command (#1766417) +- debug-generator: enable custom systemd.debug_shell tty (#1723722) + +* Thu Oct 24 2019 Lukas Nykryn - 239-19 +- core: never propagate reload failure to service result (#1735787) +- man: document systemd-analyze security (#1750343) +- man: reorder and add examples to systemd-analyze(1) (#1750343) +- travis: move to CentOS 8 docker images (#1761519) +- travis: drop SCL remains (#1761519) +- syslog: fix segfault in syslog_parse_priority() (#1761519) +- sd-bus: make strict asan shut up (#1761519) +- travis: don't run slow tests under ASan/UBSan (#1761519) +- kernel-install: do not require non-empty kernel cmdline (#1701454) +- ask-password: prevent buffer overrow when reading from keyring (#1752050) +- core: try to reopen /dev/kmsg again right after mounting /dev (#1749212) +- buildsys: don't garbage collect sections while linking (#1748258) +- udev: introduce CONST key name (#1762679) +- Call getgroups() to know size of supplementary groups array to allocate (#1743230256 KB +#1743235) +- Consider smb3 as remote filesystem (#1757257) +- process-util: introduce pid_is_my_child() helper (#1744972) +- core: reduce the number of stalled PIDs from the watched processes list when possible (#1744972) +- core: only watch processes when it's really necessary (#1744972) +- core: implement per unit journal rate limiting (#1719577) +- path: stop watching path specs once we triggered the target unit (#1763161) +- journald: fixed assertion failure when system journal rotation fails (#9893) (#1763619) +- test: use PBKDF2 instead of Argon2 in cryptsetup... (#1761519) +- test: mask several unnecessary services (#1761519) +- test: bump the second partition's size to 50M (#1761519) +- shared/sleep-config: exclude zram devices from hibernation candidates (#1763617) +- selinux: don't log SELINUX_INFO and SELINUX_WARNING messages to audit (#1763612) +- sd-device: introduce log_device_*() macros (#1753369) +- udev: Add id program and rule for FIDO security tokens (#1753369) +- shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857) +- sd-bus: adjust indentation of comments (#1746857) +- resolved: do not run loop twice (#1746857) +- resolved: allow access to Set*Link and Revert methods through polkit (#1746857) +- resolved: query polkit only after parsing the data (#1746857) + +* Fri Aug 30 2019 Lukas Nykryn - 239-18 +- shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857) +- sd-bus: adjust indentation of comments (#1746857) +- resolved: do not run loop twice (#1746857) +- resolved: allow access to Set*Link and Revert methods through polkit (#1746857) +- resolved: query polkit only after parsing the data (#1746857) + +* Wed Aug 07 2019 Lukas Nykryn - 239-17 +- mount: simplify /proc/self/mountinfo handler (#1696178) +- mount: rescan /proc/self/mountinfo before processing waitid() results (#1696178) +- swap: scan /proc/swaps before processing waitid() results (#1696178) +- analyze-security: fix potential division by zero (#1734400) + +* Fri Jul 26 2019 Lukas Nykryn - 239-16 +- sd-bus: deal with cookie overruns (#1694999) +- journal-remote: do not request Content-Length if Transfer-Encoding is chunked (#1708849) +- journal: do not remove multiple spaces after identifier in syslog message (#1691817) +- cryptsetup: Do not fallback to PLAIN mapping if LUKS data device set fails. (#1719153) +- cryptsetup: call crypt_load() for LUKS only once (#1719153) +- cryptsetup: Add LUKS2 token support. (#1719153) +- udev/scsi_id: fix incorrect page length when get device identification VPD page (#1713227) +- Change job mode of manager triggered restarts to JOB_REPLACE (#11456 +#1712524) +- bash-completion: analyze: support 'security' (#1733395) +- man: note that journal does not validate syslog fields (#1707175) +- rules: skip memory hotplug on ppc64 (#1713159) + +* Thu May 23 2019 Lukas Nykryn - 239-15 +- tree-wide: shorten error logging a bit (#1697893) +- nspawn: simplify machine terminate bus call (#1697893) +- nspawn: merge two variable declaration lines (#1697893) +- nspawn: rework how we allocate/kill scopes (#1697893) +- unit: enqueue cgroup empty check event if the last ref on a unit is dropped (#1697893) +- Revert "journal: remove journal audit socket" (#1699287) +- journal: don't enable systemd-journald-audit.socket by default (#1699287) +- logs-show: use grey color for de-emphasizing journal log output (#1695601) +- units: add [Install] section to tmp.mount (#1667065) +- nss: do not modify errno when NSS_STATUS_NOTFOUND or NSS_STATUS_SUCCESS (#1691691) +- util.h: add new UNPROTECT_ERRNO macro (#1691691) +- nss: unportect errno before writing to NSS' *errnop (#1691691) +- seccomp: reduce logging about failure to add syscall to seccomp (#1658691) +- format-table: when duplicating a cell, also copy the color (#1689832) +- format-table: optionally make specific cells clickable links (#1689832) +- format-table: before outputting a color, check if colors are available (#1689832) +- format-table: add option to store/format percent and uint64_t values in cells (#1689832) +- format-table: optionally allow reversing the sort order for a column (#1689832) +- format-table: add table_update() to update existing entries (#1689832) +- format-table: add an API for getting the cell at a specific row/column (#1689832) +- format-table: always underline header line (#1689832) +- format-table: add calls to query the data in a specific cell (#1689832) +- format-table: make sure we never call memcmp() with NULL parameters (#1689832) +- format-table: use right field for display (#1689832) +- format-table: add option to uppercase cells on display (#1689832) +- format-table: never try to reuse cells that have color/url/uppercase set (#1689832) +- locale-util: add logic to output smiley emojis at various happiness levels (#1689832) +- analyze: add new security verb (#1689832) +- tests: add a rudimentary fuzzer for server_process_syslog_message (#9979) (#1696224) +- journald: make it clear that dev_kmsg_record modifies the string passed to it (#1696224) +- journald: free the allocated memory before returning from dev_kmsg_record (#1696224) +- tests: rework the code fuzzing journald (#1696224) +- journald: make server_process_native_message compatible with fuzz_journald_processing_function (#1696224) +- tests: add a fuzzer for server_process_native_message (#1696224) +- tests: add a fuzzer for sd-ndisc (#1696224) +- ndisc: fix two infinite loops (#1696224) +- tests: add reproducers for several issues uncovered with fuzz-journald-syslog (#1696224) +- tests: add a reproducer for an infinite loop in ndisc_handle_datagram (#1696224) +- tests: add a reproducer for another infinite loop in ndisc_handle_datagram (#1696224) +- fuzz: rename "fuzz-corpus" directory to just "fuzz" (#1696224) +- test: add testcase for issue 10007 by oss-fuzz (#1696224) +- fuzz: unify the "fuzz-regressions" directory with the main corpus (#1696224) +- test-bus-marshal: use cescaping instead of hexmem (#1696224) +- meson: add -Dlog-trace to set LOG_TRACE (#1696224) +- meson: allow building resolved and machined without nss modules (#1696224) +- meson: drop duplicated condition (#1696224) +- meson: use .source_root() in more places (#1696224) +- meson: treat all fuzz cases as unit tests (#1696224) +- fuzz-bus-message: add fuzzer for message parsing (#1696224) +- bus-message: use structured initialization to avoid use of unitialized memory (#1696224) +- bus-message: avoid an infinite loop on empty structures (#1696224) +- bus-message: let's always use -EBADMSG when the message is bad (#1696224) +- bus-message: rename function for clarity (#1696224) +- bus-message: use define (#1696224) +- bus: do not print (null) if the message has unknown type (#1696224) +- bus-message: fix calculation of offsets table (#1696224) +- bus-message: remove duplicate assignment (#1696224) +- bus-message: fix calculation of offsets table for arrays (#1696224) +- bus-message: drop asserts in functions which are wrappers for varargs version (#1696224) +- bus-message: output debug information about offset troubles (#1696224) +- bus-message: fix skipping of array fields in !gvariant messages (#1696224) +- bus-message: also properly copy struct signature when skipping (#1696224) +- fuzz-bus-message: add two test cases that pass now (#1696224) +- bus-message: return -EBADMSG not -EINVAL on invalid !gvariant messages (#1696224) +- bus-message: avoid wrap-around when using length read from message (#1696224) +- util: do not use stack frame for parsing arbitrary inputs (#1696224) +- travis: enable ASan and UBSan on RHEL8 (#1683319) +- tests: keep SYS_PTRACE when running under ASan (#1683319) +- tree-wide: various ubsan zero size memory fixes (#1683319) +- util: introduce memcmp_safe() (#1683319) +- test-socket-util: avoid "memleak" reported by valgrind (#1683319) +- sd-journal: escape binary data in match_make_string() (#1683319) +- capability: introduce CAP_TO_MASK_CORRECTED() macro replacing CAP_TO_MASK() (#1683319) +- sd-bus: use size_t when dealing with memory offsets (#1683319) +- sd-bus: call cap_last_cap() only once in has_cap() (#1683319) +- mount-point: honour AT_SYMLINK_FOLLOW correctly (#1683319) +- travis: switch from trusty to xenial (#1683319) +- test-socket-util: Add tests for receive_fd_iov() and friends. (#1683319) +- socket-util: Introduce send_one_fd_iov() and receive_one_fd_iov() (#1683319) +- core: swap order of "n_storage_fds" and "n_socket_fds" parameters (#1683334) +- execute: use our usual syntax for defining bit masks (#1683334) +- core: introduce new Type=exec service type (#1683334) +- man: document the new Type=exec type (#1683334) +- sd-bus: allow connecting to the pseudo-container ".host" (#1683334) +- sd-login: let's also make sd-login understand ".host" (#1683334) +- test: add test for Type=exec (#1683334) +- journal-gateway: explicitly declare local variables (#1705971) +- tools: drop unused variable (#1705971) +- journal-gateway: use localStorage["cursor"] only when it has valid value (#1705971) + +* Tue Apr 30 2019 Lukas Nykryn - 239-14 +- rules: implement new memory hotplug policy (#1670728) +- rules: add the rule that adds elevator= kernel command line parameter (#1670126) +- bus-socket: Fix line_begins() to accept word matching full string (#1692991) +- Refuse dbus message paths longer than BUS_PATH_SIZE_MAX limit. (#1678641) +- Allocate temporary strings to hold dbus paths on the heap (#1678641) +- sd-bus: if we receive an invalid dbus message, ignore and proceeed (#1678641) +- Revert "core: one step back again, for nspawn we actually can't wait for cgroups running empty since systemd will get exactly zero notifications about it" (#1703485) + +* Tue Feb 26 2019 Lukas Nykryn - 239-13 +- rules: add the rule that adds elevator= kernel command line parameter (#1670126) + +* Fri Feb 15 2019 Lukas Nykryn - 239-12 +- core: when deserializing state always use read_line(…, LONG_LINE_MAX, …) (CVE-2018-15686) +- coredump: remove duplicate MESSAGE= prefix from message (#1664976) +- journald: remove unnecessary {} (#1664976) +- journald: do not store the iovec entry for process commandline on stack (#1664976) +- basic/process-util: limit command line lengths to _SC_ARG_MAX (#1664976) +- coredump: fix message when we fail to save a journald coredump (#1664976) +- procfs-util: expose functionality to query total memory (#1664976) +- basic/prioq: add prioq_peek_item() (#1664976) +- journal: limit the number of entries in the cache based on available memory (#1664976) +- journald: periodically drop cache for all dead PIDs (#1664976) +- process-util: don't use overly large buffer to store process command line (#1664976) +- Revert "sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 to 2" (#1653824) +- journal: fix syslog_parse_identifier() (#1664978) +- journald: set a limit on the number of fields (1k) (#1664977) +- journald: when processing a native message, bail more quickly on overbig messages (#1664977) +- journald: lower the maximum entry size limit to ½ for non-sealed fds (#1664977) +- µhttpd: use a cleanup function to call MHD_destroy_response (#1664977) +- journal-remote: verify entry length from header (#1664977) +- journal-remote: set a limit on the number of fields in a message (#1664977) +- journald: correctly attribute log messages also with cgroupsv1 (#1658115) +- rules: add elevator= kernel command line parameter (#1670126) + +* Mon Jan 14 2019 Lukas Nykryn - 239-11 +- unit: don't add Requires for tmp.mount (#1619292) +- remove bootchart dependency (#1660119) + +* Wed Dec 12 2018 Lukas Nykryn - 239-10 +- cryptsetup-generator: introduce basic keydev support (#1656869) +- cryptsetup: don't use %m if there's no error to show (#1656869) +- cryptsetup-generator: don't return error if target directory already exists (#1656869) +- cryptsetup-generator: allow whitespace characters in keydev specification (#1656869) +- rules: watch metadata changes on DASD devices (#1638676) +- sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 to 2 (#1653824) + +* Thu Dec 06 2018 Lukas Nykryn - 239-9 +- dissect-image: use right comparison function (#1602706) +- login: avoid leak of name returned by uid_to_name() (#1602706) +- firewall-util: add an assert that we're not overwriting a buffer (#1602706) +- journal-file: avoid calling ftruncate with invalid fd (#1602706) +- dhcp6: make sure we have enough space for the DHCP6 option header (#1643363) +- core: rename queued_message → pending_reload_message (#1647359) +- core: when we can't send the pending reload message, say we ignore it in the warning we log (#1647359) +- core: make sure we don't throttle change signal generator when a reload is pending (#1647359) +- proc-cmdline: introduce PROC_CMDLINE_RD_STRICT (#1643429) +- debug-generator: introduce rd.* version of all options (#1643429) +- chown-recursive: let's rework the recursive logic to use O_PATH (#1643368) +- chown-recursive: also drop ACLs when recursively chown()ing (#1643368) +- chown-recursive: TAKE_FD() is your friend (#1643368) +- test: add test case for recursive chown()ing (#1643368) +- Revert "sysctl.d: request ECN on both in and outgoing connections" (#1619790) +- detect-virt: do not try to read all of /proc/cpuinfo (#1631532) +- sd-bus: unify three code-paths which free struct bus_container (#1635435) +- sd-bus: properly initialize containers (#1635435) + +* Tue Oct 16 2018 Lukas Nykryn - 239-8 +- revert sd-bus: unify three code-paths which free struct bus_container (#1635435) + +* Fri Oct 12 2018 Michal Sekletár - 239-7 +- change default cgroup hierarchy to "legacy" (#1638650) +- we never added mymachines module to passwd: or group: in RHEL8, hence don't try to remove it (#1638450) +- bump minimal size of random pool to 1024 bytes (#1619268) +- install RHEL-7 compatible rc.local (#1625209) +- backport support for sector-size crypttab option (#1572563) +- units: don't enable per-service IP firewall by default (#1630219) +- sd-bus: unify three code-paths which free struct bus_container (#1635435) +- bus-message: do not crash on message with a string of zero length (#1635439) +- bus-message: stack based buffer overflow in free_and_strdup (#1635428) +- journal: change support URL shown in the catalog entries (#1550548) + +* Mon Sep 10 2018 Michal Sekletár - 239-6 +- move /etc/yum/protected.d/systemd.conf to /etc/dnf/ (#1626973) + +* Fri Sep 07 2018 Josh Boyer - 239-5 +- Fix file conflict between yum and systemd (#1626682) + +* Tue Aug 14 2018 Michal Sekletár - 239-4 +- drop the patch for delayed loading of config in net_setup_link and set NAME in prefixdevname udev rules (#1614681) +- bus: move BUS_DONT_DESTROY calls after asserts (#1610397) + +* Fri Aug 10 2018 Michal Sekletár - 239-3 +- net_setup_link: delay loading configuration, just before we apply it (#1614681) + +* Thu Aug 09 2018 Michal Sekletár - 239-2 +- 20-grubby.install: populate symvers.gz file (#1609698) +- net_setup_link: allow renaming interfaces that were renamed already +- units: drop DynamicUser=yes from systemd-resolved.service +- journal: remove journal audit socket + +* Wed Aug 01 2018 Michal Sekletár - 239-1 +- rebase to systemd-239 +- Override systemd-user PAM config in install and not prep (patch by Filipe Brandenburger ) +- use %%autosetup -S git_am to apply patches +- revert upstream default for RemoveIPC (#1523233) +- bump DefaultTasksMax to 80% of kernel default (#1523236) +- avoid /tmp being mounted as tmpfs without the user's will (#1578772) +- bump maximum number of processes in user slice to 80% of pid.max (#1523236) +- forwardport downstream-only udev rules from RHEL-7 (#1523227) +- don't ship systemd-networkd +- don't ship systemd-timesyncd +- add back support for WAIT_FOR to udev rules (#1523213) + +* Wed May 16 2018 Jan Synáček - 238-8 +- do not mount /tmp as tmpfs (#1578772) + +* Tue May 15 2018 Jan Synáček - 238-7 +- fix compilation (#1578318) + +* Fri Apr 27 2018 Michal Sekletar - 238-6 +- forwardport downstream-only udev rules from RHEL-7 (#1523227) +- set RemoveIPC=no by default (#1523233) + +* Thu Apr 12 2018 Michal Sekletar - 238-5 +- also drop qrencode-devel from BuildRequires as it is no longer needed (#1566158) + +* Wed Apr 11 2018 Michal Sekletar - 238-4 +- disable support for qrencode (#1566158) +- bump default journal rate limit to 10000 messages per 30s (#1563729) +- fix unit reloads (#1560549) +- don't create /var/log/journal during package installation (#1523188) + +* Fri Mar 09 2018 Troy Dawson - 238-3.1 +- Rebuild with cryptsetup-2 + +* Wed Mar 7 2018 Zbigniew Jędrzejewski-Szmek - 238-3 +- Revert the patches for GRUB BootLoaderSpec support +- Add patch for /etc/machine-id creation (#1552843) + +* Tue Mar 6 2018 Yu Watanabe - 238-2 +- Fix transfiletrigger script (#1551793) + +* Mon Mar 5 2018 Zbigniew Jędrzejewski-Szmek - 238-1 +- Update to latest version +- This fixes a hard-to-trigger potential vulnerability (CVE-2018-6954) +- New transfiletriggers are installed for udev hwdb and rules, the journal + catalog, sysctl.d, binfmt.d, sysusers.d, tmpfiles.d. + +* Tue Feb 27 2018 Javier Martinez Canillas - 237-7.git84c8da5 +- Add patch to install kernel images for GRUB BootLoaderSpec support + +* Sat Feb 24 2018 Zbigniew Jędrzejewski-Szmek - 237-6.git84c8da5 +- Create /etc/systemd in %%post libs if necessary (#1548607) + +* Fri Feb 23 2018 Adam Williamson - 237-5.git84c8da5 +- Use : not touch to create file in -libs %%post + +* Thu Feb 22 2018 Patrick Uiterwijk - 237-4.git84c8da5 +- Add coreutils dep for systemd-libs %%post +- Add patch to typecast USB IDs to avoid compile failure + +* Wed Feb 21 2018 Zbigniew Jędrzejewski-Szmek - 237-3.git84c8da5 +- Update some patches for test skipping that were updated upstream + before merging +- Add /usr/lib/systemd/purge-nobody-user — a script to check if nobody is defined + correctly and possibly replace existing mappings + +* Tue Feb 20 2018 Zbigniew Jędrzejewski-Szmek - 237-2.gitdff4849 +- Backport a bunch of patches, most notably for the journal and various + memory issues. Some minor build fixes. +- Switch to new ldconfig macros that do nothing in F28+ +- /etc/systemd/dont-synthesize-nobody is created in %%post if nfsnobody + or nobody users are defined (#1537262) + +* Fri Feb 9 2018 Zbigniew Jędrzejeweski-Szmek - 237-1.git78bd769 +- Update to first stable snapshot (various minor memory leaks and misaccesses, + some documentation bugs, build fixes). + +* Sun Jan 28 2018 Zbigniew Jędrzejewski-Szmek - 237-1 +- Update to latest version + +* Sun Jan 21 2018 Björn Esser - 236-4.git3e14c4c +- Add patch to include if needed + +* Sat Jan 20 2018 Björn Esser - 236-3.git3e14c4c +- Rebuilt for switch to libxcrypt + +* Thu Jan 11 2018 Zbigniew Jędrzejewski-Szmek - 236-2.git23e14c4 +- Backport a bunch of bugfixes from upstream (#1531502, #1531381, #1526621 + various memory corruptions in systemd-networkd) +- /dev/kvm is marked as a static node which fixes permissions on s390x + and ppc64 (#1532382) + +* Fri Dec 15 2017 Zbigniew Jędrzejewski-Szmek - 236-1 +- Update to latest version + +* Mon Dec 11 2017 Zbigniew Jędrzejewski-Szmek - 235-5.git4a0e928 +- Update to latest git snapshot, do not build for realz +- Switch to libidn2 again (#1449145) + +* Tue Nov 07 2017 Zbigniew Jędrzejewski-Szmek - 235-4 +- Rebuild for cryptsetup-2.0.0-0.2.fc28 + +* Wed Oct 25 2017 Zbigniew Jędrzejewski-Szmek - 235-3 +- Backport a bunch of patches, including LP#172535 + +* Wed Oct 18 2017 Zbigniew Jędrzejewski-Szmek - 235-2 +- Patches for cryptsetup _netdev + +* Fri Oct 6 2017 Zbigniew Jędrzejewski-Szmek - 235-1 +- Update to latest version + +* Tue Sep 26 2017 Nathaniel McCallum - 234-8 +- Backport /etc/crypttab _netdev feature from upstream + +* Thu Sep 21 2017 Michal Sekletar - 234-7 +- Make sure to remove all device units sharing the same sysfs path (#1475570) + +* Mon Sep 18 2017 Zbigniew Jędrzejewski-Szmek - 234-6 +- Bump xslt recursion limit for libxslt-1.30 + +* Mon Jul 31 2017 Zbigniew Jędrzejewski-Szmek - 234-5 +- Backport more patches (#1476005, hopefully #1462378) + +* Thu Jul 27 2017 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jul 17 2017 Zbigniew Jędrzejewski-Szmek - 234-3 +- Fix x-systemd.timeout=0 in /etc/fstab (#1462378) +- Minor patches (memleaks, --help fixes, seccomp on arm64) + +* Thu Jul 13 2017 Zbigniew Jędrzejewski-Szmek - 234-2 +- Create kvm group (#1431876) + +* Thu Jul 13 2017 Zbigniew Jędrzejewski-Szmek - 234-1 +- Latest release + +* Sat Jul 1 2017 Zbigniew Jędrzejewski-Szmek - 233-7.git74d8f1c +- Update to snapshot +- Build with meson again + +* Tue Jun 27 2017 Zbigniew Jędrzejewski-Szmek - 233-6 +- Fix an out-of-bounds write in systemd-resolved (CVE-2017-9445) + +* Fri Jun 16 2017 Zbigniew Jędrzejewski-Szmek - 233-5.gitec36d05 +- Update to snapshot version, build with meson + +* Thu Jun 15 2017 Zbigniew Jędrzejewski-Szmek - 233-4 +- Backport a bunch of small fixes (memleaks, wrong format strings, + man page clarifications, shell completion) +- Fix systemd-resolved crash on crafted DNS packet (CVE-2017-9217, #1455493) +- Fix systemd-vconsole-setup.service error on systems with no VGA console (#1272686) +- Drop soft-static uid for systemd-journal-gateway +- Use ID from /etc/os-release as ntpvendor + +* Thu Mar 16 2017 Michal Sekletar - 233-3 +- Backport bugfixes from upstream +- Don't return error when machinectl couldn't figure out container IP addresses (#1419501) + +* Thu Mar 2 2017 Zbigniew Jędrzejewski-Szmek - 233-2 +- Fix installation conflict with polkit + +* Thu Mar 2 2017 Zbigniew Jędrzejewski-Szmek - 233-1 +- New upstream release (#1416201, #1405439, #1420753, many others) +- New systemd-tests subpackage with "installed tests" + +* Thu Feb 16 2017 Zbigniew Jędrzejewski-Szmek - 232-15 +- Add %%ghost %%dir entries for .wants dirs of our targets (#1422894) + +* Tue Feb 14 2017 Zbigniew Jędrzejewski-Szmek - 232-14 +- Ignore the hwdb parser test + +* Tue Feb 14 2017 Jan Synáček - 232-14 +- machinectl fails when virtual machine is running (#1419501) + +* Sat Feb 11 2017 Fedora Release Engineering - 232-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Jan 31 2017 Zbigniew Jędrzejewski-Szmek - 232-12 +- Backport patch for initrd-switch-root.service getting killed (#1414904) +- Fix sd-journal-gatewayd -D, --trust, and COREDUMP_CONTAINER_CMDLINE + extraction by sd-coredump. + +* Sun Jan 29 2017 zbyszek - 232-11 +- Backport a number of patches (#1411299, #1413075, #1415745, + ##1415358, #1416588, #1408884) +- Fix various memleaks and unitialized variable access +- Shell completion enhancements +- Enable TPM logging by default (#1411156) +- Update hwdb (#1270124) + +* Thu Jan 19 2017 Adam Williamson - 232-10 +- Backport fix for boot failure in initrd-switch-root (#1414904) + +* Wed Jan 18 2017 Zbigniew Jędrzejewski-Szmek - 232-9 +- Add fake dependency on systemd-pam to systemd-devel to ensure systemd-pam + is available as multilib (#1414153) + +* Tue Jan 17 2017 Zbigniew Jędrzejewski-Szmek - 232-8 +- Fix buildsystem to check for lz4 correctly (#1404406) + +* Wed Jan 11 2017 Zbigniew Jędrzejewski-Szmek - 232-7 +- Various small tweaks to scriplets + +* Sat Jan 07 2017 Kevin Fenzi - 232-6 +- Fix scriptlets to never fail in libs post + +* Fri Jan 06 2017 Kevin Fenzi - 232-5 +- Add patch from Michal Schmidt to avoid process substitution (#1392236) + +* Sun Nov 6 2016 Zbigniew Jędrzejewski-Szmek - 232-4 +- Rebuild (#1392236) + +* Fri Nov 4 2016 Zbigniew Jędrzejewski-Szmek - 232-3 +- Make /etc/dbus-1/system.d directory non-%%ghost + +* Fri Nov 4 2016 Zbigniew Jędrzejewski-Szmek - 232-2 +- Fix kernel-install (#1391829) +- Restore previous systemd-user PAM config (#1391836) +- Move journal-upload.conf.5 from systemd main to journal-remote subpackage (#1391833) +- Fix permissions on /var/lib/systemd/journal-upload (#1262665) + +* Thu Nov 3 2016 Zbigniew Jędrzejewski-Szmek - 232-1 +- Update to latest version (#998615, #1181922, #1374371, #1390704, #1384150, #1287161) +- Add %%{_isa} to Provides on arch-full packages (#1387912) +- Create systemd-coredump user in %%pre (#1309574) +- Replace grubby patch with a short-circuiting install.d "plugin" +- Enable nss-systemd in the passwd, group lines in nsswith.conf +- Add [!UNAVAIL=return] fallback after nss-resolve in hosts line in nsswith.conf +- Move systemd-nspawn man pages to the right subpackage (#1391703) + +* Tue Oct 18 2016 Jan Synáček - 231-11 +- SPC - Cannot restart host operating from container (#1384523) + +* Sun Oct 9 2016 Zbigniew Jędrzejewski-Szmek - 231-10 +- Do not recreate /var/log/journal on upgrades (#1383066) +- Move nss-myhostname provides to systemd-libs (#1383271) + +* Fri Oct 7 2016 Zbigniew Jędrzejewski-Szmek - 231-9 +- Fix systemctl set-default (#1374371) +- Prevent systemd-udev-trigger.service from restarting (follow-up for #1378974) + +* Tue Oct 4 2016 Zbigniew Jędrzejewski-Szmek - 231-8 +- Apply fix for #1378974 + +* Mon Oct 3 2016 Zbigniew Jędrzejewski-Szmek - 231-7 +- Apply patches properly + +* Thu Sep 29 2016 Zbigniew Jędrzejewski-Szmek - 231-6 +- Better fix for (#1380286) + +* Thu Sep 29 2016 Zbigniew Jędrzejewski-Szmek - 231-5 +- Denial-of-service bug against pid1 (#1380286) + +* Thu Aug 25 2016 Zbigniew Jędrzejewski-Szmek - 231-4 +- Fix preset-all (#1363858) +- Fix issue with daemon-reload messing up graphics (#1367766) +- A few other bugfixes + +* Wed Aug 03 2016 Adam Williamson - 231-3 +- Revert preset-all change, it broke stuff (#1363858) + +* Wed Jul 27 2016 Zbigniew Jędrzejewski-Szmek - 231-2 +- Call preset-all on initial installation (#1118740) +- Fix botched Recommends for libxkbcommon + +* Tue Jul 26 2016 Zbigniew Jędrzejewski-Szmek - 231-1 +- Update to latest version + +* Wed Jun 8 2016 Zbigniew Jędrzejewski-Szmek - 230-3 +- Update to latest git snapshot (fixes for systemctl set-default, + polkit lingering policy, reversal of the framebuffer rules, + unaligned access fixes, fix for StartupBlockIOWeight-over-dbus). + Those changes are interspersed with other changes and new features + (mostly in lldp, networkd, and nspawn). Some of those new features + might not work, but I think that existing functionality should not + be broken, so it seems worthwile to update to the snapshot. + +* Sat May 21 2016 Zbigniew Jędrzejewski-Szmek - 230-2 +- Remove systemd-compat-libs on upgrade + +* Sat May 21 2016 Zbigniew Jędrzejewski-Szmek - 230-1 +- New version +- Drop compat-libs +- Require libxkbcommon explictly, since the automatic dependency will + not be generated anymore + +* Tue Apr 26 2016 Zbigniew Jędrzejewski-Szmek - 229-15 +- Remove duplicated entries in -container %%files (#1330395) + +* Fri Apr 22 2016 Zbigniew Jędrzejewski-Szmek - 229-14 +- Move installation of udev services to udev subpackage (#1329023) + +* Mon Apr 18 2016 Zbigniew Jędrzejewski-Szmek - 229-13 +- Split out systemd-pam subpackage (#1327402) + +* Mon Apr 18 2016 Harald Hoyer - 229-12 +- move more binaries and services from the main package to subpackages + +* Mon Apr 18 2016 Harald Hoyer - 229-11 +- move more binaries and services from the main package to subpackages + +* Mon Apr 18 2016 Harald Hoyer - 229-10 +- move device dependant stuff to the udev subpackage + +* Tue Mar 22 2016 Zbigniew Jędrzejewski-Szmek - 229-9 +- Add myhostname to /etc/nsswitch.conf (#1318303) + +* Mon Mar 21 2016 Harald Hoyer - 229-8 +- fixed kernel-install for copying files for grubby +Resolves: rhbz#1299019 + +* Thu Mar 17 2016 Zbigniew Jędrzejewski-Szmek - 229-7 +- Moar patches (#1316964, #1317928) +- Move vconsole-setup and tmpfiles-setup-dev bits to systemd-udev +- Protect systemd-udev from deinstallation + +* Fri Mar 11 2016 Zbigniew Jędrzejewski-Szmek - 229-6 +- Create /etc/resolv.conf symlink from systemd-resolved (#1313085) + +* Fri Mar 4 2016 Zbigniew Jędrzejewski-Szmek - 229-5 +- Split out systemd-container subpackage (#1163412) +- Split out system-udev subpackage +- Add various bugfix patches, incl. a tentative fix for #1308771 + +* Tue Mar 1 2016 Peter Robinson 229-4 +- Power64 and s390(x) now have libseccomp support +- aarch64 has gnu-efi + +* Tue Feb 23 2016 Jan Synáček - 229-3 +- Fix build failures on ppc64 (#1310800) + +* Tue Feb 16 2016 Dennis Gilmore - 229-2 +- revert: fixed kernel-install for copying files for grubby +Resolves: rhbz#1299019 +- this causes the dtb files to not get installed at all and the fdtdir +- line in extlinux.conf to not get updated correctly + +* Thu Feb 11 2016 Michal Sekletar - 229-1 +- New upstream release + +* Thu Feb 11 2016 Harald Hoyer - 228-10.gite35a787 +- fixed kernel-install for copying files for grubby +Resolves: rhbz#1299019 + +* Fri Feb 05 2016 Fedora Release Engineering - 228-9.gite35a787 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 27 2016 Peter Robinson 228-8.gite35a787 +- Rebuild for binutils on aarch64 fix + +* Fri Jan 08 2016 Dan Horák - 228-7.gite35a787 +- apply the conflict with fedora-release only in Fedora + +* Thu Dec 10 2015 Jan Synáček - 228-6.gite35a787 +- Fix rawhide build failures on ppc64 (#1286249) + +* Sun Nov 29 2015 Zbigniew Jędrzejewski-Szmek - 228-6.gite35a787 +- Create /etc/systemd/network (#1286397) + +* Thu Nov 26 2015 Zbigniew Jędrzejewski-Szmek - 228-5.gite35a787 +- Do not install nss modules by default + +* Tue Nov 24 2015 Zbigniew Jędrzejewski-Szmek - 228-4.gite35a787 +- Update to latest upstream git: there is a bunch of fixes + (nss-mymachines overflow bug, networkd fixes, more completions are + properly installed), mixed with some new resolved features. +- Rework file triggers so that they always run before daemons are restarted + +* Thu Nov 19 2015 Zbigniew Jędrzejewski-Szmek - 228-3 +- Enable rpm file triggers for daemon-reload + +* Thu Nov 19 2015 Zbigniew Jędrzejewski-Szmek - 228-2 +- Fix version number in obsoleted package name (#1283452) + +* Wed Nov 18 2015 Kay Sievers - 228-1 +- New upstream release + +* Thu Nov 12 2015 Zbigniew Jędrzejewski-Szmek - 227-7 +- Rename journal-gateway subpackage to journal-remote +- Ignore the access mode on /var/log/journal (#1048424) +- Do not assume fstab is present (#1281606) + +* Wed Nov 11 2015 Fedora Release Engineering - 227-6 +- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 + +* Tue Nov 10 2015 Lukáš Nykrýn - 227-5 +- Rebuild for libmicrohttpd soname bump + +* Fri Nov 06 2015 Robert Kuska - 227-4 +- Rebuilt for Python3.5 rebuild + +* Wed Nov 4 2015 Zbigniew Jędrzejewski-Szmek - 227-3 +- Fix syntax in kernel-install (#1277264) + +* Tue Nov 03 2015 Michal Schmidt - 227-2 +- Rebuild for libmicrohttpd soname bump. + +* Wed Oct 7 2015 Kay Sievers - 227-1 +- New upstream release + +* Fri Sep 18 2015 Jan Synáček - 226-3 +- user systemd-journal-upload should be in systemd-journal group (#1262743) + +* Fri Sep 18 2015 Kay Sievers - 226-2 +- Add selinux to system-user PAM config + +* Tue Sep 8 2015 Kay Sievers - 226-1 +- New upstream release + +* Thu Aug 27 2015 Kay Sievers - 225-1 +- New upstream release + +* Fri Jul 31 2015 Kay Sievers - 224-1 +- New upstream release + +* Wed Jul 29 2015 Kay Sievers - 223-2 +- update to git snapshot + +* Wed Jul 29 2015 Kay Sievers - 223-1 +- New upstream release + +* Thu Jul 9 2015 Zbigniew Jędrzejewski-Szmek - 222-2 +- Remove python subpackages (python-systemd in now standalone) + +* Tue Jul 7 2015 Kay Sievers - 222-1 +- New upstream release + +* Mon Jul 6 2015 Kay Sievers - 221-5.git619b80a +- update to git snapshot + +* Mon Jul 6 2015 Zbigniew Jędrzejewski-Szmek - 221-4.git604f02a +- Add example file with yama config (#1234951) + +* Sun Jul 5 2015 Kay Sievers - 221-3.git604f02a +- update to git snapshot + +* Mon Jun 22 2015 Kay Sievers - 221-2 +- build systemd-boot EFI tools + +* Fri Jun 19 2015 Lennart Poettering - 221-1 +- New upstream release +- Undoes botched translation check, should be reinstated later? + +* Fri Jun 19 2015 Fedora Release Engineering - 220-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Jun 11 2015 Peter Robinson 220-9 +- The gold linker is now fixed on aarch64 + +* Tue Jun 9 2015 Zbigniew Jędrzejewski-Szmek - 220-8 +- Remove gudev which is now provided as separate package (libgudev) +- Fix for spurious selinux denials (#1224211) +- Udev change events (#1225905) +- Patches for some potential crashes +- ProtectSystem=yes does not touch /home +- Man page fixes, hwdb updates, shell completion updates +- Restored persistent device symlinks for bcache, xen block devices +- Tag all DRM cards as master-of-seat + +* Tue Jun 09 2015 Harald Hoyer 220-7 +- fix udev block device watch + +* Tue Jun 09 2015 Harald Hoyer 220-6 +- add support for network disk encryption + +* Sun Jun 7 2015 Peter Robinson 220-5 +- Disable gold on aarch64 until it's fixed (tracked in rhbz #1225156) + +* Sat May 30 2015 Zbigniew Jędrzejewski-Szmek - 220-4 +- systemd-devel should require systemd-libs, not the main package (#1226301) +- Check for botched translations (#1226566) +- Make /etc/udev/hwdb.d part of the rpm (#1226379) + +* Thu May 28 2015 Richard W.M. Jones - 220-3 +- Add patch to fix udev --daemon not cleaning child processes + (upstream commit 86c3bece38bcf5). + +* Wed May 27 2015 Richard W.M. Jones - 220-2 +- Add patch to fix udev --daemon crash (upstream commit 040e689654ef08). + +* Thu May 21 2015 Lennart Poettering - 220-1 +- New upstream release +- Drop /etc/mtab hack, as that's apparently fixed in mock now (#1116158) +- Remove ghosting for %%{_sysconfdir}/systemd/system/runlevel*.target, these targets are not configurable anymore in systemd upstream +- Drop work-around for #1002806, since this is solved upstream now + +* Wed May 20 2015 Dennis Gilmore - 219-15 +- fix up the conflicts version for fedora-release + +* Wed May 20 2015 Zbigniew Jędrzejewski-Szmek - 219-14 +- Remove presets (#1221340) +- Fix (potential) crash and memory leak in timedated, locking failure + in systemd-nspawn, crash in resolved. +- journalctl --list-boots should be faster +- zsh completions are improved +- various ommissions in docs are corrected (#1147651) +- VARIANT and VARIANT_ID fields in os-release are documented +- systemd-fsck-root.service is generated in the initramfs (#1201979, #1107818) +- systemd-tmpfiles should behave better on read-only file systems (#1207083) + +* Wed Apr 29 2015 Zbigniew Jędrzejewski-Szmek - 219-13 +- Patches for some outstanding annoyances +- Small keyboard hwdb updates + +* Wed Apr 8 2015 Zbigniew Jędrzejewski-Szmek - 219-12 +- Tighten requirements between subpackages (#1207381). + +* Sun Mar 22 2015 Zbigniew Jędrzejewski-Szmek - 219-11 +- Move all parts systemd-journal-{remote,upload} to + systemd-journal-gatewayd subpackage (#1193143). +- Create /var/lib/systemd/journal-upload directory (#1193145). +- Cut out lots of stupid messages at debug level which were obscuring more + important stuff. +- Apply "tentative" state for devices only when they are added, not removed. +- Ignore invalid swap pri= settings (#1204336) +- Fix SELinux check for timedated operations to enable/disable ntp (#1014315) +- Fix comparing of filesystem paths (#1184016) + +* Sat Mar 14 2015 Zbigniew Jędrzejewski-Szmek - 219-10 +- Fixes for bugs 1186018, 1195294, 1185604, 1196452. +- Hardware database update. +- Documentation fixes. +- A fix for journalctl performance regression. +- Fix detection of inability to open files in journalctl. +- Detect SuperH architecture properly. +- The first of duplicate lines in tmpfiles wins again. +- Do vconsole setup after loading vconsole driver, not fbcon. +- Fix problem where some units were restarted during systemd reexec. +- Fix race in udevadm settle tripping up NetworkManager. +- Downgrade various log messages. +- Fix issue where journal-remote would process some messages with a delay. +- GPT /srv partition autodiscovery is fixed. +- Reconfigure old Finnish keymaps in post (#1151958) + +* Tue Mar 10 2015 Jan Synáček - 219-9 +- Buttons on Lenovo X6* tablets broken (#1198939) + +* Tue Mar 3 2015 Zbigniew Jędrzejewski-Szmek - 219-8 +- Reworked device handling (#1195761) +- ACL handling fixes (with a script in %%post) +- Various log messages downgraded (#1184712) +- Allow PIE on s390 again (#1197721) + +* Wed Feb 25 2015 Michal Schmidt - 219-7 +- arm: reenable lto. gcc-5.0.0-0.16 fixed the crash (#1193212) + +* Tue Feb 24 2015 Colin Walters - 219-6 +- Revert patch that breaks Atomic/OSTree (#1195761) + +* Fri Feb 20 2015 Michal Schmidt - 219-5 +- Undo the resolv.conf workaround, Aim for a proper fix in Rawhide. + +* Fri Feb 20 2015 Michal Schmidt - 219-4 +- Revive fedora-disable-resolv.conf-symlink.patch to unbreak composes. + +* Wed Feb 18 2015 Michal Schmidt - 219-3 +- arm: disabling gold did not help; disable lto instead (#1193212) + +* Tue Feb 17 2015 Peter Jones - 219-2 +- Update 90-default.present for dbxtool. + +* Mon Feb 16 2015 Lennart Poettering - 219-1 +- New upstream release +- This removes the sysctl/bridge hack, a different solution needs to be found for this (see #634736) +- This removes the /etc/resolv.conf hack, anaconda needs to fix their handling of /etc/resolv.conf as symlink +- This enables "%%check" +- disable gold on arm, as that is broken (see #1193212) + +* Mon Feb 16 2015 Peter Robinson 218-6 +- aarch64 now has seccomp support + +* Thu Feb 05 2015 Michal Schmidt - 218-5 +- Don't overwrite systemd.macros with unrelated Source file. + +* Thu Feb 5 2015 Jan Synáček - 218-4 +- Add a touchpad hwdb (#1189319) + +* Thu Jan 15 2015 Zbigniew Jędrzejewski-Szmek - 218-4 +- Enable xkbcommon dependency to allow checking of keymaps +- Fix permissions of /var/log/journal (#1048424) +- Enable timedatex in presets (#1187072) +- Disable rpcbind in presets (#1099595) + +* Wed Jan 7 2015 Jan Synáček - 218-3 +- RFE: journal: automatically rotate the file if it is unlinked (#1171719) + +* Mon Jan 05 2015 Zbigniew Jędrzejewski-Szmek - 218-3 +- Add firewall description files (#1176626) + +* Thu Dec 18 2014 Jan Synáček - 218-2 +- systemd-nspawn doesn't work on s390/s390x (#1175394) + +* Wed Dec 10 2014 Lennart Poettering - 218-1 +- New upstream release +- Enable "nss-mymachines" in /etc/nsswitch.conf + +* Thu Nov 06 2014 Zbigniew Jędrzejewski-Szmek - 217-4 +- Change libgudev1 to only require systemd-libs (#727499), there's + no need to require full systemd stack. +- Fixes for bugs #1159448, #1152220, #1158035. +- Bash completions updates to allow propose more units for start/restart, + and completions for set-default,get-default. +- Again allow systemctl enable of instances. +- Hardware database update and fixes. +- Udev crash on invalid options and kernel commandline timeout parsing are fixed. +- Add "embedded" chassis type. +- Sync before 'reboot -f'. +- Fix restarting of timer units. + +* Wed Nov 05 2014 Michal Schmidt - 217-3 +- Fix hanging journal flush (#1159641) + +* Fri Oct 31 2014 Michal Schmidt - 217-2 +- Fix ordering cycles involving systemd-journal-flush.service and + remote-fs.target (#1159117) + +* Tue Oct 28 2014 Lennart Poettering - 217-1 +- New upstream release + +* Fri Oct 17 2014 Zbigniew Jędrzejewski-Szmek - 216-12 +- Drop PackageKit.service from presets (#1154126) + +* Mon Oct 13 2014 Zbigniew Jędrzejewski-Szmek - 216-11 +- Conflict with old versions of initscripts (#1152183) +- Remove obsolete Finnish keymap (#1151958) + +* Fri Oct 10 2014 Zbigniew Jędrzejewski-Szmek - 216-10 +- Fix a problem with voluntary daemon exits and some other bugs + (#1150477, #1095962, #1150289) + +* Fri Oct 03 2014 Zbigniew Jędrzejewski-Szmek - 216-9 +- Update to latest git, but without the readahead removal patch + (#1114786, #634736) + +* Wed Oct 01 2014 Kay Sievers - 216-8 +- revert "don't reset selinux context during CHANGE events" + +* Wed Oct 01 2014 Lukáš Nykrýn - 216-7 +- add temporary workaround for #1147910 +- don't reset selinux context during CHANGE events + +* Wed Sep 10 2014 Michal Schmidt - 216-6 +- Update timesyncd with patches to avoid hitting NTP pool too often. + +* Tue Sep 09 2014 Michal Schmidt - 216-5 +- Use common CONFIGURE_OPTS for build2 and build3. +- Configure timesyncd with NTP servers from Fedora/RHEL vendor zone. + +* Wed Sep 03 2014 Zbigniew Jędrzejewski-Szmek - 216-4 +- Move config files for sd-j-remote/upload to sd-journal-gateway subpackage (#1136580) + +* Thu Aug 28 2014 Peter Robinson 216-3 +- Drop no LTO build option for aarch64/s390 now it's fixed in binutils (RHBZ 1091611) + +* Thu Aug 21 2014 Zbigniew Jędrzejewski-Szmek - 216-2 +- Re-add patch to disable resolve.conf symlink (#1043119) + +* Wed Aug 20 2014 Lennart Poettering - 216-1 +- New upstream release + +* Mon Aug 18 2014 Fedora Release Engineering - 215-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Aug 13 2014 Dan Horák 215-11 +- disable LTO also on s390(x) + +* Sat Aug 09 2014 Harald Hoyer 215-10 +- fixed PPC64LE + +* Wed Aug 6 2014 Tom Callaway - 215-9 +- fix license handling + +* Wed Jul 30 2014 Zbigniew Jędrzejewski-Szmek - 215-8 +- Create systemd-journal-remote and systemd-journal-upload users (#1118907) + +* Thu Jul 24 2014 Zbigniew Jędrzejewski-Szmek - 215-7 +- Split out systemd-compat-libs subpackage + +* Tue Jul 22 2014 Kalev Lember - 215-6 +- Rebuilt for gobject-introspection 1.41.4 + +* Mon Jul 21 2014 Zbigniew Jędrzejewski-Szmek - 215-5 +- Fix SELinux context of /etc/passwd-, /etc/group-, /etc/.updated (#1121806) +- Add missing BR so gnutls and elfutils are used + +* Sat Jul 19 2014 Zbigniew Jędrzejewski-Szmek - 215-4 +- Various man page updates +- Static device node logic is conditionalized on CAP_SYS_MODULES instead of CAP_MKNOD + for better behaviour in containers +- Some small networkd link handling fixes +- vconsole-setup runs setfont before loadkeys (https://bugs.freedesktop.org/show_bug.cgi?id=80685) +- New systemd-escape tool +- XZ compression settings are tweaked to greatly improve journald performance +- "watch" is accepted as chassis type +- Various sysusers fixes, most importantly correct selinux labels +- systemd-timesyncd bug fix (https://bugs.freedesktop.org/show_bug.cgi?id=80932) +- Shell completion improvements +- New udev tag ID_SOFTWARE_RADIO can be used to instruct logind to allow user access +- XEN and s390 virtualization is properly detected + +* Mon Jul 07 2014 Colin Walters - 215-3 +- Add patch to disable resolve.conf symlink (#1043119) + +* Sun Jul 06 2014 Zbigniew Jędrzejewski-Szmek - 215-2 +- Move systemd-journal-remote to systemd-journal-gateway package (#1114688) +- Disable /etc/mtab handling temporarily (#1116158) + +* Thu Jul 03 2014 Lennart Poettering - 215-1 +- New upstream release +- Enable coredump logic (which abrt would normally override) + +* Sun Jun 29 2014 Peter Robinson 214-5 +- On aarch64 disable LTO as it still has issues on that arch + +* Thu Jun 26 2014 Zbigniew Jędrzejewski-Szmek - 214-4 +- Bugfixes (#996133, #1112908) + +* Mon Jun 23 2014 Zbigniew Jędrzejewski-Szmek - 214-3 +- Actually create input group (#1054549) + +* Sun Jun 22 2014 Zbigniew Jędrzejewski-Szmek - 214-2 +- Do not restart systemd-logind on upgrades (#1110697) +- Add some patches (#1081429, #1054549, #1108568, #928962) + +* Wed Jun 11 2014 Lennart Poettering - 214-1 +- New upstream release +- Get rid of "floppy" group, since udev uses "disk" now +- Reenable LTO + +* Sun Jun 08 2014 Fedora Release Engineering - 213-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed May 28 2014 Kay Sievers - 213-3 +- fix systemd-timesync user creation + +* Wed May 28 2014 Michal Sekletar - 213-2 +- Create temporary files after installation (#1101983) +- Add sysstat-collect.timer, sysstat-summary.timer to preset policy (#1101621) + +* Wed May 28 2014 Kay Sievers - 213-1 +- New upstream release + +* Tue May 27 2014 Kalev Lember - 212-6 +- Rebuilt for https://fedoraproject.org/wiki/Changes/Python_3.4 + +* Fri May 23 2014 Adam Williamson - 212-5 +- revert change from 212-4, causes boot fail on single CPU boxes (RHBZ 1095891) + +* Wed May 07 2014 Kay Sievers - 212-4 +- add netns udev workaround + +* Wed May 07 2014 Michal Sekletar - 212-3 +- enable uuidd.socket by default (#1095353) + +* Sat Apr 26 2014 Peter Robinson 212-2 +- Disable building with -flto for the moment due to gcc 4.9 issues (RHBZ 1091611) + +* Tue Mar 25 2014 Lennart Poettering - 212-1 +- New upstream release + +* Mon Mar 17 2014 Peter Robinson 211-2 +- Explicitly define which upstream platforms support libseccomp + +* Tue Mar 11 2014 Lennart Poettering - 211-1 +- New upstream release + +* Mon Mar 10 2014 Zbigniew Jędrzejewski-Szmek - 210-8 +- Fix logind unpriviledged reboot issue and a few other minor fixes +- Limit generator execution time +- Recognize buttonless joystick types + +* Fri Mar 07 2014 Karsten Hopp 210-7 +- ppc64le needs link warnings disabled, too + +* Fri Mar 07 2014 Karsten Hopp 210-6 +- move ifarch ppc64le to correct place (libseccomp req) + +* Fri Mar 07 2014 Zbigniew Jędrzejewski-Szmek - 210-5 +- Bugfixes: #1047568, #1047039, #1071128, #1073402 +- Bash completions for more systemd tools +- Bluetooth database update +- Manpage fixes + +* Thu Mar 06 2014 Zbigniew Jędrzejewski-Szmek - 210-4 +- Apply work-around for ppc64le too (#1073647). + +* Sat Mar 01 2014 Zbigniew Jędrzejewski-Szmek - 210-3 +- Backport a few patches, add completion for systemd-nspawn. + +* Fri Feb 28 2014 Zbigniew Jędrzejewski-Szmek - 210-3 +- Apply work-arounds for ppc/ppc64 for bugs 1071278 and 1071284 + +* Mon Feb 24 2014 Lennart Poettering - 210-2 +- Check more services against preset list and enable by default + +* Mon Feb 24 2014 Lennart Poettering - 210-1 +- new upstream release + +* Sun Feb 23 2014 Zbigniew Jędrzejewski-Szmek - 209-2.gitf01de96 +- Enable dnssec-triggerd.service by default (#1060754) + +* Sun Feb 23 2014 Kay Sievers - 209-2.gitf01de96 +- git snapshot to sort out ARM build issues + +* Thu Feb 20 2014 Lennart Poettering - 209-1 +- new upstream release + +* Tue Feb 18 2014 Zbigniew Jędrzejewski-Szmek - 208-15 +- Make gpsd lazily activated (#1066421) + +* Mon Feb 17 2014 Zbigniew Jędrzejewski-Szmek - 208-14 +- Back out patch which causes user manager to be destroyed when unneeded + and spams logs (#1053315) + +* Sun Feb 16 2014 Zbigniew Jędrzejewski-Szmek - 208-13 +- A different fix for #1023820 taken from Mageia +- Backported fix for #997031 +- Hardward database updates, man pages improvements, a few small memory + leaks, utf-8 correctness and completion fixes +- Support for key-slot option in crypttab + +* Sat Jan 25 2014 Ville Skyttä - 208-12 +- Own the %%{_prefix}/lib/kernel(/*) and %%{_datadir}/zsh(/*) dirs. + +* Tue Dec 03 2013 Zbigniew Jędrzejewski-Szmek - 208-11 +- Backport a few fixes, relevant documentation updates, and HWDB changes + (#1051797, #1051768, #1047335, #1047304, #1047186, #1045849, #1043304, + #1043212, #1039351, #1031325, #1023820, #1017509, #953077) +- Flip journalctl to --full by default (#984758) + +* Tue Dec 03 2013 Zbigniew Jędrzejewski-Szmek - 208-9 +- Apply two patches for #1026860 + +* Tue Dec 03 2013 Zbigniew Jędrzejewski-Szmek - 208-8 +- Bump release to stay ahead of f20 + +* Tue Dec 03 2013 Zbigniew Jędrzejewski-Szmek - 208-7 +- Backport patches (#1023041, #1036845, #1006386?) +- HWDB update +- Some small new features: nspawn --drop-capability=, running PID 1 under + valgrind, "yearly" and "annually" in calendar specifications +- Some small documentation and logging updates + +* Tue Nov 19 2013 Zbigniew Jędrzejewski-Szmek - 208-6 +- Bump release to stay ahead of f20 + +* Tue Nov 19 2013 Zbigniew Jędrzejewski-Szmek - 208-5 +- Use unit name in PrivateTmp= directories (#957439) +- Update manual pages, completion scripts, and hardware database +- Configurable Timeouts/Restarts default values +- Support printing of timestamps on the console +- Fix some corner cases in detecting when writing to the console is safe +- Python API: convert keyword values to string, fix sd_is_booted() wrapper +- Do not tread missing /sbin/fsck.btrfs as an error (#1015467) +- Allow masking of fsck units +- Advertise hibernation to swap files +- Fix SO_REUSEPORT settings +- Prefer converted xkb keymaps to legacy keymaps (#981805, #1026872) +- Make use of newer kmod +- Assorted bugfixes: #1017161, #967521, #988883, #1027478, #821723, #1014303 + +* Tue Oct 22 2013 Zbigniew Jędrzejewski-Szmek - 208-4 +- Add temporary fix for #1002806 + +* Mon Oct 21 2013 Zbigniew Jędrzejewski-Szmek - 208-3 +- Backport a bunch of fixes and hwdb updates + +* Wed Oct 2 2013 Lennart Poettering - 208-2 +- Move old random seed and backlight files into the right place + +* Wed Oct 2 2013 Lennart Poettering - 208-1 +- New upstream release + +* Thu Sep 26 2013 Zbigniew Jędrzejewski-Szmek 207-5 +- Do not create /var/var/... dirs + +* Wed Sep 18 2013 Zbigniew Jędrzejewski-Szmek 207-4 +- Fix policykit authentication +- Resolves: rhbz#1006680 + +* Tue Sep 17 2013 Harald Hoyer 207-3 +- fixed login +- Resolves: rhbz#1005233 + +* Mon Sep 16 2013 Harald Hoyer 207-2 +- add some upstream fixes for 207 +- fixed swap activation +- Resolves: rhbz#1008604 + +* Fri Sep 13 2013 Lennart Poettering - 207-1 +- New upstream release + +* Fri Sep 06 2013 Harald Hoyer 206-11 +- support "debug" kernel command line parameter +- journald: fix fd leak in journal_file_empty +- journald: fix vacuuming of archived journals +- libudev: enumerate - do not try to match against an empty subsystem +- cgtop: fixup the online help +- libudev: fix memleak when enumerating childs + +* Wed Sep 04 2013 Harald Hoyer 206-10 +- Do not require grubby, lorax now takes care of grubby +- cherry-picked a lot of patches from upstream + +* Tue Aug 27 2013 Dennis Gilmore - 206-9 +- Require grubby, Fedora installs require grubby, +- kernel-install took over from new-kernel-pkg +- without the Requires we are unable to compose Fedora +- everyone else says that since kernel-install took over +- it is responsible for ensuring that grubby is in place +- this is really what we want for Fedora + +* Tue Aug 27 2013 Kay Sievers - 206-8 +- Revert "Require grubby its needed by kernel-install" + +* Mon Aug 26 2013 Dennis Gilmore 206-7 +- Require grubby its needed by kernel-install + +* Thu Aug 22 2013 Harald Hoyer 206-6 +- kernel-install now understands kernel flavors like PAE + +* Tue Aug 20 2013 Rex Dieter - 206-5 +- add sddm.service to preset file (#998978) + +* Fri Aug 16 2013 Zbigniew Jędrzejewski-Szmek - 206-4 +- Filter out provides for private python modules. +- Add requires on kmod >= 14 (#990994). + +* Sun Aug 11 2013 Zbigniew Jedrzejewski-Szmek - 206-3 +- New systemd-python3 package (#976427). +- Add ownership of a few directories that we create (#894202). + +* Sun Aug 04 2013 Fedora Release Engineering - 206-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 23 2013 Kay Sievers - 206-1 +- New upstream release + Resolves (#984152) + +* Wed Jul 3 2013 Lennart Poettering - 205-1 +- New upstream release + +* Wed Jun 26 2013 Michal Schmidt 204-10 +- Split systemd-journal-gateway subpackage (#908081). + +* Mon Jun 24 2013 Michal Schmidt 204-9 +- Rename nm_dispatcher to NetworkManager-dispatcher in default preset (#977433) + +* Fri Jun 14 2013 Harald Hoyer 204-8 +- fix, which helps to sucessfully browse journals with + duplicated seqnums + +* Fri Jun 14 2013 Harald Hoyer 204-7 +- fix duplicate message ID bug +Resolves: rhbz#974132 + +* Thu Jun 06 2013 Harald Hoyer 204-6 +- introduce 99-default-disable.preset + +* Thu Jun 6 2013 Lennart Poettering - 204-5 +- Rename 90-display-manager.preset to 85-display-manager.preset so that it actually takes precedence over 90-default.preset's "disable *" line (#903690) + +* Tue May 28 2013 Harald Hoyer 204-4 +- Fix kernel-install (#965897) + +* Wed May 22 2013 Kay Sievers - 204-3 +- Fix kernel-install (#965897) + +* Thu May 9 2013 Lennart Poettering - 204-2 +- New upstream release +- disable isdn by default (#959793) + +* Tue May 07 2013 Harald Hoyer 203-2 +- forward port kernel-install-grubby.patch + +* Tue May 7 2013 Lennart Poettering - 203-1 +- New upstream release + +* Wed Apr 24 2013 Harald Hoyer 202-3 +- fix ENOENT for getaddrinfo +- Resolves: rhbz#954012 rhbz#956035 +- crypt-setup-generator: correctly check return of strdup +- logind-dbus: initialize result variable +- prevent library underlinking + +* Fri Apr 19 2013 Harald Hoyer 202-2 +- nspawn create empty /etc/resolv.conf if necessary +- python wrapper: add sd_journal_add_conjunction() +- fix s390 booting +- Resolves: rhbz#953217 + +* Thu Apr 18 2013 Lennart Poettering - 202-1 +- New upstream release + +* Tue Apr 09 2013 Michal Schmidt - 201-2 +- Automatically discover whether to run autoreconf and add autotools and git + BuildRequires based on the presence of patches to be applied. +- Use find -delete. + +* Mon Apr 8 2013 Lennart Poettering - 201-1 +- New upstream release + +* Mon Apr 8 2013 Lennart Poettering - 200-4 +- Update preset file + +* Fri Mar 29 2013 Lennart Poettering - 200-3 +- Remove NetworkManager-wait-online.service from presets file again, it should default to off + +* Fri Mar 29 2013 Lennart Poettering - 200-2 +- New upstream release + +* Tue Mar 26 2013 Lennart Poettering - 199-2 +- Add NetworkManager-wait-online.service to the presets file + +* Tue Mar 26 2013 Lennart Poettering - 199-1 +- New upstream release + +* Mon Mar 18 2013 Michal Schmidt 198-7 +- Drop /usr/s?bin/ prefixes. + +* Fri Mar 15 2013 Harald Hoyer 198-6 +- run autogen to pickup all changes + +* Fri Mar 15 2013 Harald Hoyer 198-5 +- do not mount anything, when not running as pid 1 +- add initrd.target for systemd in the initrd + +* Wed Mar 13 2013 Harald Hoyer 198-4 +- fix switch-root and local-fs.target problem +- patch kernel-install to use grubby, if available + +* Fri Mar 08 2013 Harald Hoyer 198-3 +- add Conflict with dracut < 026 because of the new switch-root isolate + +* Thu Mar 7 2013 Lennart Poettering - 198-2 +- Create required users + +* Thu Mar 7 2013 Lennart Poettering - 198-1 +- New release +- Enable journal persistancy by default + +* Sun Feb 10 2013 Peter Robinson 197-3 +- Bump for ARM + +* Fri Jan 18 2013 Michal Schmidt - 197-2 +- Added qemu-guest-agent.service to presets (Lennart, #885406). +- Add missing pygobject3-base to systemd-analyze deps (Lennart). +- Do not require hwdata, it is all in the hwdb now (Kay). +- Drop dependency on dbus-python. + +* Tue Jan 8 2013 Lennart Poettering - 197-1 +- New upstream release + +* Mon Dec 10 2012 Michal Schmidt - 196-4 +- Enable rngd.service by default (#857765). + +* Mon Dec 10 2012 Michal Schmidt - 196-3 +- Disable hardening on s390(x) because PIE is broken there and produces + text relocations with __thread (#868839). + +* Wed Dec 05 2012 Michal Schmidt - 196-2 +- added spice-vdagentd.service to presets (Lennart, #876237) +- BR cryptsetup-devel instead of the legacy cryptsetup-luks-devel provide name + (requested by Milan Brož). +- verbose make to see the actual build flags + +* Wed Nov 21 2012 Lennart Poettering - 196-1 +- New upstream release + +* Tue Nov 20 2012 Lennart Poettering - 195-8 +- https://bugzilla.redhat.com/show_bug.cgi?id=873459 +- https://bugzilla.redhat.com/show_bug.cgi?id=878093 + +* Thu Nov 15 2012 Michal Schmidt - 195-7 +- Revert udev killing cgroup patch for F18 Beta. +- https://bugzilla.redhat.com/show_bug.cgi?id=873576 + +* Fri Nov 09 2012 Michal Schmidt - 195-6 +- Fix cyclical dep between systemd and systemd-libs. +- Avoid broken build of test-journal-syslog. +- https://bugzilla.redhat.com/show_bug.cgi?id=873387 +- https://bugzilla.redhat.com/show_bug.cgi?id=872638 + +* Thu Oct 25 2012 Kay Sievers - 195-5 +- require 'sed', limit HOSTNAME= match + +* Wed Oct 24 2012 Michal Schmidt - 195-4 +- add dmraid-activation.service to the default preset +- add yum protected.d fragment +- https://bugzilla.redhat.com/show_bug.cgi?id=869619 +- https://bugzilla.redhat.com/show_bug.cgi?id=869717 + +* Wed Oct 24 2012 Kay Sievers - 195-3 +- Migrate /etc/sysconfig/ i18n, keyboard, network files/variables to + systemd native files + +* Tue Oct 23 2012 Lennart Poettering - 195-2 +- Provide syslog because the journal is fine as a syslog implementation + +* Tue Oct 23 2012 Lennart Poettering - 195-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=831665 +- https://bugzilla.redhat.com/show_bug.cgi?id=847720 +- https://bugzilla.redhat.com/show_bug.cgi?id=858693 +- https://bugzilla.redhat.com/show_bug.cgi?id=863481 +- https://bugzilla.redhat.com/show_bug.cgi?id=864629 +- https://bugzilla.redhat.com/show_bug.cgi?id=864672 +- https://bugzilla.redhat.com/show_bug.cgi?id=864674 +- https://bugzilla.redhat.com/show_bug.cgi?id=865128 +- https://bugzilla.redhat.com/show_bug.cgi?id=866346 +- https://bugzilla.redhat.com/show_bug.cgi?id=867407 +- https://bugzilla.redhat.com/show_bug.cgi?id=868603 + +* Wed Oct 10 2012 Michal Schmidt - 194-2 +- Add scriptlets for migration away from systemd-timedated-ntp.target + +* Wed Oct 3 2012 Lennart Poettering - 194-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=859614 +- https://bugzilla.redhat.com/show_bug.cgi?id=859655 + +* Fri Sep 28 2012 Lennart Poettering - 193-1 +- New upstream release + +* Tue Sep 25 2012 Lennart Poettering - 192-1 +- New upstream release + +* Fri Sep 21 2012 Lennart Poettering - 191-2 +- Fix journal mmap header prototype definition to fix compilation on 32bit + +* Fri Sep 21 2012 Lennart Poettering - 191-1 +- New upstream release +- Enable all display managers by default, as discussed with Adam Williamson + +* Thu Sep 20 2012 Lennart Poettering - 190-1 +- New upstream release +- Take possession of /etc/localtime, and remove /etc/sysconfig/clock +- https://bugzilla.redhat.com/show_bug.cgi?id=858780 +- https://bugzilla.redhat.com/show_bug.cgi?id=858787 +- https://bugzilla.redhat.com/show_bug.cgi?id=858771 +- https://bugzilla.redhat.com/show_bug.cgi?id=858754 +- https://bugzilla.redhat.com/show_bug.cgi?id=858746 +- https://bugzilla.redhat.com/show_bug.cgi?id=858266 +- https://bugzilla.redhat.com/show_bug.cgi?id=858224 +- https://bugzilla.redhat.com/show_bug.cgi?id=857670 +- https://bugzilla.redhat.com/show_bug.cgi?id=856975 +- https://bugzilla.redhat.com/show_bug.cgi?id=855863 +- https://bugzilla.redhat.com/show_bug.cgi?id=851970 +- https://bugzilla.redhat.com/show_bug.cgi?id=851275 +- https://bugzilla.redhat.com/show_bug.cgi?id=851131 +- https://bugzilla.redhat.com/show_bug.cgi?id=847472 +- https://bugzilla.redhat.com/show_bug.cgi?id=847207 +- https://bugzilla.redhat.com/show_bug.cgi?id=846483 +- https://bugzilla.redhat.com/show_bug.cgi?id=846085 +- https://bugzilla.redhat.com/show_bug.cgi?id=845973 +- https://bugzilla.redhat.com/show_bug.cgi?id=845194 +- https://bugzilla.redhat.com/show_bug.cgi?id=845028 +- https://bugzilla.redhat.com/show_bug.cgi?id=844630 +- https://bugzilla.redhat.com/show_bug.cgi?id=839736 +- https://bugzilla.redhat.com/show_bug.cgi?id=835848 +- https://bugzilla.redhat.com/show_bug.cgi?id=831740 +- https://bugzilla.redhat.com/show_bug.cgi?id=823485 +- https://bugzilla.redhat.com/show_bug.cgi?id=821813 +- https://bugzilla.redhat.com/show_bug.cgi?id=807886 +- https://bugzilla.redhat.com/show_bug.cgi?id=802198 +- https://bugzilla.redhat.com/show_bug.cgi?id=767795 +- https://bugzilla.redhat.com/show_bug.cgi?id=767561 +- https://bugzilla.redhat.com/show_bug.cgi?id=752774 +- https://bugzilla.redhat.com/show_bug.cgi?id=732874 +- https://bugzilla.redhat.com/show_bug.cgi?id=858735 + +* Thu Sep 13 2012 Lennart Poettering - 189-4 +- Don't pull in pkg-config as dep +- https://bugzilla.redhat.com/show_bug.cgi?id=852828 + +* Wed Sep 12 2012 Lennart Poettering - 189-3 +- Update preset policy +- Rename preset policy file from 99-default.preset to 90-default.preset so that people can order their own stuff after the Fedora default policy if they wish + +* Thu Aug 23 2012 Lennart Poettering - 189-2 +- Update preset policy +- https://bugzilla.redhat.com/show_bug.cgi?id=850814 + +* Thu Aug 23 2012 Lennart Poettering - 189-1 +- New upstream release + +* Thu Aug 16 2012 Ray Strode 188-4 +- more scriptlet fixes + (move dm migration logic to %%posttrans so the service + files it's looking for are available at the time + the logic is run) + +* Sat Aug 11 2012 Lennart Poettering - 188-3 +- Remount file systems MS_PRIVATE before switching roots +- https://bugzilla.redhat.com/show_bug.cgi?id=847418 + +* Wed Aug 08 2012 Rex Dieter - 188-2 +- fix scriptlets + +* Wed Aug 8 2012 Lennart Poettering - 188-1 +- New upstream release +- Enable gdm and avahi by default via the preset file +- Convert /etc/sysconfig/desktop to display-manager.service symlink +- Enable hardened build + +* Mon Jul 30 2012 Kay Sievers - 187-3 +- Obsolete: system-setup-keyboard + +* Wed Jul 25 2012 Kalev Lember - 187-2 +- Run ldconfig for the new -libs subpackage + +* Thu Jul 19 2012 Lennart Poettering - 187-1 +- New upstream release + +* Mon Jul 09 2012 Harald Hoyer 186-2 +- fixed dracut conflict version + +* Tue Jul 3 2012 Lennart Poettering - 186-1 +- New upstream release + +* Fri Jun 22 2012 Nils Philippsen - 185-7.gite7aee75 +- add obsoletes/conflicts so multilib systemd -> systemd-libs updates work + +* Thu Jun 14 2012 Michal Schmidt - 185-6.gite7aee75 +- Update to current git + +* Wed Jun 06 2012 Kay Sievers - 185-5.gita2368a3 +- disable plymouth in configure, to drop the .wants/ symlinks + +* Wed Jun 06 2012 Michal Schmidt - 185-4.gita2368a3 +- Update to current git snapshot + - Add systemd-readahead-analyze + - Drop upstream patch +- Split systemd-libs +- Drop duplicate doc files +- Fixed License headers of subpackages + +* Wed Jun 06 2012 Ray Strode - 185-3 +- Drop plymouth files +- Conflict with old plymouth + +* Tue Jun 05 2012 Kay Sievers - 185-2 +- selinux udev labeling fix +- conflict with older dracut versions for new udev file names + +* Mon Jun 04 2012 Kay Sievers - 185-1 +- New upstream release + - udev selinux labeling fixes + - new man pages + - systemctl help + +* Thu May 31 2012 Lennart Poettering - 184-1 +- New upstream release + +* Thu May 24 2012 Kay Sievers - 183-1 +- New upstream release including udev merge. + +* Wed Mar 28 2012 Michal Schmidt - 44-4 +- Add triggers from Bill Nottingham to correct the damage done by + the obsoleted systemd-units's preun scriptlet (#807457). + +* Mon Mar 26 2012 Dennis Gilmore - 44-3 +- apply patch from upstream so we can build systemd on arm and ppc +- and likely the rest of the secondary arches + +* Tue Mar 20 2012 Michal Schmidt - 44-2 +- Don't build the gtk parts anymore. They're moving into systemd-ui. +- Remove a dead patch file. + +* Fri Mar 16 2012 Lennart Poettering - 44-1 +- New upstream release +- Closes #798760, #784921, #783134, #768523, #781735 + +* Mon Feb 27 2012 Dennis Gilmore - 43-2 +- don't conflict with fedora-release systemd never actually provided +- /etc/os-release so there is no actual conflict + +* Wed Feb 15 2012 Lennart Poettering - 43-1 +- New upstream release +- Closes #789758, #790260, #790522 + +* Sat Feb 11 2012 Lennart Poettering - 42-1 +- New upstream release +- Save a bit of entropy during system installation (#789407) +- Don't own /etc/os-release anymore, leave that to fedora-release + +* Thu Feb 9 2012 Adam Williamson - 41-2 +- rebuild for fixed binutils + +* Thu Feb 9 2012 Lennart Poettering - 41-1 +- New upstream release + +* Tue Feb 7 2012 Lennart Poettering - 40-1 +- New upstream release + +* Thu Jan 26 2012 Kay Sievers - 39-3 +- provide /sbin/shutdown + +* Wed Jan 25 2012 Harald Hoyer 39-2 +- increment release + +* Wed Jan 25 2012 Kay Sievers - 39-1.1 +- install everything in /usr + https://fedoraproject.org/wiki/Features/UsrMove + +* Wed Jan 25 2012 Lennart Poettering - 39-1 +- New upstream release + +* Sun Jan 22 2012 Michal Schmidt - 38-6.git9fa2f41 +- Update to a current git snapshot. +- Resolves: #781657 + +* Sun Jan 22 2012 Michal Schmidt - 38-5 +- Build against libgee06. Reenable gtk tools. +- Delete unused patches. +- Add easy building of git snapshots. +- Remove legacy spec file elements. +- Don't mention implicit BuildRequires. +- Configure with --disable-static. +- Merge -units into the main package. +- Move section 3 manpages to -devel. +- Fix unowned directory. +- Run ldconfig in scriptlets. +- Split systemd-analyze to a subpackage. + +* Sat Jan 21 2012 Dan Horák - 38-4 +- fix build on big-endians + +* Wed Jan 11 2012 Lennart Poettering - 38-3 +- Disable building of gtk tools for now + +* Wed Jan 11 2012 Lennart Poettering - 38-2 +- Fix a few (build) dependencies + +* Wed Jan 11 2012 Lennart Poettering - 38-1 +- New upstream release + +* Tue Nov 15 2011 Michal Schmidt - 37-4 +- Run authconfig if /etc/pam.d/system-auth is not a symlink. +- Resolves: #753160 + +* Wed Nov 02 2011 Michal Schmidt - 37-3 +- Fix remote-fs-pre.target and its ordering. +- Resolves: #749940 + +* Wed Oct 19 2011 Michal Schmidt - 37-2 +- A couple of fixes from upstream: +- Fix a regression in bash-completion reported in Bodhi. +- Fix a crash in isolating. +- Resolves: #717325 + +* Tue Oct 11 2011 Lennart Poettering - 37-1 +- New upstream release +- Resolves: #744726, #718464, #713567, #713707, #736756 + +* Thu Sep 29 2011 Michal Schmidt - 36-5 +- Undo the workaround. Kay says it does not belong in systemd. +- Unresolves: #741655 + +* Thu Sep 29 2011 Michal Schmidt - 36-4 +- Workaround for the crypto-on-lvm-on-crypto disk layout +- Resolves: #741655 + +* Sun Sep 25 2011 Michal Schmidt - 36-3 +- Revert an upstream patch that caused ordering cycles +- Resolves: #741078 + +* Fri Sep 23 2011 Lennart Poettering - 36-2 +- Add /etc/timezone to ghosted files + +* Fri Sep 23 2011 Lennart Poettering - 36-1 +- New upstream release +- Resolves: #735013, #736360, #737047, #737509, #710487, #713384 + +* Thu Sep 1 2011 Lennart Poettering - 35-1 +- New upstream release +- Update post scripts +- Resolves: #726683, #713384, #698198, #722803, #727315, #729997, #733706, #734611 + +* Thu Aug 25 2011 Lennart Poettering - 34-1 +- New upstream release + +* Fri Aug 19 2011 Harald Hoyer 33-2 +- fix ABRT on service file reloading +- Resolves: rhbz#732020 + +* Wed Aug 3 2011 Lennart Poettering - 33-1 +- New upstream release + +* Fri Jul 29 2011 Lennart Poettering - 32-1 +- New upstream release + +* Wed Jul 27 2011 Lennart Poettering - 31-2 +- Fix access mode of modprobe file, restart logind after upgrade + +* Wed Jul 27 2011 Lennart Poettering - 31-1 +- New upstream release + +* Wed Jul 13 2011 Lennart Poettering - 30-1 +- New upstream release + +* Thu Jun 16 2011 Lennart Poettering - 29-1 +- New upstream release + +* Mon Jun 13 2011 Michal Schmidt - 28-4 +- Apply patches from current upstream. +- Fixes memory size detection on 32-bit with >4GB RAM (BZ712341) + +* Wed Jun 08 2011 Michal Schmidt - 28-3 +- Apply patches from current upstream +- https://bugzilla.redhat.com/show_bug.cgi?id=709909 +- https://bugzilla.redhat.com/show_bug.cgi?id=710839 +- https://bugzilla.redhat.com/show_bug.cgi?id=711015 + +* Sat May 28 2011 Lennart Poettering - 28-2 +- Pull in nss-myhostname + +* Thu May 26 2011 Lennart Poettering - 28-1 +- New upstream release + +* Wed May 25 2011 Lennart Poettering - 26-2 +- Bugfix release +- https://bugzilla.redhat.com/show_bug.cgi?id=707507 +- https://bugzilla.redhat.com/show_bug.cgi?id=707483 +- https://bugzilla.redhat.com/show_bug.cgi?id=705427 +- https://bugzilla.redhat.com/show_bug.cgi?id=707577 + +* Sat Apr 30 2011 Lennart Poettering - 26-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=699394 +- https://bugzilla.redhat.com/show_bug.cgi?id=698198 +- https://bugzilla.redhat.com/show_bug.cgi?id=698674 +- https://bugzilla.redhat.com/show_bug.cgi?id=699114 +- https://bugzilla.redhat.com/show_bug.cgi?id=699128 + +* Thu Apr 21 2011 Lennart Poettering - 25-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=694788 +- https://bugzilla.redhat.com/show_bug.cgi?id=694321 +- https://bugzilla.redhat.com/show_bug.cgi?id=690253 +- https://bugzilla.redhat.com/show_bug.cgi?id=688661 +- https://bugzilla.redhat.com/show_bug.cgi?id=682662 +- https://bugzilla.redhat.com/show_bug.cgi?id=678555 +- https://bugzilla.redhat.com/show_bug.cgi?id=628004 + +* Wed Apr 6 2011 Lennart Poettering - 24-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=694079 +- https://bugzilla.redhat.com/show_bug.cgi?id=693289 +- https://bugzilla.redhat.com/show_bug.cgi?id=693274 +- https://bugzilla.redhat.com/show_bug.cgi?id=693161 + +* Tue Apr 5 2011 Lennart Poettering - 23-1 +- New upstream release +- Include systemd-sysv-convert + +* Fri Apr 1 2011 Lennart Poettering - 22-1 +- New upstream release + +* Wed Mar 30 2011 Lennart Poettering - 21-2 +- The quota services are now pulled in by mount points, hence no need to enable them explicitly + +* Tue Mar 29 2011 Lennart Poettering - 21-1 +- New upstream release + +* Mon Mar 28 2011 Matthias Clasen - 20-2 +- Apply upstream patch to not send untranslated messages to plymouth + +* Tue Mar 8 2011 Lennart Poettering - 20-1 +- New upstream release + +* Tue Mar 1 2011 Lennart Poettering - 19-1 +- New upstream release + +* Wed Feb 16 2011 Lennart Poettering - 18-1 +- New upstream release + +* Mon Feb 14 2011 Bill Nottingham - 17-6 +- bump upstart obsoletes (#676815) + +* Wed Feb 9 2011 Tom Callaway - 17-5 +- add macros.systemd file for %%{_unitdir} + +* Wed Feb 09 2011 Fedora Release Engineering - 17-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Feb 9 2011 Lennart Poettering - 17-3 +- Fix popen() of systemctl, #674916 + +* Mon Feb 7 2011 Bill Nottingham - 17-2 +- add epoch to readahead obsolete + +* Sat Jan 22 2011 Lennart Poettering - 17-1 +- New upstream release + +* Tue Jan 18 2011 Lennart Poettering - 16-2 +- Drop console.conf again, since it is not shipped in pamtmp.conf + +* Sat Jan 8 2011 Lennart Poettering - 16-1 +- New upstream release + +* Thu Nov 25 2010 Lennart Poettering - 15-1 +- New upstream release + +* Thu Nov 25 2010 Lennart Poettering - 14-1 +- Upstream update +- Enable hwclock-load by default +- Obsolete readahead +- Enable /var/run and /var/lock on tmpfs + +* Fri Nov 19 2010 Lennart Poettering - 13-1 +- new upstream release + +* Wed Nov 17 2010 Bill Nottingham 12-3 +- Fix clash + +* Wed Nov 17 2010 Lennart Poettering - 12-2 +- Don't clash with initscripts for now, so that we don't break the builders + +* Wed Nov 17 2010 Lennart Poettering - 12-1 +- New upstream release + +* Fri Nov 12 2010 Matthias Clasen - 11-2 +- Rebuild with newer vala, libnotify + +* Thu Oct 7 2010 Lennart Poettering - 11-1 +- New upstream release + +* Wed Sep 29 2010 Jesse Keating - 10-6 +- Rebuilt for gcc bug 634757 + +* Thu Sep 23 2010 Bill Nottingham - 10-5 +- merge -sysvinit into main package + +* Mon Sep 20 2010 Bill Nottingham - 10-4 +- obsolete upstart-sysvinit too + +* Fri Sep 17 2010 Bill Nottingham - 10-3 +- Drop upstart requires + +* Tue Sep 14 2010 Lennart Poettering - 10-2 +- Enable audit +- https://bugzilla.redhat.com/show_bug.cgi?id=633771 + +* Tue Sep 14 2010 Lennart Poettering - 10-1 +- New upstream release +- https://bugzilla.redhat.com/show_bug.cgi?id=630401 +- https://bugzilla.redhat.com/show_bug.cgi?id=630225 +- https://bugzilla.redhat.com/show_bug.cgi?id=626966 +- https://bugzilla.redhat.com/show_bug.cgi?id=623456 + +* Fri Sep 3 2010 Bill Nottingham - 9-3 +- move fedora-specific units to initscripts; require newer version thereof + +* Fri Sep 3 2010 Lennart Poettering - 9-2 +- Add missing tarball + +* Fri Sep 3 2010 Lennart Poettering - 9-1 +- New upstream version +- Closes 501720, 614619, 621290, 626443, 626477, 627014, 627785, 628913 + +* Fri Aug 27 2010 Lennart Poettering - 8-3 +- Reexecute after installation, take ownership of /var/run/user +- https://bugzilla.redhat.com/show_bug.cgi?id=627457 +- https://bugzilla.redhat.com/show_bug.cgi?id=627634 + +* Thu Aug 26 2010 Lennart Poettering - 8-2 +- Properly create default.target link + +* Wed Aug 25 2010 Lennart Poettering - 8-1 +- New upstream release + +* Thu Aug 12 2010 Lennart Poettering - 7-3 +- Fix https://bugzilla.redhat.com/show_bug.cgi?id=623561 + +* Thu Aug 12 2010 Lennart Poettering - 7-2 +- Fix https://bugzilla.redhat.com/show_bug.cgi?id=623430 + +* Tue Aug 10 2010 Lennart Poettering - 7-1 +- New upstream release + +* Fri Aug 6 2010 Lennart Poettering - 6-2 +- properly hide output on package installation +- pull in coreutils during package installtion + +* Fri Aug 6 2010 Lennart Poettering - 6-1 +- New upstream release +- Fixes #621200 + +* Wed Aug 4 2010 Lennart Poettering - 5-2 +- Add tarball + +* Wed Aug 4 2010 Lennart Poettering - 5-1 +- Prepare release 5 + +* Tue Jul 27 2010 Bill Nottingham - 4-4 +- Add 'sysvinit-userspace' provide to -sysvinit package to fix upgrade/install (#618537) + +* Sat Jul 24 2010 Lennart Poettering - 4-3 +- Add libselinux to build dependencies + +* Sat Jul 24 2010 Lennart Poettering - 4-2 +- Use the right tarball + +* Sat Jul 24 2010 Lennart Poettering - 4-1 +- New upstream release, and make default + +* Tue Jul 13 2010 Lennart Poettering - 3-3 +- Used wrong tarball + +* Tue Jul 13 2010 Lennart Poettering - 3-2 +- Own /cgroup jointly with libcgroup, since we don't dpend on it anymore + +* Tue Jul 13 2010 Lennart Poettering - 3-1 +- New upstream release + +* Fri Jul 9 2010 Lennart Poettering - 2-0 +- New upstream release + +* Wed Jul 7 2010 Lennart Poettering - 1-0 +- First upstream release + +* Tue Jun 29 2010 Lennart Poettering - 0-0.7.20100629git4176e5 +- New snapshot +- Split off -units package where other packages can depend on without pulling in the whole of systemd + +* Tue Jun 22 2010 Lennart Poettering - 0-0.6.20100622gita3723b +- Add missing libtool dependency. + +* Tue Jun 22 2010 Lennart Poettering - 0-0.5.20100622gita3723b +- Update snapshot + +* Mon Jun 14 2010 Rahul Sundaram - 0-0.4.20100614git393024 +- Pull the latest snapshot that fixes a segfault. Resolves rhbz#603231 + +* Fri Jun 11 2010 Rahul Sundaram - 0-0.3.20100610git2f198e +- More minor fixes as per review + +* Thu Jun 10 2010 Rahul Sundaram - 0-0.2.20100610git2f198e +- Spec improvements from David Hollis + +* Wed Jun 09 2010 Rahul Sundaram - 0-0.1.20090609git2f198e +- Address review comments + +* Tue Jun 01 2010 Rahul Sundaram - 0-0.0.git2010-06-02 +- Initial spec (adopted from Kay Sievers)